OSDN Git Service

ライブラリが読み込めなかった場合のエラーダイアログを抑制するよう変更。
[tpi/lychee.git] / src / plugin / 7zArc / 7zArc.cpp
index 40ebfcb..5b08b21 100644 (file)
 //******************************************************************************\r
 \r
 #define wxUSE_DYNLIB_CLASS 1\r
+#define MYUSE_LIBPATH 1\r
 #include "../../common/header/plugin.h"\r
 #include "../../common/header/plugin-extra.h"\r
 #include "../../common/library/library.h"\r
+#include "../../common/library/xmldoc.h"\r
 #include <wx/dynlib.h>\r
 #include "7zArc.h"\r
 \r
 #ifdef __LINUX__\r
 #define LIB_NAME wxT("7z.so")\r
+#define CFileInfo CFileInfoW\r
 #else\r
-#define LIB_NAME g_hLib.CanonicalizeName(wxT("7z"))\r
+#define LIB_NAME g_LibInfo.hLib.CanonicalizeName(wxT("7z"))\r
 #endif\r
 \r
 //******************************************************************************\r
 //    Global varients\r
 //******************************************************************************\r
 \r
-wxDynamicLibrary g_hLib;\r
-void * g_fpProc;\r
+struct g_LibInfo\r
+{\r
+       wxDynamicLibrary hLib;\r
+       int nLibIndex;\r
+       wxXmlNode node;\r
+       void * fpProc;\r
+}      g_LibInfo;\r
+\r
 TPI_PROC g_prProc;\r
-wxULongLong_t g_nEngineId;\r
 \r
 #ifdef __LINUX__\r
 extern int global_use_utf16_conversion;\r
