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