Differences From Artifact [f1f9b8362f0839ce]:
- File
src/qbga32.d
- 2011-02-23 12:53:16 - part of checkin [c2b7a98c21] on branch trunk - Initial import (user: kinaba) [annotate]
To Artifact [bcd83037acfbb1eb]:
- File
src/qbga32.d
- 2015-04-21 10:46:55 - part of checkin [4e2933c620] on branch trunk - Rebased to the latest verson dmd 2.067. Not yet verified the outcome. (user: kinaba) [annotate]
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 }