1*f8e2c85aSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*f8e2c85aSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*f8e2c85aSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*f8e2c85aSAndrew Rist * distributed with this work for additional information 6*f8e2c85aSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*f8e2c85aSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*f8e2c85aSAndrew Rist * "License"); you may not use this file except in compliance 9*f8e2c85aSAndrew Rist * with the License. You may obtain a copy of the License at 10*f8e2c85aSAndrew Rist * 11*f8e2c85aSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*f8e2c85aSAndrew Rist * 13*f8e2c85aSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*f8e2c85aSAndrew Rist * software distributed under the License is distributed on an 15*f8e2c85aSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*f8e2c85aSAndrew Rist * KIND, either express or implied. See the License for the 17*f8e2c85aSAndrew Rist * specific language governing permissions and limitations 18*f8e2c85aSAndrew Rist * under the License. 19*f8e2c85aSAndrew Rist * 20*f8e2c85aSAndrew Rist *************************************************************/ 21*f8e2c85aSAndrew Rist 22*f8e2c85aSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_shell.hxx" 26cdf0e10cSrcweir #include "internal/config.hxx" 27cdf0e10cSrcweir #include "internal/global.hxx" 28cdf0e10cSrcweir #include "internal/shlxthdl.hxx" 29cdf0e10cSrcweir #include "classfactory.hxx" 30cdf0e10cSrcweir #include "internal/registry.hxx" 31cdf0e10cSrcweir #include "internal/fileextensions.hxx" 32cdf0e10cSrcweir #include "internal/utilities.hxx" 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include <tchar.h> 35cdf0e10cSrcweir #include <string> 36cdf0e10cSrcweir #include <shlobj.h> 37cdf0e10cSrcweir 38cdf0e10cSrcweir //--------------------------- 39cdf0e10cSrcweir // Module global 40cdf0e10cSrcweir //--------------------------- 41cdf0e10cSrcweir long g_DllRefCnt = 0; 42cdf0e10cSrcweir HINSTANCE g_hModule = NULL; 43cdf0e10cSrcweir 44cdf0e10cSrcweir namespace /* private */ 45cdf0e10cSrcweir { 46cdf0e10cSrcweir const char* GUID_PLACEHOLDER = "{GUID}"; 47cdf0e10cSrcweir const char* EXTENSION_PLACEHOLDER = "{EXT}"; 48cdf0e10cSrcweir const char* FORWARDKEY_PLACEHOLDER = "{FWDKEY}"; 49cdf0e10cSrcweir 50cdf0e10cSrcweir const char* CLSID_ENTRY = "CLSID\\{GUID}\\InProcServer32"; 51cdf0e10cSrcweir const char* SHELLEX_IID_ENTRY = "{EXT}\\shellex\\{GUID}"; 52cdf0e10cSrcweir const char* SHELLEX_ENTRY = "{EXT}\\shellex"; 53cdf0e10cSrcweir const char* PROPSHEET_ENTRY = "{EXT}\\CLSID\\{GUID}\\InProcServer32"; 54cdf0e10cSrcweir const char* EXTENSION_CLSID = "{EXT}\\CLSID"; 55cdf0e10cSrcweir const char* EXTENSION_CLSID_GUID = "{EXT}\\CLSID\\{GUID}"; 56cdf0e10cSrcweir const char* FORWARD_PROPSHEET_MYPROPSHEET_ENTRY = "{FWDKEY}\\shellex\\PropertySheetHandlers\\MyPropSheet1"; 57cdf0e10cSrcweir const char* FORWARD_PROPSHEET_ENTRY = "{FWDKEY}\\shellex\\PropertySheetHandlers"; 58cdf0e10cSrcweir const char* FORWARD_SHELLEX_ENTRY = "{FWDKEY}\\shellex"; 59cdf0e10cSrcweir 60cdf0e10cSrcweir const char* SHELL_EXTENSION_APPROVED_KEY_NAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"; 61cdf0e10cSrcweir 62cdf0e10cSrcweir //--------------------------- 63cdf0e10cSrcweir // "String Placeholder" -> 64cdf0e10cSrcweir // "String Replacement" 65cdf0e10cSrcweir //--------------------------- 66cdf0e10cSrcweir void SubstitutePlaceholder(std::string& String, const std::string& Placeholder, const std::string& Replacement) 67cdf0e10cSrcweir { 68cdf0e10cSrcweir std::string::size_type idx = String.find(Placeholder); 69cdf0e10cSrcweir std::string::size_type len = Placeholder.length(); 70cdf0e10cSrcweir 71cdf0e10cSrcweir while (std::string::npos != idx) 72cdf0e10cSrcweir { 73cdf0e10cSrcweir String.replace(idx, len, Replacement); 74cdf0e10cSrcweir idx = String.find(Placeholder); 75cdf0e10cSrcweir } 76cdf0e10cSrcweir } 77cdf0e10cSrcweir 78cdf0e10cSrcweir /* Make the registry entry 79cdf0e10cSrcweir HKCR\CLSID\{GUID} 80cdf0e10cSrcweir InProcServer32 = Path\shlxthdl.dll 81cdf0e10cSrcweir ThreadingModel = Apartment 82cdf0e10cSrcweir */ 83cdf0e10cSrcweir HRESULT RegisterComComponent(const char* FilePath, const CLSID& Guid) 84cdf0e10cSrcweir { 85cdf0e10cSrcweir std::string ClsidEntry = CLSID_ENTRY; 86cdf0e10cSrcweir SubstitutePlaceholder(ClsidEntry, GUID_PLACEHOLDER, ClsidToString(Guid)); 87cdf0e10cSrcweir 88cdf0e10cSrcweir if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "", FilePath)) 89cdf0e10cSrcweir return E_FAIL; 90cdf0e10cSrcweir 91cdf0e10cSrcweir if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "ThreadingModel", "Apartment")) 92cdf0e10cSrcweir return E_FAIL; 93cdf0e10cSrcweir 94cdf0e10cSrcweir return S_OK; 95cdf0e10cSrcweir } 96cdf0e10cSrcweir 97cdf0e10cSrcweir HRESULT UnregisterComComponent(const CLSID& Guid) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir std::string tmp = "CLSID\\"; 100cdf0e10cSrcweir tmp += ClsidToString(Guid); 101cdf0e10cSrcweir return DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()) ? S_OK : E_FAIL; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir 104cdf0e10cSrcweir HRESULT RegisterColumnHandler(const char* ModuleFileName) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir if (FAILED(RegisterComComponent(ModuleFileName, CLSID_COLUMN_HANDLER))) 107cdf0e10cSrcweir return E_FAIL; 108cdf0e10cSrcweir 109cdf0e10cSrcweir std::string tmp = "Folder\\shellex\\ColumnHandlers\\"; 110cdf0e10cSrcweir tmp += ClsidToString(CLSID_COLUMN_HANDLER); 111cdf0e10cSrcweir 112cdf0e10cSrcweir return SetRegistryKey( 113cdf0e10cSrcweir HKEY_CLASSES_ROOT, 114cdf0e10cSrcweir tmp.c_str(), 115cdf0e10cSrcweir "", 116cdf0e10cSrcweir WStringToString(COLUMN_HANDLER_DESCRIPTIVE_NAME).c_str()) ? S_OK : E_FAIL; 117cdf0e10cSrcweir } 118cdf0e10cSrcweir 119cdf0e10cSrcweir HRESULT UnregisterColumnHandler() 120cdf0e10cSrcweir { 121cdf0e10cSrcweir std::string tmp = "Folder\\shellex\\ColumnHandlers\\"; 122cdf0e10cSrcweir tmp += ClsidToString(CLSID_COLUMN_HANDLER); 123cdf0e10cSrcweir 124cdf0e10cSrcweir if (!DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str())) 125cdf0e10cSrcweir return E_FAIL; 126cdf0e10cSrcweir 127cdf0e10cSrcweir return UnregisterComComponent(CLSID_COLUMN_HANDLER); 128cdf0e10cSrcweir } 129cdf0e10cSrcweir 130cdf0e10cSrcweir HRESULT RegisterInfotipHandler(const char* ModuleFileName) 131cdf0e10cSrcweir { 132cdf0e10cSrcweir if (FAILED(RegisterComComponent(ModuleFileName, CLSID_INFOTIP_HANDLER))) 133cdf0e10cSrcweir return E_FAIL; 134cdf0e10cSrcweir 135cdf0e10cSrcweir std::string iid = ClsidToString(IID_IQueryInfo); 136cdf0e10cSrcweir std::string tmp; 137cdf0e10cSrcweir 138cdf0e10cSrcweir for(size_t i = 0; i < OOFileExtensionTableSize; i++) 139cdf0e10cSrcweir { 140cdf0e10cSrcweir tmp = SHELLEX_IID_ENTRY; 141cdf0e10cSrcweir SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); 142cdf0e10cSrcweir SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid); 143cdf0e10cSrcweir 144cdf0e10cSrcweir if (!SetRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), "", ClsidToString(CLSID_INFOTIP_HANDLER).c_str())) 145cdf0e10cSrcweir return E_FAIL; 146cdf0e10cSrcweir } 147cdf0e10cSrcweir return S_OK; 148cdf0e10cSrcweir } 149cdf0e10cSrcweir 150cdf0e10cSrcweir HRESULT UnregisterInfotipHandler() 151cdf0e10cSrcweir { 152cdf0e10cSrcweir std::string iid = ClsidToString(IID_IQueryInfo); 153cdf0e10cSrcweir std::string tmp; 154cdf0e10cSrcweir 155cdf0e10cSrcweir for (size_t i = 0; i < OOFileExtensionTableSize; i++) 156cdf0e10cSrcweir { 157cdf0e10cSrcweir tmp = SHELLEX_IID_ENTRY; 158cdf0e10cSrcweir 159cdf0e10cSrcweir SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); 160cdf0e10cSrcweir SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid); 161cdf0e10cSrcweir 162cdf0e10cSrcweir DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); 163cdf0e10cSrcweir 164cdf0e10cSrcweir // if there are no further subkey below .ext\\shellex 165cdf0e10cSrcweir // delete the whole subkey 166cdf0e10cSrcweir tmp = SHELLEX_ENTRY; 167cdf0e10cSrcweir SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); 168cdf0e10cSrcweir 169cdf0e10cSrcweir bool HasSubKeys = true; 170cdf0e10cSrcweir if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), HasSubKeys) && !HasSubKeys) 171cdf0e10cSrcweir DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); 172cdf0e10cSrcweir } 173cdf0e10cSrcweir return UnregisterComComponent(CLSID_INFOTIP_HANDLER); 174cdf0e10cSrcweir } 175cdf0e10cSrcweir 176cdf0e10cSrcweir HRESULT RegisterPropSheetHandler(const char* ModuleFileName) 177cdf0e10cSrcweir { 178cdf0e10cSrcweir std::string ExtEntry; 179cdf0e10cSrcweir std::string FwdKeyEntry; 180cdf0e10cSrcweir 181cdf0e10cSrcweir if (FAILED(RegisterComComponent(ModuleFileName, CLSID_PROPERTYSHEET_HANDLER))) 182cdf0e10cSrcweir return E_FAIL; 183cdf0e10cSrcweir 184cdf0e10cSrcweir for (size_t i = 0; i < OOFileExtensionTableSize; i++) 185cdf0e10cSrcweir { 186cdf0e10cSrcweir FwdKeyEntry = FORWARD_PROPSHEET_MYPROPSHEET_ENTRY; 187cdf0e10cSrcweir SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); 188cdf0e10cSrcweir 189cdf0e10cSrcweir if (!SetRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), "", ClsidToString(CLSID_PROPERTYSHEET_HANDLER).c_str())) 190cdf0e10cSrcweir return E_FAIL; 191cdf0e10cSrcweir } 192cdf0e10cSrcweir return S_OK; 193cdf0e10cSrcweir } 194cdf0e10cSrcweir 195cdf0e10cSrcweir HRESULT UnregisterPropSheetHandler() 196cdf0e10cSrcweir { 197cdf0e10cSrcweir std::string ExtEntry; 198cdf0e10cSrcweir std::string FwdKeyEntry; 199cdf0e10cSrcweir 200cdf0e10cSrcweir for (size_t i = 0; i < OOFileExtensionTableSize; i++) 201cdf0e10cSrcweir { 202cdf0e10cSrcweir FwdKeyEntry = FORWARD_PROPSHEET_MYPROPSHEET_ENTRY; 203cdf0e10cSrcweir SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); 204cdf0e10cSrcweir 205cdf0e10cSrcweir DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); 206cdf0e10cSrcweir 207cdf0e10cSrcweir FwdKeyEntry = FORWARD_PROPSHEET_ENTRY; 208cdf0e10cSrcweir SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); 209cdf0e10cSrcweir 210cdf0e10cSrcweir bool HasSubKeys = true; 211cdf0e10cSrcweir if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), HasSubKeys) && !HasSubKeys) 212cdf0e10cSrcweir DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); 213cdf0e10cSrcweir 214cdf0e10cSrcweir FwdKeyEntry = FORWARD_SHELLEX_ENTRY; 215cdf0e10cSrcweir SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey); 216cdf0e10cSrcweir 217cdf0e10cSrcweir HasSubKeys = true; 218cdf0e10cSrcweir if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), HasSubKeys) && !HasSubKeys) 219cdf0e10cSrcweir DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str()); 220cdf0e10cSrcweir } 221cdf0e10cSrcweir 222cdf0e10cSrcweir return UnregisterComComponent(CLSID_PROPERTYSHEET_HANDLER); 223cdf0e10cSrcweir } 224cdf0e10cSrcweir 225cdf0e10cSrcweir HRESULT RegisterThumbviewerHandler(const char* ModuleFileName) 226cdf0e10cSrcweir { 227cdf0e10cSrcweir if (FAILED(RegisterComComponent(ModuleFileName, CLSID_THUMBVIEWER_HANDLER))) 228cdf0e10cSrcweir return E_FAIL; 229cdf0e10cSrcweir 230cdf0e10cSrcweir std::string iid = ClsidToString(IID_IExtractImage); 231cdf0e10cSrcweir std::string tmp; 232cdf0e10cSrcweir 233cdf0e10cSrcweir for(size_t i = 0; i < OOFileExtensionTableSize; i++) 234cdf0e10cSrcweir { 235cdf0e10cSrcweir tmp = SHELLEX_IID_ENTRY; 236cdf0e10cSrcweir 237cdf0e10cSrcweir SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); 238cdf0e10cSrcweir SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid); 239cdf0e10cSrcweir 240cdf0e10cSrcweir if (!SetRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), "", ClsidToString(CLSID_THUMBVIEWER_HANDLER).c_str())) 241cdf0e10cSrcweir return E_FAIL; 242cdf0e10cSrcweir } 243cdf0e10cSrcweir return S_OK; 244cdf0e10cSrcweir } 245cdf0e10cSrcweir 246cdf0e10cSrcweir HRESULT UnregisterThumbviewerHandler() 247cdf0e10cSrcweir { 248cdf0e10cSrcweir std::string iid = ClsidToString(IID_IExtractImage); 249cdf0e10cSrcweir std::string tmp; 250cdf0e10cSrcweir 251cdf0e10cSrcweir for (size_t i = 0; i < OOFileExtensionTableSize; i++) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir tmp = SHELLEX_IID_ENTRY; 254cdf0e10cSrcweir 255cdf0e10cSrcweir SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); 256cdf0e10cSrcweir SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid); 257cdf0e10cSrcweir 258cdf0e10cSrcweir DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); 259cdf0e10cSrcweir 260cdf0e10cSrcweir // if there are no further subkey below .ext\\shellex 261cdf0e10cSrcweir // delete the whole subkey 262cdf0e10cSrcweir tmp = SHELLEX_ENTRY; 263cdf0e10cSrcweir SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi); 264cdf0e10cSrcweir 265cdf0e10cSrcweir bool HasSubKeys = true; 266cdf0e10cSrcweir if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), HasSubKeys) && !HasSubKeys) 267cdf0e10cSrcweir DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()); 268cdf0e10cSrcweir } 269cdf0e10cSrcweir return UnregisterComComponent(CLSID_THUMBVIEWER_HANDLER); 270cdf0e10cSrcweir } 271cdf0e10cSrcweir 272cdf0e10cSrcweir /** Approving/Unapproving the Shell Extension, it's important under Windows 273cdf0e10cSrcweir NT/2000/XP, see MSDN: Creating Shell Extension Handlers */ 274cdf0e10cSrcweir HRESULT ApproveShellExtension(CLSID clsid, const std::wstring& Description) 275cdf0e10cSrcweir { 276cdf0e10cSrcweir bool bRet = SetRegistryKey( 277cdf0e10cSrcweir HKEY_LOCAL_MACHINE, 278cdf0e10cSrcweir SHELL_EXTENSION_APPROVED_KEY_NAME, 279cdf0e10cSrcweir ClsidToString(clsid).c_str(), 280cdf0e10cSrcweir WStringToString(Description).c_str()); 281cdf0e10cSrcweir 282cdf0e10cSrcweir return bRet ? S_OK : E_FAIL; 283cdf0e10cSrcweir } 284cdf0e10cSrcweir 285cdf0e10cSrcweir HRESULT UnapproveShellExtension(CLSID Clsid) 286cdf0e10cSrcweir { 287cdf0e10cSrcweir HKEY hkey; 288cdf0e10cSrcweir 289cdf0e10cSrcweir LONG rc = RegOpenKeyA( 290cdf0e10cSrcweir HKEY_LOCAL_MACHINE, 291cdf0e10cSrcweir SHELL_EXTENSION_APPROVED_KEY_NAME, 292cdf0e10cSrcweir &hkey); 293cdf0e10cSrcweir 294cdf0e10cSrcweir if (ERROR_SUCCESS == rc) 295cdf0e10cSrcweir { 296cdf0e10cSrcweir rc = RegDeleteValueA( 297cdf0e10cSrcweir hkey, 298cdf0e10cSrcweir ClsidToString(Clsid).c_str()); 299cdf0e10cSrcweir 300cdf0e10cSrcweir rc = RegCloseKey(hkey); 301cdf0e10cSrcweir } 302cdf0e10cSrcweir 303cdf0e10cSrcweir return rc == ERROR_SUCCESS ? S_OK : E_FAIL; 304cdf0e10cSrcweir } 305cdf0e10cSrcweir 306cdf0e10cSrcweir } // namespace /* private */ 307cdf0e10cSrcweir 308cdf0e10cSrcweir 309cdf0e10cSrcweir //--------------------- 310cdf0e10cSrcweir // COM exports 311cdf0e10cSrcweir //--------------------- 312cdf0e10cSrcweir 313cdf0e10cSrcweir extern "C" STDAPI DllRegisterServer() 314cdf0e10cSrcweir { 315cdf0e10cSrcweir TCHAR ModuleFileName[MAX_PATH]; 316cdf0e10cSrcweir 317cdf0e10cSrcweir GetModuleFileName( 318cdf0e10cSrcweir GetModuleHandle(MODULE_NAME), 319cdf0e10cSrcweir ModuleFileName, 320cdf0e10cSrcweir sizeof(ModuleFileName)); 321cdf0e10cSrcweir 322cdf0e10cSrcweir std::string module_path = WStringToString(ModuleFileName); 323cdf0e10cSrcweir HRESULT hr = S_OK; 324cdf0e10cSrcweir 325cdf0e10cSrcweir if (SUCCEEDED(RegisterColumnHandler(module_path.c_str()))) 326cdf0e10cSrcweir ApproveShellExtension(CLSID_COLUMN_HANDLER, COLUMN_HANDLER_DESCRIPTIVE_NAME); 327cdf0e10cSrcweir else 328cdf0e10cSrcweir hr = E_FAIL; 329cdf0e10cSrcweir 330cdf0e10cSrcweir if (SUCCEEDED(RegisterInfotipHandler(module_path.c_str()))) 331cdf0e10cSrcweir ApproveShellExtension(CLSID_INFOTIP_HANDLER, INFOTIP_HANDLER_DESCRIPTIVE_NAME); 332cdf0e10cSrcweir else 333cdf0e10cSrcweir hr = E_FAIL; 334cdf0e10cSrcweir 335cdf0e10cSrcweir if (SUCCEEDED(RegisterPropSheetHandler(module_path.c_str()))) 336cdf0e10cSrcweir ApproveShellExtension(CLSID_PROPERTYSHEET_HANDLER, PROPSHEET_HANDLER_DESCRIPTIVE_NAME); 337cdf0e10cSrcweir else 338cdf0e10cSrcweir hr = E_FAIL; 339cdf0e10cSrcweir 340cdf0e10cSrcweir if (SUCCEEDED(RegisterThumbviewerHandler(module_path.c_str()))) 341cdf0e10cSrcweir ApproveShellExtension(CLSID_THUMBVIEWER_HANDLER, THUMBVIEWER_HANDLER_DESCRIPTIVAE_NAME); 342cdf0e10cSrcweir else 343cdf0e10cSrcweir hr = E_FAIL; 344cdf0e10cSrcweir 345cdf0e10cSrcweir // notify the Shell that something has changed 346cdf0e10cSrcweir SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0); 347cdf0e10cSrcweir 348cdf0e10cSrcweir return hr; 349cdf0e10cSrcweir } 350cdf0e10cSrcweir 351cdf0e10cSrcweir extern "C" STDAPI DllUnregisterServer() 352cdf0e10cSrcweir { 353cdf0e10cSrcweir HRESULT hr = S_OK; 354cdf0e10cSrcweir 355cdf0e10cSrcweir if (FAILED(UnregisterColumnHandler())) 356cdf0e10cSrcweir hr = E_FAIL; 357cdf0e10cSrcweir 358cdf0e10cSrcweir UnapproveShellExtension(CLSID_COLUMN_HANDLER); 359cdf0e10cSrcweir 360cdf0e10cSrcweir if (FAILED(UnregisterInfotipHandler())) 361cdf0e10cSrcweir hr = E_FAIL; 362cdf0e10cSrcweir 363cdf0e10cSrcweir UnapproveShellExtension(CLSID_INFOTIP_HANDLER); 364cdf0e10cSrcweir 365cdf0e10cSrcweir if (FAILED(UnregisterPropSheetHandler())) 366cdf0e10cSrcweir hr = E_FAIL; 367cdf0e10cSrcweir 368cdf0e10cSrcweir UnapproveShellExtension(CLSID_PROPERTYSHEET_HANDLER); 369cdf0e10cSrcweir 370cdf0e10cSrcweir if (FAILED(UnregisterThumbviewerHandler())) 371cdf0e10cSrcweir hr = E_FAIL; 372cdf0e10cSrcweir 373cdf0e10cSrcweir UnapproveShellExtension(CLSID_THUMBVIEWER_HANDLER); 374cdf0e10cSrcweir 375cdf0e10cSrcweir // notify the Shell that something has changed 376cdf0e10cSrcweir SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0); 377cdf0e10cSrcweir 378cdf0e10cSrcweir return hr; 379cdf0e10cSrcweir } 380cdf0e10cSrcweir 381cdf0e10cSrcweir extern "C" STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv) 382cdf0e10cSrcweir { 383cdf0e10cSrcweir *ppv = 0; 384cdf0e10cSrcweir 385cdf0e10cSrcweir if ((rclsid != CLSID_INFOTIP_HANDLER) && 386cdf0e10cSrcweir (rclsid != CLSID_COLUMN_HANDLER) && 387cdf0e10cSrcweir (rclsid != CLSID_PROPERTYSHEET_HANDLER) && 388cdf0e10cSrcweir (rclsid != CLSID_THUMBVIEWER_HANDLER)) 389cdf0e10cSrcweir return CLASS_E_CLASSNOTAVAILABLE; 390cdf0e10cSrcweir 391cdf0e10cSrcweir if ((riid != IID_IUnknown) && (riid != IID_IClassFactory)) 392cdf0e10cSrcweir return E_NOINTERFACE; 393cdf0e10cSrcweir 394cdf0e10cSrcweir if ( rclsid == CLSID_INFOTIP_HANDLER ) 395cdf0e10cSrcweir OutputDebugStringFormat( "DllGetClassObject: Create CLSID_INFOTIP_HANDLER\n" ); 396cdf0e10cSrcweir else if ( rclsid == CLSID_COLUMN_HANDLER ) 397cdf0e10cSrcweir OutputDebugStringFormat( "DllGetClassObject: Create CLSID_COLUMN_HANDLER\n" ); 398cdf0e10cSrcweir else if ( rclsid == CLSID_PROPERTYSHEET_HANDLER ) 399cdf0e10cSrcweir OutputDebugStringFormat( "DllGetClassObject: Create CLSID_PROPERTYSHEET_HANDLER\n" ); 400cdf0e10cSrcweir else if ( rclsid == CLSID_THUMBVIEWER_HANDLER ) 401cdf0e10cSrcweir OutputDebugStringFormat( "DllGetClassObject: Create CLSID_THUMBVIEWER_HANDLER\n" ); 402cdf0e10cSrcweir 403cdf0e10cSrcweir IUnknown* pUnk = new CClassFactory(rclsid); 404cdf0e10cSrcweir if (0 == pUnk) 405cdf0e10cSrcweir return E_OUTOFMEMORY; 406cdf0e10cSrcweir 407cdf0e10cSrcweir *ppv = pUnk; 408cdf0e10cSrcweir return S_OK; 409cdf0e10cSrcweir } 410cdf0e10cSrcweir 411cdf0e10cSrcweir extern "C" STDAPI DllCanUnloadNow(void) 412cdf0e10cSrcweir { 413cdf0e10cSrcweir if (CClassFactory::IsLocked() || g_DllRefCnt > 0) 414cdf0e10cSrcweir return S_FALSE; 415cdf0e10cSrcweir 416cdf0e10cSrcweir return S_OK; 417cdf0e10cSrcweir } 418cdf0e10cSrcweir 419cdf0e10cSrcweir BOOL WINAPI DllMain(HINSTANCE hInst, ULONG /*ul_reason_for_call*/, LPVOID /*lpReserved*/) 420cdf0e10cSrcweir { 421cdf0e10cSrcweir g_hModule = hInst; 422cdf0e10cSrcweir return TRUE; 423cdf0e10cSrcweir } 424