333 lines
7.7 KiB
C++
333 lines
7.7 KiB
C++
|
//
|
|||
|
// <20>A<EFBFBD>[<5B>J<EFBFBD>C<EFBFBD>u<EFBFBD>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//
|
|||
|
// Original:NesterJ arc.cpp arc.h by Mikami Kana
|
|||
|
// Original:NNNesterJ ulunzip.cpp
|
|||
|
//
|
|||
|
// Zlib use!
|
|||
|
// Reprogrammed by Norix
|
|||
|
//
|
|||
|
#define WIN32_LEAN_AND_MEAN
|
|||
|
#include <windows.h>
|
|||
|
#include <shlwapi.h>
|
|||
|
|
|||
|
#include <stdio.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <string.h>
|
|||
|
#include <mbstring.h>
|
|||
|
#include <time.h>
|
|||
|
|
|||
|
#include "typedef.h"
|
|||
|
#include "macro.h"
|
|||
|
#include "DebugOut.h"
|
|||
|
|
|||
|
#include "App.h"
|
|||
|
#include "Pathlib.h"
|
|||
|
|
|||
|
#include "VirtuaNESres.h"
|
|||
|
|
|||
|
#define UNZ_BUFSIZE (65536)
|
|||
|
|
|||
|
#include "unzip.h"
|
|||
|
|
|||
|
#ifdef __cplusplus
|
|||
|
extern "C" {
|
|||
|
#endif
|
|||
|
int SevenZipUnCompress( char *fname, unsigned char ** ppBuf,size_t * lpdwSize);
|
|||
|
#ifdef __cplusplus
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
#pragma pack(1)
|
|||
|
#define FNAME_MAX32 512
|
|||
|
|
|||
|
typedef struct {
|
|||
|
DWORD dwOriginalSize;
|
|||
|
DWORD dwCompressedSize;
|
|||
|
DWORD dwCRC;
|
|||
|
UINT uFlag;
|
|||
|
UINT uOSType;
|
|||
|
WORD wRatio;
|
|||
|
WORD wDate;
|
|||
|
WORD wTime;
|
|||
|
char szFileName[FNAME_MAX32 + 1];
|
|||
|
char dummy1[3];
|
|||
|
char szAttribute[8];
|
|||
|
char szMode[8];
|
|||
|
} INDIVIDUALINFO, *LPINDIVIDUALINFO;
|
|||
|
#pragma pack()
|
|||
|
|
|||
|
// Un??? use function
|
|||
|
typedef int(WINAPI *EXECUTECOMMAND)(HWND,LPCSTR,LPSTR,const DWORD);
|
|||
|
typedef BOOL(WINAPI *CHECKARCHIVE)(LPCSTR,const int);
|
|||
|
typedef int(WINAPI *EXTRACTMEM)(HWND,LPCSTR,LPBYTE,const DWORD,time_t,LPWORD,LPDWORD);
|
|||
|
typedef HGLOBAL(WINAPI *OPENARCHIVE)(HWND,LPCSTR,const DWORD);
|
|||
|
typedef int(WINAPI *CLOSEARCHIVE)(HGLOBAL);
|
|||
|
typedef int(WINAPI *FINDFIRST)(HGLOBAL,LPCSTR,INDIVIDUALINFO*);
|
|||
|
|
|||
|
static LPCSTR pszArchiver[] = {
|
|||
|
"UNLHA32",
|
|||
|
"UNZIP32",
|
|||
|
"UNRAR32",
|
|||
|
"CAB32",
|
|||
|
NULL
|
|||
|
};
|
|||
|
|
|||
|
static LPCSTR pszFuncPrefix[] = {
|
|||
|
"Unlha",
|
|||
|
"UnZip",
|
|||
|
"Unrar",
|
|||
|
"Cab",
|
|||
|
};
|
|||
|
|
|||
|
static LPCSTR pszCommand[] = {
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
"-e -u \"%s\" \"%s\" \"%s\"",
|
|||
|
"-x -j \"%s\" \"%s\" \"%s\"",
|
|||
|
};
|
|||
|
|
|||
|
static LPCSTR pszExtension[] = {
|
|||
|
"*.nes",
|
|||
|
"*.fds",
|
|||
|
"*.nsf",
|
|||
|
NULL
|
|||
|
};
|
|||
|
|
|||
|
static BOOL bFileMatching[] = {
|
|||
|
FALSE,
|
|||
|
TRUE,
|
|||
|
FALSE,
|
|||
|
FALSE,
|
|||
|
};
|
|||
|
|
|||
|
#define FREEDLL(h) if( h ) { FreeLibrary(h);h=NULL; }
|
|||
|
|
|||
|
#define M_ERROR_MESSAGE_OFF 0x00800000L
|
|||
|
|
|||
|
// zlib<69><62><EFBFBD>g<EFBFBD>p<EFBFBD><70><EFBFBD><EFBFBD>ZIP<49>𓀃<EFBFBD><F0938083>[<5B>`<60><>
|
|||
|
BOOL ZlibUnZip( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize )
|
|||
|
{
|
|||
|
unzFile unzipFile = NULL;
|
|||
|
unz_global_info unzipGlobalInfo;
|
|||
|
unz_file_info unzipFileInfo;
|
|||
|
char fname_buf[256];
|
|||
|
|
|||
|
*ppBuf = NULL;
|
|||
|
*lpdwSize = 0;
|
|||
|
|
|||
|
if( !(unzipFile = unzOpen( (const char*)fname )) )
|
|||
|
return FALSE;
|
|||
|
|
|||
|
if( unzGetGlobalInfo( unzipFile, &unzipGlobalInfo ) != UNZ_OK ) {
|
|||
|
unzClose( unzipFile );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
for( uLong i = 0; i < unzipGlobalInfo.number_entry; i++ ) {
|
|||
|
if( unzGetCurrentFileInfo( unzipFile, &unzipFileInfo, fname_buf, sizeof(fname_buf), NULL, 0, NULL, 0 ) != UNZ_OK )
|
|||
|
break;
|
|||
|
|
|||
|
char* pExt = ::PathFindExtension( fname_buf );
|
|||
|
if( _stricmp( pExt, ".nes" ) == 0 || _stricmp( pExt, ".fds" ) == 0 || _stricmp( pExt, ".nsf" ) == 0 ) {
|
|||
|
if( unzipFileInfo.uncompressed_size ) {
|
|||
|
if( unzOpenCurrentFile( unzipFile ) != UNZ_OK )
|
|||
|
break;
|
|||
|
|
|||
|
if( unzipFileInfo.uncompressed_size > 0 ) {
|
|||
|
if( !(*ppBuf = (LPBYTE)::malloc( unzipFileInfo.uncompressed_size )) )
|
|||
|
break;
|
|||
|
|
|||
|
uInt size = unzReadCurrentFile( unzipFile, *ppBuf, unzipFileInfo.uncompressed_size );
|
|||
|
if( size != unzipFileInfo.uncompressed_size )
|
|||
|
break;
|
|||
|
}
|
|||
|
*lpdwSize = unzipFileInfo.uncompressed_size;
|
|||
|
|
|||
|
if( unzCloseCurrentFile( unzipFile ) != UNZ_OK )
|
|||
|
break;
|
|||
|
unzClose( unzipFile );
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Next file
|
|||
|
if( (i+1) < unzipGlobalInfo.number_entry ) {
|
|||
|
if( unzGoToNextFile( unzipFile ) != UNZ_OK ) {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
FREE( *ppBuf );
|
|||
|
|
|||
|
if( unzipFile ) {
|
|||
|
unzCloseCurrentFile( unzipFile );
|
|||
|
unzClose( unzipFile );
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL UnCompress( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize )
|
|||
|
{
|
|||
|
HMODULE hDLL;
|
|||
|
INDIVIDUALINFO idvinfo;
|
|||
|
|
|||
|
char* pExt = ::PathFindExtension( fname );
|
|||
|
if( _stricmp( pExt, ".zip" ) == 0 ) {
|
|||
|
// ZIP<49>Ȃ<EFBFBD><C882>܂<EFBFBD>zlib<69><62><EFBFBD>C<EFBFBD>u<EFBFBD><75><EFBFBD><EFBFBD><EFBFBD>̉𓀂<CC89><F0938082>g<EFBFBD><67><EFBFBD>Ă݂<C482>
|
|||
|
if( ZlibUnZip( fname, ppBuf, lpdwSize ) ) {
|
|||
|
// DEBUGOUT( "zlib unzip ok! [%s]\n", fname );
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
} else if( _stricmp( pExt, ".7z" ) == 0 ) {
|
|||
|
return SevenZipUnCompress((char*)fname, ppBuf, (size_t*)lpdwSize);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
hDLL = NULL;
|
|||
|
for( INT i = 0; pszArchiver[i]; i++ ) {
|
|||
|
// DLL<4C>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>[<5B>h
|
|||
|
FREEDLL( hDLL );
|
|||
|
|
|||
|
// DLL<4C><4C><EFBFBD>[<5B>h
|
|||
|
if( !(hDLL = LoadLibrary( pszArchiver[i] )) )
|
|||
|
continue;
|
|||
|
|
|||
|
CHAR szTemp[256];
|
|||
|
sprintf( szTemp, "%sCheckArchive", pszFuncPrefix[i] );
|
|||
|
CHECKARCHIVE CheckArchive;
|
|||
|
if( !(CheckArchive = (CHECKARCHIVE)GetProcAddress( hDLL, szTemp )) )
|
|||
|
continue;
|
|||
|
// <20>Ή<EFBFBD><CE89><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>[<5B>J<EFBFBD>C<EFBFBD>u<EFBFBD><75><EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD>
|
|||
|
if( !CheckArchive( fname, 1 ) )
|
|||
|
continue;
|
|||
|
|
|||
|
// <20>A<EFBFBD>[<5B>J<EFBFBD>C<EFBFBD>u<EFBFBD><75><EFBFBD>ɑΉ<C991><CE89><EFBFBD><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>邩<EFBFBD>̃`<60>F<EFBFBD>b<EFBFBD>N
|
|||
|
OPENARCHIVE OpenArchive;
|
|||
|
CLOSEARCHIVE CloseArchive;
|
|||
|
FINDFIRST FindFirst;
|
|||
|
|
|||
|
sprintf( szTemp, "%sOpenArchive", pszFuncPrefix[i] );
|
|||
|
OpenArchive = (OPENARCHIVE)GetProcAddress( hDLL, szTemp );
|
|||
|
sprintf( szTemp, "%sFindFirst", pszFuncPrefix[i] );
|
|||
|
FindFirst = (FINDFIRST)GetProcAddress( hDLL, szTemp );
|
|||
|
sprintf( szTemp, "%sCloseArchive", pszFuncPrefix[i] );
|
|||
|
CloseArchive = (CLOSEARCHIVE)GetProcAddress( hDLL, szTemp );
|
|||
|
|
|||
|
HGLOBAL hARC;
|
|||
|
BOOL bFound = FALSE;
|
|||
|
for( INT j = 0; pszExtension[j]; j++ ) {
|
|||
|
if( !(hARC = OpenArchive( NULL, fname, M_ERROR_MESSAGE_OFF ) ) ) {
|
|||
|
CloseArchive( hARC );
|
|||
|
break;
|
|||
|
}
|
|||
|
INT ret = FindFirst( hARC, pszExtension[j], &idvinfo );
|
|||
|
CloseArchive( hARC );
|
|||
|
if( ret == 0 ) { // Found!!
|
|||
|
bFound = TRUE;
|
|||
|
break;
|
|||
|
} else if( ret == -1 ) { // Not found.
|
|||
|
} else { // <20>ُ<EFBFBD><D98F>I<EFBFBD><49>
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if( !bFound )
|
|||
|
continue;
|
|||
|
|
|||
|
if( !pszCommand[i] ) {
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𓀂<EFBFBD><F0938082><EFBFBD>(UNLHA32,UNZIP32)
|
|||
|
*lpdwSize = idvinfo.dwOriginalSize;
|
|||
|
*ppBuf = (LPBYTE)malloc( *lpdwSize );
|
|||
|
|
|||
|
CHAR szCmd [256];
|
|||
|
CHAR szFunc[256];
|
|||
|
|
|||
|
if( !bFileMatching[i] ) {
|
|||
|
sprintf( szCmd, "\"%s\" \"%s\"", fname, idvinfo.szFileName );
|
|||
|
} else {
|
|||
|
// UNZIP32 only
|
|||
|
BYTE szFile[FNAME_MAX32+1];
|
|||
|
LPBYTE lpF0, lpF1;
|
|||
|
|
|||
|
// <20><><EFBFBD>K<EFBFBD>\<5C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D882>I<EFBFBD>v<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>....
|
|||
|
lpF0 = (LPBYTE)idvinfo.szFileName;
|
|||
|
lpF1 = szFile;
|
|||
|
while( *lpF0 ) {
|
|||
|
if( *lpF0 == '[' || *lpF0 == ']' ) {
|
|||
|
*lpF1++ = '\\';
|
|||
|
}
|
|||
|
_mbsncpy( lpF1, lpF0, 1 );
|
|||
|
lpF0 = _mbsinc( lpF0 );
|
|||
|
lpF1 = _mbsinc( lpF1 );
|
|||
|
}
|
|||
|
*lpF1 = '\0';
|
|||
|
|
|||
|
sprintf( szCmd, "\"%s\" \"%s\"", fname, szFile );
|
|||
|
}
|
|||
|
sprintf( szFunc, "%sExtractMem", pszFuncPrefix[i] );
|
|||
|
|
|||
|
EXTRACTMEM ExtractMem;
|
|||
|
ExtractMem = (EXTRACTMEM)GetProcAddress( hDLL, szFunc );
|
|||
|
INT ret = ExtractMem( NULL, szCmd, (LPBYTE)(*ppBuf), *lpdwSize, NULL, NULL, NULL );
|
|||
|
FREEDLL( hDLL );
|
|||
|
if( ret == 0 )
|
|||
|
return TRUE;
|
|||
|
} else {
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𓀂<EFBFBD><F0938082><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ꍇ
|
|||
|
CHAR szCmd [256];
|
|||
|
CHAR szTempPath[_MAX_PATH];
|
|||
|
EXECUTECOMMAND ExecuteCommand;
|
|||
|
|
|||
|
GetTempPath( _MAX_PATH, szTempPath );
|
|||
|
//DEBUGOUT( "TempPath:%s\n", szTempPath );
|
|||
|
|
|||
|
sprintf( szCmd, pszCommand[i], fname, szTempPath, idvinfo.szFileName );
|
|||
|
ExecuteCommand = (EXECUTECOMMAND)GetProcAddress( hDLL, pszFuncPrefix[i] );
|
|||
|
ExecuteCommand( NULL, szCmd, NULL, 0 );
|
|||
|
FREEDLL( hDLL );
|
|||
|
|
|||
|
string FileName = CPathlib::MakePath( szTempPath, idvinfo.szFileName );
|
|||
|
|
|||
|
FILE *fp = NULL;
|
|||
|
if( (fp = fopen( FileName.c_str(), "rb" )) ) {
|
|||
|
// <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD>擾
|
|||
|
fseek( fp, 0, SEEK_END );
|
|||
|
*lpdwSize = ftell( fp );
|
|||
|
fseek( fp, 0, SEEK_SET );
|
|||
|
if( *lpdwSize < 17 ) {
|
|||
|
// <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD><59><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD>
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_SMALLFILE );
|
|||
|
}
|
|||
|
|
|||
|
// <20>e<EFBFBD><65><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD><6D>
|
|||
|
if( !(*ppBuf = (LPBYTE)malloc( *lpdwSize )) ) {
|
|||
|
FCLOSE( fp );
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>ۏo<DB8F><6F><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
// <20>T<EFBFBD>C<EFBFBD>Y<EFBFBD><59><EFBFBD>ǂݍ<C782><DD8D><EFBFBD>
|
|||
|
if( fread( *ppBuf, *lpdwSize, 1, fp ) != 1 ) {
|
|||
|
FCLOSE( fp );
|
|||
|
FREE( *ppBuf );
|
|||
|
// <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>̓ǂݍ<C782><DD8D>݂Ɏ<DD82><C98E>s<EFBFBD><73><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
|
|||
|
throw CApp::GetErrorString( IDS_ERROR_READ );
|
|||
|
}
|
|||
|
FCLOSE( fp );
|
|||
|
DeleteFile( FileName.c_str() );
|
|||
|
} else {
|
|||
|
// xxx <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD><4A><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
|
|||
|
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
|
|||
|
sprintf( szErrorString, szErrStr, fname );
|
|||
|
throw szErrorString;
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
FREEDLL( hDLL );
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
// Archive
|