⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 archive.cpp

📁 著名的任天堂FC游戏机模拟器VirtuaNes 085版的源码!
💻 CPP
字号:
//
// 傾乕僇僀僽僼傽僀儖憖嶌
//
// 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"

#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傪巊梡偟偨ZIP夝搥儖乕僠儞
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側傜傑偢zlib儔僀僽儔儕偺夝搥傪巊偭偰傒傞
		if( ZlibUnZip( fname, ppBuf, lpdwSize ) ) {
//DEBUGOUT( "zlib unzip ok! [%s]\n", fname );
			return	TRUE;
		}
	}

	hDLL = NULL;
	for( INT i = 0; pszArchiver[i]; i++ ) {
		// DLL傾儞儘乕僪
		FREEDLL( hDLL );

		// DLL儘乕僪
		if( !(hDLL = LoadLibrary( pszArchiver[i] )) )
			continue;

		CHAR	szTemp[256];
		sprintf( szTemp, "%sCheckArchive", pszFuncPrefix[i] );
		CHECKARCHIVE	CheckArchive;
		if( !(CheckArchive = (CHECKARCHIVE)GetProcAddress( hDLL, szTemp )) )
			continue;
		// 懳墳偡傞傾乕僇僀僽偐僠僃僢僋偡傞
		if( !CheckArchive( fname, 1 ) )
			continue;

		// 傾乕僇僀僽撪偵懳墳偡傞僼傽僀儖偑偁傞偐偺僠僃僢僋
		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 {			// 堎忢廔椆
				break;
			}
		}
		if( !bFound )
			continue;

		if( !pszCommand[i] ) {
		// 儊儌儕夝搥偁傝(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;

				// 惓婯昞尰傪愗傞僆僾僔儑儞偑梸偟偐偭偨....
				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 {
		// 儊儌儕夝搥偑柍偄応崌
			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" )) ) {
				// 僼傽僀儖僒僀僘庢摼
				fseek( fp, 0, SEEK_END );
				*lpdwSize = ftell( fp );
				fseek( fp, 0, SEEK_SET );
				if( *lpdwSize < 17 ) {
					// 僼傽僀儖僒僀僘偑彫偝偡偓傑偡
					throw	CApp::GetErrorString( IDS_ERROR_SMALLFILE );
				}

				// 僥儞億儔儕儊儌儕妋曐
				if( !(*ppBuf = (LPBYTE)malloc( *lpdwSize )) ) {
					FCLOSE( fp );
					// 儊儌儕傪妋曐弌棃傑偣傫
					throw	CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
				}
				// 僒僀僘暘撉傒崬傒
				if( fread( *ppBuf, *lpdwSize, 1, fp ) != 1 ) {
					FCLOSE( fp );
					FREE( *ppBuf );
					// 僼傽僀儖偺撉傒崬傒偵幐攕偟傑偟偨
					throw	CApp::GetErrorString( IDS_ERROR_READ );
				}
				FCLOSE( fp );
				DeleteFile( FileName.c_str() );
			} else {
				// xxx 僼傽僀儖傪奐偗傑偣傫
				LPCSTR	szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
				sprintf( szErrorString, szErrStr, fname );
				throw	szErrorString;
			}
			return	TRUE;
		}
	}
	FREEDLL( hDLL );

	return	FALSE;
}
// Archive

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -