1f8e2c85aSAndrew Rist /**************************************************************
2721a7f15Smseidel *
3f8e2c85aSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4f8e2c85aSAndrew Rist * or more contributor license agreements. See the NOTICE file
5f8e2c85aSAndrew Rist * distributed with this work for additional information
6f8e2c85aSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7f8e2c85aSAndrew Rist * to you under the Apache License, Version 2.0 (the
8f8e2c85aSAndrew Rist * "License"); you may not use this file except in compliance
9f8e2c85aSAndrew Rist * with the License. You may obtain a copy of the License at
10721a7f15Smseidel *
11f8e2c85aSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12721a7f15Smseidel *
13f8e2c85aSAndrew Rist * Unless required by applicable law or agreed to in writing,
14f8e2c85aSAndrew Rist * software distributed under the License is distributed on an
15f8e2c85aSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16f8e2c85aSAndrew Rist * KIND, either express or implied. See the License for the
17f8e2c85aSAndrew Rist * specific language governing permissions and limitations
18f8e2c85aSAndrew Rist * under the License.
19721a7f15Smseidel *
20f8e2c85aSAndrew Rist *************************************************************/
21f8e2c85aSAndrew Rist
22f8e2c85aSAndrew 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;
43721a7f15Smseidel
44cdf0e10cSrcweir namespace /* private */
45cdf0e10cSrcweir {
46721a7f15Smseidel const char* GUID_PLACEHOLDER = "{GUID}";
47721a7f15Smseidel const char* EXTENSION_PLACEHOLDER = "{EXT}";
48721a7f15Smseidel const char* FORWARDKEY_PLACEHOLDER = "{FWDKEY}";
49721a7f15Smseidel
50721a7f15Smseidel const char* CLSID_ENTRY = "CLSID\\{GUID}\\InProcServer32";
51721a7f15Smseidel const char* SHELLEX_IID_ENTRY = "{EXT}\\shellex\\{GUID}";
52721a7f15Smseidel const char* SHELLEX_ENTRY = "{EXT}\\shellex";
53721a7f15Smseidel const char* PROPSHEET_ENTRY = "{EXT}\\CLSID\\{GUID}\\InProcServer32";
54721a7f15Smseidel 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";
57721a7f15Smseidel const char* FORWARD_PROPSHEET_ENTRY = "{FWDKEY}\\shellex\\PropertySheetHandlers";
58cdf0e10cSrcweir const char* FORWARD_SHELLEX_ENTRY = "{FWDKEY}\\shellex";
59cdf0e10cSrcweir
60721a7f15Smseidel const char* SHELL_EXTENSION_APPROVED_KEY_NAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
61721a7f15Smseidel
62721a7f15Smseidel //---------------------------
63721a7f15Smseidel // "String Placeholder" ->
64721a7f15Smseidel // "String Replacement"
65721a7f15Smseidel //---------------------------
SubstitutePlaceholder(std::string & String,const std::string & Placeholder,const std::string & Replacement)66721a7f15Smseidel void SubstitutePlaceholder(std::string& String, const std::string& Placeholder, const std::string& Replacement)
67721a7f15Smseidel {
68721a7f15Smseidel std::string::size_type idx = String.find(Placeholder);
69721a7f15Smseidel std::string::size_type len = Placeholder.length();
70721a7f15Smseidel
71721a7f15Smseidel while (std::string::npos != idx)
72721a7f15Smseidel {
73721a7f15Smseidel String.replace(idx, len, Replacement);
74721a7f15Smseidel idx = String.find(Placeholder);
75721a7f15Smseidel }
76721a7f15Smseidel }
77721a7f15Smseidel
78721a7f15Smseidel /* Make the registry entry
79721a7f15Smseidel HKCR\CLSID\{GUID}
80721a7f15Smseidel InProcServer32 = Path\shlxthdl.dll
81721a7f15Smseidel ThreadingModel = Apartment
82721a7f15Smseidel */
RegisterComComponent(const char * FilePath,const CLSID & Guid)83721a7f15Smseidel HRESULT RegisterComComponent(const char* FilePath, const CLSID& Guid)
84721a7f15Smseidel {
85721a7f15Smseidel std::string ClsidEntry = CLSID_ENTRY;
86721a7f15Smseidel SubstitutePlaceholder(ClsidEntry, GUID_PLACEHOLDER, ClsidToString(Guid));
87721a7f15Smseidel
88721a7f15Smseidel if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "", FilePath))
89721a7f15Smseidel return E_FAIL;
90721a7f15Smseidel
91721a7f15Smseidel if (!SetRegistryKey(HKEY_CLASSES_ROOT, ClsidEntry.c_str(), "ThreadingModel", "Apartment"))
92721a7f15Smseidel return E_FAIL;
93721a7f15Smseidel
94721a7f15Smseidel return S_OK;
95721a7f15Smseidel }
96721a7f15Smseidel
UnregisterComComponent(const CLSID & Guid)97721a7f15Smseidel HRESULT UnregisterComComponent(const CLSID& Guid)
98721a7f15Smseidel {
99721a7f15Smseidel std::string tmp = "CLSID\\";
100721a7f15Smseidel tmp += ClsidToString(Guid);
101721a7f15Smseidel return DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()) ? S_OK : E_FAIL;
102721a7f15Smseidel }
103721a7f15Smseidel
RegisterColumnHandler(const char * ModuleFileName)104721a7f15Smseidel HRESULT RegisterColumnHandler(const char* ModuleFileName)
105721a7f15Smseidel {
106721a7f15Smseidel if (FAILED(RegisterComComponent(ModuleFileName, CLSID_COLUMN_HANDLER)))
107721a7f15Smseidel return E_FAIL;
108721a7f15Smseidel
109721a7f15Smseidel std::string tmp = "Folder\\shellex\\ColumnHandlers\\";
110721a7f15Smseidel tmp += ClsidToString(CLSID_COLUMN_HANDLER);
111721a7f15Smseidel
112721a7f15Smseidel return SetRegistryKey(
113721a7f15Smseidel HKEY_CLASSES_ROOT,
114721a7f15Smseidel tmp.c_str(),
115721a7f15Smseidel "",
116cdf0e10cSrcweir WStringToString(COLUMN_HANDLER_DESCRIPTIVE_NAME).c_str()) ? S_OK : E_FAIL;
117721a7f15Smseidel }
118721a7f15Smseidel
UnregisterColumnHandler()119721a7f15Smseidel HRESULT UnregisterColumnHandler()
120721a7f15Smseidel {
121721a7f15Smseidel std::string tmp = "Folder\\shellex\\ColumnHandlers\\";
122721a7f15Smseidel tmp += ClsidToString(CLSID_COLUMN_HANDLER);
123721a7f15Smseidel
124721a7f15Smseidel if (!DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str()))
125721a7f15Smseidel return E_FAIL;
126721a7f15Smseidel
127721a7f15Smseidel return UnregisterComComponent(CLSID_COLUMN_HANDLER);
128721a7f15Smseidel }
129721a7f15Smseidel
RegisterInfotipHandler(const char * ModuleFileName)130721a7f15Smseidel HRESULT RegisterInfotipHandler(const char* ModuleFileName)
131721a7f15Smseidel {
132721a7f15Smseidel if (FAILED(RegisterComComponent(ModuleFileName, CLSID_INFOTIP_HANDLER)))
133721a7f15Smseidel return E_FAIL;
134721a7f15Smseidel
135721a7f15Smseidel std::string iid = ClsidToString(IID_IQueryInfo);
136721a7f15Smseidel std::string tmp;
137721a7f15Smseidel
138721a7f15Smseidel for(size_t i = 0; i < OOFileExtensionTableSize; i++)
139721a7f15Smseidel {
140721a7f15Smseidel tmp = SHELLEX_IID_ENTRY;
141721a7f15Smseidel SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi);
142721a7f15Smseidel SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid);
143721a7f15Smseidel
144721a7f15Smseidel if (!SetRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), "", ClsidToString(CLSID_INFOTIP_HANDLER).c_str()))
145721a7f15Smseidel return E_FAIL;
146721a7f15Smseidel }
147721a7f15Smseidel return S_OK;
148721a7f15Smseidel }
149721a7f15Smseidel
UnregisterInfotipHandler()150721a7f15Smseidel HRESULT UnregisterInfotipHandler()
151721a7f15Smseidel {
152721a7f15Smseidel std::string iid = ClsidToString(IID_IQueryInfo);
153721a7f15Smseidel std::string tmp;
154721a7f15Smseidel
155721a7f15Smseidel for (size_t i = 0; i < OOFileExtensionTableSize; i++)
156721a7f15Smseidel {
157721a7f15Smseidel tmp = SHELLEX_IID_ENTRY;
158721a7f15Smseidel
159721a7f15Smseidel SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi);
160721a7f15Smseidel SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid);
161721a7f15Smseidel
162721a7f15Smseidel DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str());
163721a7f15Smseidel
164721a7f15Smseidel // if there are no further subkey below .ext\\shellex
165721a7f15Smseidel // delete the whole subkey
166721a7f15Smseidel tmp = SHELLEX_ENTRY;
167721a7f15Smseidel SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi);
168721a7f15Smseidel
169721a7f15Smseidel bool HasSubKeys = true;
170721a7f15Smseidel if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), HasSubKeys) && !HasSubKeys)
171721a7f15Smseidel DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str());
172721a7f15Smseidel }
173721a7f15Smseidel return UnregisterComComponent(CLSID_INFOTIP_HANDLER);
174721a7f15Smseidel }
175721a7f15Smseidel
RegisterPropSheetHandler(const char * ModuleFileName)176721a7f15Smseidel HRESULT RegisterPropSheetHandler(const char* ModuleFileName)
177721a7f15Smseidel {
178721a7f15Smseidel std::string ExtEntry;
179721a7f15Smseidel std::string FwdKeyEntry;
180721a7f15Smseidel
181721a7f15Smseidel if (FAILED(RegisterComComponent(ModuleFileName, CLSID_PROPERTYSHEET_HANDLER)))
182721a7f15Smseidel return E_FAIL;
183721a7f15Smseidel
184721a7f15Smseidel for (size_t i = 0; i < OOFileExtensionTableSize; i++)
185721a7f15Smseidel {
186721a7f15Smseidel FwdKeyEntry = FORWARD_PROPSHEET_MYPROPSHEET_ENTRY;
187721a7f15Smseidel SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey);
188721a7f15Smseidel
189721a7f15Smseidel if (!SetRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), "", ClsidToString(CLSID_PROPERTYSHEET_HANDLER).c_str()))
190721a7f15Smseidel return E_FAIL;
191721a7f15Smseidel }
192721a7f15Smseidel return S_OK;
193721a7f15Smseidel }
194721a7f15Smseidel
UnregisterPropSheetHandler()195721a7f15Smseidel HRESULT UnregisterPropSheetHandler()
196721a7f15Smseidel {
197721a7f15Smseidel std::string ExtEntry;
198721a7f15Smseidel std::string FwdKeyEntry;
199721a7f15Smseidel
200721a7f15Smseidel for (size_t i = 0; i < OOFileExtensionTableSize; i++)
201721a7f15Smseidel {
202721a7f15Smseidel FwdKeyEntry = FORWARD_PROPSHEET_MYPROPSHEET_ENTRY;
203721a7f15Smseidel SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey);
204721a7f15Smseidel
205721a7f15Smseidel DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str());
206721a7f15Smseidel
207721a7f15Smseidel FwdKeyEntry = FORWARD_PROPSHEET_ENTRY;
208721a7f15Smseidel SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey);
209721a7f15Smseidel
210721a7f15Smseidel bool HasSubKeys = true;
211721a7f15Smseidel if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), HasSubKeys) && !HasSubKeys)
212721a7f15Smseidel DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str());
213721a7f15Smseidel
214721a7f15Smseidel FwdKeyEntry = FORWARD_SHELLEX_ENTRY;
215721a7f15Smseidel SubstitutePlaceholder(FwdKeyEntry, FORWARDKEY_PLACEHOLDER, OOFileExtensionTable[i].RegistryForwardKey);
216721a7f15Smseidel
217721a7f15Smseidel HasSubKeys = true;
218721a7f15Smseidel if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str(), HasSubKeys) && !HasSubKeys)
219721a7f15Smseidel DeleteRegistryKey(HKEY_CLASSES_ROOT, FwdKeyEntry.c_str());
220721a7f15Smseidel }
221721a7f15Smseidel
222721a7f15Smseidel return UnregisterComComponent(CLSID_PROPERTYSHEET_HANDLER);
223721a7f15Smseidel }
224721a7f15Smseidel
RegisterThumbviewerHandler(const char * ModuleFileName)225721a7f15Smseidel HRESULT RegisterThumbviewerHandler(const char* ModuleFileName)
226721a7f15Smseidel {
227721a7f15Smseidel if (FAILED(RegisterComComponent(ModuleFileName, CLSID_THUMBVIEWER_HANDLER)))
228721a7f15Smseidel return E_FAIL;
229721a7f15Smseidel
230721a7f15Smseidel std::string iid = ClsidToString(IID_IExtractImage);
231721a7f15Smseidel std::string tmp;
232721a7f15Smseidel
233721a7f15Smseidel for(size_t i = 0; i < OOFileExtensionTableSize; i++)
234721a7f15Smseidel {
235721a7f15Smseidel tmp = SHELLEX_IID_ENTRY;
236721a7f15Smseidel
237721a7f15Smseidel SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi);
238721a7f15Smseidel SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid);
239721a7f15Smseidel
240721a7f15Smseidel if (!SetRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), "", ClsidToString(CLSID_THUMBVIEWER_HANDLER).c_str()))
241721a7f15Smseidel return E_FAIL;
242721a7f15Smseidel }
243721a7f15Smseidel return S_OK;
244721a7f15Smseidel }
245721a7f15Smseidel
UnregisterThumbviewerHandler()246721a7f15Smseidel HRESULT UnregisterThumbviewerHandler()
247721a7f15Smseidel {
248721a7f15Smseidel std::string iid = ClsidToString(IID_IExtractImage);
249721a7f15Smseidel std::string tmp;
250721a7f15Smseidel
251721a7f15Smseidel for (size_t i = 0; i < OOFileExtensionTableSize; i++)
252721a7f15Smseidel {
253721a7f15Smseidel tmp = SHELLEX_IID_ENTRY;
254721a7f15Smseidel
255721a7f15Smseidel SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi);
256721a7f15Smseidel SubstitutePlaceholder(tmp, GUID_PLACEHOLDER, iid);
257721a7f15Smseidel
258721a7f15Smseidel DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str());
259721a7f15Smseidel
260721a7f15Smseidel // if there are no further subkey below .ext\\shellex
261721a7f15Smseidel // delete the whole subkey
262721a7f15Smseidel tmp = SHELLEX_ENTRY;
263721a7f15Smseidel SubstitutePlaceholder(tmp, EXTENSION_PLACEHOLDER, OOFileExtensionTable[i].ExtensionAnsi);
264721a7f15Smseidel
265721a7f15Smseidel bool HasSubKeys = true;
266721a7f15Smseidel if (HasSubkeysRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str(), HasSubKeys) && !HasSubKeys)
267721a7f15Smseidel DeleteRegistryKey(HKEY_CLASSES_ROOT, tmp.c_str());
268721a7f15Smseidel }
269721a7f15Smseidel return UnregisterComComponent(CLSID_THUMBVIEWER_HANDLER);
270721a7f15Smseidel }
271721a7f15Smseidel
272721a7f15Smseidel /** 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)274721a7f15Smseidel HRESULT ApproveShellExtension(CLSID clsid, const std::wstring& Description)
275cdf0e10cSrcweir {
276cdf0e10cSrcweir bool bRet = SetRegistryKey(
277721a7f15Smseidel 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 }
284721a7f15Smseidel
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()
314721a7f15Smseidel {
315cdf0e10cSrcweir TCHAR ModuleFileName[MAX_PATH];
316cdf0e10cSrcweir
317cdf0e10cSrcweir GetModuleFileName(
318cdf0e10cSrcweir GetModuleHandle(MODULE_NAME),
319cdf0e10cSrcweir ModuleFileName,
320cdf0e10cSrcweir sizeof(ModuleFileName));
321721a7f15Smseidel
322cdf0e10cSrcweir std::string module_path = WStringToString(ModuleFileName);
323cdf0e10cSrcweir HRESULT hr = S_OK;
324721a7f15Smseidel
325721a7f15Smseidel if (SUCCEEDED(RegisterColumnHandler(module_path.c_str())))
326721a7f15Smseidel ApproveShellExtension(CLSID_COLUMN_HANDLER, COLUMN_HANDLER_DESCRIPTIVE_NAME);
327721a7f15Smseidel else
328721a7f15Smseidel hr = E_FAIL;
329721a7f15Smseidel
330721a7f15Smseidel if (SUCCEEDED(RegisterInfotipHandler(module_path.c_str())))
331721a7f15Smseidel ApproveShellExtension(CLSID_INFOTIP_HANDLER, INFOTIP_HANDLER_DESCRIPTIVE_NAME);
332721a7f15Smseidel else
333721a7f15Smseidel hr = E_FAIL;
334721a7f15Smseidel
335721a7f15Smseidel if (SUCCEEDED(RegisterPropSheetHandler(module_path.c_str())))
336721a7f15Smseidel ApproveShellExtension(CLSID_PROPERTYSHEET_HANDLER, PROPSHEET_HANDLER_DESCRIPTIVE_NAME);
337721a7f15Smseidel else
338721a7f15Smseidel hr = E_FAIL;
339721a7f15Smseidel
340721a7f15Smseidel if (SUCCEEDED(RegisterThumbviewerHandler(module_path.c_str())))
341*49539899Smseidel ApproveShellExtension(CLSID_THUMBVIEWER_HANDLER, THUMBVIEWER_HANDLER_DESCRIPTIVE_NAME);
342721a7f15Smseidel else
343721a7f15Smseidel hr = E_FAIL;
344721a7f15Smseidel
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
370721a7f15Smseidel if (FAILED(UnregisterThumbviewerHandler()))
371721a7f15Smseidel hr = E_FAIL;
372721a7f15Smseidel
373721a7f15Smseidel UnapproveShellExtension(CLSID_THUMBVIEWER_HANDLER);
374721a7f15Smseidel
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
385721a7f15Smseidel if ((rclsid != CLSID_INFOTIP_HANDLER) &&
386721a7f15Smseidel (rclsid != CLSID_COLUMN_HANDLER) &&
387721a7f15Smseidel (rclsid != CLSID_PROPERTYSHEET_HANDLER) &&
388721a7f15Smseidel (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 )
395721a7f15Smseidel OutputDebugStringFormat( "DllGetClassObject: Create CLSID_INFOTIP_HANDLER\n" );
396cdf0e10cSrcweir else if ( rclsid == CLSID_COLUMN_HANDLER )
397721a7f15Smseidel OutputDebugStringFormat( "DllGetClassObject: Create CLSID_COLUMN_HANDLER\n" );
398cdf0e10cSrcweir else if ( rclsid == CLSID_PROPERTYSHEET_HANDLER )
399721a7f15Smseidel OutputDebugStringFormat( "DllGetClassObject: Create CLSID_PROPERTYSHEET_HANDLER\n" );
400cdf0e10cSrcweir else if ( rclsid == CLSID_THUMBVIEWER_HANDLER )
401721a7f15Smseidel 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 {
421721a7f15Smseidel g_hModule = hInst;
422721a7f15Smseidel return TRUE;
423cdf0e10cSrcweir }
424721a7f15Smseidel
425721a7f15Smseidel /* vim: set noet sw=4 ts=4: */
426