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