OSDN Git Service

Merge7z: Remvoe version number from DLL file name
[winmerge-jp/winmerge-jp.git] / Src / 7zCommon.cpp
index 97f1436..123fda8 100644 (file)
@@ -98,24 +98,19 @@ DATE:               BY:                                     DESCRIPTION:
 #include "stdafx.h"\r
 #include "7zCommon.h"\r
 #include <afxinet.h>\r
-#include <shlwapi.h>\r
 #include "OptionsDef.h"\r
 #include "OptionsMgr.h"\r
-#include "Merge.h"             // DirDocFilter theApp GetOptionsMgr()\r
-#include "resource.h"\r
 #include "DirView.h"\r
 #include "DirDoc.h"\r
 #include "DirActions.h"\r
 //#include "ExternalArchiveFormat.h"\r
-#include "version.h"\r
+#include "VersionInfo.h"\r
 #include "paths.h"\r
 #include "Environment.h"\r
 #include "Merge7zFormatRegister.h"\r
 \r
 #ifdef _DEBUG\r
 #define new DEBUG_NEW\r
-#undef THIS_FILE\r
-static char THIS_FILE[] = __FILE__;\r
 #endif\r
 \r
 /**\r
@@ -124,9 +119,9 @@ static char THIS_FILE[] = __FILE__;
 static __declspec(thread) Merge7z::Proxy m_Merge7z =\r
 {\r
        { 0, 0, DllBuild_Merge7z, },\r
-       "Merge7z\\Merge7z%u%02u"DECORATE_U".dll",\r
+       "Merge7z\\Merge7z.dll",\r
        "Merge7z",\r
-       NULL\r
+       nullptr\r
 };\r
 \r
 std::vector<Merge7z::Format *(*)(const String& path)> Merge7zFormatRegister::optionalFormats;\r
@@ -144,17 +139,16 @@ bool IsArchiveFile(const String& pszFile)
 {\r
        try {\r
                Merge7z::Format *piHandler = ArchiveGuessFormat(pszFile);\r
-               if (piHandler)\r
-                       return TRUE;\r
+               if (piHandler != nullptr)\r
+                       return true;\r
                else\r
-                       return FALSE;\r
+                       return false;\r
        }\r
        catch (CException *e)\r
        {\r
                e->Delete();\r
-               return FALSE;\r
+               return false;\r
        }\r
-       return FALSE;\r
 }\r
 \r
 /**\r
@@ -165,22 +159,22 @@ bool IsArchiveFile(const String& pszFile)
 Merge7z::Format *ArchiveGuessFormat(const String& path)\r
 {\r
        if (GetOptionsMgr()->GetInt(OPT_ARCHIVE_ENABLE) == 0)\r
-               return NULL;\r
-       if (paths_IsDirectory(path))\r
-               return NULL;\r
+               return nullptr;\r
+       if (paths::IsDirectory(path))\r
+               return nullptr;\r
        String path2(path);\r
        // Map extensions through ExternalArchiveFormat.ini\r
        static TCHAR null[] = _T("");\r
        static const TCHAR section[] = _T("extensions");\r
-       String entry = paths_FindExtension(path);\r
+       String entry = paths::FindExtension(path);\r
        TCHAR value[20];\r
-       static LPCTSTR filename = NULL;\r
-       if (filename == NULL)\r
+       static LPCTSTR filename = nullptr;\r
+       if (filename == nullptr)\r
        {\r
                TCHAR cPath[INTERNET_MAX_PATH_LENGTH];\r
-               DWORD cchPath = SearchPath(NULL, _T("ExternalArchiveFormat.ini"), NULL,\r
-                       INTERNET_MAX_PATH_LENGTH, cPath, NULL);\r
-               filename = cchPath && cchPath < INTERNET_MAX_PATH_LENGTH ? StrDup(cPath) : null;\r
+               DWORD cchPath = SearchPath(nullptr, _T("ExternalArchiveFormat.ini"), nullptr,\r
+                       INTERNET_MAX_PATH_LENGTH, cPath, nullptr);\r
+               filename = cchPath && cchPath < INTERNET_MAX_PATH_LENGTH ? _tcsdup(cPath) : null;\r
        }\r
        if (*filename &&\r
                GetPrivateProfileString(section, entry.c_str(), null, value, 20, filename) &&\r
@@ -210,14 +204,14 @@ Merge7z::Format *ArchiveGuessFormat(const String& path)
        try\r
        {\r
                Merge7z::Format *pFormat = m_Merge7z->GuessFormat(path2.c_str());\r
-               if (!pFormat)\r
+               if (pFormat == nullptr)\r
                        pFormat = Merge7zFormatRegister::GuessFormat(path2);\r
                return pFormat;\r
        }\r
        catch (...)\r
        {\r
                Merge7z::Format *pFormat = Merge7zFormatRegister::GuessFormat(path2);\r
-               if (pFormat)\r
+               if (pFormat != nullptr)\r
                        return pFormat;\r
                throw;\r
        }\r
@@ -255,18 +249,23 @@ CTempPathContext *CTempPathContext::DeleteHead()
        return pParent;\r
 }\r
 \r
+void CTempPathContext::Swap(int idx1, int idx2)\r
+{\r
+       std::swap(m_strDisplayRoot[idx1], m_strDisplayRoot[idx2]);\r
+       std::swap(m_strRoot[idx1], m_strRoot[idx2]);\r
+       if (m_pParent != nullptr)\r
+               m_pParent->Swap(idx1, idx2);\r
+}\r
+\r
 /**\r
  * @brief Return installed or local version of 7-Zip.\r
  */\r
 DWORD NTAPI VersionOf7z()\r
 {\r
-       TCHAR path[MAX_PATH];\r
-       GetModuleFileName(0, path, sizeof path/sizeof*path);\r
-       PathRemoveFileSpec(path);\r
-       PathAppend(path, _T("Merge7z\\7z.dll"));\r
+       String path = paths::ConcatPath(env::GetProgPath(), _T("Merge7z\\7z.dll"));\r
        unsigned versionMS = 0;\r
        unsigned versionLS = 0;\r
-       CVersionInfo(path).GetFixedFileVersion(versionMS, versionLS);\r
+       CVersionInfo(path.c_str()).GetFixedFileVersion(versionMS, versionLS);\r
        return versionMS;\r
 }\r
 \r
