Diff

Not logged in

Differences From Artifact [f1f9b8362f0839ce]:

To Artifact [bcd83037acfbb1eb]:


1 +private import core.sys.windows.dll; 2 +private import win32.windows; 3 +private import win32.winuser; 1 4 private import std.string; 2 5 private import std.file; 3 -private import win32.ansi.windows; 4 6 private import util; 5 7 private import windll; 6 8 private import bga_melter; 7 9 private import qbga_gui; 8 10 9 11 //---------------------------------------------------------------- 10 12 // おきまりのDLL初期化ルーチン 11 13 //---------------------------------------------------------------- 12 14 13 -HINSTANCE g_hinst; 14 - 15 -extern(C) 16 -{ 17 - void gc_init(); 18 - void gc_term(); 19 - void _minit(); 20 - void _moduleCtor(); 21 - void _moduleDtor(); 22 - void _moduleUnitTests(); 23 -} 15 +__gshared HINSTANCE g_hinst; 24 16 25 17 extern (Windows) 26 18 BOOL DllMain( HINSTANCE inst, ULONG reason, void* reserved ) 27 19 { 28 20 switch( reason ) 29 21 { 30 22 case DLL_PROCESS_ATTACH: 31 23 g_hinst = inst; 32 - gc_init(); // GC初期化 33 - _minit(); // モジュールリスト初期化 34 - _moduleCtor(); // モジュールコンストラクタ実行 35 - _moduleUnitTests(); // 単体テスト実行 24 + dll_process_attach( inst, true ); 36 25 if( g_orig_dll is null ) 37 26 return false; 38 27 break; 39 28 40 29 case DLL_PROCESS_DETACH: 41 - _moduleDtor(); 42 - gc_term(); // GC終了 30 + dll_process_detach( inst, true ); 31 + break; 32 + 33 + case DLL_THREAD_ATTACH: 34 + dll_thread_attach( true, true ); 35 + break; 36 + 37 + case DLL_THREAD_DETACH: 38 + dll_thread_detach( true, true ); 43 39 break; 44 40 45 41 default: 46 - case DLL_THREAD_ATTACH: 47 - case DLL_THREAD_DETACH: 48 - break; 49 42 } 50 43 return true; 51 44 } 52 45 53 46 //---------------------------------------------------------------- 54 47 // API転送処理 55 48 //---------------------------------------------------------------- 56 49 57 -WinDLL g_orig_dll = null; 58 -UINT WM_ARCEXTRACT; 50 +__gshared WinDLL g_orig_dll = null; 51 +__gshared UINT WM_ARCEXTRACT; 59 52 60 53 static this() 61 54 { 62 55 g_orig_dll = WinDLL.load( "_Bga32.DLL" ); 63 56 WM_ARCEXTRACT = RegisterWindowMessage("wm_arcextract"); 64 57 } 65 58 ................................................................................ 66 59 static ~this() 67 60 { 68 61 g_orig_dll.close(); 69 62 } 70 63 71 64 template api(FnT) 72 65 { 73 - FnT api( char[] name ) 66 + FnT api( string name ) 74 67 { 75 68 return g_orig_dll.get_api!(FnT)( name ); 76 69 } 77 70 } 78 71 79 72 //---------------------------------------------------------------- 80 73 // 統合アーカイバAPI:転送 81 74 //---------------------------------------------------------------- 82 75 83 76 extern(Windows) 84 77 { 85 - int Bga( HWND a, char* b, char* c, DWORD d ) 78 + int Bga( HWND a, immutable char* b, char* c, DWORD d ) 86 79 { 87 - int r = Bga_impl( a, toString(b) ); 80 + int r = Bga_impl( a, b.fromStringz() ); 88 81 if( r < 0 ) // このダミーDLLでは処理できないコマンドだった時 89 82 return api!(typeof(&Bga))("Bga")(a,b,c,d); 90 83 return r; 91 84 } 92 85 93 86 WORD QBgaGetVersion() 94 87 { ................................................................................ 203 196 } 204 197 } 205 198 206 199 //---------------------------------------------------------------- 207 200 // 統合アーカイバAPI:実装( Bga ) 208 201 //---------------------------------------------------------------- 209 202 210 -int Bga_impl( HWND wnd, char[] cmd_str ) 203 +int Bga_impl( HWND wnd, string cmd_str ) 211 204 { 212 205 enum { UNSUPPORTED = -1 } 213 206 214 207 // 215 208 // コマンドライン解析 216 209 // 217 - char[][] cmd = cmd_parse(cmd_str); 210 + string[] cmd = cmd_parse(cmd_str); 218 211 219 212 // x以外のコマンドは扱わないで本物DLLに回します。注意点として: 220 213 // > command はコマンドラインの最初の引数としてください。なお、command を省略 221 214 // > した場合は 'x' command が指定されたものとみなします。 222 215 if( cmd.length == 0 ) 223 216 return UNSUPPORTED; 224 217 if( cmd[0].length == 1 ) 225 218 { 226 - if( 0 <= find("adjlmnstvADJLMNSTV", cmd[0][0]) ) 219 + if( 0 <= "adjlmnstvADJLMNSTV".indexOf(cmd[0][0]) ) 227 220 return UNSUPPORTED; 228 221 if( cmd[0][0]=='x' || cmd[0][0]=='X' ) 229 - cmd = cmd[1 .. length]; 222 + cmd = cmd[1 .. $]; 230 223 } 231 224 232 - // ※ この時点で、cmdにはcommandを除いた残りの引数が入っているはず 225 + // ※ この時点で、cmdにはcommandを除いた残りの引数が入っているはず 233 226 234 227 // 235 228 // スイッチ解析、引数解析 236 229 // 237 230 bool all_attrs = false; // -a 238 231 bool silent = false; // -i 239 232 bool ignore_dir = false; // -j 240 233 bool newfile_only = false; // -n 241 234 bool force_overwrite = false; // -o 242 235 bool recursive = false; // -r 243 236 bool sanitize_path = true; 244 237 245 - char[] arc_name = null; 246 - char[] base_dir = null; 247 - char[][] paths; 238 + string arc_name = null; 239 + string base_dir = null; 240 + string[] paths; 248 241 249 - foreach( char[] param ; cmd ) 242 + foreach( string param ; cmd ) 250 243 if( param[0] == '-' ) 251 244 switch( param[1] ) 252 245 { 253 246 case 'a','A': all_attrs = true; break; 254 247 case 'i','I': silent = true; break; 255 248 case 'j','J': ignore_dir = true; break; 256 249 case 'n','N': newfile_only = true; break; ................................................................................ 263 256 arc_name = param; 264 257 } 265 258 else if( base_dir is null ) 266 259 { 267 260 if( lastChar(param) == '\\' ) 268 261 base_dir = param; 269 262 else { 270 - base_dir.length = GetCurrentDirectory(0,null)+1; 271 - GetCurrentDirectory(base_dir.length, base_dir); 272 - base_dir.length = strlen(base_dir); 263 + char[] buf; 264 + buf.length = GetCurrentDirectoryA(0,null)+1; 265 + GetCurrentDirectoryA(buf.length, buf.ptr); 266 + base_dir = buf.ptr.fromStringz().idup; 273 267 if( lastChar(base_dir) != '\\' ) 274 268 base_dir ~= '\\'; 275 269 } 276 270 } 277 271 else 278 272 paths ~= param; 279 273 ................................................................................ 289 283 if( !silent && g_handler is null ) // -i / OwnerWndProc 290 284 { 291 285 dlg = new ProgressDlg( 292 286 cast(DLGTEMPLATE*) g_orig_dll.load_dialog("#2025"), wnd ); 293 287 dlg.set_arcname(arc_name); 294 288 } 295 289 296 - char[] src_fname; // OwnerWndProc関係 290 + string src_fname; // OwnerWndProc関係 297 291 BgaHeader cur_hdr; // OwnerWndProc関係 298 292 299 - BgaAnswer handler( inout BgaHeader hdr ) 293 + BgaAnswer handler( ref BgaHeader hdr ) 300 294 { 301 295 src_fname = hdr.fname; 302 296 process_messages(); 303 297 304 298 // paths 305 299 if( paths.length > 0 ) 306 300 { 307 - char[] fname = // -r 308 - (recursive ? hdr.fname[hdr.dir_name_len..length] 309 - : hdr.fname); 310 - foreach( char[] w ; paths ) 301 + string fname = // -r 302 + (recursive ? hdr.fname[hdr.dir_name_len..$] : hdr.fname); 303 + foreach( string w ; paths ) 311 304 if( wild_match( w, fname ) ) 312 305 goto ok; 313 306 return BgaAnswer.SkipIt; 314 307 ok:; 315 308 } 316 309 // -a 317 310 if( !all_attrs && (hdr.attrib&6) ) 318 311 return BgaAnswer.SkipIt; 319 312 // dialog 320 313 if( dlg ) 321 314 if( dlg.closed ) 322 315 return BgaAnswer.Abort; 323 316 else 324 - dlg.set_filename( hdr.fname[hdr.dir_name_len .. length] ); 317 + dlg.set_filename( hdr.fname[hdr.dir_name_len..$] ); 325 318 // -j 326 319 if( ignore_dir ) 327 - hdr.fname = hdr.fname[hdr.dir_name_len .. length]; 320 + hdr.fname = hdr.fname[hdr.dir_name_len .. $]; 328 321 // sanitize 329 322 if( sanitize_path ) 330 323 hdr.fname = check_path(hdr.fname); 331 324 // base_dir 332 - hdr.fname = base_dir ~ hdr.fname; 325 + hdr.fname = (base_dir ~ hdr.fname).dup; 333 326 // -o 334 327 if( !force_overwrite ) 335 328 try { 336 - if( std.file.exists(hdr.fname) && std.file.isfile(hdr.fname) ) 329 + if( std.file.exists(hdr.fname) && std.file.isFile(hdr.fname) ) 337 330 // -n 338 331 if( newfile_only ) 339 332 { 340 333 if( newer_than(hdr.date,hdr.time,hdr.fname) ) 341 334 return BgaAnswer.SkipIt; 342 335 } 343 336 else 344 337 { 345 - int r = MessageBox( dlg?dlg.hwnd:wnd, 338 + int r = MessageBoxA( dlg?dlg.hwnd:wnd, 346 339 toStringz("Overwrite "~hdr.fname~" ?"), 347 340 "QBga32.dll", MB_YESNOCANCEL ); 348 341 if( r == IDNO ) return BgaAnswer.SkipIt; 349 342 if( r == IDCANCEL ) return BgaAnswer.Abort; 350 343 } 351 344 } catch {} 352 345 ................................................................................ 410 403 char szMode[8]; 411 404 } 412 405 413 406 HWND g_owner_window; 414 407 extern(Windows) BOOL function(HWND,UINT,UINT,EXTRACTINGINFOEX*) g_handler; 415 408 extern(Windows) BOOL noex_handler( HWND w,UINT m,UINT s, EXTRACTINGINFOEX* e ) 416 409 { 417 - return !SendMessage( w, m, s, cast(LPARAM) &e.exinfo ); 410 + return !SendMessageA( w, m, s, cast(LPARAM) &e.exinfo ); 418 411 } 419 412 420 413 void BgaSetOwnerWindow_impl( HWND wnd ) 421 414 { 422 415 g_owner_window = wnd; 423 416 g_handler = &noex_handler; 424 417 } ................................................................................ 432 425 void BgaSetOwnerWindowEx_impl( HWND wnd, ARCHIVERPROC* proc ) 433 426 { 434 427 g_owner_window = wnd; 435 428 g_handler = *proc; 436 429 } 437 430 438 431 enum { OP_FILE_BEGIN, OP_FILE_MIDDLE, OP_ARC_END, OP_ARC_BEGIN } 439 -bool do_ownerwnd_proc( UINT uState, BgaHeader* hdr, int cur, char[] src_fname ) 432 +bool do_ownerwnd_proc( UINT uState, BgaHeader* hdr, int cur, string src_fname ) 440 433 { 441 434 if( g_handler is null ) 442 435 return true; 443 436 EXTRACTINGINFOEX ex; 444 437 if( uState == OP_ARC_BEGIN || uState == OP_ARC_END ) 445 438 { 446 - lstrcpyn( ex.exinfo.szSourceFileName, toStringz(src_fname), 512 ); 439 + lstrcpynA( ex.exinfo.szSourceFileName.ptr, toStringz(src_fname), 512 ); 447 440 } 448 441 else 449 442 { 450 443 ex.exinfo.dwFileSize = hdr.original_size; 451 444 ex.exinfo.dwWriteSize = cur; 452 - lstrcpyn( ex.exinfo.szSourceFileName, toStringz(src_fname), 512 ); 453 - lstrcpyn( ex.exinfo.szDestFileName, toStringz(hdr.fname), 512 ); 445 + lstrcpynA( ex.exinfo.szSourceFileName.ptr, toStringz(src_fname), 512 ); 446 + lstrcpynA( ex.exinfo.szDestFileName.ptr, toStringz(hdr.fname), 512 ); 454 447 ex.dwCompressedSize = hdr.compressed_size; 455 - ex.wRatio = cast(int)( (cast(real)hdr.compressed_size)/hdr.original_size*1000 ); 448 + ex.wRatio = cast(ushort)( (cast(real)hdr.compressed_size)/hdr.original_size*1000 ); 456 449 ex.wDate = hdr.date; 457 450 ex.wTime = hdr.time; 458 451 ex.szAttribute[0] = (hdr.attrib&32 ? 'A': '-'); 459 452 ex.szAttribute[1] = (hdr.attrib&1 ? 'R': '-'); 460 453 ex.szAttribute[2] = (hdr.attrib&2 ? 'H': '-'); 461 454 ex.szAttribute[3] = (hdr.attrib&4 ? 'S': '-'); 462 455 ex.szAttribute[4] = (hdr.attrib&16 ? 'D': '-'); 463 456 ex.szAttribute[5] = '\0'; 464 457 if( hdr.method[0]=='G' ) 465 - lstrcpy(ex.szMode,"-gzip-"); 458 + lstrcpyA(ex.szMode.ptr,"-gzip-"); 466 459 else 467 - lstrcpy(ex.szMode,"-bzip2-"); 460 + lstrcpyA(ex.szMode.ptr,"-bzip2-"); 468 461 } 469 462 470 463 return false != g_handler( g_owner_window, WM_ARCEXTRACT, uState, &ex ); 471 464 } 472 465 473 466 //---------------------------------------------------------------- 474 467 // パス検査系 475 468 //---------------------------------------------------------------- 476 469 477 -alias std.c.windows.windows.IsDBCSLeadByte isDL; 478 -char[] replace_yen( char[] s ) 470 +alias core.sys.windows.windows.IsDBCSLeadByte isDL; 471 +string replace_yen( string s ) 479 472 { 480 - char[] ans; 473 + string ans; 481 474 int j=0; 482 475 for(int i=0; i!=s.length; i=i+(isDL(s[i])?2:1)) 483 476 if( s[i] == '\\' ) 484 477 ans~=s[j .. i], ans~='/', j=i+1; 485 - ans ~= s[j .. length]; 478 + ans ~= s[j .. $]; 486 479 return ans; 487 480 } 488 481 489 -bool wild_match( char[] wild, char[] name ) 482 +bool wild_match( string wild, string name ) 490 483 { 491 - bool wild_match_nopath( char[] w, char[] s ) 484 + bool wild_match_nopath( string w, string s ) 492 485 { 493 - char[] advance( char[] s ) 486 + string advance( string s ) 494 487 { 495 - return s[(IsDBCSLeadByte(s[0])?2:1) .. length]; 488 + return s[(IsDBCSLeadByte(s[0])?2:1) .. $]; 496 489 } 497 490 498 491 while( w.length>0 ) 499 492 switch( w[0] ) 500 493 { 501 494 case '?': 502 495 if( s.length==0 ) ................................................................................ 527 520 } 528 521 return s.length==0; 529 522 } 530 523 531 524 if( wild=="" || wild=="*.*" || wild=="*" || wild=="**" ) 532 525 return true; 533 526 534 - char[][] wilds = split( replace_yen( tolower(wild) ), "/" ); 535 - char[][] names = split( replace_yen( tolower(name) ), "/" ); 527 + string[] wilds = split( replace_yen( toLower(wild) ), "/" ); 528 + string[] names = split( replace_yen( toLower(name) ), "/" ); 536 529 537 530 if( wilds.length != names.length ) 538 531 return false; 539 532 for(int i=0; i!=wilds.length; ++i) 540 533 if( wilds[i]!="*.*" && wilds[i]!="*" && wilds[i]!="**" ) 541 534 if( !wild_match_nopath( wilds[i], names[i] ) ) 542 535 return false; 543 536 return true; 544 537 } 545 538 546 -char[] check_path( char[] path ) 539 +string check_path( string in_path ) 547 540 { 541 + char[] path = in_path.dup; 542 + 548 543 // C:\ ==> C_\ 549 544 if( path.length>=2 && path[1]==':' ) 550 - path = path.dup, path[1] = '_'; 545 + path[1] = '_'; 551 546 552 547 // \\hoge ==> hoge 553 548 // /hoge ==> hoge 554 549 while( path.length>0 && (path[0]=='\\'||path[0]=='/') ) 555 - path = path[1..length]; 550 + path = path[1..$]; 556 551 557 552 // .. ==> __ 558 - char[][] paths = split( replace_yen(path), "/" ); 553 + string[] paths = split( replace_yen(path.idup), "/" ); 559 554 L1: 560 - foreach( inout char[] pc ; paths ) 555 + foreach( ref string pc ; paths ) 561 556 if( pc.length >= 2 ) 562 557 { 563 558 foreach( char c ; pc ) 564 559 if( c != '.' ) 565 560 continue L1; 566 561 pc = replace( pc, ".", "_" ); 567 562 }