OSDN Git Service

コンパイルエラーを修正。
[tpi/lychee.git] / src / plugin / 7zArc / 7zArc.cpp
1 /*******************************************************************************\r
2   TPI - flexible but useless plug-in framework.\r
3   Copyright (C) 2002-2009 Silky\r
4 \r
5   This library is free software; you can redistribute it and/or modify it under\r
6   the terms of the GNU Lesser General Public License as published by the Free\r
7   Software Foundation; either version 2.1 of the License, or (at your option)\r
8   any later version.\r
9 \r
10   This library is distributed in the hope that it will be useful, but WITHOUT\r
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \r
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\r
13   for more details.\r
14 \r
15   You should have received a copy of the GNU Lesser General Public License along\r
16   with this library; if not, write to the Free Software Foundation, Inc.,\r
17   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r
18 \r
19   $Id$\r
20 *******************************************************************************/\r
21 \r
22 //******************************************************************************\r
23 //    Includes\r
24 //******************************************************************************\r
25 \r
26 #define wxUSE_DYNLIB_CLASS 1\r
27 #include "../../common/header/plugin.h"\r
28 #include "../../common/header/plugin-extra.h"\r
29 #include "../../common/library/library.h"\r
30 #include <wx/dynlib.h>\r
31 #include "7zArc.h"\r
32 \r
33 #ifdef __LINUX__\r
34 #define LIB_NAME wxT("7z.so")\r
35 #else\r
36 #define LIB_NAME g_hLib.CanonicalizeName(wxT("7z"))\r
37 #endif\r
38 \r
39 //******************************************************************************\r
40 //    Global varients\r
41 //******************************************************************************\r
42 \r
43 wxDynamicLibrary g_hLib;\r
44 void * g_fpProc;\r
45 TPI_PROC g_prProc;\r
46 wxULongLong_t g_nEngineId;\r
47 \r
48 #ifdef __LINUX__\r
49 extern int global_use_utf16_conversion;\r
50 #endif\r
51 \r
52 //******************************************************************************\r
53 //    Inside Functions\r
54 //******************************************************************************\r
55 \r
56 int GetFileInformation2(void * _hArchive, TPI_FILEINFO * _fiInfo, wxULongLong_t nIndex)\r
57 {\r
58         IInArchive * hArc = (IInArchive *) _hArchive;\r
59         NWindows::NCOM::CPropVariant prop;\r
60         hArc->GetProperty(nIndex, kpidAttrib, & prop);\r
61         _fiInfo->dwAttribute    = prop.vt == VT_EMPTY ? 0 : prop.uintVal;\r
62         hArc->GetProperty(nIndex, kpidEncrypted, & prop);\r
63         if (prop.vt == VT_BOOL && VARIANT_BOOLToBool(prop.boolVal))\r
64         {\r
65                 _fiInfo->dwAttribute |= TPI_ATTRIBUTE_ENCRYPTED;\r
66         }\r
67         hArc->GetProperty(nIndex, kpidIsDir, & prop);\r
68         if (prop.vt == VT_BOOL && VARIANT_BOOLToBool(prop.boolVal))\r
69         {\r
70                 _fiInfo->dwAttribute |= TPI_ATTRIBUTE_DIRECTORY;\r
71         }\r
72         hArc->GetProperty(nIndex, kpidCRC, & prop);\r
73         _fiInfo->dwCRC32        = prop.ulVal;\r
74         hArc->GetProperty(nIndex, kpidPackSize, & prop);\r
75         _fiInfo->nPackedSize    = prop.vt == VT_EMPTY ? 0 : prop.vt == VT_UI8 ? prop.uhVal.QuadPart : prop.ulVal;\r
76         hArc->GetProperty(nIndex, kpidSize, & prop);\r
77         _fiInfo->nUnpackedSize  = prop.vt == VT_EMPTY ? 0 : prop.vt == VT_UI8 ? prop.uhVal.QuadPart : prop.ulVal;\r
78         unsigned int t;\r
79         hArc->GetProperty(nIndex, kpidMTime, & prop);\r
80         if (prop.vt == VT_FILETIME)\r
81         {\r
82                 NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
83                 _fiInfo->tmModified.Set((time_t) t);\r
84         }\r
85         hArc->GetProperty(nIndex, kpidCTime, & prop);\r
86         if (prop.vt == VT_FILETIME)\r
87         {\r
88                 NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
89                 _fiInfo->tmCreate.Set((time_t) t);\r
90         }\r
91         hArc->GetProperty(nIndex, kpidATime, & prop);\r
92         if (prop.vt == VT_FILETIME)\r
93         {\r
94                 NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
95                 _fiInfo->tmAccess.Set((time_t) t);\r
96         }\r
97         hArc->GetProperty(nIndex, kpidPath, & prop);\r
98         if (prop.vt == VT_BSTR)\r
99         {\r
100                 _fiInfo->szStoredName = WC2String(prop.bstrVal);\r
101         }\r
102         else\r
103         {\r
104                 hArc->GetProperty(nIndex, kpidExtension, & prop);\r
105                 _fiInfo->szStoredName = wxT("data") + (prop.vt == VT_BSTR ? wxT(".") + WC2String(prop.bstrVal) : (wxString) wxEmptyString);\r
106         }\r
107         _fiInfo->fnFileName     = wxFileName(_fiInfo->szStoredName, wxPATH_DOS);\r
108         hArc->GetProperty(nIndex, kpidMethod, & prop);\r
109         if (prop.vt == VT_BSTR)\r
110         {\r
111                 _fiInfo->szMethod = WC2String(prop.bstrVal);\r
112         }\r
113         hArc->GetProperty(nIndex, kpidComment, & prop);\r
114         if (prop.vt == VT_BSTR)\r
115         {\r
116                 _fiInfo->szComment  = WC2String(prop.bstrVal);\r
117         }\r
118         _fiInfo->nFileId        = nIndex;\r
119         return TPI_ERROR_SUCCESS;\r
120 }\r
121 \r
122 int __stdcall GetFormatInformation2(TPI_FORMATINFO * _fiInfo, wxULongLong_t & nIndex)\r
123 {\r
124         // Initialization.\r
125         _fiInfo->fArchive           = true;\r
126         _fiInfo->fComment           = false;\r
127         _fiInfo->fEncryptKeyFile    = false;\r
128         _fiInfo->fEncryptPassword   = false;\r
129         _fiInfo->fEncryptHeader     = false;\r
130         _fiInfo->fCompressHeader    = false;\r
131         _fiInfo->fMMOptimize        = false;\r
132         _fiInfo->fMultiVolume       = false;\r
133         _fiInfo->fSFX               = false;\r
134         _fiInfo->fSolid             = false;\r
135         _fiInfo->nCompressLevelMin  = 0;\r
136         _fiInfo->nCompressLevelMax  = 0;\r
137         _fiInfo->nRecoveryRecordMin = 0;\r
138         _fiInfo->nRecoveryRecordMax = 0;\r
139         _fiInfo->szTypeName.Empty();\r
140         _fiInfo->szSuffix.Empty();\r
141         _fiInfo->szEngineName       = LIB_NAME;\r
142         _fiInfo->szTPIName          = wxT("7zArc");\r
143         _fiInfo->eSupportedCommand  = TPI_COMMAND_EXTRACT | TPI_COMMAND_TEST;\r
144         _fiInfo->nTypeId            = nIndex;\r
145         _fiInfo->pCustomInfo        = NULL;\r
146         wxULongLong_t nBase = nIndex++;\r
147         if (nBase >= sizeof(guidList) / sizeof(GUID))\r
148         {\r
149                 return TPI_ERROR_S_ENDOFDATA;\r
150         }\r
151         else if (guidList[nBase] == CLSID_CFormatZip)\r
152         {\r
153                 _fiInfo->szTypeName          = wxT("7-zip");\r
154                 _fiInfo->szSuffix            = wxT("zip");\r
155                 _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;// | TPI_COMMAND_ADD;\r
156                 _fiInfo->fSFX                = true;\r
157                 _fiInfo->fMultiVolume        = true;\r
158                 _fiInfo->fEncryptPassword    = true;\r
159                 _fiInfo->nCompressLevelMin   = 0;\r
160                 _fiInfo->nCompressLevelMax   = 9;\r
161         }\r
162         else if (guidList[nBase] == CLSID_CFormatBZip2)\r
163         {\r
164                 _fiInfo->szTypeName          = wxT("BZip2");\r
165                 _fiInfo->szSuffix            = wxT("bz2");\r
166                 _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;\r
167                 _fiInfo->fArchive            = false;\r
168                 _fiInfo->nCompressLevelMin   = 1;\r
169                 _fiInfo->nCompressLevelMax   = 9;\r
170         }\r
171 //      else if (guidList[nBase] == CLSID_CFormatRar)  { _fiInfo->szTypeName = wxT("Rar");     _fiInfo->szSuffix = wxT("rar"); }\r
172 #ifdef __LINUX__\r
173         else if (guidList[nBase] == CLSID_CFormatArj)  { _fiInfo->szTypeName = wxT("Arj");     _fiInfo->szSuffix = wxT("arj"); _fiInfo->fEncryptPassword = true; _fiInfo->fSFX = true; }\r
174 #endif\r
175         else if (guidList[nBase] == CLSID_CFormatZ)    { _fiInfo->szTypeName = wxT("Z");       _fiInfo->szSuffix = wxT("Z"); _fiInfo->fArchive = false; }\r
176 #ifdef __LINUX__\r
177         else if (guidList[nBase] == CLSID_CFormatLzh)  { _fiInfo->szTypeName = wxT("Lzh");     _fiInfo->szSuffix = wxT("lzh;lha;lzs"); _fiInfo->fSFX = true; }\r
178 #endif\r
179         else if (guidList[nBase] == CLSID_CFormat7z)\r
180         {\r
181                 _fiInfo->szTypeName          = wxT("7z");\r
182                 _fiInfo->szSuffix            = wxT("7z");\r
183                 _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;// | TPI_COMMAND_ADD;\r
184                 _fiInfo->fSFX                = true;\r
185                 _fiInfo->fMultiVolume        = true;\r
186                 _fiInfo->fSolid              = true;\r
187                 _fiInfo->fEncryptPassword    = true;\r
188                 _fiInfo->fEncryptHeader      = true;\r
189                 _fiInfo->fCompressHeader     = true;\r
190                 _fiInfo->nCompressLevelMin   = 0;\r
191                 _fiInfo->nCompressLevelMax   = 9;\r
192         }\r
193 #ifdef __LINUX__\r
194         else if (guidList[nBase] == CLSID_CFormatCab)  { _fiInfo->szTypeName = wxT("Cab");     _fiInfo->szSuffix = wxT("cab"); _fiInfo->fMultiVolume = true; _fiInfo->fSFX = true; }\r
195 #endif\r
196         else if (guidList[nBase] == CLSID_CFormatNsis) { _fiInfo->szTypeName = wxT("NSIS");    _fiInfo->szSuffix = wxT("exe"); _fiInfo->fSFX = true; }\r
197         else if (guidList[nBase] == CLSID_CFormatLzma) { _fiInfo->szTypeName = wxT("LZMA");    _fiInfo->szSuffix = wxT("lzma"); _fiInfo->fArchive = false; }\r
198         else if (guidList[nBase] == CLSID_CFormatLzma86){_fiInfo->szTypeName = wxT("LZMA86");  _fiInfo->szSuffix = wxT("lzma"); _fiInfo->fArchive = false; }\r
199         else if (guidList[nBase] == CLSID_CFormatXz)\r
200         {\r
201                 _fiInfo->szTypeName          = wxT("XZ");\r
202                 _fiInfo->szSuffix            = wxT("xz");\r
203                 _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;\r
204                 _fiInfo->fArchive            = false;\r
205                 _fiInfo->nCompressLevelMin   = 0;\r
206                 _fiInfo->nCompressLevelMax   = 9;\r
207         }\r
208         else if (guidList[nBase] == CLSID_CFormatApm)  { _fiInfo->szTypeName = wxT("Apm");     _fiInfo->szSuffix = wxT("apm"); }\r
209         else if (guidList[nBase] == CLSID_CFormatMslz) { _fiInfo->szTypeName = wxT("MSLZ");    _fiInfo->szSuffix = wxT("xx_"); _fiInfo->fArchive = false; }\r
210         else if (guidList[nBase] == CLSID_CFormatFlv)  { _fiInfo->szTypeName = wxT("Flv");     _fiInfo->szSuffix = wxT("flv"); }\r
211 //      else if (guidList[nBase] == CLSID_CFormatSwf)  { _fiInfo->szTypeName = wxT("Swf");     _fiInfo->szSuffix = wxT("swf"); }\r
212         else if (guidList[nBase] == CLSID_CFormatSwfc) { _fiInfo->szTypeName = wxT("Swfc");    _fiInfo->szSuffix = wxT("swf"); }\r
213         else if (guidList[nBase] == CLSID_CFormatNtfs) { _fiInfo->szTypeName = wxT("NTFS");    _fiInfo->szSuffix = wxT("ntfs");}\r
214         else if (guidList[nBase] == CLSID_CFormatFat)  { _fiInfo->szTypeName = wxT("FAT");     _fiInfo->szSuffix = wxT("fat"); }\r
215         else if (guidList[nBase] == CLSID_CFormatMbr)  { _fiInfo->szTypeName = wxT("Mbr");     _fiInfo->szSuffix = wxT("mbr"); }\r
216         else if (guidList[nBase] == CLSID_CFormatVhd)  { _fiInfo->szTypeName = wxT("Vhd");     _fiInfo->szSuffix = wxT("vhd"); }\r
217 //      else if (guidList[nBase] == CLSID_CFormatPe)   { _fiInfo->szTypeName = wxT("PE");      _fiInfo->szSuffix = wxT("exe"); _fiInfo->fArchive = false; }\r
218 //      else if (guidList[nBase] == CLSID_CFormatElf)  { _fiInfo->szTypeName = wxT("ELF");     _fiInfo->fArchive = false; }\r
219         else if (guidList[nBase] == CLSID_CFormatMachO){ _fiInfo->szTypeName = wxT("Mach-O"); }\r
220         else if (guidList[nBase] == CLSID_CFormatUdf)  { _fiInfo->szTypeName = wxT("Udf");     _fiInfo->szSuffix = wxT("udf"); }\r
221         else if (guidList[nBase] == CLSID_CFormatXar)  { _fiInfo->szTypeName = wxT("Xar");     _fiInfo->szSuffix = wxT("xar"); }\r
222         else if (guidList[nBase] == CLSID_CFormatMub)  { _fiInfo->szTypeName = wxT("Mub");     _fiInfo->szSuffix = wxT("mub"); }\r
223         else if (guidList[nBase] == CLSID_CFormatHfs)  { _fiInfo->szTypeName = wxT("HFS");     _fiInfo->szSuffix = wxT("hfs"); }\r
224         else if (guidList[nBase] == CLSID_CFormatDmg)  { _fiInfo->szTypeName = wxT("DMG");     _fiInfo->szSuffix = wxT("dmg"); }\r
225         else if (guidList[nBase] == CLSID_CFormatCom)  { _fiInfo->szTypeName = wxT("Compound");_fiInfo->szSuffix = wxT("msi"); _fiInfo->fSFX = true; }\r
226         else if (guidList[nBase] == CLSID_CFormatWim)\r
227         {\r
228                 _fiInfo->szTypeName          = wxT("WIM");\r
229                 _fiInfo->szSuffix            = wxT("wim");\r
230                 _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;// | TPI_COMMAND_ADD;\r
231         }\r
232         else if (guidList[nBase] == CLSID_CFormatIso)  { _fiInfo->szTypeName = wxT("ISO");     _fiInfo->szSuffix = wxT("iso"); }\r
233         else if (guidList[nBase] == CLSID_CFormatBkf)  { _fiInfo->szTypeName = wxT("Bkf");     _fiInfo->szSuffix = wxT("bkf"); }\r
234         else if (guidList[nBase] == CLSID_CFormatChm)  { _fiInfo->szTypeName = wxT("Chm");     _fiInfo->szSuffix = wxT("chm"); }\r
235         else if (guidList[nBase] == CLSID_CFormatSplit){ _fiInfo->szTypeName = wxT("Split"); }\r
236 #ifdef __LINUX__\r
237         else if (guidList[nBase] == CLSID_CFormatRpm)  { _fiInfo->szTypeName = wxT("RPM");     _fiInfo->szSuffix = wxT("rpm"); _fiInfo->fArchive = false; }\r
238         else if (guidList[nBase] == CLSID_CFormatDeb)  { _fiInfo->szTypeName = wxT("Deb");     _fiInfo->szSuffix = wxT("deb"); }\r
239         else if (guidList[nBase] == CLSID_CFormatCpio) { _fiInfo->szTypeName = wxT("Cpio");    _fiInfo->szSuffix = wxT("cpio");}\r
240         else if (guidList[nBase] == CLSID_CFormatTar)\r
241         {\r
242                 _fiInfo->szTypeName          = wxT("TAR");\r
243                 _fiInfo->szSuffix            = wxT("tar");\r
244                 _fiInfo->fSFX                = true;\r
245                 _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;// | TPI_COMMAND_ADD;\r
246         }\r
247 #endif\r
248         else if (guidList[nBase] == CLSID_CFormatGZip)\r
249         {\r
250                 _fiInfo->szTypeName          = wxT("GZip");\r
251                 _fiInfo->szSuffix            = wxT("gz");\r
252                 _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;\r
253                 _fiInfo->fArchive            = false;\r
254                 _fiInfo->nCompressLevelMin   = 1;\r
255                 _fiInfo->nCompressLevelMax   = 9;\r
256         }\r
257         else\r
258         {\r
259                 return GetFormatInformation2(_fiInfo, nIndex);\r
260         }\r
261         return TPI_ERROR_SUCCESS;\r
262 }\r
263 \r
264 //******************************************************************************\r
265 //    Callback Wrapper\r
266 //******************************************************************************\r
267 \r
268 // CArchiveOpenCallback\r
269 class CArchiveOpenCallback: public IArchiveOpenCallback, public IArchiveOpenVolumeCallback, public IArchiveOpenSetSubArchiveName, public ICryptoGetTextPassword, public CMyUnknownImp\r
270 {\r
271 public:\r
272         MY_UNKNOWN_IMP1(ICryptoGetTextPassword)\r
273         INTERFACE_IArchiveOpenCallback(;)\r
274         INTERFACE_IArchiveOpenVolumeCallback(;)\r
275         STDMETHOD(SetSubArchiveName)(const wchar_t * szName);\r
276         STDMETHOD(CryptoGetTextPassword)(BSTR *password);\r
277         int nErrorCode;\r
278         wxString szSubArchiveName;\r
279         NWindows::NFile::NFind::CFileInfoW fiInfo;\r
280 \r
281 private:\r
282         TPI_PROCESSINFO piInfo;\r
283 };\r
284 \r
285 STDMETHODIMP CArchiveOpenCallback::SetTotal(const wxULongLong_t *, const wxULongLong_t *)\r
286 {\r
287         return S_OK;\r
288 }\r
289 \r
290 STDMETHODIMP CArchiveOpenCallback::SetCompleted(const wxULongLong_t *, const wxULongLong_t *)\r
291 {\r
292         return S_OK;\r
293 }\r
294 \r
295 STDMETHODIMP CArchiveOpenCallback::GetProperty(PROPID propID, PROPVARIANT * value)\r
296 {\r
297         NWindows::NCOM::CPropVariant prop;\r
298         if (! this->szSubArchiveName.IsEmpty())\r
299         {\r
300                 switch (propID)\r
301                 {\r
302                         case kpidName: prop = (wxChar *) this->szSubArchiveName.wchar_str(); break;\r
303                 }\r
304         }\r
305         else\r
306         {\r
307                 switch (propID)\r
308                 {\r
309                         case kpidName:  prop = this->fiInfo.Name; break;\r
310                         case kpidIsDir: prop = this->fiInfo.IsDir(); break;\r
311                         case kpidSize:  prop = this->fiInfo.Size; break;\r
312                         case kpidAttrib:prop = (unsigned int) this->fiInfo.Attrib; break;\r
313                         case kpidCTime: prop = this->fiInfo.CTime; break;\r
314                         case kpidATime: prop = this->fiInfo.ATime; break;\r
315                         case kpidMTime: prop = this->fiInfo.MTime; break;\r
316                 }\r
317         }\r
318         prop.Detach(value);\r
319         return S_OK;\r
320 }\r
321 \r
322 STDMETHODIMP CArchiveOpenCallback::GetStream(const wchar_t * szName, IInStream ** inStream)\r
323 {\r
324         if (! this->szSubArchiveName.IsEmpty())\r
325         {\r
326                 return S_FALSE;\r
327         }\r
328         * inStream = NULL;\r
329         wxString szFileName = this->piInfo.fiInfo.fnFileName.GetPathWithSep() + szName;\r
330         if (! this->fiInfo.Find(szFileName.c_str()) || fiInfo.IsDir())\r
331         {\r
332                 this->nErrorCode = TPI_ERROR_IO_ARC_OPEN;\r
333                 return S_FALSE;\r
334         }\r
335 \r
336         CInFileStream * inFile = new CInFileStream;\r
337         CMyComPtr<IInStream> inStreamTemp = inFile;\r
338         if (! inFile->Open(szFileName.c_str()))\r
339         {\r
340                 this->nErrorCode = TPI_ERROR_IO_ARC_OPEN;\r
341                 return S_FALSE;\r
342         }\r
343         * inStream = inStreamTemp.Detach();\r
344         return S_OK;\r
345 }\r
346 \r
347 STDMETHODIMP CArchiveOpenCallback::SetSubArchiveName(const wchar_t * szName)\r
348 {\r
349         this->szSubArchiveName = WC2String(szName);\r
350         return S_OK;\r
351 }\r
352 \r
353 STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR * szPassword)\r
354 {\r
355         this->piInfo.eMessage           = TPI_MESSAGE_ASK;\r
356         this->piInfo.eStatus            = TPI_PARAM_PASSWORD;\r
357         return (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE) ? ::StringToBstr(this->piInfo.szParam.c_str(), szPassword) : E_ABORT;\r
358 }\r
359 \r
360 // CArchiveExtractCallback\r
361 class CArchiveExtractCallback: public IArchiveExtractCallback, public ICryptoGetTextPassword, public CMyUnknownImp\r
362 {\r
363 public:\r
364         MY_UNKNOWN_IMP1(ICryptoGetTextPassword)\r
365         INTERFACE_IArchiveExtractCallback(;)\r
366         STDMETHOD(CryptoGetTextPassword)(BSTR * szPassword);\r
367         CArchiveExtractCallback(CMyComPtr<IInArchive>, TPI_SWITCHES *);\r
368 \r
369         int nErrorCode;\r
370         TPI_SWITCHES * swInfo;\r
371 \r
372 private:\r
373         int nMode;\r
374         bool fTriedPassword;\r
375         TPI_PROCESSINFO piInfo;\r
376         wxULongLong_t nCurrentPos;\r
377         COutFileStream * _outFileStreamSpec;\r
378         CMyComPtr<ISequentialOutStream> _outFileStream;\r
379         CMyComPtr<IInArchive> hArc;\r
380 };\r
381 \r
382 CArchiveExtractCallback::CArchiveExtractCallback(CMyComPtr<IInArchive> hArc, TPI_SWITCHES * swInfo)\r
383 {\r
384         this->hArc = hArc;\r
385         this->swInfo = swInfo;\r
386         this->fTriedPassword = false;\r
387 }\r
388 \r
389 STDMETHODIMP CArchiveExtractCallback::SetTotal(wxULongLong_t)\r
390 {\r
391         return S_OK;\r
392 }\r
393 \r
394 STDMETHODIMP CArchiveExtractCallback::SetCompleted(const wxULongLong_t * nProcessed)\r
395 {\r
396         this->piInfo.eStatus                = TPI_STATUS_INPROCESS;\r
397         this->piInfo.nProcessedSize     = * nProcessed - this->nCurrentPos;\r
398         if (g_prProc == NULL || this->piInfo.fiInfo.szStoredName.IsEmpty() || ! this->piInfo.fnDestination.IsOk() || g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE)\r
399         {\r
400                 return S_OK;\r
401         }\r
402         else\r
403         {\r
404                 this->nErrorCode = TPI_ERROR_D_SKIPPED;\r
405                 return E_ABORT;\r
406         }\r
407 }\r
408 \r
409 STDMETHODIMP CArchiveExtractCallback::GetStream(unsigned int nIndex, ISequentialOutStream ** outStream, int nExtractMode)\r
410 {\r
411         * outStream = 0;\r
412         _outFileStream.Release();\r
413 \r
414         // 前のファイルの処理の終了を通知。\r
415         this->nCurrentPos += this->piInfo.fiInfo.nUnpackedSize;\r
416         if (this->nCurrentPos != 0)\r
417         {\r
418                 this->piInfo.eMessage   = TPI_MESSAGE_STATUS;\r
419                 this->piInfo.eStatus    = TPI_STATUS_ENDPROCESS;\r
420                 if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)\r
421                 {\r
422                         this->nErrorCode = TPI_ERROR_D_SKIPPED;\r
423                         return E_ABORT;\r
424                 }\r
425         }\r
426 \r
427         // ファイルを処理するか確認。\r
428         this->piInfo.eMessage   = TPI_MESSAGE_ASK;\r
429         this->piInfo.eStatus    = TPI_PARAM_DEST;\r
430         GetFileInformation2(this->hArc, & this->piInfo.fiInfo, nIndex);\r
431         this->piInfo.fnDestination          = wxFileName(swInfo->fnDestinationDirectory.GetFullPath() + wxFileName::GetPathSeparator() + (swInfo->fStoreDirectoryPathes ? this->piInfo.fiInfo.fnFileName.GetPath() : (wxString) wxEmptyString), this->piInfo.fiInfo.fnFileName.GetFullName(), wxPATH_DOS);\r
432         if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)\r
433         {\r
434                 this->nErrorCode = TPI_ERROR_D_SKIPPED;\r
435                 return E_ABORT;\r
436         }\r
437         if (! piInfo.fnDestination.IsOk())\r
438         {\r
439                 return S_OK;\r
440         }\r
441 \r
442         // ファイルの基本情報を取得。\r
443         this->piInfo.eMessage   = TPI_MESSAGE_STATUS;\r
444         this->piInfo.eStatus    = TPI_STATUS_BEGINPROCESS;\r
445         if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)\r
446         {\r
447                 this->nErrorCode = TPI_ERROR_D_SKIPPED;\r
448                 return E_ABORT;\r
449         }\r
450 \r
451         if (nExtractMode != NArchive::NExtract::NAskMode::kExtract)\r
452         {\r
453                 return S_OK;\r
454         }\r
455 \r
456         // ディレクトリかどうかを判定し、必要なディレクトリを作成。\r
457         if (! ::wxFileName::Mkdir(this->piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? this->piInfo.fnDestination.GetFullPath() : this->piInfo.fnDestination.GetPath(), 0777, wxPATH_MKDIR_FULL))\r
458         {\r
459                 this->nErrorCode = TPI_ERROR_IO_DIR_OPEN;\r
460                 return E_ABORT;\r
461         }\r
462         if (this->piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)\r
463         {\r
464                 return S_OK;\r
465         }\r
466 \r
467         // ファイルを作成。\r
468         _outFileStreamSpec = new COutFileStream;\r
469         CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);\r
470         if (! _outFileStreamSpec->Open(this->piInfo.fnDestination.GetFullPath(), CREATE_NEW))\r
471         {\r
472                 this->nErrorCode = TPI_ERROR_IO_FILE_OPEN;\r
473                 return E_ABORT;\r
474         }\r
475 \r
476         _outFileStream = outStreamLoc;\r
477         * outStream = outStreamLoc.Detach();\r
478         return S_OK;\r
479 }\r
480 \r
481 STDMETHODIMP CArchiveExtractCallback::PrepareOperation(int nExtractMode)\r
482 {\r
483         this->nMode = nExtractMode;\r
484         return S_OK;\r
485 }\r
486 \r
487 STDMETHODIMP CArchiveExtractCallback::SetOperationResult(int nResult)\r
488 {\r
489         switch (nResult)\r
490         {\r
491         case NArchive::NExtract::NOperationResult::kOK:                this->nErrorCode = TPI_ERROR_SUCCESS;         break;\r
492         case NArchive::NExtract::NOperationResult::kUnSupportedMethod: this->nErrorCode = TPI_ERROR_ARC_UNSUPPORTED; break;\r
493         case NArchive::NExtract::NOperationResult::kDataError:         this->nErrorCode = TPI_ERROR_ARC_BROKEN_MISC; break;\r
494         case NArchive::NExtract::NOperationResult::kCRCError:          this->nErrorCode = TPI_ERROR_ARC_BROKEN_SUM;  break;\r
495         default:                                                       this->nErrorCode = TPI_ERROR_UNDEFINED;       break;\r
496         }\r
497 \r
498         // 更新時刻を記録。\r
499         if (_outFileStream != NULL)\r
500         {\r
501                 FILETIME ft;\r
502                 NWindows::NTime::UnixTimeToFileTime(this->piInfo.fiInfo.tmModified.GetTicks(), ft);\r
503                 _outFileStreamSpec->SetMTime(& ft);\r
504                 _outFileStreamSpec->Close();\r
505         }\r
506         _outFileStream.Release();\r
507 \r
508         // 属性を記録。\r
509         if (this->nMode == NArchive::NExtract::NAskMode::kExtract)\r
510         {\r
511 //              NWindows::NFile::NDirectory::MySetFileAttributes(this->piInfo.fiInfo.fnFileName.GetFullPath(), this->piInfo.fiInfo.dwAttribute);\r
512         }\r
513 \r
514         return S_OK;\r
515 }\r
516 \r
517 STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR * szPassword)\r
518 {\r
519         if (this->fTriedPassword || this->swInfo->szPassword.IsEmpty())\r
520         {\r
521                 this->piInfo.eMessage           = TPI_MESSAGE_ASK;\r
522                 this->piInfo.eStatus            = TPI_PARAM_PASSWORD;\r
523                 // 次のファイル名が取得できないので、とりあえず空にしておく。\r
524                 this->piInfo.fiInfo.fnFileName.Clear();\r
525                 return (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE) ? ::StringToBstr(this->piInfo.szParam.c_str(), szPassword) : E_ABORT;\r
526         }\r
527         else\r
528         {\r
529                 // 既定のパスワードがある場合はまずそれを試す。\r
530                 this->fTriedPassword = true;\r
531                 return ::StringToBstr(this->swInfo->szPassword, szPassword);\r
532         }\r
533 }\r
534 \r
535 // CArchiveUpdateCallback\r
536 class CArchiveUpdateCallback: public IArchiveUpdateCallback2, public ICryptoGetTextPassword2, public CMyUnknownImp\r
537 {\r
538 public:\r
539         MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)\r
540         INTERFACE_IArchiveUpdateCallback2(;)\r
541         STDMETHOD(CryptoGetTextPassword2)(int * nPasswordIsDefined, BSTR * szPassword);\r
542         CArchiveUpdateCallback(TPI_SWITCHES *, CObjectVector<NWindows::NFile::NFind::CFileInfoW> *);\r
543 \r
544         const CObjectVector<NWindows::NFile::NFind::CFileInfoW> * fiItems;\r
545         int nErrorCode;\r
546 \r
547 private:\r
548         wxULongLong_t nCurrentPos;\r
549         TPI_PROCESSINFO piInfo;\r
550         TPI_SWITCHES * swInfo;\r
551 };\r
552 \r
553 CArchiveUpdateCallback::CArchiveUpdateCallback(TPI_SWITCHES * swInfo, CObjectVector<NWindows::NFile::NFind::CFileInfoW> * fiItems)\r
554 {\r
555         this->swInfo = swInfo;\r
556         this->fiItems = fiItems;\r
557 }\r
558 \r
559 STDMETHODIMP CArchiveUpdateCallback::SetTotal(wxULongLong_t)\r
560 {\r
561         return S_OK;\r
562 }\r
563 \r
564 STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const wxULongLong_t * nProcessed)\r
565 {\r
566         this->piInfo.eStatus            = TPI_STATUS_INPROCESS;\r
567         this->piInfo.nProcessedSize     = * nProcessed - this->nCurrentPos;\r
568         if (g_prProc == NULL || this->piInfo.fiInfo.szStoredName.IsEmpty() || g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE)\r
569         {\r
570                 return S_OK;\r
571         }\r
572         else\r
573         {\r
574                 this->nErrorCode = TPI_ERROR_D_SKIPPED;\r
575                 return E_ABORT;\r
576         }\r
577 }\r
578 \r
579 STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(unsigned int /* index */, int *newData, int *newProperties, unsigned int *indexInArchive)\r
580 {\r
581         if (newData != NULL)\r
582         {\r
583                 * newData = 1;\r
584         }\r
585         if (newProperties != NULL)\r
586         {\r
587                 * newProperties = 1;\r
588         }\r
589         if (indexInArchive != NULL)\r
590         {\r
591                 * indexInArchive = (unsigned) -1;\r
592         }\r
593         return S_OK;\r
594 }\r
595 \r
596 STDMETHODIMP CArchiveUpdateCallback::GetProperty(unsigned int nIndex, PROPID propID, PROPVARIANT * value)\r
597 {\r
598         NWindows::NCOM::CPropVariant prop;\r
599         if (propID == kpidIsAnti)\r
600         {\r
601                 prop = false;\r
602                 prop.Detach(value);\r
603                 return S_OK;\r
604         }\r
605 \r
606         const NWindows::NFile::NFind::CFileInfoW fiItem = (* this->fiItems)[nIndex];\r
607         switch (propID)\r
608         {\r
609                 case kpidPath:  prop = fiItem.Name;  break;\r
610                 case kpidIsDir: prop = (unsigned int) fiItem.Attrib & TPI_ATTRIBUTE_DIRECTORY ? true : false; break;\r
611                 case kpidSize:  prop = fiItem.Size;  break;\r
612                 case kpidAttrib:prop = (unsigned int) fiItem.Attrib;break;\r
613                 case kpidCTime: prop = fiItem.CTime; break;\r
614                 case kpidATime: prop = fiItem.ATime; break;\r
615                 case kpidMTime: prop = fiItem.MTime; break;\r
616         }\r
617         prop.Detach(value);\r
618         return S_OK;\r
619 }\r
620 \r
621 STDMETHODIMP CArchiveUpdateCallback::GetStream(unsigned int nIndex, ISequentialInStream ** inStream)\r
622 {\r
623         // 前のファイルの処理の終了を通知。\r
624         this->nCurrentPos += this->piInfo.fiInfo.nUnpackedSize;\r
625         this->piInfo.eMessage               = TPI_MESSAGE_STATUS;\r
626         if (this->nCurrentPos != 0)\r
627         {\r
628                 this->piInfo.eStatus            = TPI_STATUS_ENDPROCESS;\r
629                 if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)\r
630                 {\r
631                         this->nErrorCode = TPI_ERROR_D_SKIPPED;\r
632                         return E_ABORT;\r
633                 }\r
634         }\r
635 \r
636         // ファイルの基本情報を取得。\r
637         NWindows::NCOM::CPropVariant prop;\r
638         this->GetProperty(nIndex, kpidAttrib, & prop);\r
639         this->piInfo.fiInfo.dwAttribute     = prop.uintVal;\r
640         this->GetProperty(nIndex, kpidSize, & prop);\r
641         this->piInfo.fiInfo.nUnpackedSize   = prop.vt == VT_UI8 ? prop.uhVal.QuadPart : prop.ulVal;\r
642         unsigned int t;\r
643         this->GetProperty(nIndex, kpidMTime, & prop);\r
644         NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
645         this->piInfo.fiInfo.tmModified.Set((time_t) t);\r
646         this->GetProperty(nIndex, kpidCTime, & prop);\r
647         NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
648         this->piInfo.fiInfo.tmCreate.Set((time_t) t);\r
649         this->GetProperty(nIndex, kpidATime, & prop);\r
650         NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
651         this->piInfo.fiInfo.tmAccess.Set((time_t) t);\r
652         this->GetProperty(nIndex, kpidPath, & prop);\r
653         this->piInfo.fiInfo.szStoredName = WC2String(prop.bstrVal);\r
654         this->piInfo.fiInfo.nFileId         = nIndex;\r
655         this->piInfo.fiInfo.fnFileName      = wxFileName(this->piInfo.fiInfo.szStoredName, wxPATH_DOS);\r
656         this->piInfo.fiInfo.fnFileName.Normalize(wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG, this->swInfo->fnDestinationDirectory.GetFullPath());\r
657         this->piInfo.eStatus                = TPI_STATUS_BEGINPROCESS;\r
658         this->piInfo.fnDestination          = wxFileName(this->piInfo.fiInfo.szStoredName, wxPATH_DOS);\r
659 \r
660         // コールバック関数に送信。\r
661         if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)\r
662         {\r
663                 this->nErrorCode = TPI_ERROR_D_SKIPPED;\r
664                 return E_ABORT;\r
665         }\r
666 \r
667         if (this->piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)\r
668         {\r
669                 return S_OK;\r
670         }\r
671 \r
672         CInFileStream * inStreamSpec = new CInFileStream;\r
673         CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);\r
674         if (! inStreamSpec->Open(this->piInfo.fiInfo.fnFileName.GetFullPath().c_str()))\r
675         {\r
676                 this->nErrorCode = TPI_ERROR_IO_FILE_OPEN;\r
677                 return S_FALSE;\r
678         }\r
679 \r
680         * inStream = inStreamLoc.Detach();\r
681         return S_OK;\r
682 }\r
683 \r
684 STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(int nResult)\r
685 {\r
686         switch (nResult)\r
687         {\r
688         case NArchive::NUpdate::NOperationResult::kOK:                 this->nErrorCode = TPI_ERROR_SUCCESS;         break;\r
689         case NArchive::NUpdate::NOperationResult::kError:\r
690         default:                                                       this->nErrorCode = TPI_ERROR_UNDEFINED;       break;\r
691         }\r
692         return S_OK;\r
693 }\r
694 \r
695 STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(unsigned int, wxULongLong_t * nSplitSize)\r
696 {\r
697         * nSplitSize = this->swInfo->nSplitSize;\r
698         return S_OK;\r
699 }\r
700 \r
701 STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(unsigned int nIndex, ISequentialOutStream ** volumeStream)\r
702 {\r
703         COutFileStream * streamSpec = new COutFileStream;\r
704         CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);\r
705         if (! streamSpec->Create(this->piInfo.fiInfo.fnFileName.GetFullPath() + wxString::Format(wxT(".%03d"), nIndex + 1), false))\r
706         {\r
707                 return TPI_ERROR_IO_ARC_OPEN;\r
708         }\r
709         * volumeStream = streamLoc.Detach();\r
710         return S_OK;\r
711 }\r
712 \r
713 STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(int * nPasswordIsDefined, BSTR * szPassword)\r
714 {\r
715         * nPasswordIsDefined = ! this->swInfo->szPassword.IsEmpty();\r
716         return ::StringToBstr(this->swInfo->szPassword.c_str(), szPassword);\r
717 }\r
718 \r
719 //******************************************************************************\r
720 //    Functions\r
721 //******************************************************************************\r
722 \r
723 #ifdef __cplusplus\r
724 extern "C"\r
725 {\r
726 #endif\r
727 \r
728 int __stdcall GetPluginInformation\r
729 (\r
730         unsigned int _uInfoId,\r
731         wxULongLong_t,\r
732         void * _pPtr\r
733 )\r
734 {\r
735         if (_pPtr == NULL)\r
736         {\r
737                 return TPI_ERROR_D_PARAMETER;\r
738         }\r
739         switch (_uInfoId)\r
740         {\r
741         case TPI_INFO_VERSION_MAJOR:\r
742         case TPI_INFO_VERSION_MINOR:\r
743                 * (int *) _pPtr = 0;\r
744                 break;\r
745         case TPI_INFO_VERSION_API:\r
746                 * (int *) _pPtr = 2;\r
747                 break;\r
748         default:\r
749                 return TPI_ERROR_D_UNSUPPORTED;\r
750         }\r
751         return TPI_ERROR_SUCCESS;\r
752 }\r
753 \r
754 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)\r
755 {\r
756         static wxULongLong_t s_nTypeId;\r
757         if (_bFirst)\r
758         {\r
759                 s_nTypeId = 0;\r
760         }\r
761         return GetFormatInformation2(_fiInfo, s_nTypeId);\r
762 }\r
763 \r
764 int __stdcall LoadPlugin\r
765 (\r
766         const wxString & _szArcName,\r
767         wxULongLong_t _nTypeId\r
768 )\r
769 {\r
770         ::RemoveCwdFromSearchPath();\r
771 #ifdef __LINUX__\r
772         global_use_utf16_conversion = 1;\r
773 #endif\r
774         g_hLib.Load(LIB_NAME);\r
775         if (! g_hLib.IsLoaded())\r
776         {\r
777                 g_hLib.Unload();\r
778                 return TPI_ERROR_U_LOAD_LIBRARY;\r
779         }\r
780 \r
781         if (! g_hLib.HasSymbol(wxT("CreateObject")))\r
782         {\r
783                 return TPI_ERROR_U_USE_LIBRARY;\r
784         }\r
785         g_fpProc = g_hLib.GetSymbol(wxT("CreateObject"));\r
786         if (! g_fpProc)\r
787         {\r
788                 return TPI_ERROR_U_USE_LIBRARY;\r
789         }\r
790 \r
791         if (! ::wxFileExists(_szArcName))\r
792         {\r
793                 g_nEngineId = _nTypeId;\r
794         }\r
795 \r
796         return TPI_ERROR_SUCCESS;\r
797 }\r
798 \r
799 int __stdcall FreePlugin\r
800 (\r
801         void * // _pReserved\r
802 )\r
803 {\r
804         g_hLib.Unload();\r
805         return TPI_ERROR_SUCCESS;\r
806 }\r
807 \r
808 int __stdcall OpenArchive\r
809 (\r
810         const wxString & _szArcName,\r
811         void * * _hArchive,\r
812         wxULongLong_t * _nFileCount\r
813 )\r
814 {\r
815         // ***.tar.xxxは不便なので弾く。\r
816         wxString s = _szArcName.BeforeLast(wxT('.'));\r
817         if (s.Find(wxT('.')) != wxNOT_FOUND && s.AfterLast(wxT('.')) == wxT("tar"))\r
818         {\r
819                 return TPI_ERROR_IO_ARC_OPEN;\r
820         }\r
821 \r
822         // 書庫形式を認識。\r
823         IInArchive * hArc;\r
824         for (wxULongLong_t i = 0; i < sizeof(guidList) / sizeof(GUID); )\r
825         {\r
826                 if (((unsigned int (__stdcall *)(const GUID *, const GUID *, void * *)) g_fpProc)(& guidList[i], & IID_IInArchive, (void **) & hArc) != S_OK)\r
827                 {\r
828                         i++;\r
829                         continue;\r
830                 }\r
831 \r
832                 // 書庫を開く。\r
833                 CInFileStream * fileSpec = new CInFileStream;\r
834                 CMyComPtr<IInStream> file = fileSpec;\r
835                 if (! fileSpec->Open(_szArcName.c_str()))\r
836                 {\r
837                         return TPI_ERROR_IO_ARC_OPEN;\r
838                 }\r
839 \r
840                 // 形式の情報を取得。\r
841                 g_nEngineId = i;\r
842                 TPI_FORMATINFO fiInfo;\r
843                 GetFormatInformation2(& fiInfo, i);\r
844 \r
845                 // 書庫として開く。\r
846                 CArchiveOpenCallback * openCallbackSpec = new CArchiveOpenCallback;\r
847                 CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);\r
848                 // SFXを完全に検出するには全体をロードする必要がある。\r
849                 wxULongLong_t nMax = fiInfo.fSFX ? 262114 : 1024;\r
850 /*\r
851                 if (fiInfo.fSFX)\r
852                 {\r
853                         fileSpec->GetSize(& nMax);\r
854                 }\r
855 */\r
856                 if (hArc->Open(file, & nMax, openCallback) == S_OK)\r
857                 {\r
858                         if (_nFileCount != NULL)\r
859                         {\r
860                                 unsigned int n;\r
861                                 hArc->GetNumberOfItems(& n);\r
862                                 * _nFileCount = n;\r
863                         }\r
864                         * _hArchive = hArc;\r
865                         return TPI_ERROR_SUCCESS;\r
866                 }\r
867         }\r
868         return TPI_ERROR_IO_ARC_OPEN;\r
869 }\r
870 \r
871 int __stdcall CloseArchive\r
872 (\r
873         void * _hArchive\r
874 )\r
875 {\r
876     IInArchive * hArc = (IInArchive *) _hArchive;\r
877         hArc->Close();\r
878         hArc->Release();\r
879         return TPI_ERROR_SUCCESS;\r
880 }\r
881 \r
882 int __stdcall GetFileInformation\r
883 (\r
884         void * _hArchive,\r
885         TPI_FILEINFO * _fiInfo,\r
886         bool _bFirst\r
887 )\r
888 {\r
889         static unsigned int s_uFileId, s_uFileCount;\r
890         if (_bFirst)\r
891         {\r
892                 s_uFileId = 0;\r
893                 ((IInArchive *) _hArchive)->GetNumberOfItems(& s_uFileCount);\r
894         }\r
895 \r
896         if (s_uFileId >= s_uFileCount)\r
897         {\r
898                 return TPI_ERROR_S_ENDOFDATA;\r
899         }\r
900 \r
901         return GetFileInformation2(_hArchive, _fiInfo, s_uFileId++);\r
902 }\r
903 \r
904 int __stdcall GetArchiveInformation\r
905 (\r
906         void * _hArchive,\r
907         TPI_ARCHIVEINFO * _aiInfo\r
908 )\r
909 {\r
910     IInArchive * hArc = (IInArchive *) _hArchive;\r
911         NWindows::NCOM::CPropVariant prop;\r
912         hArc->GetArchiveProperty(kpidSolid, & prop);\r
913         _aiInfo->fSolid         = VARIANT_BOOLToBool(prop.boolVal);\r
914         hArc->GetArchiveProperty(kpidComment, & prop);\r
915         if (prop.vt == VT_BSTR)\r
916         {\r
917                 _aiInfo->szComment  = WC2String(prop.bstrVal);\r
918         }\r
919         wxULongLong_t n = g_nEngineId;\r
920         GetFormatInformation2(& _aiInfo->fiInfo, n);\r
921         return TPI_ERROR_SUCCESS;\r
922 }\r
923 \r
924 int __stdcall Command\r
925 (\r
926         wxULongLong_t _eCommand,\r
927         TPI_SWITCHES * _swInfo,\r
928         const wxString & _szArcName,\r
929         const wxArrayString & _szFiles\r
930 )\r
931 {\r
932         // コマンドを実行。\r
933         int nErrorCode;\r
934         switch (_eCommand)\r
935         {\r
936         case TPI_COMMAND_EXTRACT:\r
937         case TPI_COMMAND_TEST:\r
938         {\r
939                 // 開きなおす。\r
940                 IInArchive * hArc;\r
941                 nErrorCode = OpenArchive(_szArcName, (void **) & hArc);\r
942                 if (nErrorCode != TPI_ERROR_SUCCESS)\r
943                 {\r
944                         return nErrorCode;\r
945                 }\r
946 \r
947                 // ファイル名からインデックスを取得。\r
948                 TPI_FILEINFO fiInfo;\r
949                 CRecordVector<unsigned int> nIndexes;\r
950                 if (GetFileInformation(hArc, & fiInfo, true) == TPI_ERROR_SUCCESS)\r
951                 {\r
952                         do\r
953                         {\r
954                                 if (_szFiles.Index(fiInfo.szStoredName) != wxNOT_FOUND)\r
955                                 {\r
956                                         nIndexes.Add(fiInfo.nFileId);\r
957                                 }\r
958                         }\r
959                         while (GetFileInformation(hArc, & fiInfo) == TPI_ERROR_SUCCESS);\r
960                 }\r
961 \r
962                 CArchiveExtractCallback * extractCallbackSpec = new CArchiveExtractCallback(hArc,_swInfo);\r
963                 CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);\r
964                 hArc->Extract(& nIndexes.Front(), nIndexes.Size(), _eCommand == TPI_COMMAND_TEST, extractCallback);\r
965                 nErrorCode = extractCallbackSpec->nErrorCode;\r
966                 CloseArchive(hArc);\r
967                 break;\r
968         }\r
969         case TPI_COMMAND_CREATE:\r
970 //      case TPI_COMMAND_ADD:\r
971         {\r
972                 // 入力リストを作成。\r
973                 CObjectVector<NWindows::NFile::NFind::CFileInfoW> fiItems;\r
974                 for (unsigned int i = 0; i < _szFiles.GetCount(); i++)\r
975                 {\r
976                         NWindows::NFile::NFind::CFileInfoW fi;\r
977                         wxFileName fn(_szFiles[i]);\r
978                         fn.Normalize(wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG, _swInfo->fnDestinationDirectory.GetFullPath());\r
979                         if (! fi.Find(fn.GetFullPath().c_str()))\r
980                         {\r
981                                 return TPI_ERROR_IO_FILE_ACCESS;\r
982                         }\r
983                         fiItems.Add(fi);\r
984                 }\r
985 \r
986                 // 書庫を作成。\r
987                 COutFileStream * outFileStreamSpec = new COutFileStream;\r
988                 CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;\r
989                 if (! outFileStreamSpec->Create(_szArcName.c_str(), false))\r
990                 {\r
991                         return TPI_ERROR_IO_ARC_OPEN;\r
992                 }\r
993 \r
994                 // エンジンを読み込み。\r
995                 IOutArchive * hArc;\r
996                 if (((unsigned int (__stdcall *)(const GUID *, const GUID *, void **)) g_fpProc)(& guidList[g_nEngineId], & IID_IOutArchive, (void **) & hArc) != S_OK)\r
997                 {\r
998                         return TPI_ERROR_ARC_UNSUPPORTED;\r
999                 }\r
1000 \r
1001                 // 形式情報を取得。\r
1002                 TPI_FORMATINFO fiInfo;\r
1003                 wxULongLong_t nIndex = g_nEngineId;\r
1004                 GetFormatInformation2(& fiInfo, nIndex);\r
1005 \r
1006                 // パラメータを設定。\r
1007                 ISetProperties * setProp;\r
1008                 if (hArc->QueryInterface(IID_ISetProperties, (void **) & setProp) == S_OK)\r
1009                 {\r
1010                         CRecordVector<const wchar_t *> szProps;\r
1011                         NWindows::NCOM::CPropVariant propValues[15];\r
1012                         wxString szProp;\r
1013                         // 圧縮レベル。\r
1014                         if (fiInfo.nCompressLevelMin != fiInfo.nCompressLevelMax)\r
1015                         {\r
1016                                 szProp = wxString::Format(wxT("x%d"), _swInfo->nCompressLevel);\r
1017                                 szProps.Add(szProp.c_str());\r
1018                         }\r
1019                         // Solid圧縮。\r
1020                         if (fiInfo.fSolid)\r
1021                         {\r
1022                                 propValues[szProps.Size()] = _swInfo->fSolid;\r
1023                                 szProps.Add(wxT("s"));\r
1024                         }\r
1025                         // ヘッダ圧縮。\r
1026                         if (fiInfo.fCompressHeader)\r
1027                         {\r
1028                                 propValues[szProps.Size()] = _swInfo->fCompressHeader;\r
1029                                 szProps.Add(wxT("hc"));\r
1030                         }\r
1031                         // ヘッダ暗号化。\r
1032                         if (fiInfo.fEncryptHeader)\r
1033                         {\r
1034                                 propValues[szProps.Size()] = _swInfo->fEncryptHeader;\r
1035                                 szProps.Add(wxT("he"));\r
1036                         }\r
1037 \r
1038 //                      szProp = wxString::Format(wxT("m"));\r
1039 //                      propValues[szProps.Size()] = L"Deflate";\r
1040 //                      szProps.Add(szProp.c_str());\r
1041 \r
1042 //                      szProp = wxString::Format(wxT("fb%d"), );\r
1043 //                      szProps.Add(szProp.c_str());\r
1044 \r
1045                         setProp->SetProperties(& szProps.Front(), propValues, szProps.Size());\r
1046                 }\r
1047 \r
1048                 // 更新処理を実行。\r
1049                 CArchiveUpdateCallback * updateCallbackSpec = new CArchiveUpdateCallback(_swInfo, & fiItems);\r
1050                 CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);\r
1051                 hArc->UpdateItems(outFileStream, fiItems.Size(), updateCallback);\r
1052                 nErrorCode = updateCallbackSpec->nErrorCode;\r
1053                 break;\r
1054         }\r
1055         default:\r
1056                 nErrorCode = TPI_ERROR_D_UNSUPPORTED;\r
1057         }\r
1058         return nErrorCode;\r
1059 }\r
1060 \r
1061 int __stdcall SetCallbackProc\r
1062 (\r
1063         TPI_PROC _prArcProc\r
1064 )\r
1065 {\r
1066         // ポインタを保存。\r
1067         if (_prArcProc == NULL)\r
1068         {\r
1069                 return TPI_ERROR_D_PARAMETER;\r
1070         }\r
1071         g_prProc = * _prArcProc;\r
1072 \r
1073         return TPI_ERROR_SUCCESS;\r
1074 }\r
1075 \r
1076 #ifdef __cplusplus\r
1077 }\r
1078 #endif\r