@@ -278,20 +277,18 @@ interface Merge7z *Merge7z::Proxy::operator->()
        // As long as the Merge7z*.DLL has not yet been loaded, Merge7z\r
        // [0] points to the name of the DLL (with placeholders for 7-\r
        // Zip major and minor version numbers). Once the DLL has been\r
-       // loaded successfully, Merge7z[0] is set to NULL, causing the\r
+       // loaded successfully, Merge7z[0] is set to nullptr, causing the\r
        // if to fail on subsequent calls.\r
 \r
        if (const char *format = Merge7z[0])\r
        {\r
                // Merge7z has not yet been loaded\r
 \r
-               if (!GetOptionsMgr()->GetInt(OPT_ARCHIVE_ENABLE))\r
+               if (GetOptionsMgr()->GetInt(OPT_ARCHIVE_ENABLE) == 0)\r
                        throw new CResourceException();\r
                if (DWORD ver = VersionOf7z())\r
                {\r
-                       char name[MAX_PATH];\r
-                       wsprintfA(name, format, UINT HIWORD(ver), UINT LOWORD(ver));\r
-                       Merge7z[0] = name;\r
+                       Merge7z[0] = format;\r
                        stub.Load();\r
                }\r
                else\r
@@ -392,7 +389,10 @@ UINT DirItemEnumerator::Open()
 {\r
        m_nIndex = -1;\r
        m_curFolderPrefix = m_rgFolderPrefix.begin();\r
-       m_index = (m_nFlags & Right) != 0 ? 1 : 0;\r
+       if (m_pView->GetDocument()->m_nDirs < 3)\r
+               m_index = (m_nFlags & Right) != 0 ? 1 : 0;\r
+       else\r
+               m_index = ((m_nFlags & Right) != 0) ? 2 : ((m_nFlags & Middle) != 0 ? 1 : 0);\r
        size_t nrgFolderPrefix = m_rgFolderPrefix.size();\r
        if (nrgFolderPrefix)\r
        {\r
@@ -404,7 +404,7 @@ UINT DirItemEnumerator::Open()
        }\r
        return\r
        static_cast<UINT>((\r
-               m_nFlags & LVNI_SELECTED\r
+               (m_nFlags & LVNI_SELECTED)\r
        ?       pView(m_pView)->GetSelectedCount()\r
        :       pView(m_pView)->GetItemCount()\r
        ) * nrgFolderPrefix);\r
@@ -436,7 +436,7 @@ const DIFFITEM &DirItemEnumerator::Next()
  * storage, along with the Envelope itself. The Envelope pointer is passed to\r
  * Merge7z as the return value of the function. It is not meant to be a success\r
  * indicator, so if no temporary storage is required, it is perfectly alright\r
- * to return NULL.\r
+ * to return `nullptr`.\r
  */\r
 Merge7z::Envelope *DirItemEnumerator::Enum(Item &item)\r
 {\r
@@ -455,10 +455,10 @@ Merge7z::Envelope *DirItemEnumerator::Enum(Item &item)
        const String &sFilename = di.diffFileInfo[m_index].filename;\r
        const String &sSubdir = di.diffFileInfo[m_index].path;\r
        if (sSubdir.length())\r
-               envelope->Name = paths_ConcatPath(sSubdir, sFilename);\r
+               envelope->Name = paths::ConcatPath(sSubdir, sFilename);\r
        else\r
                envelope->Name = sFilename;\r
-       envelope->FullPath = paths_ConcatPath(\r
+       envelope->FullPath = paths::ConcatPath(\r
                        di.getFilepath(m_index, ctxt.GetNormalizedPath(m_index)),\r
                        sFilename);\r
 \r
@@ -471,7 +471,7 @@ Merge7z::Envelope *DirItemEnumerator::Enum(Item &item)
                {\r
                        // Item is missing on right side\r
                        PVOID &implied = m_rgImpliedFolders[m_index][di.diffFileInfo[1-m_index].path.get()];\r
-                       if (!implied)\r
+                       if (implied == nullptr)\r
                        {\r
                                // Folder is not implied by some other file, and has\r
                                // not been enumerated so far, so enumerate it now!\r
@@ -509,7 +509,7 @@ bool DirItemEnumerator::MultiStepCompressArchive(LPCTSTR path)
 {\r
        DeleteFile(path);\r
        Merge7z::Format *piHandler = ArchiveGuessFormat(path);\r
-       if (piHandler)\r
+       if (piHandler != nullptr)\r
        {\r
                HWND hwndOwner = CWnd::GetSafeOwner()->GetSafeHwnd();\r
                CString pathIntermediate;\r
@@ -520,8 +520,8 @@ bool DirItemEnumerator::MultiStepCompressArchive(LPCTSTR path)
                bool bDone = MultiStepCompressArchive(pathIntermediate);\r
                if (bDone)\r
                {\r
-                       piHandler->CompressArchive(hwndOwner, path,\r
-                               &SingleItemEnumerator(path, pathIntermediate));\r
+                       SingleItemEnumerator tmpEnumerator(path, pathIntermediate);\r
+                       piHandler->CompressArchive(hwndOwner, path, &tmpEnumerator);\r
                        DeleteFile(pathIntermediate);\r
                }\r
                else\r
@@ -539,11 +539,8 @@ bool DirItemEnumerator::MultiStepCompressArchive(LPCTSTR path)
 void DirItemEnumerator::CompressArchive(LPCTSTR path)\r
 {\r
        String strPath;\r
-       if (path == 0)\r
+       if (path == nullptr)\r
        {\r
-               // No path given, so prompt for path!\r
-               static const TCHAR _T_Merge7z[] = _T("Merge7z");\r
-               static const TCHAR _T_FilterIndex[] = _T("FilterIndex");\r
                // 7z311 can only write 7z, zip, and tar(.gz|.bz2) archives, so don't\r
                // offer other formats here!\r
                static const TCHAR _T_Filter[]\r
@@ -582,7 +579,7 @@ void DirItemEnumerator::CompressArchive(LPCTSTR path)
                        OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOREADONLYRETURN,\r
                        strFilter.c_str()\r
                );\r
-               dlg.m_ofn.nFilterIndex = AfxGetApp()->GetProfileInt(_T_Merge7z, _T_FilterIndex, 1);\r
+               dlg.m_ofn.nFilterIndex = GetOptionsMgr()->GetInt(OPT_ARCHIVE_FILTER_INDEX);\r
                // Use extension from current filter as default extension:\r
                if (int i = dlg.m_ofn.nFilterIndex)\r
                {\r
@@ -601,7 +598,7 @@ void DirItemEnumerator::CompressArchive(LPCTSTR path)
                {\r
                        strPath = dlg.GetPathName();\r
                        path = strPath.c_str();\r
-                       AfxGetApp()->WriteProfileInt(_T_Merge7z, _T_FilterIndex, dlg.m_ofn.nFilterIndex);\r
+                       GetOptionsMgr()->SaveOption(OPT_ARCHIVE_FILTER_INDEX, static_cast<int>(dlg.m_ofn.nFilterIndex));\r
                }\r
        }\r
        if (path && !MultiStepCompressArchive(path))\r
@@ -613,17 +610,18 @@ void DirItemEnumerator::CompressArchive(LPCTSTR path)
 \r
 DecompressResult DecompressArchive(HWND hWnd, const PathContext& files)\r
 {\r
-       DecompressResult res(files, NULL, IS_EXISTING_DIR);\r
+       DecompressResult res(files, nullptr, paths::IS_EXISTING_DIR);\r
        try\r
        {\r
                String path;\r
                USES_CONVERSION;\r
                // Handle archives using 7-zip\r
                Merge7z::Format *piHandler;\r
-               if (piHandler = ArchiveGuessFormat(res.files[0].c_str()))\r
+               piHandler = ArchiveGuessFormat(res.files[0]);\r
+               if (piHandler  != nullptr)\r
                {\r
                        res.pTempPathContext = new CTempPathContext;\r
-                       path = env_GetTempChildPath();\r
+                       path = env::GetTempChildPath();\r
                        for (int index = 0; index < res.files.GetSize(); index++)\r
                                res.pTempPathContext->m_strDisplayRoot[index] = res.files[index];\r
                        if (res.files.GetSize() == 2 && res.files[0] == res.files[1])\r
@@ -634,64 +632,70 @@ DecompressResult DecompressArchive(HWND hWnd, const PathContext& files)
                                        break;\r
                                if (res.files[0].find(path) == 0)\r
                                {\r
-                                       VERIFY(::DeleteFile(res.files[0].c_str()) || (LogErrorString(string_format(_T("DeleteFile(%s) failed"), res.files[0].c_str())), false));\r
+                                       VERIFY(::DeleteFile(res.files[0].c_str()) || (LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), res.files[0].c_str())), false));\r
                                }\r
                                BSTR pTmp = piHandler->GetDefaultName(hWnd, res.files[0].c_str());\r
                                res.files[0] = OLE2T(pTmp);\r
                                SysFreeString(pTmp);\r
                                res.files[0].insert(0, _T("\\"));\r
                                res.files[0].insert(0, path);\r
-                       } while (piHandler = ArchiveGuessFormat(res.files[0].c_str()));\r
+                               piHandler = ArchiveGuessFormat(res.files[0]);\r
+                       } while (piHandler != nullptr);\r
                        res.files[0] = path;\r
                }\r
-               if (!res.files[1].empty() && (piHandler = ArchiveGuessFormat(res.files[1].c_str())))\r
+               piHandler = res.files[1].empty() ? nullptr\r
+                                                                                : ArchiveGuessFormat(res.files[1]);\r
+               if (piHandler != nullptr)\r
                {\r
-                       if (!res.pTempPathContext)\r
+                       if (res.pTempPathContext == nullptr)\r
                        {\r
                                res.pTempPathContext = new CTempPathContext;\r
                                for (int index = 0; index < res.files.GetSize(); index++)\r
                                        res.pTempPathContext->m_strDisplayRoot[index] = res.files[index];\r
                        }\r
-                       path = env_GetTempChildPath();\r
+                       path = env::GetTempChildPath();\r
                        do\r
                        {\r
                                if (FAILED(piHandler->DeCompressArchive(hWnd, res.files[1].c_str(), path.c_str())))\r
                                        break;;\r
                                if (res.files[1].find(path) == 0)\r
                                {\r
-                                       VERIFY(::DeleteFile(res.files[1].c_str()) || (LogErrorString(string_format(_T("DeleteFile(%s) failed"), res.files[1].c_str())), false));\r
+                                       VERIFY(::DeleteFile(res.files[1].c_str()) || (LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), res.files[1].c_str())), false));\r
                                }\r
                                BSTR pTmp = piHandler->GetDefaultName(hWnd, res.files[1].c_str());\r
                                res.files[1] = OLE2T(pTmp);\r
                                SysFreeString(pTmp);\r
                                res.files[1].insert(0, _T("\\"));\r
                                res.files[1].insert(0, path);\r
-                       } while (piHandler = ArchiveGuessFormat(res.files[1].c_str()));\r
+                               piHandler = ArchiveGuessFormat(res.files[1]);\r
+                       } while (piHandler != nullptr);\r
                        res.files[1] = path;\r
                }\r
-               if (res.files.GetSize() > 2 && (piHandler = ArchiveGuessFormat(res.files[2].c_str())))\r
+               piHandler = (res.files.GetSize() <= 2) ? nullptr : ArchiveGuessFormat(res.files[2]);\r
+               if (piHandler != nullptr)\r
                {\r
-                       if (!res.pTempPathContext)\r
+                       if (res.pTempPathContext == nullptr)\r
                        {\r
                                res.pTempPathContext = new CTempPathContext;\r
                                for (int index = 0; index < res.files.GetSize(); index++)\r
                                        res.pTempPathContext->m_strDisplayRoot[index] = res.files[index];\r
                        }\r
-                       path = env_GetTempChildPath();\r
+                       path = env::GetTempChildPath();\r
                        do\r
                        {\r
                                if (FAILED(piHandler->DeCompressArchive(hWnd, res.files[2].c_str(), path.c_str())))\r
                                        break;;\r
                                if (res.files[2].find(path) == 0)\r
                                {\r
-                                       VERIFY(::DeleteFile(res.files[2].c_str()) || (LogErrorString(string_format(_T("DeleteFile(%s) failed"), res.files[2].c_str())), false));\r
+                                       VERIFY(::DeleteFile(res.files[2].c_str()) || (LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), res.files[2].c_str())), false));\r
                                }\r
                                BSTR pTmp = piHandler->GetDefaultName(hWnd, res.files[1].c_str());\r
                                res.files[2] = OLE2T(pTmp);\r
                                SysFreeString(pTmp);\r
                                res.files[2].insert(0, _T("\\"));\r
                                res.files[2].insert(0, path);\r
-                       } while (piHandler = ArchiveGuessFormat(res.files[2].c_str()));\r
+                               piHandler = ArchiveGuessFormat(res.files[2]);\r
+                       } while (piHandler != nullptr);\r
                        res.files[2] = path;\r
                }\r
                if (res.files[1].empty())\r