@@ -69,6 +77,13 @@ int GetFileInformation2(void * _hArchive, TPI_FILEINFO * _fiInfo, wxULongLong_t
        {\r
                _fiInfo->dwAttribute |= TPI_ATTRIBUTE_DIRECTORY;\r
        }\r
+       hArc->GetProperty(nIndex, kpidPosixAttrib, & prop);\r
+       _fiInfo->wPermission    = prop.vt == VT_EMPTY ? 0664 : prop.uintVal;\r
+       hArc->GetProperty(nIndex, kpidEncrypted, & prop);\r
+       if (prop.vt == VT_BOOL && VARIANT_BOOLToBool(prop.boolVal))\r
+       {\r
+               _fiInfo->dwAttribute |= TPI_ATTRIBUTE_ENCRYPTED;\r
+       }\r
        hArc->GetProperty(nIndex, kpidCRC, & prop);\r
        _fiInfo->dwCRC32        = prop.ulVal;\r
        hArc->GetProperty(nIndex, kpidPackSize, & prop);\r
@@ -77,180 +92,52 @@ int GetFileInformation2(void * _hArchive, TPI_FILEINFO * _fiInfo, wxULongLong_t
        _fiInfo->nUnpackedSize  = prop.vt == VT_EMPTY ? 0 : prop.vt == VT_UI8 ? prop.uhVal.QuadPart : prop.ulVal;\r
        unsigned int t;\r
        hArc->GetProperty(nIndex, kpidMTime, & prop);\r
-       NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
-       _fiInfo->tmModified.Set((time_t) t);\r
-       hArc->GetProperty(nIndex, kpidCTime, & prop);\r
-       NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
-       _fiInfo->tmCreate.Set((time_t) t);\r
-       hArc->GetProperty(nIndex, kpidATime, & prop);\r
-       NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
-       _fiInfo->tmAccess.Set((time_t) t);\r
-       hArc->GetProperty(nIndex, kpidPath, & prop);\r
-       if (prop.vt == VT_BSTR)\r
+       if (prop.vt == VT_FILETIME)\r
        {\r
-               _fiInfo->szStoredName = WC2String(prop.bstrVal);\r
-               _fiInfo->fnFileName     = wxFileName(_fiInfo->szStoredName, wxPATH_DOS);\r
+               NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
+               _fiInfo->tmModify.Set((time_t) t);\r
        }\r
        else\r
        {\r
-               hArc->GetProperty(nIndex, kpidExtension, & prop);\r
-               _fiInfo->szStoredName = wxT("data") + (prop.vt == VT_BSTR ? wxT(".") + WC2String(prop.bstrVal) : (wxString) wxEmptyString);\r
-               _fiInfo->fnFileName     = wxFileName(_fiInfo->szStoredName, wxPATH_DOS);\r
-       }\r
-       hArc->GetProperty(nIndex, kpidMethod, & prop);\r
-       if (prop.vt == VT_BSTR)\r
-       {\r
-               _fiInfo->szMethod = WC2String(prop.bstrVal);\r
+               _fiInfo->tmModify.SetToCurrent();\r
        }\r
-       hArc->GetProperty(nIndex, kpidCommented, & prop);\r
-       if (prop.vt == VT_BOOL && VARIANT_BOOLToBool(prop.boolVal))\r
-       {\r
-               hArc->GetProperty(nIndex, kpidComment, & prop);\r
-               _fiInfo->szComment  = WC2String(prop.bstrVal);\r
-       }\r
-       _fiInfo->nFileId        = nIndex;\r
-       return TPI_ERROR_SUCCESS;\r
-}\r
-\r
-int __stdcall GetFormatInformation2(TPI_FORMATINFO * _fiInfo, wxULongLong_t & nIndex)\r
-{\r
-       // Initialization.\r
-       _fiInfo->fArchive           = true;\r
-       _fiInfo->fComment           = false;\r
-       _fiInfo->fEncryptKeyFile    = false;\r
-       _fiInfo->fEncryptPassword   = false;\r
-       _fiInfo->fEncryptHeader     = false;\r
-       _fiInfo->fCompressHeader    = false;\r
-       _fiInfo->fMMOptimize        = false;\r
-       _fiInfo->fMultiVolume       = false;\r
-       _fiInfo->fSFX               = false;\r
-       _fiInfo->fSolid             = false;\r
-       _fiInfo->nCompressLevelMin  = 0;\r
-       _fiInfo->nCompressLevelMax  = 0;\r
-       _fiInfo->nRecoveryRecordMin = 0;\r
-       _fiInfo->nRecoveryRecordMax = 0;\r
-       _fiInfo->szTypeName.Empty();\r
-       _fiInfo->szSuffix.Empty();\r
-       _fiInfo->szEngineName       = LIB_NAME;\r
-       _fiInfo->szTPIName          = wxT("7zArc");\r
-       _fiInfo->eSupportedCommand  = TPI_COMMAND_EXTRACT | TPI_COMMAND_TEST;\r
-       _fiInfo->nTypeId            = nIndex;\r
-       _fiInfo->pCustomInfo        = NULL;\r
-       wxULongLong_t nBase = nIndex++;\r
-       if (nBase >= sizeof(guidList) / sizeof(GUID))\r
+       hArc->GetProperty(nIndex, kpidCTime, & prop);\r
+       if (prop.vt == VT_FILETIME)\r
        {\r
-               return TPI_ERROR_S_ENDOFDATA;\r
+               NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
+               _fiInfo->tmCreate.Set((time_t) t);\r
        }\r
-       else if (guidList[nBase] == CLSID_CFormatZip)\r
+       else\r
        {\r
-               _fiInfo->szTypeName          = wxT("7-zip");\r
-               _fiInfo->szSuffix            = wxT("zip");\r
-               _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;// | TPI_COMMAND_ADD;\r
-               _fiInfo->fSFX                = true;\r
-               _fiInfo->fMultiVolume        = true;\r
-               _fiInfo->fEncryptPassword    = true;\r
-               _fiInfo->nCompressLevelMin   = 0;\r
-               _fiInfo->nCompressLevelMax   = 9;\r
+               _fiInfo->tmCreate.SetToCurrent();\r
        }\r
-       else if (guidList[nBase] == CLSID_CFormatBZip2)\r
+       hArc->GetProperty(nIndex, kpidATime, & prop);\r
+       if (prop.vt == VT_FILETIME)\r
        {\r
-               _fiInfo->szTypeName          = wxT("BZip2");\r
-               _fiInfo->szSuffix            = wxT("bz2");\r
-               _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;\r
-               _fiInfo->fArchive            = false;\r
-               _fiInfo->nCompressLevelMin   = 1;\r
-               _fiInfo->nCompressLevelMax   = 9;\r
+               NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
+               _fiInfo->tmAccess.Set((time_t) t);\r
        }\r
-//     else if (guidList[nBase] == CLSID_CFormatRar)  { _fiInfo->szTypeName = wxT("Rar");     _fiInfo->szSuffix = wxT("rar"); }\r
-#ifdef __LINUX__\r
-       else if (guidList[nBase] == CLSID_CFormatArj)  { _fiInfo->szTypeName = wxT("Arj");     _fiInfo->szSuffix = wxT("arj"); _fiInfo->fEncryptPassword = true; _fiInfo->fSFX = true; }\r
-#endif\r
-       else if (guidList[nBase] == CLSID_CFormatZ)    { _fiInfo->szTypeName = wxT("Z");       _fiInfo->szSuffix = wxT("Z"); _fiInfo->fArchive = false; }\r
-#ifdef __LINUX__\r
-       else if (guidList[nBase] == CLSID_CFormatLzh)  { _fiInfo->szTypeName = wxT("Lzh");     _fiInfo->szSuffix = wxT("lzh;lha;lzs"); _fiInfo->fSFX = true; }\r
-#endif\r
-       else if (guidList[nBase] == CLSID_CFormat7z)\r
-       {\r
-               _fiInfo->szTypeName          = wxT("7z");\r
-               _fiInfo->szSuffix            = wxT("7z");\r
-               _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;// | TPI_COMMAND_ADD;\r
-               _fiInfo->fSFX                = true;\r
-               _fiInfo->fMultiVolume        = true;\r
-               _fiInfo->fSolid              = true;\r
-               _fiInfo->fEncryptPassword    = true;\r
-               _fiInfo->fEncryptHeader      = true;\r
-               _fiInfo->fCompressHeader     = true;\r
-               _fiInfo->nCompressLevelMin   = 0;\r
-               _fiInfo->nCompressLevelMax   = 9;\r
-       }\r
-#ifdef __LINUX__\r
-       else if (guidList[nBase] == CLSID_CFormatCab)  { _fiInfo->szTypeName = wxT("Cab");     _fiInfo->szSuffix = wxT("cab"); _fiInfo->fMultiVolume = true; _fiInfo->fSFX = true; }\r
-#endif\r
-       else if (guidList[nBase] == CLSID_CFormatNsis) { _fiInfo->szTypeName = wxT("NSIS");    _fiInfo->szSuffix = wxT("exe"); _fiInfo->fSFX = true; }\r
-       else if (guidList[nBase] == CLSID_CFormatLzma) { _fiInfo->szTypeName = wxT("LZMA");    _fiInfo->szSuffix = wxT("lzma"); _fiInfo->fArchive = false; }\r
-       else if (guidList[nBase] == CLSID_CFormatLzma86){_fiInfo->szTypeName = wxT("LZMA86");  _fiInfo->szSuffix = wxT("lzma"); _fiInfo->fArchive = false; }\r
-       else if (guidList[nBase] == CLSID_CFormatXz)\r
-       {\r
-               _fiInfo->szTypeName          = wxT("XZ");\r
-               _fiInfo->szSuffix            = wxT("xz");\r
-               _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;\r
-               _fiInfo->fArchive            = false;\r
-               _fiInfo->nCompressLevelMin   = 0;\r
-               _fiInfo->nCompressLevelMax   = 9;\r
-       }\r
-       else if (guidList[nBase] == CLSID_CFormatApm)  { _fiInfo->szTypeName = wxT("Apm");     _fiInfo->szSuffix = wxT("apm"); }\r
-       else if (guidList[nBase] == CLSID_CFormatMslz) { _fiInfo->szTypeName = wxT("MSLZ");    _fiInfo->szSuffix = wxT("xx_"); _fiInfo->fArchive = false; }\r
-       else if (guidList[nBase] == CLSID_CFormatFlv)  { _fiInfo->szTypeName = wxT("Flv");     _fiInfo->szSuffix = wxT("flv"); }\r
-//     else if (guidList[nBase] == CLSID_CFormatSwf)  { _fiInfo->szTypeName = wxT("Swf");     _fiInfo->szSuffix = wxT("swf"); }\r
-       else if (guidList[nBase] == CLSID_CFormatSwfc) { _fiInfo->szTypeName = wxT("Swfc");    _fiInfo->szSuffix = wxT("swf"); }\r
-       else if (guidList[nBase] == CLSID_CFormatNtfs) { _fiInfo->szTypeName = wxT("NTFS");    _fiInfo->szSuffix = wxT("ntfs");}\r
-       else if (guidList[nBase] == CLSID_CFormatFat)  { _fiInfo->szTypeName = wxT("FAT");     _fiInfo->szSuffix = wxT("fat"); }\r
-       else if (guidList[nBase] == CLSID_CFormatMbr)  { _fiInfo->szTypeName = wxT("Mbr");     _fiInfo->szSuffix = wxT("mbr"); }\r
-       else if (guidList[nBase] == CLSID_CFormatVhd)  { _fiInfo->szTypeName = wxT("Vhd");     _fiInfo->szSuffix = wxT("vhd"); }\r
-//     else if (guidList[nBase] == CLSID_CFormatPe)   { _fiInfo->szTypeName = wxT("PE");      _fiInfo->szSuffix = wxT("exe"); _fiInfo->fArchive = false; }\r
-//     else if (guidList[nBase] == CLSID_CFormatElf)  { _fiInfo->szTypeName = wxT("ELF");     _fiInfo->fArchive = false; }\r
-       else if (guidList[nBase] == CLSID_CFormatMachO){ _fiInfo->szTypeName = wxT("Mach-O"); }\r
-       else if (guidList[nBase] == CLSID_CFormatUdf)  { _fiInfo->szTypeName = wxT("Udf");     _fiInfo->szSuffix = wxT("udf"); }\r
-       else if (guidList[nBase] == CLSID_CFormatXar)  { _fiInfo->szTypeName = wxT("Xar");     _fiInfo->szSuffix = wxT("xar"); }\r
-       else if (guidList[nBase] == CLSID_CFormatMub)  { _fiInfo->szTypeName = wxT("Mub");     _fiInfo->szSuffix = wxT("mub"); }\r
-       else if (guidList[nBase] == CLSID_CFormatHfs)  { _fiInfo->szTypeName = wxT("HFS");     _fiInfo->szSuffix = wxT("hfs"); }\r
-       else if (guidList[nBase] == CLSID_CFormatDmg)  { _fiInfo->szTypeName = wxT("DMG");     _fiInfo->szSuffix = wxT("dmg"); }\r
-       else if (guidList[nBase] == CLSID_CFormatCom)  { _fiInfo->szTypeName = wxT("Compound");_fiInfo->szSuffix = wxT("msi"); _fiInfo->fSFX = true; }\r
-       else if (guidList[nBase] == CLSID_CFormatWim)\r
-       {\r
-               _fiInfo->szTypeName          = wxT("WIM");\r
-               _fiInfo->szSuffix            = wxT("wim");\r
-               _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;// | TPI_COMMAND_ADD;\r
-       }\r
-       else if (guidList[nBase] == CLSID_CFormatIso)  { _fiInfo->szTypeName = wxT("ISO");     _fiInfo->szSuffix = wxT("iso"); }\r
-       else if (guidList[nBase] == CLSID_CFormatBkf)  { _fiInfo->szTypeName = wxT("Bkf");     _fiInfo->szSuffix = wxT("bkf"); }\r
-       else if (guidList[nBase] == CLSID_CFormatChm)  { _fiInfo->szTypeName = wxT("Chm");     _fiInfo->szSuffix = wxT("chm"); }\r
-       else if (guidList[nBase] == CLSID_CFormatSplit){ _fiInfo->szTypeName = wxT("Split"); }\r
-#ifdef __LINUX__\r
-       else if (guidList[nBase] == CLSID_CFormatRpm)  { _fiInfo->szTypeName = wxT("RPM");     _fiInfo->szSuffix = wxT("rpm"); _fiInfo->fArchive = false; }\r
-       else if (guidList[nBase] == CLSID_CFormatDeb)  { _fiInfo->szTypeName = wxT("Deb");     _fiInfo->szSuffix = wxT("deb"); }\r
-       else if (guidList[nBase] == CLSID_CFormatCpio) { _fiInfo->szTypeName = wxT("Cpio");    _fiInfo->szSuffix = wxT("cpio");}\r
-       else if (guidList[nBase] == CLSID_CFormatTar)\r
+       else\r
        {\r
-               _fiInfo->szTypeName          = wxT("TAR");\r
-               _fiInfo->szSuffix            = wxT("tar");\r
-               _fiInfo->fSFX                = true;\r
-               _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;// | TPI_COMMAND_ADD;\r
+               _fiInfo->tmAccess.SetToCurrent();\r
        }\r
-#endif\r
-       else if (guidList[nBase] == CLSID_CFormatGZip)\r
+       hArc->GetProperty(nIndex, kpidPath, & prop);\r
+       if (prop.vt == VT_BSTR)\r
        {\r
-               _fiInfo->szTypeName          = wxT("GZip");\r
-               _fiInfo->szSuffix            = wxT("gz");\r
-               _fiInfo->eSupportedCommand  |= TPI_COMMAND_CREATE;\r
-               _fiInfo->fArchive            = false;\r
-               _fiInfo->nCompressLevelMin   = 1;\r
-               _fiInfo->nCompressLevelMax   = 9;\r
+               _fiInfo->szStoredName = WC2String(prop.bstrVal);\r
+               _fiInfo->fnFileName   = wxFileName(_fiInfo->szStoredName, wxPATH_DOS);\r
        }\r
        else\r
        {\r
-               return GetFormatInformation2(_fiInfo, nIndex);\r
+               hArc->GetProperty(nIndex, kpidExtension, & prop);\r
+               _fiInfo->szStoredName.Empty();\r
+               _fiInfo->fnFileName.SetExt(prop.vt == VT_BSTR ? WC2String(prop.bstrVal) : (wxString) wxEmptyString);\r
        }\r
+       hArc->GetProperty(nIndex, kpidMethod,  & prop); _fiInfo->szMethod   = prop.vt == VT_BSTR ? WC2String(prop.bstrVal) : (wxString) wxEmptyString;\r
+       hArc->GetProperty(nIndex, kpidComment, & prop); _fiInfo->szComment  = prop.vt == VT_BSTR ? WC2String(prop.bstrVal) : (wxString) wxEmptyString;\r
+       hArc->GetProperty(nIndex, kpidUser,    & prop); _fiInfo->szUser     = prop.vt == VT_BSTR ? WC2String(prop.bstrVal) : (wxString) wxEmptyString;\r
+       hArc->GetProperty(nIndex, kpidComment, & prop); _fiInfo->szGroup    = prop.vt == VT_BSTR ? WC2String(prop.bstrVal) : (wxString) wxEmptyString;\r
+       _fiInfo->nFileId        = nIndex;\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
@@ -262,14 +149,14 @@ int __stdcall GetFormatInformation2(TPI_FORMATINFO * _fiInfo, wxULongLong_t & nI
 class CArchiveOpenCallback: public IArchiveOpenCallback, public IArchiveOpenVolumeCallback, public IArchiveOpenSetSubArchiveName, public ICryptoGetTextPassword, public CMyUnknownImp\r
 {\r
 public:\r
-       MY_UNKNOWN_IMP1(ICryptoGetTextPassword)\r
+       MY_UNKNOWN_IMP3(ICryptoGetTextPassword, IArchiveOpenVolumeCallback, IArchiveOpenSetSubArchiveName)\r
        INTERFACE_IArchiveOpenCallback(;)\r
        INTERFACE_IArchiveOpenVolumeCallback(;)\r
        STDMETHOD(SetSubArchiveName)(const wchar_t * szName);\r
        STDMETHOD(CryptoGetTextPassword)(BSTR *password);\r
        int nErrorCode;\r
        wxString szSubArchiveName;\r
-       NWindows::NFile::NFind::CFileInfoW fiInfo;\r
+       NWindows::NFile::NFind::CFileInfo fiInfo;\r
 \r
 private:\r
        TPI_PROCESSINFO piInfo;\r
@@ -343,11 +230,13 @@ STDMETHODIMP CArchiveOpenCallback::SetSubArchiveName(const wchar_t * szName)
        return S_OK;\r
 }\r
 \r
-STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR * szPassword)\r
+STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR * sz)\r
 {\r
        this->piInfo.eMessage           = TPI_MESSAGE_ASK;\r
        this->piInfo.eStatus            = TPI_PARAM_PASSWORD;\r
-       return (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE) ? ::StringToBstr(this->piInfo.szParam.c_str(), szPassword) : E_ABORT;\r
+       return\r
+               (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE) ? ::StringToBstr(this->piInfo.szParam.c_str(), sz) :\r
+               E_ABORT;\r
 }\r
 \r
 // CArchiveExtractCallback\r
@@ -357,10 +246,11 @@ public:
        MY_UNKNOWN_IMP1(ICryptoGetTextPassword)\r
        INTERFACE_IArchiveExtractCallback(;)\r
        STDMETHOD(CryptoGetTextPassword)(BSTR * szPassword);\r
+       CArchiveExtractCallback(CMyComPtr<IInArchive>, TPI_SWITCHES *);\r
 \r
        int nErrorCode;\r
-       CMyComPtr<IInArchive> hArc;\r
        TPI_SWITCHES * swInfo;\r
+       wxFileName fnArchive;\r
 \r
 private:\r
        int nMode;\r
@@ -369,8 +259,17 @@ private:
        wxULongLong_t nCurrentPos;\r
        COutFileStream * _outFileStreamSpec;\r
        CMyComPtr<ISequentialOutStream> _outFileStream;\r
+       CMyComPtr<IInArchive> hArc;\r
 };\r
 \r
