serialui/tests: Add some tests for CommConfigDialog.
[wine/wine64.git] / dlls / shdocvw / regsvr.c
blobc8cd8149400090c719b25fa00cc4d69e2af3d518
1 /*
2 * self-registerable dll functions for shdocvw.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
21 #include <stdarg.h>
22 #include <string.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "winreg.h"
28 #include "winerror.h"
30 #include "shdocvw.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
37 * Near the bottom of this file are the exported DllRegisterServer and
38 * DllUnregisterServer, which make all this worthwhile.
41 /***********************************************************************
42 * interface for self-registering
44 struct regsvr_interface
46 IID const *iid; /* NULL for end of list */
47 LPCSTR name; /* can be NULL to omit */
48 IID const *base_iid; /* can be NULL to omit */
49 int num_methods; /* can be <0 to omit */
50 CLSID const *ps_clsid; /* can be NULL to omit */
51 CLSID const *ps_clsid32; /* can be NULL to omit */
54 static HRESULT register_interfaces(struct regsvr_interface const *list);
55 static HRESULT unregister_interfaces(struct regsvr_interface const *list);
57 struct regsvr_coclass
59 CLSID const *clsid; /* NULL for end of list */
60 LPCSTR name; /* can be NULL 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 */
64 LPCSTR progid; /* can be NULL to omit */
65 LPCSTR viprogid; /* can be NULL to omit */
66 LPCSTR progid_extra; /* can be NULL to omit */
67 DWORD flags;
68 DWORD dwAttributes;
69 DWORD dwCallForAttributes;
72 /* flags for regsvr_coclass.flags */
73 #define SHELLEX_MAYCHANGEDEFAULTMENU 0x00000001
74 #define SHELLFOLDER_WANTSFORPARSING 0x00000002
75 #define SHELLFOLDER_ATTRIBUTES 0x00000004
76 #define SHELLFOLDER_CALLFORATTRIBUTES 0x00000008
78 static HRESULT register_coclasses(struct regsvr_coclass const *list);
79 static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
81 /***********************************************************************
82 * static string constants
84 static WCHAR const interface_keyname[10] = {
85 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
86 static WCHAR const base_ifa_keyname[14] = {
87 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
88 'e', 0 };
89 static WCHAR const num_methods_keyname[11] = {
90 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
91 static WCHAR const ps_clsid_keyname[15] = {
92 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
93 'i', 'd', 0 };
94 static WCHAR const ps_clsid32_keyname[17] = {
95 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
96 'i', 'd', '3', '2', 0 };
97 static WCHAR const clsid_keyname[6] = {
98 'C', 'L', 'S', 'I', 'D', 0 };
99 static WCHAR const curver_keyname[7] = {
100 'C', 'u', 'r', 'V', 'e', 'r', 0 };
101 static WCHAR const ips_keyname[13] = {
102 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
103 0 };
104 static WCHAR const ips32_keyname[15] = {
105 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
106 '3', '2', 0 };
107 static WCHAR const progid_keyname[7] = {
108 'P', 'r', 'o', 'g', 'I', 'D', 0 };
109 static WCHAR const viprogid_keyname[25] = {
110 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
111 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
112 0 };
113 static WCHAR const shellex_keyname[8] = {
114 's', 'h', 'e', 'l', 'l', 'e', 'x', 0 };
115 static WCHAR const shellfolder_keyname[12] = {
116 'S', 'h', 'e', 'l', 'l', 'F', 'o', 'l', 'd', 'e', 'r', 0 };
117 static WCHAR const mcdm_keyname[21] = {
118 'M', 'a', 'y', 'C', 'h', 'a', 'n', 'g', 'e', 'D', 'e', 'f',
119 'a', 'u', 'l', 't', 'M', 'e', 'n', 'u', 0 };
120 static char const tmodel_valuename[] = "ThreadingModel";
121 static char const wfparsing_valuename[] = "WantsFORPARSING";
122 static char const attributes_valuename[] = "Attributes";
123 static char const cfattributes_valuename[] = "CallForAttributes";
124 static WCHAR const lcs32_keyname[] = {
125 'L','o','c','a','l','S','e','r','v','e','r','3','2',0 };
126 static const WCHAR szIERelPath[] = {
127 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
128 'i','e','x','p','l','o','r','e','.','e','x','e',0 };
130 /***********************************************************************
131 * static helper functions
133 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
134 static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
135 WCHAR const *value);
136 static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
137 char const *value);
138 static LONG register_progid(WCHAR const *clsid,
139 char const *progid, char const *curver_progid,
140 char const *name, char const *extra);
141 static LONG recursive_delete_key(HKEY key);
142 static LONG recursive_delete_keyA(HKEY base, char const *name);
143 static LONG recursive_delete_keyW(HKEY base, WCHAR const *name);
145 /***********************************************************************
146 * register_interfaces
148 static HRESULT register_interfaces(struct regsvr_interface const *list)
150 LONG res = ERROR_SUCCESS;
151 HKEY interface_key;
153 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
154 KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
155 if (res != ERROR_SUCCESS) goto error_return;
157 for (; res == ERROR_SUCCESS && list->iid; ++list) {
158 WCHAR buf[39];
159 HKEY iid_key;
161 StringFromGUID2(list->iid, buf, 39);
162 res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
163 KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
164 if (res != ERROR_SUCCESS) goto error_close_interface_key;
166 if (list->name) {
167 res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
168 (CONST BYTE*)(list->name),
169 strlen(list->name) + 1);
170 if (res != ERROR_SUCCESS) goto error_close_iid_key;
173 if (list->base_iid) {
174 res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
175 if (res != ERROR_SUCCESS) goto error_close_iid_key;
178 if (0 <= list->num_methods) {
179 static WCHAR const fmt[3] = { '%', 'd', 0 };
180 HKEY key;
182 res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
183 KEY_READ | KEY_WRITE, NULL, &key, NULL);
184 if (res != ERROR_SUCCESS) goto error_close_iid_key;
186 wsprintfW(buf, fmt, list->num_methods);
187 res = RegSetValueExW(key, NULL, 0, REG_SZ,
188 (CONST BYTE*)buf,
189 (lstrlenW(buf) + 1) * sizeof(WCHAR));
190 RegCloseKey(key);
192 if (res != ERROR_SUCCESS) goto error_close_iid_key;
195 if (list->ps_clsid) {
196 res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
197 if (res != ERROR_SUCCESS) goto error_close_iid_key;
200 if (list->ps_clsid32) {
201 res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
202 if (res != ERROR_SUCCESS) goto error_close_iid_key;
205 error_close_iid_key:
206 RegCloseKey(iid_key);
209 error_close_interface_key:
210 RegCloseKey(interface_key);
211 error_return:
212 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
215 /***********************************************************************
216 * unregister_interfaces
218 static HRESULT unregister_interfaces(struct regsvr_interface const *list)
220 LONG res = ERROR_SUCCESS;
221 HKEY interface_key;
223 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
224 KEY_READ | KEY_WRITE, &interface_key);
225 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
226 if (res != ERROR_SUCCESS) goto error_return;
228 for (; res == ERROR_SUCCESS && list->iid; ++list) {
229 WCHAR buf[39];
231 StringFromGUID2(list->iid, buf, 39);
232 res = recursive_delete_keyW(interface_key, buf);
235 RegCloseKey(interface_key);
236 error_return:
237 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
240 /***********************************************************************
241 * register_coclasses
243 static HRESULT register_coclasses(struct regsvr_coclass const *list)
245 LONG res = ERROR_SUCCESS;
246 HKEY coclass_key;
248 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
249 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
250 if (res != ERROR_SUCCESS) goto error_return;
252 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
253 WCHAR buf[39];
254 HKEY clsid_key;
256 StringFromGUID2(list->clsid, buf, 39);
257 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
258 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
259 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
261 if (list->name) {
262 res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
263 (CONST BYTE*)(list->name),
264 strlen(list->name) + 1);
265 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
268 if (list->ips) {
269 res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
270 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
273 if (list->ips32) {
274 HKEY ips32_key;
276 res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
277 KEY_READ | KEY_WRITE, NULL,
278 &ips32_key, NULL);
279 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
281 res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
282 (CONST BYTE*)list->ips32,
283 lstrlenA(list->ips32) + 1);
284 if (res == ERROR_SUCCESS && list->ips32_tmodel)
285 res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
286 (CONST BYTE*)list->ips32_tmodel,
287 strlen(list->ips32_tmodel) + 1);
288 RegCloseKey(ips32_key);
289 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
292 if (list->flags & SHELLEX_MAYCHANGEDEFAULTMENU) {
293 HKEY shellex_key, mcdm_key;
295 res = RegCreateKeyExW(clsid_key, shellex_keyname, 0, NULL, 0,
296 KEY_READ | KEY_WRITE, NULL,
297 &shellex_key, NULL);
298 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
299 res = RegCreateKeyExW(shellex_key, mcdm_keyname, 0, NULL, 0,
300 KEY_READ | KEY_WRITE, NULL,
301 &mcdm_key, NULL);
302 RegCloseKey(shellex_key);
303 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
304 RegCloseKey(mcdm_key);
307 if (list->flags &
308 (SHELLFOLDER_WANTSFORPARSING|SHELLFOLDER_ATTRIBUTES|SHELLFOLDER_CALLFORATTRIBUTES))
310 HKEY shellfolder_key;
312 res = RegCreateKeyExW(clsid_key, shellfolder_keyname, 0, NULL, 0,
313 KEY_READ | KEY_WRITE, NULL,
314 &shellfolder_key, NULL);
315 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
316 if (list->flags & SHELLFOLDER_WANTSFORPARSING)
317 res = RegSetValueExA(shellfolder_key, wfparsing_valuename, 0, REG_SZ, (const BYTE *)"", 1);
318 if (list->flags & SHELLFOLDER_ATTRIBUTES)
319 res = RegSetValueExA(shellfolder_key, attributes_valuename, 0, REG_DWORD,
320 (const BYTE *)&list->dwAttributes, sizeof(DWORD));
321 if (list->flags & SHELLFOLDER_CALLFORATTRIBUTES)
322 res = RegSetValueExA(shellfolder_key, cfattributes_valuename, 0, REG_DWORD,
323 (const BYTE *)&list->dwCallForAttributes, sizeof(DWORD));
324 RegCloseKey(shellfolder_key);
325 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
328 if (list->progid) {
329 res = register_key_defvalueA(clsid_key, progid_keyname,
330 list->progid);
331 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
333 res = register_progid(buf, list->progid, NULL,
334 list->name, list->progid_extra);
335 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
338 if (list->viprogid) {
339 res = register_key_defvalueA(clsid_key, viprogid_keyname,
340 list->viprogid);
341 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
343 res = register_progid(buf, list->viprogid, list->progid,
344 list->name, list->progid_extra);
345 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
348 error_close_clsid_key:
349 RegCloseKey(clsid_key);
352 error_close_coclass_key:
353 RegCloseKey(coclass_key);
354 error_return:
355 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
358 /***********************************************************************
359 * unregister_coclasses
361 static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
363 LONG res = ERROR_SUCCESS;
364 HKEY coclass_key;
366 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
367 KEY_READ | KEY_WRITE, &coclass_key);
368 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
369 if (res != ERROR_SUCCESS) goto error_return;
371 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
372 WCHAR buf[39];
374 StringFromGUID2(list->clsid, buf, 39);
375 res = recursive_delete_keyW(coclass_key, buf);
376 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
378 if (list->progid) {
379 res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
380 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
383 if (list->viprogid) {
384 res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->viprogid);
385 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
389 error_close_coclass_key:
390 RegCloseKey(coclass_key);
391 error_return:
392 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
395 /***********************************************************************
396 * regsvr_key_guid
398 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
400 WCHAR buf[39];
402 StringFromGUID2(guid, buf, 39);
403 return register_key_defvalueW(base, name, buf);
406 /***********************************************************************
407 * regsvr_key_defvalueW
409 static LONG register_key_defvalueW(
410 HKEY base,
411 WCHAR const *name,
412 WCHAR const *value)
414 LONG res;
415 HKEY key;
417 res = RegCreateKeyExW(base, name, 0, NULL, 0,
418 KEY_READ | KEY_WRITE, NULL, &key, NULL);
419 if (res != ERROR_SUCCESS) return res;
420 res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
421 (lstrlenW(value) + 1) * sizeof(WCHAR));
422 RegCloseKey(key);
423 return res;
426 /***********************************************************************
427 * regsvr_key_defvalueA
429 static LONG register_key_defvalueA(
430 HKEY base,
431 WCHAR const *name,
432 char const *value)
434 LONG res;
435 HKEY key;
437 res = RegCreateKeyExW(base, name, 0, NULL, 0,
438 KEY_READ | KEY_WRITE, NULL, &key, NULL);
439 if (res != ERROR_SUCCESS) return res;
440 res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
441 lstrlenA(value) + 1);
442 RegCloseKey(key);
443 return res;
446 /***********************************************************************
447 * regsvr_progid
449 static LONG register_progid(
450 WCHAR const *clsid,
451 char const *progid,
452 char const *curver_progid,
453 char const *name,
454 char const *extra)
456 LONG res;
457 HKEY progid_key;
459 res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
460 NULL, 0, KEY_READ | KEY_WRITE, NULL,
461 &progid_key, NULL);
462 if (res != ERROR_SUCCESS) return res;
464 if (name) {
465 res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
466 (CONST BYTE*)name, strlen(name) + 1);
467 if (res != ERROR_SUCCESS) goto error_close_progid_key;
470 if (clsid) {
471 res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
472 if (res != ERROR_SUCCESS) goto error_close_progid_key;
475 if (curver_progid) {
476 res = register_key_defvalueA(progid_key, curver_keyname,
477 curver_progid);
478 if (res != ERROR_SUCCESS) goto error_close_progid_key;
481 if (extra) {
482 HKEY extra_key;
484 res = RegCreateKeyExA(progid_key, extra, 0,
485 NULL, 0, KEY_READ | KEY_WRITE, NULL,
486 &extra_key, NULL);
487 if (res == ERROR_SUCCESS)
488 RegCloseKey(extra_key);
491 error_close_progid_key:
492 RegCloseKey(progid_key);
493 return res;
496 /***********************************************************************
497 * recursive_delete_key
499 static LONG recursive_delete_key(HKEY key)
501 LONG res;
502 WCHAR subkey_name[MAX_PATH];
503 DWORD cName;
504 HKEY subkey;
506 for (;;) {
507 cName = sizeof(subkey_name) / sizeof(WCHAR);
508 res = RegEnumKeyExW(key, 0, subkey_name, &cName,
509 NULL, NULL, NULL, NULL);
510 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
511 res = ERROR_SUCCESS; /* presumably we're done enumerating */
512 break;
514 res = RegOpenKeyExW(key, subkey_name, 0,
515 KEY_READ | KEY_WRITE, &subkey);
516 if (res == ERROR_FILE_NOT_FOUND) continue;
517 if (res != ERROR_SUCCESS) break;
519 res = recursive_delete_key(subkey);
520 RegCloseKey(subkey);
521 if (res != ERROR_SUCCESS) break;
524 if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
525 return res;
528 /***********************************************************************
529 * recursive_delete_keyA
531 static LONG recursive_delete_keyA(HKEY base, char const *name)
533 LONG res;
534 HKEY key;
536 res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
537 if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
538 if (res != ERROR_SUCCESS) return res;
539 res = recursive_delete_key(key);
540 RegCloseKey(key);
541 return res;
544 /***********************************************************************
545 * recursive_delete_keyW
547 static LONG recursive_delete_keyW(HKEY base, WCHAR const *name)
549 LONG res;
550 HKEY key;
552 res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key);
553 if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
554 if (res != ERROR_SUCCESS) return res;
555 res = recursive_delete_key(key);
556 RegCloseKey(key);
557 return res;
561 static const GUID CLSID_MicrosoftBrowserArchitecture =
562 {0xa5e46e3a, 0x8849, 0x11d1, {0x9d, 0x8c, 0x00, 0xc0, 0x4f, 0xc9, 0x9d, 0x61}};
563 static const GUID CLSID_MruLongList =
564 {0x53bd6b4e, 0x3780, 0x4693, {0xaf, 0xc3, 0x71, 0x61, 0xc2, 0xf3, 0xee, 0x9c}};
566 /***********************************************************************
567 * coclass list
569 static struct regsvr_coclass const coclass_list[] = {
570 { &CLSID_WebBrowser_V1,
571 "Microsoft Web Browser Version 1",
572 NULL,
573 "shdocvw.dll",
574 "Apartment",
575 "Shell.Explorer.1",
576 "Shell.Explorer"
578 { &CLSID_WebBrowser,
579 "Microsoft Web Browser",
580 NULL,
581 "shdocvw.dll",
582 "Apartment",
583 "Shell.Explorer.2",
584 "Shell.Explorer"
586 { &CLSID_InternetExplorer,
587 "Internet Explorer(Ver 1.0)",
588 NULL,
589 NULL,
590 NULL,
591 "InternetExplorer.Application.1",
592 "InternetExplorer.Application"
594 { &CLSID_ShellSearchAssistantOC,
595 "SearchAssistantOC",
596 NULL,
597 "shdocvw.dll",
598 "Apartment",
599 "SearchAssistantOC.SearchAssistantOC.1",
600 "SearchAssistantOC.SearchAssistantOC"
602 { &CLSID_ShellShellNameSpace,
603 "Shell Name Space",
604 NULL,
605 "shdocvw.dll",
606 "Apartment",
607 "ShellNameSpace.ShellNameSpace.1",
608 "ShellNameSpace.ShellNameSpace"
610 { &CLSID_ShellNameSpace,
611 "Shell Name Space",
612 NULL,
613 "shdocvw.dll",
614 "Apartment",
615 "ShellNameSpace.ShellNameSpace.1",
616 "ShellNameSpace.ShellNameSpace"
618 { &CLSID_ShellUIHelper,
619 "Microsoft Shell UI Helper",
620 NULL,
621 "shdocvw.dll",
622 "Apartment",
623 "Shell.UIHelper.1",
624 NULL
626 { &CLSID_ShellWindows,
627 "ShellWindows",
628 NULL,
629 "shdocvw.dll",
630 "Apartment",
631 NULL,
632 NULL
634 { &CLSID_SearchAssistantOC,
635 "SearchAssistantOC",
636 NULL,
637 "shdocvw.dll",
638 "Apartment",
639 "SearchAssistantOC.SearchAssistantOC.1",
640 "SearchAssistantOC.SearchAssistantOC"
643 &CLSID_MicrosoftBrowserArchitecture,
644 "Microsoft Browser Architecture",
645 NULL,
646 "shdocvw.dll",
647 "Apartment",
648 NULL,
649 NULL
652 &CLSID_MruLongList,
653 "MruLongList",
654 NULL,
655 "shdocvw.dll",
656 "Apartment",
657 NULL,
658 NULL
661 &CLSID_CUrlHistory,
662 "Microsoft Url History Service",
663 NULL,
664 "shdocvw.dll",
665 "Apartment",
666 NULL,
667 NULL
670 &CLSID_Internet,
671 "Internet Explorer",
672 NULL,
673 "shdocvw.dll",
674 "Apartment",
675 NULL,
676 NULL,
677 NULL,
678 SHELLFOLDER_ATTRIBUTES,
679 SFGAO_CANDELETE|SFGAO_CANLINK
681 { NULL } /* list terminator */
684 /***********************************************************************
685 * interface list
688 static struct regsvr_interface const interface_list[] = {
689 { NULL } /* list terminator */
692 static HRESULT register_localserver(void)
694 HKEY coclass_key = 0, clsid_key = 0;
695 WCHAR buf[39], path[MAX_PATH];
696 LONG res;
697 UINT len;
699 res = SHGetFolderPathW(NULL, CSIDL_FLAG_CREATE|CSIDL_PROGRAM_FILES,
700 NULL, SHGFP_TYPE_CURRENT, path);
701 if (FAILED(res))
702 return res;
704 len = lstrlenW(path);
705 if ((len + (sizeof szIERelPath/sizeof(WCHAR)) + 1) > MAX_PATH)
706 return E_FAIL;
708 path[len] = '\\';
709 lstrcpyW(&path[len+1], szIERelPath);
711 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
712 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
713 if (res != ERROR_SUCCESS) goto err;
715 StringFromGUID2(&CLSID_InternetExplorer, buf, 39);
716 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
717 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
718 if (res != ERROR_SUCCESS) goto err;
720 res = register_key_defvalueW(clsid_key, lcs32_keyname, path);
721 if (res != ERROR_SUCCESS) goto err;
723 err:
724 if (clsid_key) RegCloseKey(clsid_key);
725 if (coclass_key) RegCloseKey(coclass_key);
726 return (res == ERROR_SUCCESS) ? S_OK : E_FAIL;
729 static HRESULT register_typelib(void)
731 ITypeLib *typelib;
732 HRESULT hres;
734 static const WCHAR wszSHDocVw[] = {'s','h','d','o','c','v','w','.','d','l','l',0};
736 hres = LoadTypeLibEx(wszSHDocVw, REGKIND_REGISTER, &typelib);
737 if(FAILED(hres)) {
738 ERR("Could not load typelib: %08x\n", hres);
739 return hres;
742 ITypeLib_Release(typelib);
744 return hres;
747 static HRESULT unregister_typelib(void)
749 return UnRegisterTypeLib(&LIBID_SHDocVw, 1, 1, LOCALE_SYSTEM_DEFAULT, SYS_WIN32);
752 /***********************************************************************
753 * DllRegisterServer (SHDOCVW.@)
755 HRESULT WINAPI DllRegisterServer(void)
757 HRESULT hr;
759 TRACE("\n");
761 hr = register_coclasses(coclass_list);
762 if (SUCCEEDED(hr))
763 hr = register_interfaces(interface_list);
764 if (SUCCEEDED(hr))
765 hr = register_localserver();
766 if(SUCCEEDED(hr))
767 hr = register_typelib();
769 return hr;
772 /***********************************************************************
773 * DllUnregisterServer (SHDOCVW.@)
775 HRESULT WINAPI DllUnregisterServer(void)
777 HRESULT hr;
779 TRACE("\n");
781 hr = unregister_coclasses(coclass_list);
782 if (SUCCEEDED(hr))
783 hr = unregister_interfaces(interface_list);
784 if(SUCCEEDED(hr))
785 hr = unregister_typelib();
787 return hr;