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 * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 7 */ 8 9 #include "precomp.h" 10 11 HMODULE g_hModule = NULL; 12 LONG g_ModuleRefCnt = 0; 13 14 #include <initguid.h> 15 16 DEFINE_GUID(CLSID_ZipFolderStorageHandler, 0xe88dcce0, 0xb7b3, 0x11d1, 0xa9, 0xf0, 0x00, 0xaa, 0x00, 0x60, 0xfa, 0x31); 17 DEFINE_GUID(CLSID_ZipFolderSendTo, 0x888dca60, 0xfc0a, 0x11cf, 0x8f, 0x0f, 0x00, 0xc0, 0x4f, 0xd7, 0xd0, 0x62); 18 DEFINE_GUID(CLSID_ZipFolderContextMenu, 0xb8cdcb65, 0xb1bf, 0x4b42, 0x94, 0x28, 0x1d, 0xfd, 0xb7, 0xee, 0x92, 0xaf); 19 DEFINE_GUID(CLSID_ZipFolderRightDragHandler,0xbd472f60, 0x27fa, 0x11cf, 0xb8, 0xb4, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00); 20 DEFINE_GUID(CLSID_ZipFolderDropHandler, 0xed9d80b9, 0xd157, 0x457b, 0x91, 0x92, 0x0e, 0x72, 0x80, 0x31, 0x3b, 0xf0); 21 22 /* IExplorerCommand: Extract All */ 23 DEFINE_GUID(CLSID_ZipFolderExtractAllCommand, 0xc3d9647b, 0x8fd9, 0x4ee6, 0x8b, 0xc7, 0x82, 0x7, 0x80, 0x9, 0x10, 0x5a); 24 25 26 class CZipFldrModule : public CComModule 27 { 28 public: 29 }; 30 31 32 BEGIN_OBJECT_MAP(ObjectMap) 33 OBJECT_ENTRY(CLSID_ZipFolderStorageHandler, CZipFolder) 34 OBJECT_ENTRY(CLSID_ZipFolderContextMenu, CZipFolder) 35 OBJECT_ENTRY(CLSID_ZipFolderSendTo, CSendToZip) 36 END_OBJECT_MAP() 37 38 CZipFldrModule gModule; 39 40 41 #include "minizip/ioapi.h" 42 #include "minizip/iowin32.h" 43 44 zlib_filefunc64_def g_FFunc; 45 46 static void init_zlib() 47 { 48 fill_win32_filefunc64W(&g_FFunc); 49 } 50 51 static BOOL 52 CreateEmptyFile(PCWSTR pszFile) 53 { 54 HANDLE hFile; 55 hFile = CreateFileW(pszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, 56 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 57 if (hFile != INVALID_HANDLE_VALUE) 58 { 59 CloseHandle(hFile); 60 return TRUE; 61 } 62 return FALSE; 63 } 64 65 static HRESULT 66 CreateSendToZip(PCWSTR pszSendTo) 67 { 68 WCHAR szTarget[MAX_PATH], szSendToFile[MAX_PATH]; 69 70 LoadStringW(g_hModule, IDS_FRIENDLYNAME, szTarget, _countof(szTarget)); 71 72 StringCbCopyW(szSendToFile, sizeof(szSendToFile), pszSendTo); 73 PathAppendW(szSendToFile, szTarget); 74 StringCbCatW(szSendToFile, sizeof(szSendToFile), L".ZFSendToTarget"); 75 if (!CreateEmptyFile(szSendToFile)) 76 { 77 DPRINT1("CreateEmptyFile('%ls')\n", szSendToFile); 78 return E_FAIL; 79 } 80 return S_OK; 81 } 82 83 static HRESULT 84 GetDefaultUserSendTo(PWSTR pszPath) 85 { 86 return SHGetFolderPathW(NULL, CSIDL_SENDTO, INVALID_HANDLE_VALUE, 87 SHGFP_TYPE_DEFAULT, pszPath); 88 } 89 90 UINT GetZipCodePage(BOOL bUnZip) 91 { 92 WCHAR szValue[16]; 93 DWORD dwType, cbValue = sizeof(szValue); 94 UINT nDefaultCodePage = (bUnZip ? CP_ACP : CP_UTF8); 95 96 LONG error = SHGetValueW(HKEY_CURRENT_USER, L"Software\\ReactOS", 97 (bUnZip ? L"UnZipCodePage" : L"ZipCodePage"), 98 &dwType, szValue, &cbValue); 99 if (error != ERROR_SUCCESS) 100 return nDefaultCodePage; 101 102 if (cbValue == sizeof(DWORD) && (dwType == REG_DWORD || dwType == REG_BINARY)) 103 return *(DWORD*)szValue; 104 105 if (dwType != REG_SZ && dwType != REG_EXPAND_SZ) 106 return nDefaultCodePage; 107 108 szValue[_countof(szValue) - 1] = UNICODE_NULL; 109 return (UINT)wcstol(szValue, NULL, 0); 110 } 111 112 EXTERN_C 113 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 114 { 115 switch (dwReason) 116 { 117 case DLL_PROCESS_ATTACH: 118 DisableThreadLibraryCalls(hInstance); 119 g_hModule = hInstance; 120 gModule.Init(ObjectMap, hInstance, NULL); 121 init_zlib(); 122 break; 123 } 124 125 return TRUE; 126 } 127 128 STDAPI DllCanUnloadNow() 129 { 130 if (g_ModuleRefCnt) 131 return S_FALSE; 132 return gModule.DllCanUnloadNow(); 133 } 134 135 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 136 { 137 return gModule.DllGetClassObject(rclsid, riid, ppv); 138 } 139 140 STDAPI DllRegisterServer() 141 { 142 HRESULT hr; 143 144 hr = gModule.DllRegisterServer(FALSE); 145 if (FAILED_UNEXPECTEDLY(hr)) 146 return hr; 147 148 hr = gModule.UpdateRegistryFromResource(IDR_ZIPFLDR, TRUE, NULL); 149 if (FAILED(hr)) 150 return hr; 151 152 WCHAR szSendTo[MAX_PATH]; 153 hr = GetDefaultUserSendTo(szSendTo); 154 if (SUCCEEDED(hr)) 155 CreateSendToZip(szSendTo); 156 157 return S_OK; 158 } 159 160 STDAPI DllUnregisterServer() 161 { 162 HRESULT hr; 163 164 hr = gModule.DllUnregisterServer(FALSE); 165 if (FAILED_UNEXPECTEDLY(hr)) 166 return hr; 167 168 hr = gModule.UpdateRegistryFromResource(IDR_ZIPFLDR, FALSE, NULL); 169 if (FAILED(hr)) 170 return hr; 171 172 return S_OK; 173 } 174 175 EXTERN_C 176 BOOL WINAPI 177 RouteTheCallW(IN HWND hWndOwner, IN HINSTANCE hInstance, IN PCWSTR lpStringArg, IN INT Show) 178 { 179 CStringW path = lpStringArg; 180 PathRemoveBlanksW(path.GetBuffer()); 181 path.ReleaseBuffer(); 182 path = L"\"" + path + L"\""; 183 184 WCHAR app[MAX_PATH]; 185 GetWindowsDirectoryW(app, _countof(app)); 186 PathAppendW(app, L"explorer.exe"); 187 188 ShellExecuteW(NULL, L"open", app, path.GetString(), NULL, Show ? Show : SW_SHOWNORMAL); 189 return TRUE; 190 } 191