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     }