Artifact Content

Not logged in

Artifact 83474074d1b2482abf1bea0809d4cf2f7ee0beb7


     1  
     2  #include "stdafx.h"
     3  #include "ArcDLL.h"
     4  #include "NoahApp.h"
     5  
     6  int CArcDLL::v_load()
     7  {
     8  	// DLLの存在確認
     9  	if( !dll.exist() )
    10  		return 0;
    11  
    12  	// 圧縮メソッドリストを設定
    13  	DWORD cp = set_cmpr_mhd();
    14  
    15  	// Abiltyを返す
    16  	return (m_Ecmd ? aCheck|aMelt : 0) | (m_Xcmd ? aList|aMeltEach : 0) | cp | (m_Scmd ? aSfx : 0);
    17  }
    18  
    19  int CArcDLL::v_melt( const arcname& aname, const kiPath& ddir, const aflArray* files )
    20  {
    21  	// 出力先をカレントに
    22  	::SetCurrentDirectory( ddir );
    23  
    24  	// 解凍コマンド
    25  	kiStr cmd = ( !files || files->len()==0 ) ? m_Ecmd : m_Xcmd;
    26  
    27  	// 書庫名
    28  	cmd += " \"", cmd += aname.basedir, cmd += aname.lname, cmd += "\" \"";
    29  	// 出力先ディレクトリ
    30  	cmd += ddir, cmd += '"';
    31  
    32  	// ( もしあれば )ファイルリスト
    33  	if( files )
    34  		for( unsigned int i=0; i!=files->len(); i++ )
    35  			if( (*files)[i].selected )
    36  				cmd += " \"",
    37  				decorate_add_melt( cmd, (*files)[i].inf.szFileName ),
    38  				cmd += '"';
    39  
    40  	// コマンド実行!
    41  	return dll.cmd( cmd );
    42  }
    43  
    44  int  CArcDLL::v_compress( const kiPath&	  base,
    45  						  const wfdArray& files,
    46  						  const kiPath&   ddir,
    47  						  const int       method,
    48  						  const bool      sfx )
    49  {
    50  	// 基底はカレント
    51  	::SetCurrentDirectory( base );
    52  
    53  	// ファイル名リスト作成
    54  	kiStr lst;
    55  	for( unsigned int i=0; i!=files.len(); i++ )
    56  	{
    57  		lst += '"';
    58  		decorate_add_cmpr( lst, files[i].cFileName );
    59  		if( files[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
    60  			if( m_Wild==1 )
    61  				lst += "\\*";
    62  			else if( m_Wild==2 )
    63  				lst += "\\*.*";
    64  		lst += "\" ";
    65  	}
    66  
    67  	// 書庫名作成
    68  
    69  	// Ver 3.14 -- フォルダなら拡張子を除かない
    70  	//  b2eの方は今更どーしようもないので、ここだけ変更
    71  	// Ver 3.19 -- 削る拡張子は一個だけ
    72  	kiStr aname;
    73  	if( files[0].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
    74  	{
    75  		aname = kiPath::name( files[0].cFileName );
    76  	}
    77  	else
    78  	{
    79  		switch(mycnf().extnum())
    80  		{
    81  		case 0: aname = files[0].cFileName;break; 
    82  		case 1: kiPath(files[0].cFileName).getBody_all(aname);break;
    83  		default:kiPath(files[0].cFileName).getBody(aname);break;
    84  		}
    85  	}
    86  
    87  
    88  	// 圧縮!
    89  	if( sfx )
    90  	{
    91  		kiPath tmp;
    92  		myapp().get_tempdir( tmp );
    93  
    94  		kiPath tsfx(tmp);  tsfx+=aname; tsfx+=".exe";
    95  		kiPath rsfx(ddir); rsfx+=aname; rsfx+=".exe";
    96  
    97  		int ans = cmpr( method, aname, tmp, lst );
    98  		if( ans < 0x8000 )
    99  		{
   100  			ans = 0x8020;
   101  			::SetCurrentDirectory( tmp );
   102  			if( arc2sfx( aname ) )
   103  				if( ::CopyFile( tsfx, rsfx, FALSE ) )
   104  					ans = 0;
   105  			// カレントを戻しておかないとあとで削除できない…
   106  			::SetCurrentDirectory( base );
   107  		}
   108  
   109  		tmp.remove();
   110  		return ans;
   111  	}
   112  	else
   113  		return cmpr( method, aname, ddir, lst );
   114  }
   115  
   116  int CArcDLL::cmpr( int mhd, kiStr& aname,const kiPath& to,const kiStr& lst )
   117  {
   118  	aname += '.', aname+=get_cmpr_ext(mhd);
   119  
   120  	kiStr cmd = get_cmpr_cmd(mhd);
   121  	cmd += " \"";
   122  	cmd += to;
   123  	cmd += aname;
   124  	cmd += "\" ";
   125  	cmd += lst;
   126  	return dll.cmd( cmd );
   127  }
   128  
   129  bool CArcDLL::arc2sfx( const kiStr& aname )
   130  {
   131  	kiStr cmd=m_Scmd; cmd+=" \"", cmd+=aname, cmd+='"';
   132  	return 0x8000>dll.cmd( cmd );
   133  }
   134  
   135  //----------------------------------------------------------------------//
   136  
   137  void CArcDLL::decorate_add_cmpr( kiStr& lst, const char* fname )
   138  {
   139  	lst += fname;
   140  }
   141  
   142  void CArcDLL::decorate_add_melt( kiStr& lst, const char* fname )
   143  {
   144  	lst += fname;
   145  }
   146  
   147  void CArcDLL_DotSlash::decorate_add_cmpr( kiStr& lst, const char* fname )
   148  {
   149  	// 先頭 - や @ 対策に、.\\ でエスケープする
   150  	if( *fname=='-' || *fname=='@' )
   151  		lst += ".\\";
   152  	lst += fname;
   153  }
   154  
   155  void CArcLzh::decorate_add_cmpr( kiStr& lst, const char* fname )
   156  {
   157  	// UNLHA32.DLL にはこの問題回避用のオプション -gb が。
   158  	if( *fname=='-' )
   159  		lst += "-gb";
   160  	lst += fname;
   161  }
   162  
   163  void CArcLzh::decorate_add_melt( kiStr& lst, const char* fname )
   164  {
   165  	// UNLHA32.DLL にはこの問題回避用のオプション -gb が。
   166  	if( *fname=='-' )
   167  		lst += "-gb";
   168  	lst += fname;
   169  }
   170  
   171  void CArcZip::decorate_add_cmpr( kiStr& lst, const char* fname )
   172  {
   173  	// 先頭 - や @ 対策に、[-] [@] と置換する
   174  	if( *fname=='-' || *fname=='@' )
   175  		lst+='[', lst+=*fname++, lst+=']';
   176  
   177  	// 途中の [ を [[] に置換する
   178  	while( *fname )
   179  		if( kiStr::isLeadByte(*fname) )
   180  		{
   181  			lst += *fname++, lst += *fname++;
   182  		}
   183  		else
   184  		{
   185  			lst += *fname;
   186  			if( *fname++=='[' )
   187  				lst += "[]";
   188  		}
   189  }
   190  
   191  //----------------------------------------------------------------------//
   192  
   193  DWORD CArcLzh::set_cmpr_mhd()
   194  {
   195  	set_cmp_ext( "lzh" );
   196  	add_cmp_mhd( "lh5" ), add_cmp_mhd( "lh6" ), add_cmp_mhd( "lh7" );
   197  	return aCompress|aArchive;
   198  }
   199  
   200  const char* CArcLzh::get_cmpr_cmd( int method )
   201  {
   202  	static char cmd[] = "a -d -jso1 -- -jm2";
   203  	cmd[ sizeof(cmd)-2 ] = (char)('2'+method);
   204  	return cmd;
   205  }
   206  
   207  //----------------------------------------------------------------------//
   208  
   209  DWORD CArcZip::set_cmpr_mhd()
   210  {
   211  	set_cmp_ext( "zip" );
   212  	add_cmp_mhd( "store" ),
   213  	add_cmp_mhd( "normal", true ), add_cmp_mhd( "password" );
   214  	return aCompress|aArchive;
   215  }
   216  
   217  const char* CArcZip::get_cmpr_cmd( int method )
   218  {
   219  	switch( method )
   220  	{
   221  	case 0: return "-rS0";
   222  	case 2: return "-rS9e";
   223  	}
   224  	return "-rS9";
   225  }
   226  
   227  //----------------------------------------------------------------------//
   228  
   229  DWORD CArcCab::set_cmpr_mhd()
   230  {
   231  	set_cmp_ext( "cab" );
   232  	add_cmp_mhd( "MSZIP" ), add_cmp_mhd( "LZX21",true );
   233  	return aCompress|aArchive;
   234  }
   235  
   236  const char* CArcCab::get_cmpr_cmd( int method )
   237  {
   238  	return method==0 ? "-a -r -mz" : "-a -r -ml:21";
   239  }
   240  
   241  //----------------------------------------------------------------------//
   242  
   243  DWORD CArcTar::set_cmpr_mhd()
   244  {
   245  	set_cmp_ext( "tar" );
   246  	add_cmp_mhd( "normal" ), add_cmp_mhd( "gzip",true ), add_cmp_mhd( "bzip2" );
   247  	add_cmp_mhd( "xz" ), add_cmp_mhd( "lzma" );
   248  	return aCompress|aArchive;
   249  }
   250  
   251  const char* CArcTar::get_cmpr_ext( int method )
   252  {
   253  	switch( method )
   254  	{
   255  	case 1: return "tgz";
   256  	case 2: return "tbz";
   257  	case 3: return "tar.xz";
   258  	case 4: return "tar.lzma";
   259  	}
   260  	return "tar";
   261  }
   262  
   263  const char* CArcTar::get_cmpr_cmd( int method )
   264  {
   265  	switch( method )
   266  	{
   267  	case 1: return "-cvz9 --";
   268  	case 2: return "-cvB --";
   269  	case 3: return "-cvJ9 --";
   270  	case 4: return "-cv --lzma=9 --";
   271  	}
   272  	return "-cv --";
   273  }
   274  
   275  //----------------------------------------------------------------------//
   276  
   277  DWORD CArcBga::set_cmpr_mhd()
   278  {
   279  	set_cmp_ext( "bga" );
   280  	add_cmp_mhd( "gzip" ), add_cmp_mhd( "bzip2",true );
   281  	return aCompress|aArchive;
   282  }
   283  
   284  const char* CArcBga::get_cmpr_ext( int method )
   285  {
   286  	return method==0 ? "gza" : "bza";
   287  }
   288  
   289  const char* CArcBga::get_cmpr_cmd( int method )
   290  {
   291  	return "a -r -a";
   292  }
   293  
   294  //----------------------------------------------------------------------//
   295  
   296  DWORD CArcYz1::set_cmpr_mhd()
   297  {
   298  	set_cmp_ext( "yz1" );
   299  	add_cmp_mhd( "normal" ), add_cmp_mhd( "password" );
   300  	return aCompress|aArchive;
   301  }
   302  
   303  const char* CArcYz1::get_cmpr_cmd( int method )
   304  {
   305  	return method==0 ? "c --" : "c -p --";
   306  }
   307  
   308  //----------------------------------------------------------------------//
   309  
   310  bool CArcRar::v_check( const kiPath& aname )
   311  {
   312  	// Unrar.dll のバグ?のため、ファイルハンドルが解放されないことが
   313  	// あるので、自前のチェックルーチンを用いる
   314  	// # Subset of XacRett #39
   315  
   316  	bool ans=false;
   317  	kiFile rar;
   318  	if( !rar.open(aname) )
   319  		return false;
   320  
   321  	unsigned char mark[10];
   322  	if( 10!=rar.read(mark,10) )
   323  		return false;
   324  
   325  	if( mark[0]==0x52 && mark[1]==0x45 && mark[2]==0x7e && mark[3]==0x5e )
   326  		return true;
   327  	else if( mark[0]==0x52 && mark[1]==0x61 &&
   328  			 mark[2]==0x72 && mark[3]==0x21 &&
   329  			 mark[4]==0x1a && mark[5]==0x07 &&
   330  			 mark[6]==0x00 && mark[9]==0x73 )
   331  		return true;
   332  	else
   333  	{
   334  		unsigned char* mem=new unsigned char[0x20000];
   335  		int siz = rar.read( mem, 0x1FFF0 );
   336  
   337  		for( unsigned char* p=mem; p<mem+siz-9; p++ )
   338  		{
   339  			if( *p!=0x52 )continue;
   340  			if( p[1]==0x45 && p[2]==0x7e && p[3]==0x5e &&
   341  				mem[18]==0x52 && mem[19]==0x53 &&
   342  				mem[20]==0x46 && mem[21]==0x58)
   343  				{ ans=true; break; }
   344  
   345  			if( p[1]==0x61 && p[2]==0x72 && p[3]==0x21 &&
   346  				p[4]==0x1a && p[5]==0x07 && p[6]==0x00 &&
   347  				p[9]==0x73 )
   348  				{ ans=true; break; }
   349  		}
   350  		delete [] mem;
   351      }
   352  
   353  	return ans;
   354  }
   355  
   356  int CArcRar::v_melt( const arcname& aname, const kiPath& ddir, const aflArray* files )
   357  {
   358  	// Unrarはコマンド指定でダイアログを消せないので、
   359  	// OwnerWindowを指定する
   360  
   361  	if( files && files->len() )
   362  		dll.own( app()->mainhwnd() );
   363  
   364  	int ans = CArcDLL::v_melt( aname, ddir, files );
   365  
   366  	if( files && files->len() )
   367  		dll.fre();
   368  
   369  	return ans;
   370  }
   371  
   372  int CArcUnZip::v_melt( const arcname& aname, const kiPath& ddir, const aflArray* files )
   373  {
   374  	// UnZip32.dllが妙なフォルダを作り出すバグ対策
   375  
   376  	int ans = CArcDLL::v_melt( aname, ddir, files );
   377  	dll.unload();
   378  	return ans;
   379  }
   380  
   381  //----------------------------------------------------------------------//
   382  
   383  DWORD CArc7z::set_cmpr_mhd()
   384  {
   385  	set_cmp_ext( "7z" );
   386  	add_cmp_mhd( "LZMA", true );
   387  	add_cmp_mhd( "LZMA(std)" );
   388  	add_cmp_mhd( "LZMA(fast)" );
   389  	add_cmp_mhd( "PPMd" );
   390  	return aCompress|aArchive;
   391  }
   392  
   393  const char* CArc7z::get_cmpr_cmd( int method )
   394  {
   395  	if( m_SfxMode )
   396  		switch( method )
   397  		{
   398  			case 0:  return "a -t7z -sfx -m0=LZMA -r0 -mx=9 --";
   399  			case 1:  return "a -t7z -sfx -m0=LZMA -r0 -mx=5 --";
   400  			case 2:  return "a -t7z -sfx -m0=LZMA -r0 -mx=1 --";
   401  			default: return "a -t7z -sfx -m0=PPMd -r0 -mx=9 --";
   402  		}
   403  	else
   404  		switch( method )
   405  		{
   406  			case 0:  return "a -t7z -m0=LZMA -r0 -mx=9 --";
   407  			case 1:  return "a -t7z -m0=LZMA -r0 -mx=5 --";
   408  			case 2:  return "a -t7z -m0=LZMA -r0 -mx=1 --";
   409  			default: return "a -t7z -m0=PPMd -r0 -mx=9 --";
   410  		}
   411  }
   412  
   413  int CArc7z::v_compress( const kiPath& base, const wfdArray& files, const kiPath& ddir, int method, bool sfx )
   414  {
   415  	m_SfxMode = sfx; // 処理を横取りしてSFXモードを記憶
   416  	return CArcDLL::v_compress(base,files,ddir,method,false);
   417  }
   418  
   419  const char* CArc7z::get_cmpr_ext( int method )
   420  {
   421  	return m_SfxMode ? "exe" : "7z";
   422  }
   423  
   424  //----------------------------------------------------------------------//
   425  
   426  DWORD CArc7zZip::set_cmpr_mhd()
   427  {
   428  	set_cmp_ext( "zip" );
   429  	add_cmp_mhd( "7-zip", true );
   430  	return aCompress|aArchive;
   431  }
   432  
   433  const char* CArc7zZip::get_cmpr_cmd( int method )
   434  {
   435  	return "a -tzip -r0 -mx=9 --";
   436  }
   437  
   438  int CArc7zZip::v_compress( const kiPath& base, const wfdArray& files, const kiPath& ddir, int method, bool sfx )
   439  {
   440  	// 処理を横取りして通常圧縮
   441  	return CArcDLL::v_compress(base,files,ddir,method,false);
   442  }
   443