OSDN Git Service

Improve plugin system (#797) (6)
[winmerge-jp/winmerge-jp.git] / Src / Merge7zFormatShellImpl.cpp
1 /** 
2  * @file  Merge7zFormatShellImpl.cpp
3  *
4  * @brief Implementation file for Merge7zFormatShellImpl class
5  */
6 #include "pch.h"
7 #include "Merge7zFormatShellImpl.h"
8 #pragma warning (push)                  // prevent "warning C4091: 'typedef ': ignored on left of 'tagGPFIDL_FLAGS' when no variable is declared"
9 #pragma warning (disable:4091)  // VC bug when using XP enabled toolsets.
10 #include <shlobj.h>
11 #pragma warning (pop)
12 #include <ShObjIdl.h>
13 #include <comip.h>
14 #include <vector>
15 #include "unicoder.h"
16 #include "Merge7zFormatRegister.h"
17
18 typedef _com_ptr_t<_com_IIID<IFileOperation, &__uuidof(IFileOperation)>> IFileOperationPtr;
19 typedef _com_ptr_t<_com_IIID<IShellItem, &__uuidof(IShellItem)>> IShellItemPtr;
20 typedef _com_ptr_t<_com_IIID<IEnumShellItems, &__uuidof(IEnumShellItems)>> IEnumShellItemsPtr;
21
22 static Merge7zFormatRegister g_autoregister(&Merge7zFormatShellImpl::GuessFormat);
23 static Merge7zFormatShellImpl g_shellformat;
24
25 static HRESULT MySHCreateShellItemFromPath(PCWSTR pszPath, IShellItem **ppShellItem)
26 {
27         PIDLIST_ABSOLUTE pidl;
28         HRESULT hr = SHParseDisplayName(pszPath, nullptr, &pidl, 0, nullptr);
29         if (FAILED(hr))
30                 return hr;
31         hr = SHCreateShellItem(nullptr, nullptr, pidl, ppShellItem);
32         ILFree(pidl);
33         return hr;
34 }
35
36 struct IEnumShellItems;
37
38 static HRESULT MySHCreateEnumShellItemsFromPath(PCWSTR pszPath, IEnumShellItems **ppEnumShellItems)
39 {
40         IShellItemPtr pShellItem;
41         HRESULT hr = MySHCreateShellItemFromPath(pszPath, &pShellItem);
42         if (FAILED(hr))
43                 return hr;
44         return pShellItem->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(ppEnumShellItems));
45 }
46
47 Merge7z::Format *Merge7zFormatShellImpl::GuessFormat(const String& path)
48 {
49         int i;
50         static const TCHAR *exts[] = {_T(".zip"), _T(".lzh"), _T("://"), _T("::{")};
51         for (i = 0; i < sizeof(exts)/sizeof(exts[0]); ++i)
52         {
53                 if (path.find(exts[i]) != String::npos)
54                         break;
55         }
56         if (i == sizeof(exts)/sizeof(exts[0]))
57                 return nullptr;
58         IEnumShellItemsPtr pEnumShellItems;
59         if (FAILED(MySHCreateEnumShellItemsFromPath(ucr::toUTF16(path).c_str(), &pEnumShellItems)))
60                 return nullptr;
61         return &g_shellformat;
62 }
63
64 HRESULT Merge7zFormatShellImpl::DeCompressArchive(HWND, LPCTSTR path, LPCTSTR folder)
65 {
66         IFileOperationPtr pFileOperation;
67         HRESULT hr = pFileOperation.CreateInstance(CLSID_FileOperation, nullptr, CLSCTX_ALL);
68         if (FAILED(hr))
69                 return hr;
70
71         pFileOperation->SetOperationFlags(0);
72
73         IShellItemPtr pShellItemDest, pShellItem;
74         IEnumShellItemsPtr pEnumShellItems;
75         ULONG ulRetNo;
76
77         hr = MySHCreateShellItemFromPath(ucr::toUTF16(folder).c_str(), &pShellItemDest);
78         if (FAILED(hr))
79                 return hr;
80         hr = MySHCreateEnumShellItemsFromPath(ucr::toUTF16(path).c_str(), &pEnumShellItems);
81         if (FAILED(hr))
82                 return hr;
83
84         while ((hr = pEnumShellItems->Next(1, &pShellItem, &ulRetNo)) == NOERROR)
85         {
86                 pFileOperation->CopyItem(pShellItem, pShellItemDest, nullptr, nullptr);
87                 pShellItem.Release();
88         }
89         if (FAILED(hr))
90                 return hr;
91
92         return pFileOperation->PerformOperations();
93 }
94
95 HRESULT Merge7zFormatShellImpl::CompressArchive(HWND, LPCTSTR path, Merge7z::DirItemEnumerator *)
96 {
97         return E_FAIL;
98 }
99
100 Merge7z::Format::Inspector *Merge7zFormatShellImpl::Open(HWND, LPCTSTR) { return nullptr; }
101 Merge7z::Format::Updater *Merge7zFormatShellImpl::Update(HWND, LPCTSTR) { return nullptr; }
102 HRESULT Merge7zFormatShellImpl::GetHandlerProperty(HWND, PROPID, PROPVARIANT *, VARTYPE) { return E_FAIL; }
103 BSTR Merge7zFormatShellImpl::GetHandlerName(HWND) { return nullptr; }
104 BSTR Merge7zFormatShellImpl::GetHandlerClassID(HWND) { return nullptr; }
105 BSTR Merge7zFormatShellImpl::GetHandlerExtension(HWND) { return nullptr; }
106 BSTR Merge7zFormatShellImpl::GetHandlerAddExtension(HWND) { return nullptr; }
107 VARIANT_BOOL Merge7zFormatShellImpl::GetHandlerUpdate(HWND) { return VARIANT_FALSE; }
108 VARIANT_BOOL Merge7zFormatShellImpl::GetHandlerKeepName(HWND) { return VARIANT_FALSE; }
109
110 BSTR Merge7zFormatShellImpl::GetDefaultName(HWND, LPCTSTR path)
111 {
112         return SysAllocString(L"");
113 }