+CArchiveExtractCallback::CArchiveExtractCallback(CMyComPtr<IInArchive> hArc, TPI_SWITCHES * swInfo)\r
+{\r
+       this->hArc = hArc;\r
+       this->swInfo = swInfo;\r
+       this->nCurrentPos = 0;\r
+       this->fTriedPassword = false;\r
+}\r
+\r
 STDMETHODIMP CArchiveExtractCallback::SetTotal(wxULongLong_t)\r
 {\r
        return S_OK;\r
@@ -380,7 +279,7 @@ STDMETHODIMP CArchiveExtractCallback::SetCompleted(const wxULongLong_t * nProces
 {\r
        this->piInfo.eStatus                = TPI_STATUS_INPROCESS;\r
        this->piInfo.nProcessedSize     = * nProcessed - this->nCurrentPos;\r
-       if (g_prProc == NULL || this->piInfo.fiInfo.szStoredName.IsEmpty() || g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE)\r
+       if (g_prProc == NULL || this->piInfo.fiInfo.szStoredName.IsEmpty() || ! this->piInfo.fnDestination.IsOk() || g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE)\r
        {\r
                return S_OK;\r
        }\r
@@ -398,10 +297,10 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(unsigned int nIndex, ISequential
 \r
        // 前のファイルの処理の終了を通知。\r
        this->nCurrentPos += this->piInfo.fiInfo.nUnpackedSize;\r
-       this->piInfo.eMessage               = TPI_MESSAGE_STATUS;\r
        if (this->nCurrentPos != 0)\r
        {\r
-               this->piInfo.eStatus            = TPI_STATUS_ENDPROCESS;\r
+               this->piInfo.eMessage   = TPI_MESSAGE_STATUS;\r
+               this->piInfo.eStatus    = TPI_STATUS_ENDPROCESS;\r
                if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)\r
                {\r
                        this->nErrorCode = TPI_ERROR_D_SKIPPED;\r
@@ -409,15 +308,39 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(unsigned int nIndex, ISequential
                }\r
        }\r
 \r
-       // ファイルの基本情報を取得。\r
-       this->piInfo.eStatus                = TPI_STATUS_BEGINPROCESS;\r
+       // ファイルを処理するか確認。\r
+       this->piInfo.eMessage   = TPI_MESSAGE_ASK;\r
+       this->piInfo.eStatus    = TPI_PARAM_DEST;\r
        GetFileInformation2(this->hArc, & this->piInfo.fiInfo, nIndex);\r
+       if (this->piInfo.fiInfo.szStoredName.IsEmpty())\r
+       {\r
+               this->piInfo.fiInfo.szStoredName = this->fnArchive.GetName();\r
+               if (this->piInfo.fiInfo.fnFileName.HasExt())\r
+               {\r
+                       this->piInfo.fiInfo.szStoredName += wxT('.') + this->piInfo.fiInfo.fnFileName.GetExt();\r
+               }\r
+               this->piInfo.fiInfo.fnFileName = wxFileName(this->piInfo.fiInfo.szStoredName);\r
+       }\r
+\r
        this->piInfo.fnDestination          = wxFileName(swInfo->fnDestinationDirectory.GetFullPath() + wxFileName::GetPathSeparator() + (swInfo->fStoreDirectoryPathes ? this->piInfo.fiInfo.fnFileName.GetPath() : (wxString) wxEmptyString), this->piInfo.fiInfo.fnFileName.GetFullName());\r
        if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)\r
        {\r
                this->nErrorCode = TPI_ERROR_D_SKIPPED;\r
                return E_ABORT;\r
        }\r
+       if (! piInfo.fnDestination.IsOk())\r
+       {\r
+               return S_OK;\r
+       }\r
+\r
+       // ファイルの基本情報を取得。\r
+       this->piInfo.eMessage   = TPI_MESSAGE_STATUS;\r
+       this->piInfo.eStatus    = TPI_STATUS_BEGINPROCESS;\r
+       if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)\r
+       {\r
+               this->nErrorCode = TPI_ERROR_D_SKIPPED;\r
+               return E_ABORT;\r
+       }\r
 \r
        if (nExtractMode != NArchive::NExtract::NAskMode::kExtract)\r
        {\r
@@ -435,19 +358,10 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(unsigned int nIndex, ISequential
                return S_OK;\r
        }\r
 \r
-       if (::wxFileExists(this->piInfo.fnDestination.GetFullPath()))\r
-       {\r
-               // 既にファイルが存在する場合。\r
-               if (! ::wxRemoveFile(this->piInfo.fnDestination.GetFullPath()))\r
-               {\r
-                       this->nErrorCode = TPI_ERROR_IO_FILE_DELETE;\r
-                       return E_ABORT;\r
-               }\r
-       }\r
-\r
+       // ファイルを作成。\r
        _outFileStreamSpec = new COutFileStream;\r
        CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);\r
-       if (! _outFileStreamSpec->Open(this->piInfo.fnDestination.GetFullPath(), CREATE_ALWAYS))\r
+       if (! _outFileStreamSpec->Open(this->piInfo.fnDestination.GetFullPath(), CREATE_NEW))\r
        {\r
                this->nErrorCode = TPI_ERROR_IO_FILE_OPEN;\r
                return E_ABORT;\r
@@ -475,12 +389,14 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(int nResult)
        default:                                                       this->nErrorCode = TPI_ERROR_UNDEFINED;       break;\r
        }\r
 \r
-       // æ\9b´æ\96°æ\99\82å\88»ã\82\92è¨\98é\8c²ã\80\82\r
+       // 時刻を記録。\r
        if (_outFileStream != NULL)\r
        {\r
-               FILETIME ft;\r
-               NWindows::NTime::UnixTimeToFileTime(this->piInfo.fiInfo.tmModified.GetTicks(), ft);\r
-               _outFileStreamSpec->SetMTime(& ft);\r
+               FILETIME ftAccess, ftCreate, ftModify;\r
+               NWindows::NTime::UnixTimeToFileTime(this->piInfo.fiInfo.tmAccess.GetTicks(), ftAccess);\r
+               NWindows::NTime::UnixTimeToFileTime(this->piInfo.fiInfo.tmCreate.GetTicks(), ftCreate);\r
+               NWindows::NTime::UnixTimeToFileTime(this->piInfo.fiInfo.tmModify.GetTicks(), ftModify);\r
+               _outFileStreamSpec->SetTime(& ftCreate, & ftAccess, & ftModify);\r
                _outFileStreamSpec->Close();\r
        }\r
        _outFileStream.Release();\r
@@ -488,7 +404,10 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(int nResult)
        // 属性を記録。\r
        if (this->nMode == NArchive::NExtract::NAskMode::kExtract)\r
        {\r
-//             NWindows::NFile::NDirectory::MySetFileAttributes(this->piInfo.fiInfo.fnFileName.GetFullPath(), this->piInfo.fiInfo.dwAttribute);\r
+               chmod(this->piInfo.fnDestination.GetFullPath().ToUTF8(), this->piInfo.fiInfo.wPermission);\r
+#ifdef __WINDOWS__\r
+               NWindows::NFile::NDirectory::MySetFileAttributes(this->piInfo.fnDestination.GetFullPath(), this->piInfo.fiInfo.dwAttribute);\r
+#endif\r
        }\r
 \r
        return S_OK;\r
@@ -500,6 +419,8 @@ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR * szPassword)
        {\r
                this->piInfo.eMessage           = TPI_MESSAGE_ASK;\r
                this->piInfo.eStatus            = TPI_PARAM_PASSWORD;\r
+               // 次のファイル名が取得できないので、とりあえず空にしておく。\r
+               this->piInfo.fiInfo.fnFileName.Clear();\r
                return (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) == TPI_CALLBACK_CONTINUE) ? ::StringToBstr(this->piInfo.szParam.c_str(), szPassword) : E_ABORT;\r
        }\r
        else\r
