OSDN Git Service

上書きスキップができなくなっていたのを修正。
[tpi/lychee.git] / src / plugin / 7zArc / 7zArc.cpp
index 60c1cb2..78f37b1 100644 (file)
 #include <wx/dynlib.h>\r
 #include "7zArc.h"\r
 \r
+#ifdef __LINUX__\r
+#define LIB_NAME wxT("7z.so")\r
+#else\r
+#define LIB_NAME g_hLib.CanonicalizeName(wxT("7z"))\r
+#endif\r
+\r
 //******************************************************************************\r
 //    Global varients\r
 //******************************************************************************\r
@@ -39,6 +45,10 @@ void * g_fpProc;
 TPI_PROC g_prProc;\r
 wxULongLong_t g_nEngineId;\r
 \r
+#ifdef __LINUX__\r
+extern int global_use_utf16_conversion;\r
+#endif\r
+\r
 //******************************************************************************\r
 //    Inside Functions\r
 //******************************************************************************\r
@@ -121,7 +131,7 @@ int __stdcall GetFormatInformation2(TPI_FORMATINFO * _fiInfo, wxULongLong_t & nI
        _fiInfo->nRecoveryRecordMax = 0;\r
        _fiInfo->szTypeName.Empty();\r
        _fiInfo->szSuffix.Empty();\r
-       _fiInfo->szEngineName       = g_hLib.CanonicalizeName(wxT("7z"));\r
+       _fiInfo->szEngineName       = LIB_NAME;\r
        _fiInfo->szTPIName          = wxT("7zArc");\r
        _fiInfo->eSupportedCommand  = TPI_COMMAND_EXTRACT | TPI_COMMAND_TEST;\r
        _fiInfo->nTypeId            = nIndex;\r
@@ -151,9 +161,7 @@ int __stdcall GetFormatInformation2(TPI_FORMATINFO * _fiInfo, wxULongLong_t & nI
                _fiInfo->nCompressLevelMin   = 1;\r
                _fiInfo->nCompressLevelMax   = 9;\r
        }\r
-#if 0\r
-       else if (guidList[nBase] == CLSID_CFormatRar)  { _fiInfo->szTypeName = wxT("Rar");     _fiInfo->szSuffix = wxT("rar"); }\r
-#endif\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
@@ -172,7 +180,6 @@ int __stdcall GetFormatInformation2(TPI_FORMATINFO * _fiInfo, wxULongLong_t & nI
                _fiInfo->fEncryptPassword    = true;\r
                _fiInfo->fEncryptHeader      = true;\r
                _fiInfo->fCompressHeader     = true;\r
-               _fiInfo->fMultiVolume        = true;\r
                _fiInfo->nCompressLevelMin   = 0;\r
                _fiInfo->nCompressLevelMax   = 9;\r
        }\r
@@ -194,16 +201,14 @@ int __stdcall GetFormatInformation2(TPI_FORMATINFO * _fiInfo, wxULongLong_t & nI
        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("swfc");}\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
-#if 0\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
-#endif\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
@@ -211,7 +216,12 @@ int __stdcall GetFormatInformation2(TPI_FORMATINFO * _fiInfo, wxULongLong_t & nI
        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)  { _fiInfo->szTypeName = wxT("Wim");     _fiInfo->szSuffix = wxT("wim"); }\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
@@ -347,9 +357,9 @@ 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
 \r
 private:\r
@@ -359,8 +369,16 @@ 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->fTriedPassword = false;\r
+}\r
+\r
 STDMETHODIMP CArchiveExtractCallback::SetTotal(wxULongLong_t)\r
 {\r
        return S_OK;\r
@@ -370,7 +388,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
@@ -388,10 +406,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
@@ -399,8 +417,9 @@ 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
        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
@@ -408,6 +427,19 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(unsigned int nIndex, ISequential
                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
@@ -425,19 +457,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
@@ -490,6 +513,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
@@ -507,17 +532,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::CFileInfoW> *);\r
 \r
        const CObjectVector<NWindows::NFile::NFind::CFileInfoW> * 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::CFileInfoW> * fiItems)\r
+{\r
+       this->swInfo = swInfo;\r
+       this->fiItems = fiItems;\r
+}\r
+\r
 STDMETHODIMP CArchiveUpdateCallback::SetTotal(wxULongLong_t)\r
 {\r
        return S_OK;\r
@@ -729,7 +760,11 @@ int __stdcall LoadPlugin
        wxULongLong_t _nTypeId\r
 )\r
 {\r
-       g_hLib.Load(g_hLib.CanonicalizeName(wxT("7z")));\r
+       ::RemoveCwdFromSearchPath();\r
+#ifdef __LINUX__\r
+       global_use_utf16_conversion = 1;\r
+#endif\r
+       g_hLib.Load(LIB_NAME);\r
        if (! g_hLib.IsLoaded())\r
        {\r
                g_hLib.Unload();\r
@@ -763,35 +798,20 @@ int __stdcall FreePlugin
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
-int __stdcall CheckArchive\r
+int __stdcall OpenArchive\r
 (\r
        const wxString & _szArcName,\r
-       wxULongLong_t * _llFileCount\r
+       void * * _hArchive,\r
+       wxULongLong_t * _nFileCount\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
+       // ***.tar.xxxは不便なので弾く。\r
+       wxString s = _szArcName.BeforeLast(wxT('.'));\r
+       if (s.Find(wxT('.')) != wxNOT_FOUND && s.AfterLast(wxT('.')) == wxT("tar"))\r
        {\r
-               unsigned int nFileCount = 0;\r
-               ((IInArchive *) _hArchive)->GetNumberOfItems(& nFileCount);\r
-               * _llFileCount = nFileCount;\r
+               return TPI_ERROR_IO_ARC_OPEN;\r
        }\r
 \r
-       return CloseArchive(_hArchive);\r
-}\r
-\r
-int __stdcall OpenArchive\r
-(\r
-       const wxString & _szArcName,\r
-       void * * _hArchive\r
-)\r
-{\r
        // 書庫形式を認識。\r
        IInArchive * hArc;\r
        for (wxULongLong_t i = 0; i < sizeof(guidList) / sizeof(GUID); )\r
@@ -802,14 +822,6 @@ int __stdcall OpenArchive
                        continue;\r
                }\r
 \r
-               // ***.tar.xxxは不便なので弾く。\r
-               wxString s = _szArcName.BeforeLast(wxT('.')); \r
-               if (s.Find(wxT('.')) != wxNOT_FOUND && s.AfterLast(wxT('.')) == wxT("tar"))\r
-               {\r
-                       i++;\r
-                       continue;\r
-               }\r
-\r
                // 書庫を開く。\r
                CInFileStream * fileSpec = new CInFileStream;\r
                CMyComPtr<IInStream> file = fileSpec;\r
@@ -833,6 +845,12 @@ int __stdcall OpenArchive
                }\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
@@ -928,13 +946,11 @@ int __stdcall Command
                                        nIndexes.Add(fiInfo.nFileId);\r
                                }\r
                        }\r
-                       while (GetFileInformation(hArc, & fiInfo, false) == TPI_ERROR_SUCCESS);\r
+                       while (GetFileInformation(hArc, & fiInfo) == TPI_ERROR_SUCCESS);\r
                }\r
 \r
-               CArchiveExtractCallback * extractCallbackSpec = new CArchiveExtractCallback;\r
+               CArchiveExtractCallback * extractCallbackSpec = new CArchiveExtractCallback(hArc,_swInfo);\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
                nErrorCode = extractCallbackSpec->nErrorCode;\r
                CloseArchive(hArc);\r
@@ -1020,10 +1036,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