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