@@ -517,17 +438,23 @@ public:
        MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)\r
        INTERFACE_IArchiveUpdateCallback2(;)\r
        STDMETHOD(CryptoGetTextPassword2)(int * nPasswordIsDefined, BSTR * szPassword);\r
-       CArchiveUpdateCallback(): fiItems(0) {};\r
+       CArchiveUpdateCallback(TPI_SWITCHES *, CObjectVector<NWindows::NFile::NFind::CFileInfo> *);\r
 \r
-       const CObjectVector<NWindows::NFile::NFind::CFileInfoW> * fiItems;\r
+       const CObjectVector<NWindows::NFile::NFind::CFileInfo> * fiItems;\r
        int nErrorCode;\r
-       TPI_SWITCHES * swInfo;\r
 \r
 private:\r
        wxULongLong_t nCurrentPos;\r
        TPI_PROCESSINFO piInfo;\r
+       TPI_SWITCHES * swInfo;\r
 };\r
 \r
+CArchiveUpdateCallback::CArchiveUpdateCallback(TPI_SWITCHES * swInfo, CObjectVector<NWindows::NFile::NFind::CFileInfo> * fiItems)\r
+{\r
+       this->swInfo = swInfo;\r
+       this->fiItems = fiItems;\r
+}\r
+\r
 STDMETHODIMP CArchiveUpdateCallback::SetTotal(wxULongLong_t)\r
 {\r
        return S_OK;\r
@@ -575,7 +502,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(unsigned int nIndex, PROPID pro
                return S_OK;\r
        }\r
 \r
-       const NWindows::NFile::NFind::CFileInfoW fiItem = (* this->fiItems)[nIndex];\r
+       const NWindows::NFile::NFind::CFileInfo fiItem = (* this->fiItems)[nIndex];\r
        switch (propID)\r
        {\r
                case kpidPath:  prop = fiItem.Name;  break;\r
@@ -595,7 +522,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(unsigned int nIndex, ISequentialI
        // 前のファイルの処理の終了を通知。\r
        this->nCurrentPos += this->piInfo.fiInfo.nUnpackedSize;\r
        this->piInfo.eMessage               = TPI_MESSAGE_STATUS;\r
-       if (this->nCurrentPos != 0)\r
+       if (this->nCurrentPos > 0)\r
        {\r
                this->piInfo.eStatus            = TPI_STATUS_ENDPROCESS;\r
                if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & this->piInfo) != TPI_CALLBACK_CONTINUE)\r
@@ -612,15 +539,9 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(unsigned int nIndex, ISequentialI
        this->GetProperty(nIndex, kpidSize, & prop);\r
        this->piInfo.fiInfo.nUnpackedSize   = prop.vt == VT_UI8 ? prop.uhVal.QuadPart : prop.ulVal;\r
        unsigned int t;\r
-       this->GetProperty(nIndex, kpidMTime, & prop);\r
-       NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
-       this->piInfo.fiInfo.tmModified.Set((time_t) t);\r
-       this->GetProperty(nIndex, kpidCTime, & prop);\r
-       NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
-       this->piInfo.fiInfo.tmCreate.Set((time_t) t);\r
-       this->GetProperty(nIndex, kpidATime, & prop);\r
-       NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
-       this->piInfo.fiInfo.tmAccess.Set((time_t) t);\r
+       this->GetProperty(nIndex, kpidMTime, & prop); NWindows::NTime::FileTimeToUnixTime(prop.filetime, t); this->piInfo.fiInfo.tmModify.Set((time_t) t);\r
+       this->GetProperty(nIndex, kpidCTime, & prop); NWindows::NTime::FileTimeToUnixTime(prop.filetime, t); this->piInfo.fiInfo.tmCreate.Set((time_t) t);\r
+       this->GetProperty(nIndex, kpidATime, & prop); NWindows::NTime::FileTimeToUnixTime(prop.filetime, t); this->piInfo.fiInfo.tmAccess.Set((time_t) t);\r
        this->GetProperty(nIndex, kpidPath, & prop);\r
        this->piInfo.fiInfo.szStoredName = WC2String(prop.bstrVal);\r
        this->piInfo.fiInfo.nFileId         = nIndex;\r
@@ -717,6 +638,9 @@ int __stdcall GetPluginInformation
        case TPI_INFO_VERSION_API:\r
                * (int *) _pPtr = 2;\r
                break;\r
+       case TPI_INFO_HANDLE_ON_COMMAND:\r
+               * (int *) _pPtr = 1;\r
+               break;\r
        default:\r
                return TPI_ERROR_D_UNSUPPORTED;\r
        }\r
@@ -725,17 +649,32 @@ int __stdcall GetPluginInformation
 \r
 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)\r
 {\r
-       static wxULongLong_t s_nTypeId;\r
+       static wxULongLong_t s_nFileId;\r
+       static wxXmlDocument xmlDoc(myMakeXMLName(wxT("7zArc")));\r
+       static wxXmlNode * xmlLibrary;\r
        if (_bFirst)\r
        {\r
-               s_nTypeId = 0;\r
+               // xml解析開始。\r
+               s_nFileId = 0;\r
+               xmlLibrary = myGetFirstLib(& xmlDoc);\r
+       }\r
+       else\r
+       {\r
+               xmlLibrary = myGetNextLib(xmlLibrary);\r
+       }\r
+       if (xmlLibrary == NULL)\r
+       {\r
+               // データの終端に達した場合。\r
+               return TPI_ERROR_S_ENDOFDATA;\r
        }\r
-       return GetFormatInformation2(_fiInfo, s_nTypeId);\r
+       MakeFormatInfo(xmlLibrary, wxT("7zArc"), _fiInfo, s_nFileId++);\r
+       return TPI_ERROR_SUCCESS;\r
 }\r
 \r
 int __stdcall LoadPlugin\r
 (\r
        const wxString & _szArcName,\r
+       TPI_PROC _prProc,\r
        wxULongLong_t _nTypeId\r
 )\r
 {\r
@@ -743,28 +682,47 @@ int __stdcall LoadPlugin
 #ifdef __LINUX__\r
        global_use_utf16_conversion = 1;\r
 #endif\r
-       g_hLib.Load(LIB_NAME);\r
-       if (! g_hLib.IsLoaded())\r
+       g_LibInfo.hLib.Load(LIB_NAME, wxDL_QUIET);\r
+       if (! g_LibInfo.hLib.IsLoaded())\r
        {\r
-               g_hLib.Unload();\r
                return TPI_ERROR_U_LOAD_LIBRARY;\r
        }\r
 \r
-       if (! g_hLib.HasSymbol(wxT("CreateObject")))\r
+       if (! g_LibInfo.hLib.HasSymbol(wxT("CreateObject")))\r
        {\r
                return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
-       g_fpProc = g_hLib.GetSymbol(wxT("CreateObject"));\r
-       if (! g_fpProc)\r
+       g_LibInfo.fpProc = g_LibInfo.hLib.GetSymbol(wxT("CreateObject"));\r
+       if (! g_LibInfo.fpProc)\r
        {\r
                return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
 \r
+       // 対象が存在しないならば指示されたライブラリをロード。\r
+       // 対象が空文字列なら処理を終了。\r
+       if (_szArcName.IsEmpty())\r
+       {\r
+               return TPI_ERROR_SUCCESS;\r
+       }\r
        if (! ::wxFileExists(_szArcName))\r
        {\r
-               g_nEngineId = _nTypeId;\r
+               // xml解析開始。\r
+               wxXmlDocument xmlDoc(myMakeXMLName(wxT("7zArc")));\r
+               wxXmlNode * xmlLibrary = myGetFirstLib(& xmlDoc, _nTypeId);\r
+               if (xmlLibrary == NULL)\r
+               {\r
+                       // xml文法エラー。\r
+                       return TPI_ERROR_UNDEFINED;\r
+               }\r
+               g_LibInfo.node = * xmlLibrary;\r
+               g_LibInfo.nLibIndex = _nTypeId;\r
        }\r
 \r
+       // コールバック関数を設定。\r
+       if (_prProc != NULL)\r
+       {\r
+               g_prProc = * _prProc;\r
+       }\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
@@ -773,37 +731,15 @@ int __stdcall FreePlugin
        void * // _pReserved\r
 )\r
 {\r
-       g_hLib.Unload();\r
+       g_LibInfo.hLib.Unload();\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
-int __stdcall CheckArchive\r
-(\r
-       const wxString & _szArcName,\r
-       wxULongLong_t * _llFileCount\r
-)\r
-{\r
-       void * _hArchive;\r
-       int nErrorCode = OpenArchive(_szArcName, & _hArchive);\r
-       if (nErrorCode != TPI_ERROR_SUCCESS)\r
-       {\r
-               return nErrorCode;\r
-       }\r
-\r
-       if (_llFileCount != NULL)\r
-       {\r
-               unsigned int nFileCount = 0;\r
-               ((IInArchive *) _hArchive)->GetNumberOfItems(& nFileCount);\r
-               * _llFileCount = nFileCount;\r
-       }\r
-\r
-       return CloseArchive(_hArchive);\r
-}\r
-\r
 int __stdcall OpenArchive\r
 (\r
        const wxString & _szArcName,\r
-       void * * _hArchive\r
+       void * * _hArchive,\r
+       wxULongLong_t * _nFileCount\r
 )\r
 {\r
        // ***.tar.xxxは不便なので弾く。\r
@@ -813,15 +749,23 @@ int __stdcall OpenArchive
                return TPI_ERROR_IO_ARC_OPEN;\r
        }\r
 \r
-       // 書庫形式を認識\r
+       // xml解析開始\r
        IInArchive * hArc;\r
-       for (wxULongLong_t i = 0; i < sizeof(guidList) / sizeof(GUID); )\r
+       wxXmlDocument xmlDoc(myMakeXMLName(wxT("7zArc")));\r
+       wxXmlNode * xmlLibrary = myGetFirstLib(& xmlDoc);\r
+\r
+       // 対応するライブラリを調査。\r
+       // 無限ループに陥らないよう上限を設定。\r
+       for (g_LibInfo.nLibIndex = 0; g_LibInfo.nLibIndex < 300 && xmlLibrary != NULL; g_LibInfo.nLibIndex++)\r
        {\r
-               if (((unsigned int (__stdcall *)(const GUID *, const GUID *, void * *)) g_fpProc)(& guidList[i], & IID_IInArchive, (void **) & hArc) != S_OK)\r
+               // ライブラリをロード。\r
+               const GUID guid = {0x23170F69, 0x40C1, 0x278A, {0x10, 0x00, 0x00, 0x01, 0x10, (unsigned char) myGetAttributeInt(xmlLibrary, wxT("name"), 0, 16), 0x00, 0x00}};\r
+               if (((unsigned int (__stdcall *)(const GUID *, const GUID *, void * *)) g_LibInfo.fpProc)(& guid, & IID_IInArchive, (void **) & hArc) != S_OK)\r
                {\r
-                       i++;\r
+                       xmlLibrary = myGetNextLib(xmlLibrary);\r
                        continue;\r
                }\r
+               g_LibInfo.node = * xmlLibrary;\r
 \r
                // 書庫を開く。\r
                CInFileStream * fileSpec = new CInFileStream;\r
@@ -832,24 +776,34 @@ int __stdcall OpenArchive
                }\r
 \r
                // 形式の情報を取得。\r
-               g_nEngineId = i;\r
                TPI_FORMATINFO fiInfo;\r
-               GetFormatInformation2(& fiInfo, i);\r
+               MakeFormatInfo(xmlLibrary, wxT("7zArc"), & fiInfo, g_LibInfo.nLibIndex);\r
 \r
-               // æ\9b¸åº«ã\81¨ã\81\97ã\81¦é\96\8bã\81\8f\r
+               // æ\9b¸åº«ã\81«å¯¾å¿\9cã\81\97ã\81¦ã\81\84ã\82\8bã\81\8bã\83\81ã\82§ã\83\83ã\82¯\r
                CArchiveOpenCallback * openCallbackSpec = new CArchiveOpenCallback;\r
                CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);\r
-               wxULongLong_t nMax = 0;\r
+               // SFXを完全に検出するには全体をロードする必要がある。\r
+               wxULongLong_t nMax = fiInfo.fSFX ? 262114 : 1024;\r
+/*\r
                if (fiInfo.fSFX)\r
                {\r
                        fileSpec->GetSize(& nMax);\r
                }\r
+*/\r
                if (hArc->Open(file, & nMax, openCallback) == S_OK)\r
                {\r
+                       if (_nFileCount != NULL)\r
+                       {\r
+                               unsigned int n;\r
+                               hArc->GetNumberOfItems(& n);\r
+                               * _nFileCount = n;\r
+                       }\r
                        * _hArchive = hArc;\r
                        return TPI_ERROR_SUCCESS;\r
                }\r
+               xmlLibrary = myGetNextLib(xmlLibrary);\r
        }\r
+\r
        return TPI_ERROR_IO_ARC_OPEN;\r
 }\r
 \r
@@ -858,7 +812,7 @@ int __stdcall CloseArchive
        void * _hArchive\r
 )\r
 {\r
-    IInArchive * hArc = (IInArchive *) _hArchive;\r
+       IInArchive * hArc = (IInArchive *) _hArchive;\r
        hArc->Close();\r
        hArc->Release();\r
        return TPI_ERROR_SUCCESS;\r
@@ -901,8 +855,29 @@ int __stdcall GetArchiveInformation
        {\r
                _aiInfo->szComment  = WC2String(prop.bstrVal);\r
        }\r
-       wxULongLong_t n = g_nEngineId;\r
-       GetFormatInformation2(& _aiInfo->fiInfo, n);\r
+\r
+       // Time.\r
+       unsigned int t;\r
+       hArc->GetArchiveProperty(kpidMTime, & prop);\r
+       if (prop.vt == VT_FILETIME)\r
+       {\r
+               NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
+               _aiInfo->tmModify.Set((time_t) t);\r
+       }\r
+       hArc->GetArchiveProperty(kpidCTime, & prop);\r
+       if (prop.vt == VT_FILETIME)\r
+       {\r
+               NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
+               _aiInfo->tmCreate.Set((time_t) t);\r
+       }\r
+       hArc->GetArchiveProperty(kpidATime, & prop);\r
+       if (prop.vt == VT_FILETIME)\r
+       {\r
+               NWindows::NTime::FileTimeToUnixTime(prop.filetime, t);\r
+               _aiInfo->tmAccess.Set((time_t) t);\r
+       }\r
+\r
+       MakeFormatInfo(& g_LibInfo.node, wxT("7zArc"), & _aiInfo->fiInfo, g_LibInfo.nLibIndex);\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
@@ -910,7 +885,7 @@ int __stdcall Command
 (\r
        wxULongLong_t _eCommand,\r
        TPI_SWITCHES * _swInfo,\r
-       const wxString & _szArcName,\r
+       void * _hArchive,\r
        const wxArrayString & _szFiles\r
 )\r
 {\r
@@ -921,46 +896,45 @@ int __stdcall Command
        case TPI_COMMAND_EXTRACT:\r
        case TPI_COMMAND_TEST:\r
        {\r
-               // 開きなおす。\r
-               IInArchive * hArc;\r
-               nErrorCode = OpenArchive(_szArcName, (void **) & hArc);\r
-               if (nErrorCode != TPI_ERROR_SUCCESS)\r
-               {\r
-                       return nErrorCode;\r
-               }\r
-\r
                // ファイル名からインデックスを取得。\r
                TPI_FILEINFO fiInfo;\r
                CRecordVector<unsigned int> nIndexes;\r
-               if (GetFileInformation(hArc, & fiInfo, true) == TPI_ERROR_SUCCESS)\r
+               wxFileName fnArchive = wxFileName(_swInfo->szArcName);\r
+               if (GetFileInformation(_hArchive, & fiInfo, true) == TPI_ERROR_SUCCESS)\r
                {\r
                        do\r
                        {\r
+                               if (fiInfo.szStoredName.IsEmpty())\r
+                               {\r
+                                       fiInfo.szStoredName = fnArchive.GetName();\r
+                                       if (fiInfo.fnFileName.HasExt())\r
+                                       {\r
+                                               fiInfo.szStoredName += wxT('.') + fiInfo.fnFileName.GetExt();\r
+                                       }\r
+                               }\r
                                if (_szFiles.Index(fiInfo.szStoredName) != wxNOT_FOUND)\r
                                {\r
                                        nIndexes.Add(fiInfo.nFileId);\r
                                }\r
                        }\r
-                       while (GetFileInformation(hArc, & fiInfo, false) == TPI_ERROR_SUCCESS);\r
+                       while (GetFileInformation(_hArchive, & fiInfo) == TPI_ERROR_SUCCESS);\r
                }\r
 \r
-               CArchiveExtractCallback * extractCallbackSpec = new CArchiveExtractCallback;\r
+               CArchiveExtractCallback * extractCallbackSpec = new CArchiveExtractCallback((IInArchive *) _hArchive, _swInfo);\r
+               extractCallbackSpec->fnArchive = fnArchive;\r
                CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);\r
-               extractCallbackSpec->hArc = hArc;\r
-               extractCallbackSpec->swInfo = _swInfo;\r
-               hArc->Extract(& nIndexes.Front(), nIndexes.Size(), _eCommand == TPI_COMMAND_TEST, extractCallback);\r
+               ((IInArchive *) _hArchive)->Extract(& nIndexes.Front(), nIndexes.Size(), _eCommand == TPI_COMMAND_TEST, extractCallback);\r
                nErrorCode = extractCallbackSpec->nErrorCode;\r
-               CloseArchive(hArc);\r
                break;\r
        }\r
        case TPI_COMMAND_CREATE:\r
-//     case TPI_COMMAND_ADD:\r
+       case TPI_COMMAND_ADD:\r
        {\r
                // 入力リストを作成。\r
-               CObjectVector<NWindows::NFile::NFind::CFileInfoW> fiItems;\r
+               CObjectVector<NWindows::NFile::NFind::CFileInfo> fiItems;\r
                for (unsigned int i = 0; i < _szFiles.GetCount(); i++)\r
                {\r
-                       NWindows::NFile::NFind::CFileInfoW fi;\r
+                       NWindows::NFile::NFind::CFileInfo fi;\r
                        wxFileName fn(_szFiles[i]);\r
                        fn.Normalize(wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG, _swInfo->fnDestinationDirectory.GetFullPath());\r
                        if (! fi.Find(fn.GetFullPath().c_str()))\r
@@ -970,25 +944,42 @@ int __stdcall Command
                        fiItems.Add(fi);\r
                }\r
 \r
-               // 書庫を作成。\r
                COutFileStream * outFileStreamSpec = new COutFileStream;\r
                CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;\r
-               if (! outFileStreamSpec->Create(_szArcName.c_str(), false))\r
+               IOutArchive * hArc;\r
+               if (_eCommand == TPI_COMMAND_CREATE)\r
                {\r
-                       return TPI_ERROR_IO_ARC_OPEN;\r
-               }\r
+                       // 書庫を作成。\r
+                       if (! outFileStreamSpec->Create(_swInfo->szArcName.c_str(), false))\r
+                       {\r
+                               return TPI_ERROR_IO_ARC_OPEN;\r
+                       }\r
 \r
-               // エンジンを読み込み。\r
-               IOutArchive * hArc;\r
-               if (((unsigned int (__stdcall *)(const GUID *, const GUID *, void **)) g_fpProc)(& guidList[g_nEngineId], & IID_IOutArchive, (void **) & hArc) != S_OK)\r
+                       // エンジンを読み込み。\r
+                       const GUID guid = {0x23170F69, 0x40C1, 0x278A, {0x10, 0x00, 0x00, 0x01, 0x10, (unsigned char) myGetAttributeInt(& g_LibInfo.node, wxT("name"), 0, 16), 0x00, 0x00}};\r
+                       if (((unsigned int (__stdcall *)(const GUID *, const GUID *, void **)) g_LibInfo.fpProc)(& guid, & IID_IOutArchive, (void **) & hArc) != S_OK)\r
+                       {\r
+                               return TPI_ERROR_ARC_UNSUPPORTED;\r
+                       }\r
+               }\r
+               else\r
                {\r
-                       return TPI_ERROR_ARC_UNSUPPORTED;\r
+                       // 書庫を開く。\r
+                       if (! outFileStreamSpec->Open(_swInfo->szArcName.c_str(), OPEN_EXISTING))\r
+                       {\r
+                               return TPI_ERROR_IO_ARC_OPEN;\r
+                       }\r
+\r
+                       // IOutArchiveインタフェースを取得。\r
+                       if (((IInArchive *) _hArchive)->QueryInterface(IID_IOutArchive, (void **) & hArc) != S_OK)\r
+                       {\r
+                               return TPI_ERROR_ARC_UNSUPPORTED;\r
+                       }\r
                }\r
 \r
                // 形式情報を取得。\r
                TPI_FORMATINFO fiInfo;\r
-               wxULongLong_t nIndex = g_nEngineId;\r
-               GetFormatInformation2(& fiInfo, nIndex);\r
+               MakeFormatInfo(& g_LibInfo.node, wxT("7zArc"), & fiInfo, g_LibInfo.nLibIndex);\r
 \r
                // パラメータを設定。\r
                ISetProperties * setProp;\r
@@ -1033,10 +1024,8 @@ int __stdcall Command
                }\r
 \r
                // 更新処理を実行。\r
-               CArchiveUpdateCallback * updateCallbackSpec = new CArchiveUpdateCallback;\r
+               CArchiveUpdateCallback * updateCallbackSpec = new CArchiveUpdateCallback(_swInfo, & fiItems);\r
                CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);\r
-               updateCallbackSpec->fiItems = & fiItems;\r
-               updateCallbackSpec->swInfo = _swInfo;\r
                hArc->UpdateItems(outFileStream, fiItems.Size(), updateCallback);\r
                nErrorCode = updateCallbackSpec->nErrorCode;\r
                break;\r
@@ -1047,21 +1036,6 @@ int __stdcall Command
        return nErrorCode;\r
 }\r
 \r
-int __stdcall SetCallbackProc\r
-(\r
-       TPI_PROC _prArcProc\r
-)\r
-{\r
-       // ポインタを保存。\r
-       if (_prArcProc == NULL)\r
-       {\r
-               return TPI_ERROR_D_PARAMETER;\r
-       }\r
-       g_prProc = * _prArcProc;\r
-\r
-       return TPI_ERROR_SUCCESS;\r
-}\r
-\r
 #ifdef __cplusplus\r
 }\r
 #endif\r