File Annotation

Not logged in
c2b7a98c21 2011-02-23        kinaba: private import std.string;
c2b7a98c21 2011-02-23        kinaba: private import std.file;
c2b7a98c21 2011-02-23        kinaba: private import win32.ansi.windows;
c2b7a98c21 2011-02-23        kinaba: private import util;
c2b7a98c21 2011-02-23        kinaba: private import windll;
c2b7a98c21 2011-02-23        kinaba: private import bga_melter;
c2b7a98c21 2011-02-23        kinaba: private import qbga_gui;
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: // おきまりのDLL初期化ルーチン
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: HINSTANCE g_hinst;
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: extern(C)
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	void gc_init();
c2b7a98c21 2011-02-23        kinaba: 	void gc_term();
c2b7a98c21 2011-02-23        kinaba: 	void _minit();
c2b7a98c21 2011-02-23        kinaba: 	void _moduleCtor();
c2b7a98c21 2011-02-23        kinaba: 	void _moduleDtor();
c2b7a98c21 2011-02-23        kinaba: 	void _moduleUnitTests();
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: extern (Windows)
c2b7a98c21 2011-02-23        kinaba: BOOL DllMain( HINSTANCE inst, ULONG reason, void* reserved )
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	switch( reason )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 	case DLL_PROCESS_ATTACH:
c2b7a98c21 2011-02-23        kinaba: 		g_hinst = inst;
c2b7a98c21 2011-02-23        kinaba: 		gc_init();          // GC初期化
c2b7a98c21 2011-02-23        kinaba: 		_minit();           // モジュールリスト初期化
c2b7a98c21 2011-02-23        kinaba: 		_moduleCtor();      // モジュールコンストラクタ実行
c2b7a98c21 2011-02-23        kinaba: 		_moduleUnitTests(); // 単体テスト実行
c2b7a98c21 2011-02-23        kinaba: 		if( g_orig_dll is null )
c2b7a98c21 2011-02-23        kinaba: 			return false;
c2b7a98c21 2011-02-23        kinaba: 		break;
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	case DLL_PROCESS_DETACH:
c2b7a98c21 2011-02-23        kinaba: 		_moduleDtor();
c2b7a98c21 2011-02-23        kinaba: 		gc_term();     // GC終了
c2b7a98c21 2011-02-23        kinaba: 		break;
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	default:
c2b7a98c21 2011-02-23        kinaba: 	case DLL_THREAD_ATTACH:
c2b7a98c21 2011-02-23        kinaba: 	case DLL_THREAD_DETACH:
c2b7a98c21 2011-02-23        kinaba: 		break;
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 	return true;
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: // API転送処理
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: WinDLL g_orig_dll = null;
c2b7a98c21 2011-02-23        kinaba: UINT   WM_ARCEXTRACT;
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: static this()
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	g_orig_dll = WinDLL.load( "_Bga32.DLL" );
c2b7a98c21 2011-02-23        kinaba: 	WM_ARCEXTRACT = RegisterWindowMessage("wm_arcextract");
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: static ~this()
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	g_orig_dll.close();
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: template api(FnT)
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	FnT api( char[] name )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return g_orig_dll.get_api!(FnT)( name );
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: // 統合アーカイバAPI:転送
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: extern(Windows)
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	int Bga( HWND a, char* b, char* c, DWORD d )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		int r = Bga_impl( a, toString(b) );
c2b7a98c21 2011-02-23        kinaba: 		if( r < 0 ) // このダミーDLLでは処理できないコマンドだった時
c2b7a98c21 2011-02-23        kinaba: 			return api!(typeof(&Bga))("Bga")(a,b,c,d);
c2b7a98c21 2011-02-23        kinaba: 		return r;
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	WORD QBgaGetVersion()
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return 4;
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	WORD BgaGetVersion()
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaGetVersion))("BgaGetVersion")();
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	BOOL BgaGetRunning()
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaGetRunning))("BgaGetRunning")();
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	BOOL BgaCheckArchive( char* a, int b )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaCheckArchive))("BgaCheckArchive")(a,b);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	BOOL BgaConfigDialog( HWND a, char* b, int c )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaConfigDialog))("BgaConfigDialog")(a,b,c);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	int BgaGetFileCount( char* a )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaGetFileCount))("BgaGetFileCount")(a);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	BOOL BgaQueryFunctionList( int a )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaQueryFunctionList))("BgaQueryFunctionList")(a);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	alias void* HARC;
c2b7a98c21 2011-02-23        kinaba: 	HARC BgaOpenArchive( HWND a, char* b, DWORD c )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaOpenArchive))("BgaOpenArchive")(a,b,c);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	int BgaCloseArchive( HARC a )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaCloseArchive))("BgaCloseArchive")(a);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	alias void* LPINDIVIDUALINFO;
c2b7a98c21 2011-02-23        kinaba: 	int BgaFindFirst( HARC a, char* b, LPINDIVIDUALINFO c )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaFindFirst))("BgaFindFirst")(a,b,c);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	int BgaFindNext( HARC a, LPINDIVIDUALINFO b )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaFindNext))("BgaFindNext")(a,b);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	DWORD BgaGetArcOriginalSize( HARC a )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaGetArcOriginalSize))("BgaGetArcOriginalSize")(a);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	DWORD BgaGetArcCompressedSize( HARC a )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaGetArcCompressedSize))("BgaGetArcCompressedSize")(a);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	WORD BgaGetArcRatio( HARC a )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaGetArcRatio))("BgaGetArcRatio")(a);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	BOOL BgaSetOwnerWindow( HWND a )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		BOOL r = api!(typeof(&BgaSetOwnerWindow))("BgaSetOwnerWindow")(a);
c2b7a98c21 2011-02-23        kinaba: 		if( r ) BgaSetOwnerWindow_impl(a);
c2b7a98c21 2011-02-23        kinaba: 		return r;
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	BOOL BgaClearOwnerWindow()
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		BOOL r = api!(typeof(&BgaClearOwnerWindow))("BgaClearOwnerWindow")();
c2b7a98c21 2011-02-23        kinaba: 		BgaClearOwnerWindow_impl();
c2b7a98c21 2011-02-23        kinaba: 		return r;
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	alias BOOL function(HWND,UINT,UINT,EXTRACTINGINFOEX*) ARCHIVERPROC;
c2b7a98c21 2011-02-23        kinaba: 	BOOL BgaSetOwnerWindowEx( HWND a, ARCHIVERPROC* b )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		BOOL r = api!(typeof(&BgaSetOwnerWindowEx))("BgaSetOwnerWindowEx")(a,b);
c2b7a98c21 2011-02-23        kinaba: 		if( r ) BgaSetOwnerWindowEx_impl(a,b);
c2b7a98c21 2011-02-23        kinaba: 		return r;
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	BOOL BgaKillOwnerWindowEx( HWND a )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		BOOL r = api!(typeof(&BgaKillOwnerWindowEx))("BgaKillOwnerWindowEx")(a);
c2b7a98c21 2011-02-23        kinaba: 		BgaClearOwnerWindow_impl();
c2b7a98c21 2011-02-23        kinaba: 		return r;
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	alias void* UNLHA_WND_ENUMMEMBPROC;
c2b7a98c21 2011-02-23        kinaba: 	BOOL BgaSetEnumMembersProc( UNLHA_WND_ENUMMEMBPROC a )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaSetEnumMembersProc))("BgaSetEnumMembersProc")(a);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	BOOL BgaClearEnumMembersProc()
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return api!(typeof(&BgaClearEnumMembersProc))("BgaClearEnumMembersProc")();
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: // 統合アーカイバAPI:実装( Bga )
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: int Bga_impl( HWND wnd, char[] cmd_str )
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	enum { UNSUPPORTED = -1 }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	//
c2b7a98c21 2011-02-23        kinaba: 	// コマンドライン解析
c2b7a98c21 2011-02-23        kinaba: 	//
c2b7a98c21 2011-02-23        kinaba: 	char[][] cmd = cmd_parse(cmd_str);
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	// x以外のコマンドは扱わないで本物DLLに回します。注意点として:
c2b7a98c21 2011-02-23        kinaba: 	//  > command はコマンドラインの最初の引数としてください。なお、command を省略
c2b7a98c21 2011-02-23        kinaba: 	//  > した場合は 'x' command が指定されたものとみなします。
c2b7a98c21 2011-02-23        kinaba: 	if( cmd.length == 0 )
c2b7a98c21 2011-02-23        kinaba: 		return UNSUPPORTED;
c2b7a98c21 2011-02-23        kinaba: 	if( cmd[0].length == 1 )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		if( 0 <= find("adjlmnstvADJLMNSTV", cmd[0][0]) )
c2b7a98c21 2011-02-23        kinaba: 			return UNSUPPORTED;
c2b7a98c21 2011-02-23        kinaba: 		if( cmd[0][0]=='x' || cmd[0][0]=='X' )
c2b7a98c21 2011-02-23        kinaba: 			cmd = cmd[1 .. length];
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 		// ※ この時点で、cmdにはcommandを除いた残りの引数が入っているはず
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	//
c2b7a98c21 2011-02-23        kinaba: 	// スイッチ解析、引数解析
c2b7a98c21 2011-02-23        kinaba: 	//
c2b7a98c21 2011-02-23        kinaba: 	bool all_attrs       = false; // -a
c2b7a98c21 2011-02-23        kinaba: 	bool silent          = false; // -i
c2b7a98c21 2011-02-23        kinaba: 	bool ignore_dir      = false; // -j
c2b7a98c21 2011-02-23        kinaba: 	bool newfile_only    = false; // -n
c2b7a98c21 2011-02-23        kinaba: 	bool force_overwrite = false; // -o
c2b7a98c21 2011-02-23        kinaba: 	bool recursive       = false; // -r
c2b7a98c21 2011-02-23        kinaba: 	bool sanitize_path   = true;
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	char[] arc_name = null;
c2b7a98c21 2011-02-23        kinaba: 	char[] base_dir = null;
c2b7a98c21 2011-02-23        kinaba: 	char[][] paths;
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	foreach( char[] param ; cmd )
c2b7a98c21 2011-02-23        kinaba: 		if( param[0] == '-' )
c2b7a98c21 2011-02-23        kinaba: 			switch( param[1] )
c2b7a98c21 2011-02-23        kinaba: 			{
c2b7a98c21 2011-02-23        kinaba: 			case 'a','A': all_attrs       = true; break;
c2b7a98c21 2011-02-23        kinaba: 			case 'i','I': silent          = true; break;
c2b7a98c21 2011-02-23        kinaba: 			case 'j','J': ignore_dir      = true; break;
c2b7a98c21 2011-02-23        kinaba: 			case 'n','N': newfile_only    = true; break;
c2b7a98c21 2011-02-23        kinaba: 			case 'o','O': force_overwrite = true; break;
c2b7a98c21 2011-02-23        kinaba: 			case 'r','R': recursive       = true; break;
c2b7a98c21 2011-02-23        kinaba: 			default:  break;
c2b7a98c21 2011-02-23        kinaba: 			}
c2b7a98c21 2011-02-23        kinaba: 		else if( arc_name is null )
c2b7a98c21 2011-02-23        kinaba: 		{
c2b7a98c21 2011-02-23        kinaba: 			arc_name = param;
c2b7a98c21 2011-02-23        kinaba: 		}
c2b7a98c21 2011-02-23        kinaba: 		else if( base_dir is null )
c2b7a98c21 2011-02-23        kinaba: 		{
c2b7a98c21 2011-02-23        kinaba: 			if( lastChar(param) == '\\' )
c2b7a98c21 2011-02-23        kinaba: 				base_dir = param;
c2b7a98c21 2011-02-23        kinaba: 			else {
c2b7a98c21 2011-02-23        kinaba: 				base_dir.length = GetCurrentDirectory(0,null)+1;
c2b7a98c21 2011-02-23        kinaba: 				GetCurrentDirectory(base_dir.length, base_dir);
c2b7a98c21 2011-02-23        kinaba: 				base_dir.length = strlen(base_dir);
c2b7a98c21 2011-02-23        kinaba: 				if( lastChar(base_dir) != '\\' )
c2b7a98c21 2011-02-23        kinaba: 					base_dir ~= '\\';
c2b7a98c21 2011-02-23        kinaba: 			}
c2b7a98c21 2011-02-23        kinaba: 		}
c2b7a98c21 2011-02-23        kinaba: 		else
c2b7a98c21 2011-02-23        kinaba: 			paths ~= param;
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	//
c2b7a98c21 2011-02-23        kinaba: 	// 展開処理にGo!
c2b7a98c21 2011-02-23        kinaba: 	//
c2b7a98c21 2011-02-23        kinaba: 	ProgressDlg dlg = null;
c2b7a98c21 2011-02-23        kinaba: 	if( !do_ownerwnd_proc( OP_ARC_BEGIN, null, 0, arc_name ) )
c2b7a98c21 2011-02-23        kinaba: 		return 0x8020;
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	try
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		if( !silent && g_handler is null ) // -i / OwnerWndProc
c2b7a98c21 2011-02-23        kinaba: 		{
c2b7a98c21 2011-02-23        kinaba: 			dlg = new ProgressDlg(
c2b7a98c21 2011-02-23        kinaba: 				cast(DLGTEMPLATE*) g_orig_dll.load_dialog("#2025"), wnd );
c2b7a98c21 2011-02-23        kinaba: 			dlg.set_arcname(arc_name);
c2b7a98c21 2011-02-23        kinaba: 		}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 		char[]    src_fname; // OwnerWndProc関係
c2b7a98c21 2011-02-23        kinaba: 		BgaHeader cur_hdr;   // OwnerWndProc関係
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 		BgaAnswer handler( inout BgaHeader hdr )
c2b7a98c21 2011-02-23        kinaba: 		{
c2b7a98c21 2011-02-23        kinaba: 			src_fname = hdr.fname;
c2b7a98c21 2011-02-23        kinaba: 			process_messages();
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 			// paths
c2b7a98c21 2011-02-23        kinaba: 			if( paths.length > 0 )
c2b7a98c21 2011-02-23        kinaba: 			{
c2b7a98c21 2011-02-23        kinaba: 				char[] fname = // -r
c2b7a98c21 2011-02-23        kinaba: 					(recursive ? hdr.fname[hdr.dir_name_len..length]
c2b7a98c21 2011-02-23        kinaba: 					           : hdr.fname);
c2b7a98c21 2011-02-23        kinaba: 				foreach( char[] w ; paths )
c2b7a98c21 2011-02-23        kinaba: 					if( wild_match( w, fname ) )
c2b7a98c21 2011-02-23        kinaba: 						goto ok;
c2b7a98c21 2011-02-23        kinaba: 				return BgaAnswer.SkipIt;
c2b7a98c21 2011-02-23        kinaba: 			ok:;
c2b7a98c21 2011-02-23        kinaba: 			}
c2b7a98c21 2011-02-23        kinaba: 			// -a
c2b7a98c21 2011-02-23        kinaba: 			if( !all_attrs && (hdr.attrib&6) )
c2b7a98c21 2011-02-23        kinaba: 				return BgaAnswer.SkipIt;
c2b7a98c21 2011-02-23        kinaba: 			// dialog
c2b7a98c21 2011-02-23        kinaba: 			if( dlg )
c2b7a98c21 2011-02-23        kinaba: 				if( dlg.closed )
c2b7a98c21 2011-02-23        kinaba: 					return BgaAnswer.Abort;
c2b7a98c21 2011-02-23        kinaba: 				else
c2b7a98c21 2011-02-23        kinaba: 					dlg.set_filename( hdr.fname[hdr.dir_name_len .. length] );
c2b7a98c21 2011-02-23        kinaba: 			// -j
c2b7a98c21 2011-02-23        kinaba: 			if( ignore_dir )
c2b7a98c21 2011-02-23        kinaba: 				hdr.fname = hdr.fname[hdr.dir_name_len .. length];
c2b7a98c21 2011-02-23        kinaba: 			// sanitize
c2b7a98c21 2011-02-23        kinaba: 			if( sanitize_path )
c2b7a98c21 2011-02-23        kinaba: 				hdr.fname = check_path(hdr.fname);
c2b7a98c21 2011-02-23        kinaba: 			// base_dir
c2b7a98c21 2011-02-23        kinaba: 			hdr.fname = base_dir ~ hdr.fname;
c2b7a98c21 2011-02-23        kinaba: 			// -o
c2b7a98c21 2011-02-23        kinaba: 			if( !force_overwrite )
c2b7a98c21 2011-02-23        kinaba: 				try {
c2b7a98c21 2011-02-23        kinaba: 				if( std.file.exists(hdr.fname) && std.file.isfile(hdr.fname) )
c2b7a98c21 2011-02-23        kinaba: 					// -n
c2b7a98c21 2011-02-23        kinaba: 					if( newfile_only )
c2b7a98c21 2011-02-23        kinaba: 					{
c2b7a98c21 2011-02-23        kinaba: 						if( newer_than(hdr.date,hdr.time,hdr.fname) )
c2b7a98c21 2011-02-23        kinaba: 							return BgaAnswer.SkipIt;
c2b7a98c21 2011-02-23        kinaba: 					}
c2b7a98c21 2011-02-23        kinaba: 					else
c2b7a98c21 2011-02-23        kinaba: 					{
c2b7a98c21 2011-02-23        kinaba: 						int r = MessageBox( dlg?dlg.hwnd:wnd,
c2b7a98c21 2011-02-23        kinaba: 							toStringz("Overwrite "~hdr.fname~" ?"),
c2b7a98c21 2011-02-23        kinaba: 							"QBga32.dll", MB_YESNOCANCEL );
c2b7a98c21 2011-02-23        kinaba: 						if( r == IDNO )     return BgaAnswer.SkipIt;
c2b7a98c21 2011-02-23        kinaba: 						if( r == IDCANCEL ) return BgaAnswer.Abort;
c2b7a98c21 2011-02-23        kinaba: 					}
c2b7a98c21 2011-02-23        kinaba: 				} catch {}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 			cur_hdr = hdr;
c2b7a98c21 2011-02-23        kinaba: 			if( !do_ownerwnd_proc( OP_FILE_BEGIN, &cur_hdr, 0, src_fname ) )
c2b7a98c21 2011-02-23        kinaba: 				return BgaAnswer.Abort;
c2b7a98c21 2011-02-23        kinaba: 			return BgaAnswer.MeltIt;
c2b7a98c21 2011-02-23        kinaba: 		}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 		BgaAnswer progress_handler( int cur, int max )
c2b7a98c21 2011-02-23        kinaba: 		{
c2b7a98c21 2011-02-23        kinaba: 			process_messages();
c2b7a98c21 2011-02-23        kinaba: 			if( dlg )
c2b7a98c21 2011-02-23        kinaba: 				if( dlg.closed )
c2b7a98c21 2011-02-23        kinaba: 					return BgaAnswer.Abort;
c2b7a98c21 2011-02-23        kinaba: 				else
c2b7a98c21 2011-02-23        kinaba: 					dlg.set_pos( cast(real)(cur)/max );
c2b7a98c21 2011-02-23        kinaba: 			if( !do_ownerwnd_proc( OP_FILE_MIDDLE, &cur_hdr, cur, src_fname ) )
c2b7a98c21 2011-02-23        kinaba: 				return BgaAnswer.Abort;
c2b7a98c21 2011-02-23        kinaba: 			return BgaAnswer.MeltIt;
c2b7a98c21 2011-02-23        kinaba: 		}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 		(new BgaMelter(arc_name)).start(&handler,&progress_handler);
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 	catch( BgaMelterError e )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		return e.errcode;
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 	finally
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		do_ownerwnd_proc( OP_ARC_END, null, 0, arc_name );
c2b7a98c21 2011-02-23        kinaba: 		if( dlg )
c2b7a98c21 2011-02-23        kinaba: 			dlg.close();
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 	return 0;
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: // 統合アーカイバAPI:実装( SetOwnerWindow )
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: align(1) struct EXTRACTINGINFO
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	DWORD   dwFileSize;
c2b7a98c21 2011-02-23        kinaba: 	DWORD   dwWriteSize;
c2b7a98c21 2011-02-23        kinaba: 	char    szSourceFileName[512 + 1];
c2b7a98c21 2011-02-23        kinaba: 	char    dummy1[3];
c2b7a98c21 2011-02-23        kinaba: 	char    szDestFileName[512 + 1];
c2b7a98c21 2011-02-23        kinaba: 	char    dummy[3];
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: align(1) struct EXTRACTINGINFOEX
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	EXTRACTINGINFO exinfo;
c2b7a98c21 2011-02-23        kinaba: 	DWORD dwCompressedSize;
c2b7a98c21 2011-02-23        kinaba: 	DWORD dwCRC;
c2b7a98c21 2011-02-23        kinaba: 	UINT  uOSType;
c2b7a98c21 2011-02-23        kinaba: 	WORD  wRatio;
c2b7a98c21 2011-02-23        kinaba: 	WORD  wDate;
c2b7a98c21 2011-02-23        kinaba: 	WORD  wTime;
c2b7a98c21 2011-02-23        kinaba: 	char  szAttribute[8];
c2b7a98c21 2011-02-23        kinaba: 	char  szMode[8];
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: HWND g_owner_window;
c2b7a98c21 2011-02-23        kinaba: extern(Windows) BOOL function(HWND,UINT,UINT,EXTRACTINGINFOEX*) g_handler;
c2b7a98c21 2011-02-23        kinaba: extern(Windows) BOOL noex_handler( HWND w,UINT m,UINT s, EXTRACTINGINFOEX* e )
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	return !SendMessage( w, m, s, cast(LPARAM) &e.exinfo );
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: void BgaSetOwnerWindow_impl( HWND wnd )
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	g_owner_window = wnd;
c2b7a98c21 2011-02-23        kinaba: 	g_handler      = &noex_handler;
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: void BgaClearOwnerWindow_impl()
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	g_owner_window = null;
c2b7a98c21 2011-02-23        kinaba: 	g_handler      = null;
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: void BgaSetOwnerWindowEx_impl( HWND wnd, ARCHIVERPROC* proc )
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	g_owner_window = wnd;
c2b7a98c21 2011-02-23        kinaba: 	g_handler      = *proc;
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: enum { OP_FILE_BEGIN, OP_FILE_MIDDLE, OP_ARC_END, OP_ARC_BEGIN }
c2b7a98c21 2011-02-23        kinaba: bool do_ownerwnd_proc( UINT uState, BgaHeader* hdr, int cur, char[] src_fname )
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	if( g_handler is null )
c2b7a98c21 2011-02-23        kinaba: 		return true;
c2b7a98c21 2011-02-23        kinaba: 	EXTRACTINGINFOEX ex;
c2b7a98c21 2011-02-23        kinaba: 	if( uState == OP_ARC_BEGIN || uState == OP_ARC_END )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		lstrcpyn( ex.exinfo.szSourceFileName, toStringz(src_fname), 512 );
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 	else
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		ex.exinfo.dwFileSize  = hdr.original_size;
c2b7a98c21 2011-02-23        kinaba: 		ex.exinfo.dwWriteSize = cur;
c2b7a98c21 2011-02-23        kinaba: 		lstrcpyn( ex.exinfo.szSourceFileName, toStringz(src_fname), 512 );
c2b7a98c21 2011-02-23        kinaba: 		lstrcpyn( ex.exinfo.szDestFileName, toStringz(hdr.fname), 512 );
c2b7a98c21 2011-02-23        kinaba: 		ex.dwCompressedSize = hdr.compressed_size;
c2b7a98c21 2011-02-23        kinaba: 		ex.wRatio = cast(int)( (cast(real)hdr.compressed_size)/hdr.original_size*1000 );
c2b7a98c21 2011-02-23        kinaba: 		ex.wDate  = hdr.date;
c2b7a98c21 2011-02-23        kinaba: 		ex.wTime  = hdr.time;
c2b7a98c21 2011-02-23        kinaba: 		ex.szAttribute[0] = (hdr.attrib&32 ? 'A': '-');
c2b7a98c21 2011-02-23        kinaba: 		ex.szAttribute[1] = (hdr.attrib&1  ? 'R': '-');
c2b7a98c21 2011-02-23        kinaba: 		ex.szAttribute[2] = (hdr.attrib&2  ? 'H': '-');
c2b7a98c21 2011-02-23        kinaba: 		ex.szAttribute[3] = (hdr.attrib&4  ? 'S': '-');
c2b7a98c21 2011-02-23        kinaba: 		ex.szAttribute[4] = (hdr.attrib&16 ? 'D': '-');
c2b7a98c21 2011-02-23        kinaba: 		ex.szAttribute[5] = '\0';
c2b7a98c21 2011-02-23        kinaba: 		if( hdr.method[0]=='G' )
c2b7a98c21 2011-02-23        kinaba: 			lstrcpy(ex.szMode,"-gzip-");
c2b7a98c21 2011-02-23        kinaba: 		else
c2b7a98c21 2011-02-23        kinaba: 			lstrcpy(ex.szMode,"-bzip2-");
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	return false != g_handler( g_owner_window, WM_ARCEXTRACT, uState, &ex );
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: // パス検査系
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: alias std.c.windows.windows.IsDBCSLeadByte isDL;
c2b7a98c21 2011-02-23        kinaba: char[] replace_yen( char[] s )
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	char[] ans;
c2b7a98c21 2011-02-23        kinaba: 	int j=0;
c2b7a98c21 2011-02-23        kinaba: 	for(int i=0; i!=s.length; i=i+(isDL(s[i])?2:1))
c2b7a98c21 2011-02-23        kinaba: 		if( s[i] == '\\' )
c2b7a98c21 2011-02-23        kinaba: 			ans~=s[j .. i], ans~='/', j=i+1;
c2b7a98c21 2011-02-23        kinaba: 	ans ~= s[j .. length];
c2b7a98c21 2011-02-23        kinaba: 	return ans;
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: bool wild_match( char[] wild, char[] name )
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	bool wild_match_nopath( char[] w, char[] s )
c2b7a98c21 2011-02-23        kinaba: 	{
c2b7a98c21 2011-02-23        kinaba: 		char[] advance( char[] s )
c2b7a98c21 2011-02-23        kinaba: 		{
c2b7a98c21 2011-02-23        kinaba: 			return s[(IsDBCSLeadByte(s[0])?2:1) .. length];
c2b7a98c21 2011-02-23        kinaba: 		}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 		while( w.length>0 )
c2b7a98c21 2011-02-23        kinaba: 			switch( w[0] )
c2b7a98c21 2011-02-23        kinaba: 			{
c2b7a98c21 2011-02-23        kinaba: 			case '?':
c2b7a98c21 2011-02-23        kinaba: 				if( s.length==0 )
c2b7a98c21 2011-02-23        kinaba: 					return false;
c2b7a98c21 2011-02-23        kinaba: 				w = advance(w);
c2b7a98c21 2011-02-23        kinaba: 				s = advance(s);
c2b7a98c21 2011-02-23        kinaba: 				break;
c2b7a98c21 2011-02-23        kinaba: 			case '*':
c2b7a98c21 2011-02-23        kinaba: 				if( s.length==0 )
c2b7a98c21 2011-02-23        kinaba: 					return false;
c2b7a98c21 2011-02-23        kinaba: 				w = advance(w);
c2b7a98c21 2011-02-23        kinaba: 				if( w.length == 0 )
c2b7a98c21 2011-02-23        kinaba: 					return true;
c2b7a98c21 2011-02-23        kinaba: 				for( ; s.length!=0; s=advance(s) )
c2b7a98c21 2011-02-23        kinaba: 					if( wild_match_nopath(w,s) )
c2b7a98c21 2011-02-23        kinaba: 						return true;
c2b7a98c21 2011-02-23        kinaba: 				return false;
c2b7a98c21 2011-02-23        kinaba: 			default:
c2b7a98c21 2011-02-23        kinaba: 				if( s.length==0 )
c2b7a98c21 2011-02-23        kinaba: 					return false;
c2b7a98c21 2011-02-23        kinaba: 				if( isDL(w[0]) )
c2b7a98c21 2011-02-23        kinaba: 				  { if( w[0..2] != s[0..2] ) return false; }
c2b7a98c21 2011-02-23        kinaba: 				else
c2b7a98c21 2011-02-23        kinaba: 				  { if( w[0]    != s[0]    ) return false; }
c2b7a98c21 2011-02-23        kinaba: 				w = advance(w);
c2b7a98c21 2011-02-23        kinaba: 				s = advance(s);
c2b7a98c21 2011-02-23        kinaba: 				break;
c2b7a98c21 2011-02-23        kinaba: 			}
c2b7a98c21 2011-02-23        kinaba: 		return s.length==0;
c2b7a98c21 2011-02-23        kinaba: 	}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	if( wild=="" || wild=="*.*" || wild=="*" || wild=="**" )
c2b7a98c21 2011-02-23        kinaba: 		return true;
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	char[][] wilds = split( replace_yen( tolower(wild) ), "/" );
c2b7a98c21 2011-02-23        kinaba: 	char[][] names = split( replace_yen( tolower(name) ), "/" );
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	if( wilds.length != names.length )
c2b7a98c21 2011-02-23        kinaba: 		return false;
c2b7a98c21 2011-02-23        kinaba: 	for(int i=0; i!=wilds.length; ++i)
c2b7a98c21 2011-02-23        kinaba: 		if( wilds[i]!="*.*" && wilds[i]!="*" && wilds[i]!="**" )
c2b7a98c21 2011-02-23        kinaba: 			if( !wild_match_nopath( wilds[i], names[i] ) )
c2b7a98c21 2011-02-23        kinaba: 				return false;
c2b7a98c21 2011-02-23        kinaba: 	return true;
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: char[] check_path( char[] path )
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	// C:\ ==> C_\
c2b7a98c21 2011-02-23        kinaba: 	if( path.length>=2 && path[1]==':' )
c2b7a98c21 2011-02-23        kinaba: 		path = path.dup, path[1] = '_';
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	// \\hoge ==> hoge
c2b7a98c21 2011-02-23        kinaba: 	// /hoge  ==> hoge
c2b7a98c21 2011-02-23        kinaba: 	while( path.length>0 && (path[0]=='\\'||path[0]=='/') )
c2b7a98c21 2011-02-23        kinaba: 		path = path[1..length];
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	// .. ==> __
c2b7a98c21 2011-02-23        kinaba: 	char[][] paths = split( replace_yen(path), "/" );
c2b7a98c21 2011-02-23        kinaba: 	L1:
c2b7a98c21 2011-02-23        kinaba: 	foreach( inout char[] pc ; paths )
c2b7a98c21 2011-02-23        kinaba: 		if( pc.length >= 2 )
c2b7a98c21 2011-02-23        kinaba: 		{
c2b7a98c21 2011-02-23        kinaba: 			foreach( char c ; pc )
c2b7a98c21 2011-02-23        kinaba: 				if( c != '.' )
c2b7a98c21 2011-02-23        kinaba: 					continue L1;
c2b7a98c21 2011-02-23        kinaba: 			pc = replace( pc, ".", "_" );
c2b7a98c21 2011-02-23        kinaba: 		}
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 	return join( paths, "\\" );
c2b7a98c21 2011-02-23        kinaba: }
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: // 簡易テスト@もっとマジメに書かなきゃ…
c2b7a98c21 2011-02-23        kinaba: //----------------------------------------------------------------
c2b7a98c21 2011-02-23        kinaba: 
c2b7a98c21 2011-02-23        kinaba: unittest
c2b7a98c21 2011-02-23        kinaba: {
c2b7a98c21 2011-02-23        kinaba: 	assert( check_path(`\\\\hoge\fuga`)==`hoge\fuga` );
c2b7a98c21 2011-02-23        kinaba: 	assert( check_path(`/usr/local/`)==`usr\local\` );
c2b7a98c21 2011-02-23        kinaba: 	assert( check_path(`..\abc def\...\.\g`)==`__\abc def\___\.\g` );
c2b7a98c21 2011-02-23        kinaba: 	assert( wild_match(`a/b/c`,`A\b\C`) );
c2b7a98c21 2011-02-23        kinaba: 	assert( wild_match(`a/*.*/a?x`,`A\hoge\Afx`) );
c2b7a98c21 2011-02-23        kinaba: 	assert( Bga_impl(null,"a hoge") < 0 );
c2b7a98c21 2011-02-23        kinaba: }