2 * self-registerable dll functions for shell32.dll
4 * Copyright (C) 2003 John K. Hohm
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 const GUID CLSID_AdminFolderShortcut
= {0xD20EA4E1, 0x3957, 0x11D2, {0xA4, 0x0B, 0x0C, 0x50, 0x20, 0x52, 0x41, 0x53}};
23 const GUID CLSID_StartMenu
= {0x4622AD11, 0xFF23, 0x11D0, {0x8D, 0x34, 0x00, 0xA0, 0xC9, 0x0F, 0x27, 0x19}};
24 const GUID CLSID_MenuBandSite
= {0xE13EF4E4, 0xD2F2, 0x11d0, {0x98, 0x16, 0x00, 0xC0, 0x4F, 0xD9, 0x19, 0x72}};
25 const GUID CLSID_OpenWith
= {0x09799AFB, 0xAD67, 0x11d1, {0xAB, 0xCD, 0x00, 0xC0, 0x4F, 0xC3, 0x09, 0x36}};
26 const GUID CLSID_UnixFolder
= {0xcc702eb2, 0x7dc5, 0x11d9, {0xc6, 0x87, 0x00, 0x04, 0x23, 0x8a, 0x01, 0xcd}};
27 const GUID CLSID_UnixDosFolder
= {0x9d20aae8, 0x0625, 0x44b0, {0x9c, 0xa7, 0x71, 0x88, 0x9c, 0x22, 0x54, 0xd9}};
28 const GUID CLSID_FontsFolderShortcut
= {0xD20EA4E1, 0x3957, 0x11D2, {0xA4, 0x0B, 0x0C, 0x50, 0x20, 0x52, 0x41,0x52}};
29 const GUID SHELL32_AdvtShortcutProduct
= {0x9db1186f, 0x40df, 0x11d1, {0xaa, 0x8c, 0x00, 0xc0, 0x4f, 0xb6, 0x78, 0x63}};
30 const GUID SHELL32_AdvtShortcutComponent
= {0x9db1186e, 0x40df, 0x11d1, {0xaa, 0x8c, 0x00, 0xc0, 0x4f, 0xb6, 0x78, 0x63}};
33 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
36 * Near the bottom of this file are the exported DllRegisterServer and
37 * DllUnregisterServer, which make all this worthwhile.
40 /***********************************************************************
41 * interface for self-registering
43 struct regsvr_interface
45 IID
const *iid
; /* NULL for end of list */
46 LPCSTR name
; /* can be NULL to omit */
47 IID
const *base_iid
; /* can be NULL to omit */
48 int num_methods
; /* can be <0 to omit */
49 CLSID
const *ps_clsid
; /* can be NULL to omit */
50 CLSID
const *ps_clsid32
; /* can be NULL to omit */
53 static HRESULT
register_interfaces(struct regsvr_interface
const *list
);
54 static HRESULT
unregister_interfaces(struct regsvr_interface
const *list
);
58 CLSID
const *clsid
; /* NULL for end of list */
59 LPCSTR name
; /* can be NULL to omit */
60 UINT idName
; /* can be 0 to omit */
61 LPCSTR ips
; /* can be NULL to omit */
62 LPCSTR ips32
; /* can be NULL to omit */
63 LPCSTR ips32_tmodel
; /* can be NULL to omit */
66 DWORD dwCallForAttributes
;
67 LPCSTR clsid_str
; /* can be NULL to omit */
68 LPCSTR progid
; /* can be NULL to omit */
69 UINT idDefaultIcon
; /* can be 0 to omit */
70 // CLSID const *clsid_menu; /* can be NULL to omit */
73 /* flags for regsvr_coclass.flags */
74 #define SHELLEX_MAYCHANGEDEFAULTMENU 0x00000001
75 #define SHELLFOLDER_WANTSFORPARSING 0x00000002
76 #define SHELLFOLDER_ATTRIBUTES 0x00000004
77 #define SHELLFOLDER_CALLFORATTRIBUTES 0x00000008
78 #define SHELLFOLDER_WANTSFORDISPLAY 0x00000010
79 #define SHELLFOLDER_HIDEASDELETEPERUSER 0x00000020
81 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
);
82 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
);
84 struct regsvr_namespace
86 CLSID
const *clsid
; /* CLSID of the namespace extension. NULL for end of list */
87 LPCWSTR parent
; /* Mount point (MyComputer, Desktop, ..). */
88 LPCWSTR value
; /* Display name of the extension. */
91 static HRESULT
register_namespace_extensions(struct regsvr_namespace
const *list
);
92 static HRESULT
unregister_namespace_extensions(struct regsvr_namespace
const *list
);
94 /***********************************************************************
95 * static string constants
97 static WCHAR
const interface_keyname
[10] = {
98 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
99 static WCHAR
const base_ifa_keyname
[14] = {
100 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
102 static WCHAR
const num_methods_keyname
[11] = {
103 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
104 static WCHAR
const ps_clsid_keyname
[15] = {
105 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
107 static WCHAR
const ps_clsid32_keyname
[17] = {
108 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
109 'i', 'd', '3', '2', 0 };
110 static WCHAR
const clsid_keyname
[6] = {
111 'C', 'L', 'S', 'I', 'D', 0 };
112 static WCHAR
const ips_keyname
[13] = {
113 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
115 static WCHAR
const ips32_keyname
[15] = {
116 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
118 static WCHAR
const progid_keyname
[7] = {
119 'P', 'r', 'o', 'g', 'I', 'D', 0 };
120 static WCHAR
const shellex_keyname
[8] = {
121 's', 'h', 'e', 'l', 'l', 'e', 'x', 0 };
122 static WCHAR
const shellfolder_keyname
[12] = {
123 'S', 'h', 'e', 'l', 'l', 'F', 'o', 'l', 'd', 'e', 'r', 0 };
124 static WCHAR
const mcdm_keyname
[21] = {
125 'M', 'a', 'y', 'C', 'h', 'a', 'n', 'g', 'e', 'D', 'e', 'f',
126 'a', 'u', 'l', 't', 'M', 'e', 'n', 'u', 0 };
127 static WCHAR
const defaulticon_keyname
[] = {
128 'D','e','f','a','u','l','t','I','c','o','n',0};
129 static WCHAR
const contextmenu_keyname
[] = { 'C', 'o', 'n', 't', 'e', 'x', 't', 'M', 'e', 'n', 'u', 'H', 'a', 'n', 'd', 'l', 'e', 'r', 's', 0 };
130 static char const tmodel_valuename
[] = "ThreadingModel";
131 static char const wfparsing_valuename
[] = "WantsFORPARSING";
132 static char const wfdisplay_valuename
[] = "WantsFORDISPLAY";
133 static char const hideasdeleteperuser_valuename
[] = "HideAsDeletePerUser";
134 static char const attributes_valuename
[] = "Attributes";
135 static char const cfattributes_valuename
[] = "CallForAttributes";
136 static char const localized_valuename
[] = "LocalizedString";
138 /***********************************************************************
139 * static helper functions
141 static LONG
register_key_guid(HKEY base
, WCHAR
const *name
, GUID
const *guid
);
142 static LONG
register_key_defvalueW(HKEY base
, WCHAR
const *name
,
144 static LONG
register_key_defvalueA(HKEY base
, WCHAR
const *name
,
147 /***********************************************************************
148 * register_interfaces
150 static HRESULT
register_interfaces(struct regsvr_interface
const *list
)
152 LONG res
= ERROR_SUCCESS
;
155 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, interface_keyname
, 0, NULL
, 0,
156 KEY_READ
| KEY_WRITE
, NULL
, &interface_key
, NULL
);
157 if (res
!= ERROR_SUCCESS
) goto error_return
;
159 for (; res
== ERROR_SUCCESS
&& list
->iid
; ++list
) {
163 StringFromGUID2(list
->iid
, buf
, 39);
164 res
= RegCreateKeyExW(interface_key
, buf
, 0, NULL
, 0,
165 KEY_READ
| KEY_WRITE
, NULL
, &iid_key
, NULL
);
166 if (res
!= ERROR_SUCCESS
) goto error_close_interface_key
;
169 res
= RegSetValueExA(iid_key
, NULL
, 0, REG_SZ
,
170 (CONST BYTE
*)(list
->name
),
171 strlen(list
->name
) + 1);
172 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
175 if (list
->base_iid
) {
176 res
= register_key_guid(iid_key
, base_ifa_keyname
, list
->base_iid
);
177 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
180 if (0 <= list
->num_methods
) {
181 static WCHAR
const fmt
[3] = { '%', 'd', 0 };
184 res
= RegCreateKeyExW(iid_key
, num_methods_keyname
, 0, NULL
, 0,
185 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
186 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
188 swprintf(buf
, fmt
, list
->num_methods
);
189 res
= RegSetValueExW(key
, NULL
, 0, REG_SZ
,
191 (wcslen(buf
) + 1) * sizeof(WCHAR
));
194 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
197 if (list
->ps_clsid
) {
198 res
= register_key_guid(iid_key
, ps_clsid_keyname
, list
->ps_clsid
);
199 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
202 if (list
->ps_clsid32
) {
203 res
= register_key_guid(iid_key
, ps_clsid32_keyname
, list
->ps_clsid32
);
204 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
208 RegCloseKey(iid_key
);
211 error_close_interface_key
:
212 RegCloseKey(interface_key
);
214 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
217 /***********************************************************************
218 * unregister_interfaces
220 static HRESULT
unregister_interfaces(struct regsvr_interface
const *list
)
222 LONG res
= ERROR_SUCCESS
;
225 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, interface_keyname
, 0,
226 KEY_READ
| KEY_WRITE
, &interface_key
);
227 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
228 if (res
!= ERROR_SUCCESS
) goto error_return
;
230 for (; res
== ERROR_SUCCESS
&& list
->iid
; ++list
) {
233 StringFromGUID2(list
->iid
, buf
, 39);
234 res
= RegDeleteTreeW(interface_key
, buf
);
235 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
238 RegCloseKey(interface_key
);
240 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
243 /***********************************************************************
246 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
)
248 LONG res
= ERROR_SUCCESS
;
251 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
252 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
253 if (res
!= ERROR_SUCCESS
) goto error_return
;
255 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
259 StringFromGUID2(list
->clsid
, buf
, 39);
260 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
261 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
262 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
265 res
= RegSetValueExA(clsid_key
, NULL
, 0, REG_SZ
,
266 (CONST BYTE
*)(list
->name
),
267 strlen(list
->name
) + 1);
268 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
273 sprintf(buffer
, "@shell32.dll,-%u", list
->idName
);
274 res
= RegSetValueExA(clsid_key
, localized_valuename
, 0, REG_SZ
,
275 (CONST BYTE
*)(buffer
), strlen(buffer
)+1);
276 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
279 if (list
->idDefaultIcon
) {
283 res
= RegCreateKeyExW(clsid_key
, defaulticon_keyname
, 0, NULL
, 0,
284 KEY_READ
| KEY_WRITE
, NULL
, &icon_key
, NULL
);
285 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
287 sprintf(buffer
, "shell32.dll,-%u", list
->idDefaultIcon
);
288 res
= RegSetValueExA(icon_key
, NULL
, 0, REG_SZ
,
289 (CONST BYTE
*)(buffer
), strlen(buffer
)+1);
290 RegCloseKey(icon_key
);
291 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
295 res
= register_key_defvalueA(clsid_key
, ips_keyname
, list
->ips
);
296 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
302 res
= RegCreateKeyExW(clsid_key
, ips32_keyname
, 0, NULL
, 0,
303 KEY_READ
| KEY_WRITE
, NULL
,
305 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
307 res
= RegSetValueExA(ips32_key
, NULL
, 0, REG_SZ
,
308 (CONST BYTE
*)list
->ips32
,
309 lstrlenA(list
->ips32
) + 1);
310 if (res
== ERROR_SUCCESS
&& list
->ips32_tmodel
)
311 res
= RegSetValueExA(ips32_key
, tmodel_valuename
, 0, REG_SZ
,
312 (CONST BYTE
*)list
->ips32_tmodel
,
313 strlen(list
->ips32_tmodel
) + 1);
314 RegCloseKey(ips32_key
);
315 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
318 if (list
->flags
& SHELLEX_MAYCHANGEDEFAULTMENU
) {
319 HKEY shellex_key
, mcdm_key
;
321 res
= RegCreateKeyExW(clsid_key
, shellex_keyname
, 0, NULL
, 0,
322 KEY_READ
| KEY_WRITE
, NULL
,
324 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
325 res
= RegCreateKeyExW(shellex_key
, mcdm_keyname
, 0, NULL
, 0,
326 KEY_READ
| KEY_WRITE
, NULL
,
328 RegCloseKey(shellex_key
);
329 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
330 RegCloseKey(mcdm_key
);
334 (SHELLFOLDER_WANTSFORPARSING
|SHELLFOLDER_ATTRIBUTES
|SHELLFOLDER_CALLFORATTRIBUTES
|SHELLFOLDER_WANTSFORDISPLAY
|SHELLFOLDER_HIDEASDELETEPERUSER
))
336 HKEY shellfolder_key
;
338 res
= RegCreateKeyExW(clsid_key
, shellfolder_keyname
, 0, NULL
, 0,
339 KEY_READ
| KEY_WRITE
, NULL
,
340 &shellfolder_key
, NULL
);
341 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
342 if (list
->flags
& SHELLFOLDER_WANTSFORPARSING
)
343 res
= RegSetValueExA(shellfolder_key
, wfparsing_valuename
, 0, REG_SZ
, (const BYTE
*)"", 1);
344 if (list
->flags
& SHELLFOLDER_ATTRIBUTES
)
345 res
= RegSetValueExA(shellfolder_key
, attributes_valuename
, 0, REG_DWORD
,
346 (const BYTE
*)&list
->dwAttributes
, sizeof(DWORD
));
347 if (list
->flags
& SHELLFOLDER_CALLFORATTRIBUTES
)
348 res
= RegSetValueExA(shellfolder_key
, cfattributes_valuename
, 0, REG_DWORD
,
349 (const BYTE
*)&list
->dwCallForAttributes
, sizeof(DWORD
));
350 if (list
->flags
& SHELLFOLDER_WANTSFORDISPLAY
)
351 res
= RegSetValueExA(shellfolder_key
, wfdisplay_valuename
, 0, REG_SZ
, (const BYTE
*)"", 1);
352 if (list
->flags
& SHELLFOLDER_HIDEASDELETEPERUSER
)
353 res
= RegSetValueExA(shellfolder_key
, hideasdeleteperuser_valuename
, 0, REG_SZ
, (const BYTE
*)"", 1);
354 RegCloseKey(shellfolder_key
);
355 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
358 if (list
->clsid_str
) {
359 res
= register_key_defvalueA(clsid_key
, clsid_keyname
,
361 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
367 res
= register_key_defvalueA(clsid_key
, progid_keyname
,
369 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
371 res
= RegCreateKeyExA(HKEY_CLASSES_ROOT
, list
->progid
, 0,
372 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
374 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
376 res
= register_key_defvalueW(progid_key
, clsid_keyname
, buf
);
377 RegCloseKey(progid_key
);
378 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
380 if (IsEqualIID(list
->clsid
, &CLSID_RecycleBin
)) {//if (list->clsid_menu) {
381 HKEY shellex_key
, cmenu_key
, menuhandler_key
;
382 res
= RegCreateKeyExW(clsid_key
, shellex_keyname
, 0, NULL
, 0,
383 KEY_READ
| KEY_WRITE
, NULL
,
385 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
386 res
= RegCreateKeyExW(shellex_key
, contextmenu_keyname
, 0, NULL
, 0,
387 KEY_READ
| KEY_WRITE
, NULL
,
389 if (res
!= ERROR_SUCCESS
) {
390 RegCloseKey(shellex_key
);
391 goto error_close_clsid_key
;
394 StringFromGUID2(list
->clsid
, buf
, 39); //clsid_menu
395 res
= RegCreateKeyExW(cmenu_key
, buf
, 0, NULL
, 0,
396 KEY_READ
| KEY_WRITE
, NULL
,
397 &menuhandler_key
, NULL
);
398 RegCloseKey(menuhandler_key
);
399 RegCloseKey(cmenu_key
);
400 RegCloseKey(shellex_key
);
403 error_close_clsid_key
:
404 RegCloseKey(clsid_key
);
407 error_close_coclass_key
:
408 RegCloseKey(coclass_key
);
410 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
413 /***********************************************************************
414 * unregister_coclasses
416 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
)
418 LONG res
= ERROR_SUCCESS
;
421 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
422 KEY_READ
| KEY_WRITE
, &coclass_key
);
423 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
424 if (res
!= ERROR_SUCCESS
) goto error_return
;
426 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
429 StringFromGUID2(list
->clsid
, buf
, 39);
430 res
= RegDeleteTreeW(coclass_key
, buf
);
431 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
432 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
435 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->progid
);
436 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
437 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
441 error_close_coclass_key
:
442 RegCloseKey(coclass_key
);
444 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
447 /**********************************************************************
448 * register_namespace_extensions
450 static WCHAR
*get_namespace_key(struct regsvr_namespace
const *list
) {
451 static const WCHAR wszExplorerKey
[] = {
452 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
453 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
454 'E','x','p','l','o','r','e','r','\\',0 };
455 static const WCHAR wszNamespace
[] = { '\\','N','a','m','e','s','p','a','c','e','\\',0 };
456 WCHAR
*pwszKey
, *pwszCLSID
;
458 pwszKey
= HeapAlloc(GetProcessHeap(), 0, sizeof(wszExplorerKey
)+sizeof(wszNamespace
)+
459 sizeof(WCHAR
)*(wcslen(list
->parent
)+CHARS_IN_GUID
));
463 wcscpy(pwszKey
, wszExplorerKey
);
464 wcscat(pwszKey
, list
->parent
);
465 wcscat(pwszKey
, wszNamespace
);
466 if (FAILED(StringFromCLSID(list
->clsid
, &pwszCLSID
))) {
467 HeapFree(GetProcessHeap(), 0, pwszKey
);
470 wcscat(pwszKey
, pwszCLSID
);
471 CoTaskMemFree(pwszCLSID
);
476 static HRESULT
register_namespace_extensions(struct regsvr_namespace
const *list
) {
480 for (; list
->clsid
; list
++) {
481 pwszKey
= get_namespace_key(list
);
483 /* Create the key and set the value. */
484 if (pwszKey
&& ERROR_SUCCESS
==
485 RegCreateKeyExW(HKEY_LOCAL_MACHINE
, pwszKey
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hKey
, NULL
))
487 RegSetValueExW(hKey
, NULL
, 0, REG_SZ
, (const BYTE
*)list
->value
, sizeof(WCHAR
)*(wcslen(list
->value
)+1));
491 HeapFree(GetProcessHeap(), 0, pwszKey
);
496 static HRESULT
unregister_namespace_extensions(struct regsvr_namespace
const *list
) {
499 for (; list
->clsid
; list
++) {
500 pwszKey
= get_namespace_key(list
);
501 RegDeleteKeyW(HKEY_LOCAL_MACHINE
, pwszKey
);
502 HeapFree(GetProcessHeap(), 0, pwszKey
);
507 /***********************************************************************
510 static LONG
register_key_guid(HKEY base
, WCHAR
const *name
, GUID
const *guid
)
514 StringFromGUID2(guid
, buf
, 39);
515 return register_key_defvalueW(base
, name
, buf
);
518 /***********************************************************************
519 * regsvr_key_defvalueW
521 static LONG
register_key_defvalueW(
529 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
530 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
531 if (res
!= ERROR_SUCCESS
) return res
;
532 res
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (CONST BYTE
*)value
,
533 (wcslen(value
) + 1) * sizeof(WCHAR
));
538 /***********************************************************************
539 * regsvr_key_defvalueA
541 static LONG
register_key_defvalueA(
549 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
550 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
551 if (res
!= ERROR_SUCCESS
) return res
;
552 res
= RegSetValueExA(key
, NULL
, 0, REG_SZ
, (CONST BYTE
*)value
,
553 lstrlenA(value
) + 1);
558 /***********************************************************************
561 static GUID
const CLSID_Desktop
= {
562 0x00021400, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
564 static GUID
const CLSID_Shortcut
= {
565 0x00021401, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
567 static struct regsvr_coclass
const coclass_list
[] = {
575 { &CLSID_ControlPanel
,
576 "Shell Control Panel Folder",
581 SHELLFOLDER_WANTSFORDISPLAY
|SHELLFOLDER_ATTRIBUTES
|SHELLFOLDER_HIDEASDELETEPERUSER
,
582 SFGAO_FOLDER
|SFGAO_HASSUBFOLDER
,
586 IDI_SHELL_CONTROL_PANEL1
588 { &CLSID_DragDropHelper
,
589 "Shell Drag and Drop Helper",
601 SHELLFOLDER_ATTRIBUTES
,
606 IDI_SHELL_PRINTERS_FOLDER
615 { &CLSID_NetworkPlaces
,
621 SHELLFOLDER_ATTRIBUTES
|SHELLFOLDER_CALLFORATTRIBUTES
,
622 SFGAO_FOLDER
|SFGAO_HASPROPSHEET
,
626 IDI_SHELL_MY_NETWORK_PLACES
628 { &CLSID_FontsFolderShortcut
,
634 SHELLFOLDER_ATTRIBUTES
,
639 IDI_SHELL_FONTS_FOLDER
641 { &CLSID_AdminFolderShortcut
,
642 "Administrative Tools",
643 IDS_ADMINISTRATIVETOOLS
,
647 SHELLFOLDER_ATTRIBUTES
,
652 IDI_SHELL_ADMINTOOLS
//FIXME
660 SHELLEX_MAYCHANGEDEFAULTMENU
662 { &CLSID_AutoComplete
,
669 { &CLSID_FolderShortcut
,
675 SHELLFOLDER_ATTRIBUTES
|SHELLFOLDER_CALLFORATTRIBUTES
,
676 SFGAO_FILESYSTEM
|SFGAO_FOLDER
|SFGAO_LINK
,
677 SFGAO_HASSUBFOLDER
|SFGAO_FILESYSTEM
|SFGAO_FOLDER
|SFGAO_FILESYSANCESTOR
679 { &CLSID_MyDocuments
,
685 SHELLFOLDER_WANTSFORPARSING
|SHELLFOLDER_ATTRIBUTES
|SHELLFOLDER_CALLFORATTRIBUTES
,
686 SFGAO_FILESYSANCESTOR
|SFGAO_FOLDER
|SFGAO_HASSUBFOLDER
,
691 IDS_RECYCLEBIN_FOLDER_NAME
,
695 SHELLFOLDER_ATTRIBUTES
|SHELLFOLDER_CALLFORATTRIBUTES
,
696 SFGAO_FOLDER
|SFGAO_DROPTARGET
|SFGAO_HASPROPSHEET
,
700 IDI_SHELL_FULL_RECYCLE_BIN
703 { &CLSID_ShellFSFolder
,
704 "Shell File System Folder",
710 { &CLSID_ShellFolderViewOC
,
711 "Microsoft Shell Folder View Router",
724 { &CLSID_MenuBandSite
,
731 { NULL
} /* list terminator */
734 /***********************************************************************
738 static struct regsvr_interface
const interface_list
[] = {
739 { NULL
} /* list terminator */
742 /***********************************************************************
743 * namespace extensions list
745 static const WCHAR wszDesktop
[] = { 'D','e','s','k','t','o','p',0 };
746 static const WCHAR wszSlash
[] = { '/', 0 };
747 static const WCHAR wszMyDocuments
[] = { 'M','y',' ','D','o','c','u','m','e','n','t','s', 0 };
748 static const WCHAR wszRecycleBin
[] = { 'T','r','a','s','h', 0 };
749 static const WCHAR wszMyComputer
[] = { 'M','y','C','o','m','p','u','t','e','r',0 };
750 static const WCHAR wszControlPanel
[] = { 'C','o','n','t','r','o','l','P','a','n','e','l',0 };
751 static const WCHAR wszFolderOptions
[] = { 'F','o','l','d','e','r',' ','O','p','t','i','o','n','s',0 };
752 static const WCHAR wszNethoodFolder
[] = { 'N','e','t','h','o','o','d',' ','f','o','l','d','e','r',0};
753 static const WCHAR wszPrinters
[] = { 'P','r','i','n','t','e','r','s',0 };
754 static const WCHAR wszFonts
[] = { 'F','o','n','t','s',0 };
755 static const WCHAR wszAdminTools
[] = { 'A','d','m','i','n','T','o','o','l','s',0 };
756 const GUID CLSID_FolderOptions
= { 0x6DFD7C5C, 0x2451, 0x11d3, {0xa2,0x99,0x00,0xC0,0x4F,0x8e,0xf6,0xaf} };
758 static struct regsvr_namespace
const namespace_extensions_list
[] = {
761 &CLSID_UnixDosFolder
,
772 &CLSID_NetworkPlaces
,
787 &CLSID_FolderOptions
,
792 &CLSID_FontsFolderShortcut
,
802 &CLSID_AdminFolderShortcut
,
809 /***********************************************************************
810 * DllRegisterServer (SHELL32.@)
812 HRESULT WINAPI
DllRegisterServer(void)
818 hr
= register_coclasses(coclass_list
);
820 hr
= register_interfaces(interface_list
);
822 hr
= SHELL_RegisterShellFolders();
824 hr
= register_namespace_extensions(namespace_extensions_list
);
828 /***********************************************************************
829 * DllUnregisterServer (SHELL32.@)
831 HRESULT WINAPI
DllUnregisterServer(void)
837 hr
= unregister_coclasses(coclass_list
);
839 hr
= unregister_interfaces(interface_list
);
841 hr
= unregister_namespace_extensions(namespace_extensions_list
);