1 /*******************************************************************************
\r
2 TPI - flexible but useless plug-in framework.
\r
3 Copyright (C) 2002-2009 Silky
\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
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
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
20 *******************************************************************************/
\r
22 //******************************************************************************
\r
24 //******************************************************************************
\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
33 //******************************************************************************
\r
35 //******************************************************************************
\r
37 wxDynamicLibrary g_hLib;
\r
40 wxULongLong g_llEngineId;
\r
42 //******************************************************************************
\r
44 //******************************************************************************
\r
46 int GetFileInformation2(void * _hArchive, TPI_FILEINFO * _fiInfo, unsigned int nIndex)
\r
48 IInArchive * hArc = (IInArchive *) _hArchive;
\r
50 NWindows::NCOM::CPropVariant prop;
\r
51 hArc->GetProperty(nIndex, kpidAttrib, & prop);
\r
52 _fiInfo->dwAttribute = prop.vt == VT_EMPTY ? 0 : prop.uintVal;
\r
53 hArc->GetProperty(nIndex, kpidEncrypted, & prop);
\r
54 if (prop.vt == VT_BOOL && VARIANT_BOOLToBool(prop.boolVal))
\r
56 _fiInfo->dwAttribute |= TPI_ATTRIBUTE_ENCRYPTED;
\r
58 hArc->GetProperty(nIndex, kpidIsDir, & prop);
\r
59 if (prop.vt == VT_BOOL && VARIANT_BOOLToBool(prop.boolVal))
\r
61 _fiInfo->dwAttribute |= TPI_ATTRIBUTE_DIRECTORY;
\r
63 hArc->GetProperty(nIndex, kpidCRC, & prop);
\r
64 _fiInfo->dwCRC32 = prop.ulVal;
\r
65 hArc->GetProperty(nIndex, kpidPackSize, & prop);
\r
66 _fiInfo->llPackedSize = prop.vt == VT_EMPTY ? 0 : prop.vt == VT_UI8 ? prop.uhVal.QuadPart : prop.ulVal;
\r
67 hArc->GetProperty(nIndex, kpidSize, & prop);
\r
68 _fiInfo->llUnpackedSize = prop.vt == VT_EMPTY ? 0 : prop.vt == VT_UI8 ? prop.uhVal.QuadPart : prop.ulVal;
\r
70 hArc->GetProperty(nIndex, kpidMTime, & prop);
\r
71 NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);
\r
72 _fiInfo->tmModified.Set((time_t) t);
\r
73 hArc->GetProperty(nIndex, kpidCTime, & prop);
\r
74 NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);
\r
75 _fiInfo->tmCreate.Set((time_t) t);
\r
76 hArc->GetProperty(nIndex, kpidATime, & prop);
\r
77 NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);
\r
78 _fiInfo->tmAccess.Set((time_t) t);
\r
79 // _fiInfo->uOSType = hdInfo.HostOS;
\r
80 hArc->GetProperty(nIndex, kpidPath, & prop);
\r
81 if (prop.vt == VT_BSTR)
\r
83 _fiInfo->szStoredName = WC2String(prop.bstrVal);
\r
87 hArc->GetProperty(nIndex, kpidExtension, & prop);
\r
88 _fiInfo->szStoredName = wxT("data.") + WC2String(prop.bstrVal);
\r
90 hArc->GetProperty(nIndex, kpidMethod, & prop);
\r
91 if (prop.vt == VT_BSTR)
\r
93 _fiInfo->szMethod = WC2String(prop.bstrVal);
\r
95 hArc->GetProperty(nIndex, kpidCommented, & prop);
\r
96 if (prop.vt == VT_BOOL && VARIANT_BOOLToBool(prop.boolVal))
\r
98 hArc->GetProperty(nIndex, kpidComment, & prop);
\r
99 _fiInfo->szComment = WC2String(prop.bstrVal);
\r
101 _fiInfo->llFileId = nIndex;
\r
102 _fiInfo->fnFileName = wxFileName(_fiInfo->szStoredName, wxPATH_DOS);
\r
103 return TPI_ERROR_SUCCESS;
\r
106 int __stdcall GetFormatInformation2(TPI_FORMATINFO * _fiInfo, unsigned int & nIndex)
\r
108 _fiInfo->szEngineName = g_hLib.CanonicalizeName(wxT("7z"));
\r
109 _fiInfo->szTPIName = wxT("7zArc");
\r
110 _fiInfo->llSupportedCommand = TPI_COMMAND_EXTRACT | TPI_COMMAND_TEST;
\r
111 _fiInfo->llTypeId = nIndex;
\r
112 _fiInfo->fArchive = true;
\r
116 _fiInfo->szTypeName = wxT("7-zip");
\r
117 _fiInfo->szSuffix = wxT("zip");
\r
118 _fiInfo->llSupportedCommand |= TPI_COMMAND_CREATE | TPI_COMMAND_ADD;
\r
119 _fiInfo->fSFX = true;
\r
120 _fiInfo->fEncryptPassword = true;
\r
121 _fiInfo->sCompressLevelMin = 0;
\r
122 _fiInfo->sCompressLevelMax = 9;
\r
125 case 1: _fiInfo->szTypeName = wxT("Arj"); _fiInfo->szSuffix = wxT("arj"); _fiInfo->fEncryptPassword = true; break;
\r
126 case 2: _fiInfo->szTypeName = wxT("Lzh"); _fiInfo->szSuffix = wxT("lzh;lha;lzs"); break;
\r
129 _fiInfo->szTypeName = wxT("7z");
\r
130 _fiInfo->szSuffix = wxT("7z");
\r
131 _fiInfo->llSupportedCommand |= TPI_COMMAND_CREATE | TPI_COMMAND_ADD;
\r
132 _fiInfo->fSFX = true;
\r
133 _fiInfo->fSolid = true;
\r
134 _fiInfo->fEncryptPassword = true;
\r
135 _fiInfo->fEncryptHeader=true;
\r
136 _fiInfo->fMultiVolume = true;
\r
137 _fiInfo->sCompressLevelMin = 0;
\r
138 _fiInfo->sCompressLevelMax = 9;
\r
141 case 4: _fiInfo->szTypeName = wxT("Cab"); _fiInfo->szSuffix = wxT("cab"); _fiInfo->fMultiVolume = true; break;
\r
143 case 5: _fiInfo->szTypeName = wxT("NSIS"); _fiInfo->szSuffix = wxT("exe"); break;
\r
144 case 6: _fiInfo->szTypeName = wxT("MSLZ"); _fiInfo->szSuffix = wxT("xx_"); _fiInfo->fArchive = false; break;
\r
145 case 7: _fiInfo->szTypeName = wxT("Flv"); _fiInfo->szSuffix = wxT("flv"); break;
\r
146 case 8: _fiInfo->szTypeName = wxT("Swf"); _fiInfo->szSuffix = wxT("swf"); break;
\r
147 case 9: _fiInfo->szTypeName = wxT("Swfc"); _fiInfo->szSuffix = wxT("swfc");break;
\r
148 case 10:_fiInfo->szTypeName = wxT("Udf"); _fiInfo->szSuffix = wxT("udf"); break;
\r
149 case 11:_fiInfo->szTypeName = wxT("HFS"); _fiInfo->szSuffix = wxT("hfs"); break;
\r
150 case 12:_fiInfo->szTypeName = wxT("DMG"); _fiInfo->szSuffix = wxT("dmg"); break;
\r
151 case 13:_fiInfo->szTypeName = wxT("ISO"); _fiInfo->szSuffix = wxT("iso"); break;
\r
152 case 14:_fiInfo->szTypeName = wxT("Chm"); _fiInfo->szSuffix = wxT("chm"); break;
\r
154 case 15:_fiInfo->szTypeName = wxT("RPM"); _fiInfo->szSuffix = wxT("rpm"); _fiInfo->fArchive = false; break;
\r
155 case 16:_fiInfo->szTypeName = wxT("Deb"); _fiInfo->szSuffix = wxT("deb"); break;
\r
156 case 17:_fiInfo->szTypeName = wxT("Cpio"); _fiInfo->szSuffix = wxT("cpio");break;
\r
158 _fiInfo->szTypeName = wxT("TAR");
\r
159 _fiInfo->szSuffix = wxT("tar");
\r
160 _fiInfo->llSupportedCommand |= TPI_COMMAND_CREATE | TPI_COMMAND_ADD;
\r
164 return nIndex > 18 ? TPI_ERROR_S_ENDOFDATA : GetFormatInformation2(_fiInfo, nIndex);
\r
166 return TPI_ERROR_SUCCESS;
\r
169 //******************************************************************************
\r
170 // Callback Wrapper
\r
171 //******************************************************************************
\r
173 // CArchiveOpenCallback
\r
174 class CArchiveOpenCallback: public IArchiveOpenCallback, public ICryptoGetTextPassword, public CMyUnknownImp
\r
177 MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
\r
178 STDMETHOD(SetTotal)(const wxULongLong_t *, const wxULongLong_t *);
\r
179 STDMETHOD(SetCompleted)(const wxULongLong_t *, const wxULongLong_t *);
\r
180 STDMETHOD(CryptoGetTextPassword)(BSTR *password);
\r
184 TPI_PROCESSINFO piInfo;
\r
187 STDMETHODIMP CArchiveOpenCallback::SetTotal(const wxULongLong_t *, const wxULongLong_t *)
\r
192 STDMETHODIMP CArchiveOpenCallback::SetCompleted(const wxULongLong_t *, const wxULongLong_t *)
\r
197 STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR * szPassword)
\r
199 this->piInfo.uMessage = TPI_MESSAGE_ASK;
\r
200 this->piInfo.uStatus = TPI_PARAM_PASSWORD;
\r
201 return (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE) ? ::StringToBstr(this->piInfo.szParam.c_str(), szPassword) : E_ABORT;
\r
204 // CArchiveExtractCallback
\r
205 class CArchiveExtractCallback: public IArchiveExtractCallback, public ICryptoGetTextPassword, public CMyUnknownImp
\r
208 MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
\r
209 STDMETHOD(SetTotal)(wxULongLong_t size);
\r
210 STDMETHOD(SetCompleted)(const wxULongLong_t *completeValue);
\r
211 STDMETHOD(GetStream)(unsigned int nIndex, ISequentialOutStream ** outStream, int nExtractMode);
\r
212 STDMETHOD(PrepareOperation)(int nExtractMode);
\r
213 STDMETHOD(SetOperationResult)(int nErrorCode);
\r
214 STDMETHOD(CryptoGetTextPassword)(BSTR * szPassword);
\r
217 CMyComPtr<IInArchive> hArc;
\r
218 TPI_SWITCHES * swInfo;
\r
222 bool fTriedPassword;
\r
223 TPI_PROCESSINFO piInfo;
\r
224 wxULongLong llCurrentPos;
\r
225 COutFileStream * _outFileStreamSpec;
\r
226 CMyComPtr<ISequentialOutStream> _outFileStream;
\r
229 STDMETHODIMP CArchiveExtractCallback::SetTotal(wxULongLong_t)
\r
234 STDMETHODIMP CArchiveExtractCallback::SetCompleted(const wxULongLong_t * llProcessed)
\r
236 this->piInfo.uStatus = TPI_STATUS_INPROCESS;
\r
237 this->piInfo.llProcessedSize = * llProcessed - this->llCurrentPos;
\r
238 if (g_prProc == NULL || this->piInfo.fiInfo.szStoredName.IsEmpty() || g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE)
\r
244 this->nErrorCode = TPI_ERROR_D_SKIPPED;
\r
249 STDMETHODIMP CArchiveExtractCallback::GetStream(unsigned int nIndex, ISequentialOutStream ** outStream, int nExtractMode)
\r
252 _outFileStream.Release();
\r
255 this->llCurrentPos += this->piInfo.fiInfo.llUnpackedSize;
\r
258 this->piInfo.uMessage = TPI_MESSAGE_STATUS;
\r
259 this->piInfo.uStatus = TPI_STATUS_BEGINPROCESS;
\r
260 GetFileInformation2(this->hArc, & this->piInfo.fiInfo, nIndex);
\r
261 this->piInfo.fnDestination = wxFileName(swInfo->fnDestinationDirectory.GetFullPath() + wxFileName::GetPathSeparator() + (swInfo->fStoreDirectoryPathes ? this->piInfo.fiInfo.fnFileName.GetPath() : (wxString) wxEmptyString), this->piInfo.fiInfo.fnFileName.GetFullName());
\r
264 if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)
\r
266 this->nErrorCode = TPI_ERROR_D_SKIPPED;
\r
270 if (nExtractMode != NArchive::NExtract::NAskMode::kExtract)
\r
275 // ディレクトリかどうかを判定し、必要なディレクトリを作成。
\r
276 if (! ::wxFileName::Mkdir(this->piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? this->piInfo.fnDestination.GetFullPath() : this->piInfo.fnDestination.GetPath(), 0777, wxPATH_MKDIR_FULL))
\r
278 this->nErrorCode = TPI_ERROR_IO_DIR_OPEN;
\r
281 if (this->piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
\r
286 if (::wxFileExists(this->piInfo.fnDestination.GetFullPath()))
\r
289 if (! ::wxRemoveFile(this->piInfo.fnDestination.GetFullPath()))
\r
291 this->nErrorCode = TPI_ERROR_IO_FILE_DELETE;
\r
296 _outFileStreamSpec = new COutFileStream;
\r
297 CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
\r
298 if (! _outFileStreamSpec->Open(this->piInfo.fnDestination.GetFullPath(), CREATE_ALWAYS))
\r
300 this->nErrorCode = TPI_ERROR_IO_FILE_OPEN;
\r
304 _outFileStream = outStreamLoc;
\r
305 * outStream = outStreamLoc.Detach();
\r
309 STDMETHODIMP CArchiveExtractCallback::PrepareOperation(int nExtractMode)
\r
311 this->nMode = nExtractMode;
\r
315 STDMETHODIMP CArchiveExtractCallback::SetOperationResult(int nResult)
\r
319 case NArchive::NExtract::NOperationResult::kOK: this->nErrorCode = TPI_ERROR_SUCCESS; break;
\r
320 case NArchive::NExtract::NOperationResult::kUnSupportedMethod: this->nErrorCode = TPI_ERROR_ARC_UNSUPPORTED; break;
\r
321 case NArchive::NExtract::NOperationResult::kDataError: this->nErrorCode = TPI_ERROR_ARC_BROKEN_MISC; break;
\r
322 case NArchive::NExtract::NOperationResult::kCRCError: this->nErrorCode = TPI_ERROR_ARC_BROKEN_SUM; break;
\r
323 default: this->nErrorCode = TPI_ERROR_UNDEFINED; break;
\r
327 if (_outFileStream != NULL)
\r
330 NWindows::NTime::UnixTimeToFileTime(this->piInfo.fiInfo.tmModified.GetTicks(), ft);
\r
331 _outFileStreamSpec->SetMTime(& ft);
\r
332 _outFileStreamSpec->Close();
\r
334 _outFileStream.Release();
\r
337 if (this->nMode == NArchive::NExtract::NAskMode::kExtract)
\r
339 // NWindows::NFile::NDirectory::MySetFileAttributes(this->piInfo.fiInfo.fnFileName.GetFullPath(), this->piInfo.fiInfo.dwAttribute);
\r
345 STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR * szPassword)
\r
347 if (this->fTriedPassword || this->swInfo->szPassword.IsEmpty())
\r
349 this->piInfo.uMessage = TPI_MESSAGE_ASK;
\r
350 this->piInfo.uStatus = TPI_PARAM_PASSWORD;
\r
351 return (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE) ? ::StringToBstr(this->piInfo.szParam.c_str(), szPassword) : E_ABORT;
\r
355 // 既定のパスワードがある場合はまずそれを試す。
\r
356 this->fTriedPassword = true;
\r
357 return ::StringToBstr(this->swInfo->szPassword, szPassword);
\r
361 // CArchiveUpdateCallback
\r
362 class CArchiveUpdateCallback: public IArchiveUpdateCallback2, public ICryptoGetTextPassword2, public CMyUnknownImp
\r
365 MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)
\r
366 STDMETHOD(SetTotal)(wxULongLong_t size);
\r
367 STDMETHOD(SetCompleted)(const wxULongLong_t * completeValue);
\r
368 STDMETHOD(EnumProperties)(IEnumSTATPROPSTG ** enumerator);
\r
369 STDMETHOD(GetUpdateItemInfo)(unsigned int nIndex, int * newData, int * newProperties, unsigned int * indexInArchive);
\r
370 STDMETHOD(GetProperty)(unsigned int nIndex, PROPID propID, PROPVARIANT * value);
\r
371 STDMETHOD(GetStream)(unsigned int index, ISequentialInStream ** inStream);
\r
372 STDMETHOD(SetOperationResult)(int operationResult);
\r
373 STDMETHOD(GetVolumeSize)(unsigned int nIndex, wxULongLong_t * size);
\r
374 STDMETHOD(GetVolumeStream)(unsigned int nIndex, ISequentialOutStream ** volumeStream);
\r
375 STDMETHOD(CryptoGetTextPassword2)(int * nPasswordIsDefined, BSTR * szPassword);
\r
376 CArchiveUpdateCallback(): fiItems(0) {};
\r
378 CRecordVector<wxULongLong_t> VolumesSizes;
\r
379 wxString szVolumeName;
\r
380 wxString szVolumeExtension;
\r
381 const CObjectVector<NWindows::NFile::NFind::CFileInfoW> * fiItems;
\r
383 TPI_SWITCHES * swInfo;
\r
386 wxULongLong llCurrentPos;
\r
387 TPI_PROCESSINFO piInfo;
\r
390 STDMETHODIMP CArchiveUpdateCallback::SetTotal(wxULongLong_t)
\r
395 STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const wxULongLong_t * llProcessed)
\r
397 this->piInfo.uStatus = TPI_STATUS_INPROCESS;
\r
398 this->piInfo.llProcessedSize = * llProcessed - this->llCurrentPos;
\r
399 if (g_prProc == NULL || this->piInfo.fiInfo.szStoredName.IsEmpty() || g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE)
\r
405 this->nErrorCode = TPI_ERROR_D_SKIPPED;
\r
410 STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG ** /* enumerator */)
\r
415 STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(unsigned int /* index */, int *newData, int *newProperties, unsigned int *indexInArchive)
\r
417 if (newData != NULL)
\r
419 * newData = BoolToInt(true);
\r
421 if (newProperties != NULL)
\r
423 * newProperties = BoolToInt(true);
\r
425 if (indexInArchive != NULL)
\r
427 *indexInArchive = (unsigned int)-1;
\r
432 STDMETHODIMP CArchiveUpdateCallback::GetProperty(unsigned int nIndex, PROPID propID, PROPVARIANT * value)
\r
434 NWindows::NCOM::CPropVariant prop;
\r
435 if (propID == kpidIsAnti)
\r
438 prop.Detach(value);
\r
442 const NWindows::NFile::NFind::CFileInfoW fiItem = (* this->fiItems)[nIndex];
\r
445 case kpidPath: prop = fiItem.Name; break;
\r
446 case kpidIsDir: prop = (unsigned int) fiItem.Attrib & TPI_ATTRIBUTE_DIRECTORY ? true : false; break;
\r
447 case kpidSize: prop = fiItem.Size; break;
\r
448 case kpidAttrib:prop = (unsigned int) fiItem.Attrib;break;
\r
449 case kpidCTime: prop = fiItem.CTime; break;
\r
450 case kpidATime: prop = fiItem.ATime; break;
\r
451 case kpidMTime: prop = fiItem.MTime; break;
\r
453 prop.Detach(value);
\r
457 STDMETHODIMP CArchiveUpdateCallback::GetStream(unsigned int nIndex, ISequentialInStream ** inStream)
\r
460 this->llCurrentPos += this->piInfo.fiInfo.llUnpackedSize;
\r
463 NWindows::NCOM::CPropVariant prop;
\r
464 this->GetProperty(nIndex, kpidAttrib, & prop);
\r
465 this->piInfo.fiInfo.dwAttribute = prop.uintVal;
\r
466 this->GetProperty(nIndex, kpidSize, & prop);
\r
467 this->piInfo.fiInfo.llUnpackedSize = prop.vt == VT_UI8 ? prop.uhVal.QuadPart : prop.ulVal;
\r
469 this->GetProperty(nIndex, kpidMTime, & prop);
\r
470 NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);
\r
471 this->piInfo.fiInfo.tmModified.Set((time_t) t);
\r
472 this->GetProperty(nIndex, kpidCTime, & prop);
\r
473 NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);
\r
474 this->piInfo.fiInfo.tmCreate.Set((time_t) t);
\r
475 this->GetProperty(nIndex, kpidATime, & prop);
\r
476 NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);
\r
477 this->piInfo.fiInfo.tmAccess.Set((time_t) t);
\r
478 this->GetProperty(nIndex, kpidPath, & prop);
\r
479 this->piInfo.fiInfo.szStoredName = WC2String(prop.bstrVal);
\r
480 this->piInfo.fiInfo.llFileId = nIndex;
\r
481 this->piInfo.fiInfo.fnFileName = wxFileName(this->piInfo.fiInfo.szStoredName);
\r
482 this->piInfo.fiInfo.fnFileName.Normalize(wxPATH_NORM_ALL, this->swInfo->fnDestinationDirectory.GetFullPath());
\r
483 this->piInfo.uMessage = TPI_MESSAGE_STATUS;
\r
484 this->piInfo.uStatus = TPI_STATUS_BEGINPROCESS;
\r
485 this->piInfo.fnDestination = wxFileName(this->piInfo.fiInfo.szStoredName);
\r
488 if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)
\r
490 this->nErrorCode = TPI_ERROR_D_SKIPPED;
\r
494 if (this->piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
\r
499 CInFileStream * inStreamSpec = new CInFileStream;
\r
500 CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
\r
501 if (! inStreamSpec->Open(this->piInfo.fiInfo.fnFileName.GetFullPath().c_str()))
\r
503 this->nErrorCode = TPI_ERROR_IO_FILE_OPEN;
\r
507 * inStream = inStreamLoc.Detach();
\r
511 STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(int nResult)
\r
515 case NArchive::NUpdate::NOperationResult::kOK: this->nErrorCode = TPI_ERROR_SUCCESS; break;
\r
516 case NArchive::NUpdate::NOperationResult::kError:
\r
517 default: this->nErrorCode = TPI_ERROR_UNDEFINED; break;
\r
522 STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(unsigned int index, wxULongLong_t *size)
\r
524 if (VolumesSizes.Size() == 0)
\r
528 if (index >= (unsigned int)VolumesSizes.Size())
\r
530 index = VolumesSizes.Size() - 1;
\r
533 * size = VolumesSizes[index];
\r
537 STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(unsigned int nIndex, ISequentialOutStream ** volumeStream)
\r
539 COutFileStream * streamSpec = new COutFileStream;
\r
540 CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
\r
541 if (! streamSpec->Create(szVolumeName + wxString::Format(wxT(".%03d"), nIndex + 1) + szVolumeExtension, false))
\r
543 return TPI_ERROR_IO_ARC_OPEN;
\r
545 * volumeStream = streamLoc.Detach();
\r
549 STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(int * nPasswordIsDefined, BSTR * szPassword)
\r
551 * nPasswordIsDefined = ! this->swInfo->szPassword.IsEmpty();
\r
552 return ::StringToBstr(this->swInfo->szPassword.c_str(), szPassword);
\r
555 //******************************************************************************
\r
557 //******************************************************************************
\r
564 int __stdcall GetPluginInformation
\r
566 unsigned int _uInfoId,
\r
573 return TPI_ERROR_D_PARAMETER;
\r
577 case TPI_INFO_VERSION_MAJOR:
\r
578 case TPI_INFO_VERSION_MINOR:
\r
579 * (int *) _pPtr = 0;
\r
581 case TPI_INFO_VERSION_API:
\r
582 * (int *) _pPtr = 2;
\r
585 return TPI_ERROR_D_UNSUPPORTED;
\r
587 return TPI_ERROR_SUCCESS;
\r
590 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)
\r
592 static unsigned int s_uTypeId;
\r
597 return GetFormatInformation2(_fiInfo, s_uTypeId);
\r
600 int __stdcall LoadPlugin
\r
602 const wxString & _szArcName,
\r
603 wxULongLong _llTypeId
\r
606 g_hLib.Load(g_hLib.CanonicalizeName(wxT("7z")));
\r
607 if (! g_hLib.IsLoaded())
\r
610 return TPI_ERROR_U_LOAD_LIBRARY;
\r
613 if (! g_hLib.HasSymbol(wxT("CreateObject")))
\r
615 return TPI_ERROR_U_USE_LIBRARY;
\r
617 g_fpProc = g_hLib.GetSymbol(wxT("CreateObject"));
\r
620 return TPI_ERROR_U_USE_LIBRARY;
\r
623 if (! ::wxFileExists(_szArcName))
\r
625 g_llEngineId = _llTypeId;
\r
628 return TPI_ERROR_SUCCESS;
\r
631 int __stdcall FreePlugin
\r
633 void * // _pReserved
\r
637 return TPI_ERROR_SUCCESS;
\r
640 int __stdcall CheckArchive
\r
642 const wxString & _szArcName,
\r
643 wxULongLong * _llFileCount
\r
647 int nErrorCode = OpenArchive(_szArcName, & _hArchive);
\r
648 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
653 if (_llFileCount != NULL)
\r
655 unsigned int nFileCount = 0;
\r
656 ((IInArchive *) _hArchive)->GetNumberOfItems(& nFileCount);
\r
657 * _llFileCount = nFileCount;
\r
660 return CloseArchive(_hArchive);
\r
663 int __stdcall OpenArchive
\r
665 const wxString & _szArcName,
\r
671 for (unsigned int i = 0; i < sizeof(guidList) / sizeof(GUID); i++)
\r
673 if (((unsigned int (__stdcall *)(const GUID *, const GUID *, void * *)) g_fpProc)(& guidList[i], & IID_IInArchive, (void **) & hArc) != S_OK)
\r
679 CInFileStream * fileSpec = new CInFileStream;
\r
680 CMyComPtr<IInStream> file = fileSpec;
\r
681 if (! fileSpec->Open(_szArcName.c_str()))
\r
683 return TPI_ERROR_IO_ARC_OPEN;
\r
687 CArchiveOpenCallback * openCallbackSpec = new CArchiveOpenCallback;
\r
688 CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);
\r
689 if (hArc->Open(file, 0, openCallback) == S_OK)
\r
692 * _hArchive = hArc;
\r
693 return TPI_ERROR_SUCCESS;
\r
696 return TPI_ERROR_IO_ARC_OPEN;
\r
699 int __stdcall CloseArchive
\r
704 IInArchive * hArc = (IInArchive *) _hArchive;
\r
707 return TPI_ERROR_SUCCESS;
\r
710 int __stdcall GetFileInformation
\r
713 TPI_FILEINFO * _fiInfo,
\r
717 static unsigned int s_uFileId, s_uFileCount;
\r
721 ((IInArchive *) _hArchive)->GetNumberOfItems(& s_uFileCount);
\r
724 if (s_uFileId >= s_uFileCount)
\r
726 return TPI_ERROR_S_ENDOFDATA;
\r
729 return GetFileInformation2(_hArchive, _fiInfo, s_uFileId++);
\r
732 int __stdcall GetArchiveInformation
\r
735 TPI_ARCHIVEINFO * _aiInfo
\r
738 IInArchive * hArc = (IInArchive *) _hArchive;
\r
739 NWindows::NCOM::CPropVariant prop;
\r
740 hArc->GetArchiveProperty(kpidSolid, & prop);
\r
741 _aiInfo->fSolid = VARIANT_BOOLToBool(prop.boolVal);
\r
742 hArc->GetArchiveProperty(kpidComment, & prop);
\r
743 if (prop.vt == VT_BSTR)
\r
745 _aiInfo->szComment = WC2String(prop.bstrVal);
\r
747 unsigned int u = g_llEngineId.ToULong();
\r
748 GetFormatInformation2(& _aiInfo->fiInfo, u);
\r
749 return TPI_ERROR_SUCCESS;
\r
752 int __stdcall Command
\r
754 unsigned int _uCommand,
\r
755 TPI_SWITCHES * _swInfo,
\r
756 const wxString & _szArcName,
\r
757 const wxArrayString & _szFiles
\r
764 case TPI_COMMAND_EXTRACT:
\r
765 case TPI_COMMAND_TEST:
\r
769 nErrorCode = OpenArchive(_szArcName, (void **) & hArc);
\r
770 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
775 // ファイル名からインデックスを取得。
\r
776 TPI_FILEINFO fiInfo;
\r
777 CRecordVector<unsigned int> nIndexes;
\r
778 if (GetFileInformation(hArc, & fiInfo, true) == TPI_ERROR_SUCCESS)
\r
782 if (_szFiles.Index(fiInfo.szStoredName) != wxNOT_FOUND)
\r
784 nIndexes.Add(fiInfo.llFileId.ToULong());
\r
787 while (GetFileInformation(hArc, & fiInfo, false) == TPI_ERROR_SUCCESS);
\r
790 CArchiveExtractCallback * extractCallbackSpec = new CArchiveExtractCallback;
\r
791 CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
\r
792 extractCallbackSpec->hArc = hArc;
\r
793 extractCallbackSpec->swInfo = _swInfo;
\r
794 hArc->Extract(& nIndexes.Front(), nIndexes.Size(), _uCommand == TPI_COMMAND_TEST, extractCallback);
\r
795 nErrorCode = extractCallbackSpec->nErrorCode;
\r
796 CloseArchive(hArc);
\r
799 case TPI_COMMAND_CREATE:
\r
800 // case TPI_COMMAND_ADD:
\r
802 CObjectVector<NWindows::NFile::NFind::CFileInfoW> fiItems;
\r
803 for (unsigned int i = 0; i < _szFiles.GetCount(); i++)
\r
805 NWindows::NFile::NFind::CFileInfoW fi;
\r
806 wxFileName fn(_szFiles[i]);
\r
807 fn.Normalize(wxPATH_NORM_ALL, _swInfo->fnDestinationDirectory.GetFullPath());
\r
808 if (! fi.Find(fn.GetFullPath().c_str()))
\r
810 return TPI_ERROR_IO_FILE_ACCESS;
\r
815 COutFileStream * outFileStreamSpec = new COutFileStream;
\r
816 CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
\r
817 if (! outFileStreamSpec->Create(_szArcName.c_str(), false))
\r
819 return TPI_ERROR_IO_ARC_OPEN;
\r
822 IOutArchive * hArc;
\r
823 if (((unsigned int (__stdcall *)(const GUID *, const GUID *, void **)) g_fpProc)(& guidList[g_llEngineId.ToULong()], & IID_IOutArchive, (void **) & hArc) != S_OK)
\r
825 return TPI_ERROR_ARC_UNSUPPORTED;
\r
828 CArchiveUpdateCallback * updateCallbackSpec = new CArchiveUpdateCallback;
\r
829 CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);
\r
830 updateCallbackSpec->fiItems = & fiItems;
\r
831 updateCallbackSpec->swInfo = _swInfo;
\r
832 hArc->UpdateItems(outFileStream, fiItems.Size(), updateCallback);
\r
833 nErrorCode = updateCallbackSpec->nErrorCode;
\r
837 nErrorCode = TPI_ERROR_D_UNSUPPORTED;
\r
842 int __stdcall SetCallbackProc
\r
844 TPI_PROC _prArcProc
\r
848 if (_prArcProc == NULL)
\r
850 return TPI_ERROR_D_PARAMETER;
\r
852 g_prProc = * _prArcProc;
\r
854 return TPI_ERROR_SUCCESS;
\r