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