xref: /reactos/dll/shellext/zipfldr/zipfldr.cpp (revision 032b5aac)
1 /*
2  * PROJECT:     ReactOS Zip Shell Extension
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     zipfldr entrypoint
5  * COPYRIGHT:   Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
10 HMODULE g_hModule = NULL;
11 LONG g_ModuleRefCnt = 0;
12 
13 #include <initguid.h>
14 
15 DEFINE_GUID(CLSID_ZipFolderStorageHandler, 0xe88dcce0, 0xb7b3, 0x11d1, 0xa9, 0xf0, 0x00, 0xaa, 0x00, 0x60, 0xfa, 0x31);
16 DEFINE_GUID(CLSID_ZipFolderSendTo,         0x888dca60, 0xfc0a, 0x11cf, 0x8f, 0x0f, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62);
17 DEFINE_GUID(CLSID_ZipFolderContextMenu,    0xb8cdcb65, 0xb1bf, 0x4b42, 0x94, 0x28, 0x1d, 0xfd, 0xb7, 0xee, 0x92, 0xaf);
18 DEFINE_GUID(CLSID_ZipFolderRightDragHandler,0xbd472f60, 0x27fa, 0x11cf, 0xb8, 0xb4, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
19 DEFINE_GUID(CLSID_ZipFolderDropHandler,    0xed9d80b9, 0xd157, 0x457b, 0x91, 0x92, 0x0e, 0x72, 0x80, 0x31, 0x3b, 0xf0);
20 
21 /* IExplorerCommand: Extract All */
22 DEFINE_GUID(CLSID_ZipFolderExtractAllCommand, 0xc3d9647b, 0x8fd9, 0x4ee6, 0x8b, 0xc7, 0x82, 0x7, 0x80, 0x9, 0x10, 0x5a);
23 
24 
25 class CZipFldrModule : public CComModule
26 {
27 public:
28 };
29 
30 
31 BEGIN_OBJECT_MAP(ObjectMap)
32     OBJECT_ENTRY(CLSID_ZipFolderStorageHandler, CZipFolder)
33     OBJECT_ENTRY(CLSID_ZipFolderContextMenu, CZipFolder)
34     OBJECT_ENTRY(CLSID_ZipFolderSendTo, CSendToZip)
35 END_OBJECT_MAP()
36 
37 CZipFldrModule gModule;
38 
39 
40 #include "minizip/ioapi.h"
41 #include "minizip/iowin32.h"
42 
43 zlib_filefunc64_def g_FFunc;
44 
45 static void init_zlib()
46 {
47     fill_win32_filefunc64W(&g_FFunc);
48 }
49 
50 static BOOL
51 CreateEmptyFile(LPCWSTR pszFile)
52 {
53     HANDLE hFile;
54     hFile = CreateFileW(pszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
55                         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
56     if (hFile != INVALID_HANDLE_VALUE)
57     {
58         CloseHandle(hFile);
59         return TRUE;
60     }
61     return FALSE;
62 }
63 
64 static HRESULT
65 CreateSendToZip(LPCWSTR pszSendTo)
66 {
67     WCHAR szTarget[MAX_PATH], szSendToFile[MAX_PATH];
68 
69     LoadStringW(g_hModule, IDS_FRIENDLYNAME, szTarget, _countof(szTarget));
70 
71     StringCbCopyW(szSendToFile, sizeof(szSendToFile), pszSendTo);
72     PathAppendW(szSendToFile, szTarget);
73     StringCbCatW(szSendToFile, sizeof(szSendToFile), L".ZFSendToTarget");
74     if (!CreateEmptyFile(szSendToFile))
75     {
76         DPRINT1("CreateEmptyFile('%ls')\n", szSendToFile);
77         return E_FAIL;
78     }
79     return S_OK;
80 }
81 
82 static HRESULT
83 GetDefaultUserSendTo(LPWSTR pszPath)
84 {
85     return SHGetFolderPathW(NULL, CSIDL_SENDTO, INVALID_HANDLE_VALUE,
86                             SHGFP_TYPE_DEFAULT, pszPath);
87 }
88 
89 EXTERN_C
90 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
91 {
92     switch (dwReason)
93     {
94     case DLL_PROCESS_ATTACH:
95         DisableThreadLibraryCalls(hInstance);
96         g_hModule = hInstance;
97         gModule.Init(ObjectMap, hInstance, NULL);
98         init_zlib();
99         break;
100     }
101 
102     return TRUE;
103 }
104 
105 STDAPI DllCanUnloadNow()
106 {
107     if (g_ModuleRefCnt)
108         return S_FALSE;
109     return gModule.DllCanUnloadNow();
110 }
111 
112 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
113 {
114     return gModule.DllGetClassObject(rclsid, riid, ppv);
115 }
116 
117 STDAPI DllRegisterServer()
118 {
119     HRESULT hr;
120 
121     hr = gModule.DllRegisterServer(FALSE);
122     if (FAILED_UNEXPECTEDLY(hr))
123         return hr;
124 
125     hr = gModule.UpdateRegistryFromResource(IDR_ZIPFLDR, TRUE, NULL);
126     if (FAILED(hr))
127         return hr;
128 
129     WCHAR szSendTo[MAX_PATH];
130     hr = GetDefaultUserSendTo(szSendTo);
131     if (SUCCEEDED(hr))
132         CreateSendToZip(szSendTo);
133 
134     return S_OK;
135 }
136 
137 STDAPI DllUnregisterServer()
138 {
139     HRESULT hr;
140 
141     hr = gModule.DllUnregisterServer(FALSE);
142     if (FAILED_UNEXPECTEDLY(hr))
143         return hr;
144 
145     hr = gModule.UpdateRegistryFromResource(IDR_ZIPFLDR, FALSE, NULL);
146     if (FAILED(hr))
147         return hr;
148 
149     return S_OK;
150 }
151 
152 EXTERN_C
153 BOOL WINAPI
154 RouteTheCall(
155     IN HWND hWndOwner,
156     IN HINSTANCE hInstance,
157     IN LPCSTR lpStringArg,
158     IN INT Show)
159 {
160     CStringW path = lpStringArg;
161     PathRemoveBlanksW(path.GetBuffer());
162     path.ReleaseBuffer();
163     path = L"\"" + path + L"\"";
164     ShellExecuteW(NULL, L"open", L"explorer.exe", path.GetString(), NULL, SW_SHOWNORMAL);
165     return TRUE;
166 }
167