2 * self-registerable dll functions for quartz.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define COM_NO_WINDOWS_H
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
39 * Near the bottom of this file are the exported DllRegisterServer and
40 * DllUnregisterServer, which make all this worthwhile.
43 /***********************************************************************
44 * interface for self-registering
46 struct regsvr_interface
48 IID const *iid; /* NULL for end of list */
49 LPCSTR name; /* can be NULL to omit */
50 IID const *base_iid; /* can be NULL to omit */
51 int num_methods; /* can be <0 to omit */
52 CLSID const *ps_clsid; /* can be NULL to omit */
53 CLSID const *ps_clsid32; /* can be NULL to omit */
56 static HRESULT register_interfaces(struct regsvr_interface const *list);
57 static HRESULT unregister_interfaces(struct regsvr_interface const *list);
61 CLSID const *clsid; /* NULL for end of list */
62 LPCSTR name; /* can be NULL to omit */
63 LPCSTR ips; /* can be NULL to omit */
64 LPCSTR ips32; /* can be NULL to omit */
65 LPCSTR ips32_tmodel; /* can be NULL to omit */
66 LPCSTR progid; /* can be NULL to omit */
67 LPCSTR viprogid; /* can be NULL to omit */
68 LPCSTR progid_extra; /* can be NULL to omit */
71 static HRESULT register_coclasses(struct regsvr_coclass const *list);
72 static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
74 struct regsvr_mediatype_parsing
76 CLSID const *majortype; /* NULL for end of list */
78 LPCSTR line[11]; /* NULL for end of list */
81 static HRESULT register_mediatypes_parsing(struct regsvr_mediatype_parsing const *list);
82 static HRESULT unregister_mediatypes_parsing(struct regsvr_mediatype_parsing const *list);
84 struct regsvr_mediatype_extension
86 CLSID const *majortype; /* NULL for end of list */
91 static HRESULT register_mediatypes_extension(struct regsvr_mediatype_extension const *list);
92 static HRESULT unregister_mediatypes_extension(struct regsvr_mediatype_extension 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 curver_keyname[7] = {
113 'C', 'u', 'r', 'V', 'e', 'r', 0 };
114 static WCHAR const ips_keyname[13] = {
115 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
117 static WCHAR const ips32_keyname[15] = {
118 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
120 static WCHAR const progid_keyname[7] = {
121 'P', 'r', 'o', 'g', 'I', 'D', 0 };
122 static WCHAR const viprogid_keyname[25] = {
123 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
124 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
126 static char const tmodel_valuename[] = "ThreadingModel";
127 static WCHAR const mediatype_name[11] = {
128 'M', 'e', 'd', 'i', 'a', ' ', 'T', 'y', 'p', 'e', 0 };
129 static WCHAR const subtype_valuename[8] = {
130 'S', 'u', 'b', 't', 'y', 'p', 'e', 0 };
131 static WCHAR const sourcefilter_valuename[14] = {
132 'S', 'o', 'u', 'r', 'c', 'e', ' ', 'F', 'i', 'l', 't', 'e', 'r', 0 };
133 static WCHAR const extensions_keyname[11] = {
134 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', 0 };
136 /***********************************************************************
137 * static helper functions
139 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
140 static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
142 static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
144 static LONG register_progid(WCHAR const *clsid,
145 char const *progid, char const *curver_progid,
146 char const *name, char const *extra);
147 static LONG recursive_delete_key(HKEY key);
148 static LONG recursive_delete_keyA(HKEY base, char const *name);
149 static LONG recursive_delete_keyW(HKEY base, WCHAR const *name);
151 /***********************************************************************
152 * register_interfaces
154 static HRESULT register_interfaces(struct regsvr_interface const *list)
156 LONG res = ERROR_SUCCESS;
159 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
160 KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
161 if (res != ERROR_SUCCESS) goto error_return;
163 for (; res == ERROR_SUCCESS && list->iid; ++list) {
167 StringFromGUID2(list->iid, buf, 39);
168 res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
169 KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
170 if (res != ERROR_SUCCESS) goto error_close_interface_key;
173 res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
174 (CONST BYTE*)(list->name),
175 strlen(list->name) + 1);
176 if (res != ERROR_SUCCESS) goto error_close_iid_key;
179 if (list->base_iid) {
180 register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
181 if (res != ERROR_SUCCESS) goto error_close_iid_key;
184 if (0 <= list->num_methods) {
185 static WCHAR const fmt[3] = { '%', 'd', 0 };
188 res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
189 KEY_READ | KEY_WRITE, NULL, &key, NULL);
190 if (res != ERROR_SUCCESS) goto error_close_iid_key;
192 wsprintfW(buf, fmt, list->num_methods);
193 res = RegSetValueExW(key, NULL, 0, REG_SZ,
195 (lstrlenW(buf) + 1) * sizeof(WCHAR));
198 if (res != ERROR_SUCCESS) goto error_close_iid_key;
201 if (list->ps_clsid) {
202 register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
203 if (res != ERROR_SUCCESS) goto error_close_iid_key;
206 if (list->ps_clsid32) {
207 register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
208 if (res != ERROR_SUCCESS) goto error_close_iid_key;
212 RegCloseKey(iid_key);
215 error_close_interface_key:
216 RegCloseKey(interface_key);
218 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
221 /***********************************************************************
222 * unregister_interfaces
224 static HRESULT unregister_interfaces(struct regsvr_interface const *list)
226 LONG res = ERROR_SUCCESS;
229 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
230 KEY_READ | KEY_WRITE, &interface_key);
231 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
232 if (res != ERROR_SUCCESS) goto error_return;
234 for (; res == ERROR_SUCCESS && list->iid; ++list) {
237 StringFromGUID2(list->iid, buf, 39);
238 res = recursive_delete_keyW(interface_key, buf);
241 RegCloseKey(interface_key);
243 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
246 /***********************************************************************
249 static HRESULT register_coclasses(struct regsvr_coclass const *list)
251 LONG res = ERROR_SUCCESS;
254 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
255 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
256 if (res != ERROR_SUCCESS) goto error_return;
258 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
262 StringFromGUID2(list->clsid, buf, 39);
263 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
264 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
265 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
268 res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
269 (CONST BYTE*)(list->name),
270 strlen(list->name) + 1);
271 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
275 res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
276 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
282 res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
283 KEY_READ | KEY_WRITE, NULL,
285 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
287 res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
288 (CONST BYTE*)list->ips32,
289 lstrlenA(list->ips32) + 1);
290 if (res == ERROR_SUCCESS && list->ips32_tmodel)
291 res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
292 (CONST BYTE*)list->ips32_tmodel,
293 strlen(list->ips32_tmodel) + 1);
294 RegCloseKey(ips32_key);
295 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
299 res = register_key_defvalueA(clsid_key, progid_keyname,
301 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
303 res = register_progid(buf, list->progid, NULL,
304 list->name, list->progid_extra);
305 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
308 if (list->viprogid) {
309 res = register_key_defvalueA(clsid_key, viprogid_keyname,
311 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
313 res = register_progid(buf, list->viprogid, list->progid,
314 list->name, list->progid_extra);
315 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
318 error_close_clsid_key:
319 RegCloseKey(clsid_key);
322 error_close_coclass_key:
323 RegCloseKey(coclass_key);
325 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
328 /***********************************************************************
329 * unregister_coclasses
331 static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
333 LONG res = ERROR_SUCCESS;
336 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
337 KEY_READ | KEY_WRITE, &coclass_key);
338 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
339 if (res != ERROR_SUCCESS) goto error_return;
341 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
344 StringFromGUID2(list->clsid, buf, 39);
345 res = recursive_delete_keyW(coclass_key, buf);
346 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
349 res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
350 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
353 if (list->viprogid) {
354 res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->viprogid);
355 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
359 error_close_coclass_key:
360 RegCloseKey(coclass_key);
362 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
365 /***********************************************************************
366 * register_mediatypes_parsing
368 static HRESULT register_mediatypes_parsing(struct regsvr_mediatype_parsing const *list)
370 LONG res = ERROR_SUCCESS;
375 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0, NULL, 0,
376 KEY_READ | KEY_WRITE, NULL, &mediatype_key, NULL);
377 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
379 for (; res == ERROR_SUCCESS && list->majortype; ++list) {
380 HKEY majortype_key = NULL;
381 HKEY subtype_key = NULL;
383 StringFromGUID2(list->majortype, buf, 39);
384 res = RegCreateKeyExW(mediatype_key, buf, 0, NULL, 0,
385 KEY_READ | KEY_WRITE, NULL, &majortype_key, NULL);
386 if (res != ERROR_SUCCESS) goto error_close_keys;
388 StringFromGUID2(list->subtype, buf, 39);
389 res = RegCreateKeyExW(majortype_key, buf, 0, NULL, 0,
390 KEY_READ | KEY_WRITE, NULL, &subtype_key, NULL);
391 if (res != ERROR_SUCCESS) goto error_close_keys;
393 StringFromGUID2(&CLSID_AsyncReader, buf, 39);
394 res = RegSetValueExW(subtype_key, sourcefilter_valuename, 0, REG_SZ, (CONST BYTE*)buf,
395 (lstrlenW(buf) + 1) * sizeof(WCHAR));
396 if (res != ERROR_SUCCESS) goto error_close_keys;
398 for(i = 0; list->line[i]; i++) {
400 wsprintfA(buffer, "%d", i);
401 res = RegSetValueExA(subtype_key, buffer, 0, REG_SZ, (CONST BYTE*)list->line[i],
402 lstrlenA(list->line[i]));
403 if (res != ERROR_SUCCESS) goto error_close_keys;
408 RegCloseKey(majortype_key);
410 RegCloseKey(subtype_key);
413 RegCloseKey(mediatype_key);
415 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
418 /***********************************************************************
419 * register_mediatypes_extension
421 static HRESULT register_mediatypes_extension(struct regsvr_mediatype_extension const *list)
423 LONG res = ERROR_SUCCESS;
425 HKEY extensions_root_key = NULL;
428 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0, NULL, 0,
429 KEY_READ | KEY_WRITE, NULL, &mediatype_key, NULL);
430 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
432 res = RegCreateKeyExW(mediatype_key, extensions_keyname, 0, NULL, 0,
433 KEY_READ | KEY_WRITE, NULL, &extensions_root_key, NULL);
434 if (res != ERROR_SUCCESS) goto error_return;
436 for (; res == ERROR_SUCCESS && list->majortype; ++list) {
439 res = RegCreateKeyExA(extensions_root_key, list->extension, 0, NULL, 0,
440 KEY_READ | KEY_WRITE, NULL, &extension_key, NULL);
441 if (res != ERROR_SUCCESS) break;
443 StringFromGUID2(list->majortype, buf, 39);
444 res = RegSetValueExW(extension_key, mediatype_name, 0, REG_SZ, (CONST BYTE*)buf,
445 (lstrlenW(buf) + 1) * sizeof(WCHAR));
446 if (res != ERROR_SUCCESS) goto error_close_key;
448 StringFromGUID2(list->subtype, buf, 39);
449 res = RegSetValueExW(extension_key, subtype_valuename, 0, REG_SZ, (CONST BYTE*)buf,
450 (lstrlenW(buf) + 1) * sizeof(WCHAR));
451 if (res != ERROR_SUCCESS) goto error_close_key;
453 StringFromGUID2(&CLSID_AsyncReader, buf, 39);
454 res = RegSetValueExW(extension_key, sourcefilter_valuename, 0, REG_SZ, (CONST BYTE*)buf,
455 (lstrlenW(buf) + 1) * sizeof(WCHAR));
456 if (res != ERROR_SUCCESS) goto error_close_key;
459 RegCloseKey(extension_key);
463 RegCloseKey(mediatype_key);
464 if (extensions_root_key)
465 RegCloseKey(extensions_root_key);
467 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
470 /***********************************************************************
471 * unregister_mediatypes_parsing
473 static HRESULT unregister_mediatypes_parsing(struct regsvr_mediatype_parsing const *list)
480 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0,
481 KEY_READ | KEY_WRITE, &mediatype_key);
482 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
483 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
485 for (; res == ERROR_SUCCESS && list->majortype; ++list) {
486 StringFromGUID2(list->majortype, buf, 39);
487 res = RegOpenKeyExW(mediatype_key, buf, 0,
488 KEY_READ | KEY_WRITE, &majortype_key);
489 if (res == ERROR_FILE_NOT_FOUND) {
493 if (res != ERROR_SUCCESS) break;
495 StringFromGUID2(list->subtype, buf, 39);
496 res = recursive_delete_keyW(majortype_key, buf);
497 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
499 /* Removed majortype key if there is no more subtype key */
500 res = RegDeleteKeyW(majortype_key, 0);
501 if (res == ERROR_ACCESS_DENIED) res = ERROR_SUCCESS;
503 RegCloseKey(majortype_key);
506 RegCloseKey(mediatype_key);
508 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
511 /***********************************************************************
512 * unregister_mediatypes_extension
514 static HRESULT unregister_mediatypes_extension(struct regsvr_mediatype_extension const *list)
518 HKEY extensions_root_key = NULL;
520 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0,
521 KEY_READ | KEY_WRITE, &mediatype_key);
522 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
523 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
525 res = RegOpenKeyExW(mediatype_key, extensions_keyname, 0,
526 KEY_READ | KEY_WRITE, &extensions_root_key);
527 if (res == ERROR_FILE_NOT_FOUND)
529 else if (res == ERROR_SUCCESS)
530 for (; res == ERROR_SUCCESS && list->majortype; ++list) {
531 res = recursive_delete_keyA(extensions_root_key, list->extension);
532 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
535 RegCloseKey(mediatype_key);
536 if (extensions_root_key)
537 RegCloseKey(extensions_root_key);
539 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
542 /***********************************************************************
545 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
549 StringFromGUID2(guid, buf, 39);
550 return register_key_defvalueW(base, name, buf);
553 /***********************************************************************
554 * regsvr_key_defvalueW
556 static LONG register_key_defvalueW(
564 res = RegCreateKeyExW(base, name, 0, NULL, 0,
565 KEY_READ | KEY_WRITE, NULL, &key, NULL);
566 if (res != ERROR_SUCCESS) return res;
567 res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
568 (lstrlenW(value) + 1) * sizeof(WCHAR));
573 /***********************************************************************
574 * regsvr_key_defvalueA
576 static LONG register_key_defvalueA(
584 res = RegCreateKeyExW(base, name, 0, NULL, 0,
585 KEY_READ | KEY_WRITE, NULL, &key, NULL);
586 if (res != ERROR_SUCCESS) return res;
587 res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
588 lstrlenA(value) + 1);
593 /***********************************************************************
596 static LONG register_progid(
599 char const *curver_progid,
606 res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
607 NULL, 0, KEY_READ | KEY_WRITE, NULL,
609 if (res != ERROR_SUCCESS) return res;
612 res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
613 (CONST BYTE*)name, strlen(name) + 1);
614 if (res != ERROR_SUCCESS) goto error_close_progid_key;
618 res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
619 if (res != ERROR_SUCCESS) goto error_close_progid_key;
623 res = register_key_defvalueA(progid_key, curver_keyname,
625 if (res != ERROR_SUCCESS) goto error_close_progid_key;
631 res = RegCreateKeyExA(progid_key, extra, 0,
632 NULL, 0, KEY_READ | KEY_WRITE, NULL,
634 if (res == ERROR_SUCCESS)
635 RegCloseKey(extra_key);
638 error_close_progid_key:
639 RegCloseKey(progid_key);
643 /***********************************************************************
644 * recursive_delete_key
646 static LONG recursive_delete_key(HKEY key)
649 WCHAR subkey_name[MAX_PATH];
654 cName = sizeof(subkey_name) / sizeof(WCHAR);
655 res = RegEnumKeyExW(key, 0, subkey_name, &cName,
656 NULL, NULL, NULL, NULL);
657 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
658 res = ERROR_SUCCESS; /* presumably we're done enumerating */
661 res = RegOpenKeyExW(key, subkey_name, 0,
662 KEY_READ | KEY_WRITE, &subkey);
663 if (res == ERROR_FILE_NOT_FOUND) continue;
664 if (res != ERROR_SUCCESS) break;
666 res = recursive_delete_key(subkey);
668 if (res != ERROR_SUCCESS) break;
671 if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
675 /***********************************************************************
676 * recursive_delete_keyA
678 static LONG recursive_delete_keyA(HKEY base, char const *name)
683 res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
684 if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
685 if (res != ERROR_SUCCESS) return res;
686 res = recursive_delete_key(key);
691 /***********************************************************************
692 * recursive_delete_keyW
694 static LONG recursive_delete_keyW(HKEY base, WCHAR const *name)
699 res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key);
700 if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
701 if (res != ERROR_SUCCESS) return res;
702 res = recursive_delete_key(key);
707 /***********************************************************************
710 static struct regsvr_coclass const coclass_list[] = {
711 { &CLSID_FilterGraph,
717 { &CLSID_FilterMapper,
723 { &CLSID_FilterMapper2,
729 { &CLSID_SystemClock,
735 { &CLSID_MemoryAllocator,
741 { &CLSID_AsyncReader,
742 "File Source Filter",
747 { &CLSID_AviSplitter,
759 { &CLSID_DSoundRender,
760 "DirectSound Audio Renderer",
765 { &CLSID_VideoRenderer,
771 { NULL } /* list terminator */
774 /***********************************************************************
778 static struct regsvr_interface const interface_list[] = {
779 { NULL } /* list terminator */
782 /***********************************************************************
786 static struct regsvr_mediatype_parsing const mediatype_parsing_list[] = {
789 { "0,4,,52494646,8,4,,41564920",
793 &MEDIASUBTYPE_MPEG1System,
794 { "0, 16, FFFFFFFFF100010001800001FFFFFFFF, 000001BA2100010001800001000001BB",
798 &MEDIASUBTYPE_MPEG1VideoCD,
799 { "0, 4, , 52494646, 8, 8, , 43445841666D7420, 36, 20, FFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFF, 646174610000000000FFFFFFFFFFFFFFFFFFFF00",
803 &MEDIASUBTYPE_MPEG1Video,
804 { "0, 4, , 000001B3",
808 &MEDIASUBTYPE_MPEG1Audio,
809 { "0, 2, FFE0, FFE0",
810 "0, 10, FFFFFFFF000000000000, 494433030080808080",
814 &MEDIASUBTYPE_QTMovie,
815 { "4, 4, , 6d646174",
821 { "0,4,,52494646,8,4,,57415645",
831 { "0,4,,464f524d,8,4,,41494646",
832 "0,4,,464f524d,8,4,,41494643",
843 { "0,4,,52494646,8,4,,524D4944",
847 { NULL } /* list terminator */
850 /***********************************************************************
854 static struct regsvr_mediatype_extension const mediatype_extension_list[] = {
856 &MEDIASUBTYPE_MPEG1Audio,
859 { NULL } /* list terminator */
862 /***********************************************************************
863 * DllRegisterServer (QUARTZ.@)
865 HRESULT WINAPI QUARTZ_DllRegisterServer(void)
871 hr = register_coclasses(coclass_list);
873 hr = register_interfaces(interface_list);
875 hr = register_mediatypes_parsing(mediatype_parsing_list);
877 hr = register_mediatypes_extension(mediatype_extension_list);
881 /***********************************************************************
882 * DllUnregisterServer (QUARTZ.@)
884 HRESULT WINAPI QUARTZ_DllUnregisterServer(void)
890 hr = unregister_coclasses(coclass_list);
892 hr = unregister_interfaces(interface_list);
894 hr = unregister_mediatypes_parsing(mediatype_parsing_list);
896 hr = unregister_mediatypes_extension(mediatype_extension_list);