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 //---------------------------
SubstitutePlaceholder(std::string & String,const std::string & Placeholder,const std::string & Replacement)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 */
RegisterComComponent(const char * FilePath,const CLSID & Guid)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
UnregisterComComponent(const CLSID & Guid)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
RegisterColumnHandler(const char * ModuleFileName)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
UnregisterColumnHandler()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
RegisterInfotipHandler(const char * ModuleFileName)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
UnregisterInfotipHandler()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
RegisterPropSheetHandler(const char * ModuleFileName)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
UnregisterPropSheetHandler()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
RegisterThumbviewerHandler(const char * ModuleFileName)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
UnregisterThumbviewerHandler()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 */
ApproveShellExtension(CLSID clsid,const std::wstring & Description)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
UnapproveShellExtension(CLSID Clsid)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
DllRegisterServer()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
DllUnregisterServer()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
DllGetClassObject(REFCLSID rclsid,REFIID riid,void ** ppv)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
DllCanUnloadNow(void)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
DllMain(HINSTANCE hInst,ULONG,LPVOID)419cdf0e10cSrcweir BOOL WINAPI DllMain(HINSTANCE hInst, ULONG /*ul_reason_for_call*/, LPVOID /*lpReserved*/)
420cdf0e10cSrcweir {
421cdf0e10cSrcweir g_hModule = hInst;
422cdf0e10cSrcweir return TRUE;
423cdf0e10cSrcweir }
424