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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define NONAMELESSUNION
22 #define NONAMELESSSTRUCT
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
43 * Near the bottom of this file are the exported DllRegisterServer and
44 * DllUnregisterServer, which make all this worthwhile.
47 /***********************************************************************
48 * interface for self-registering
50 struct regsvr_interface
52 IID const *iid; /* NULL for end of list */
53 LPCSTR name; /* can be NULL to omit */
54 IID const *base_iid; /* can be NULL to omit */
55 int num_methods; /* can be <0 to omit */
56 CLSID const *ps_clsid; /* can be NULL to omit */
57 CLSID const *ps_clsid32; /* can be NULL to omit */
60 static HRESULT register_interfaces(struct regsvr_interface const *list);
61 static HRESULT unregister_interfaces(struct regsvr_interface const *list);
65 CLSID const *clsid; /* NULL for end of list */
66 LPCSTR name; /* can be NULL to omit */
67 LPCSTR ips; /* can be NULL to omit */
68 LPCSTR ips32; /* can be NULL to omit */
69 LPCSTR ips32_tmodel; /* can be NULL to omit */
70 LPCSTR progid; /* can be NULL to omit */
71 LPCSTR viprogid; /* can be NULL to omit */
72 LPCSTR progid_extra; /* can be NULL to omit */
75 static HRESULT register_coclasses(struct regsvr_coclass const *list);
76 static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
78 struct regsvr_mediatype_parsing
80 CLSID const *majortype; /* NULL for end of list */
82 LPCSTR line[11]; /* NULL for end of list */
85 static HRESULT register_mediatypes_parsing(struct regsvr_mediatype_parsing const *list);
86 static HRESULT unregister_mediatypes_parsing(struct regsvr_mediatype_parsing const *list);
88 struct regsvr_mediatype_extension
90 CLSID const *majortype; /* NULL for end of list */
97 CLSID const *majortype; /* NULL for end of list */
104 DWORD flags; /* 0xFFFFFFFF for end of list */
105 struct mediatype mediatypes[11];
110 CLSID const *clsid; /* NULL for end of list */
111 CLSID const *category;
117 static HRESULT register_mediatypes_extension(struct regsvr_mediatype_extension const *list);
118 static HRESULT unregister_mediatypes_extension(struct regsvr_mediatype_extension const *list);
120 static HRESULT register_filters(struct regsvr_filter const *list);
121 static HRESULT unregister_filters(struct regsvr_filter const *list);
123 /***********************************************************************
124 * static string constants
126 static WCHAR const interface_keyname[10] = {
127 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
128 static WCHAR const base_ifa_keyname[14] = {
129 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
131 static WCHAR const num_methods_keyname[11] = {
132 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
133 static WCHAR const ps_clsid_keyname[15] = {
134 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
136 static WCHAR const ps_clsid32_keyname[17] = {
137 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
138 'i', 'd', '3', '2', 0 };
139 static WCHAR const clsid_keyname[6] = {
140 'C', 'L', 'S', 'I', 'D', 0 };
141 static WCHAR const curver_keyname[7] = {
142 'C', 'u', 'r', 'V', 'e', 'r', 0 };
143 static WCHAR const ips_keyname[13] = {
144 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
146 static WCHAR const ips32_keyname[15] = {
147 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
149 static WCHAR const progid_keyname[7] = {
150 'P', 'r', 'o', 'g', 'I', 'D', 0 };
151 static WCHAR const viprogid_keyname[25] = {
152 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
153 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
155 static char const tmodel_valuename[] = "ThreadingModel";
156 static WCHAR const mediatype_name[11] = {
157 'M', 'e', 'd', 'i', 'a', ' ', 'T', 'y', 'p', 'e', 0 };
158 static WCHAR const subtype_valuename[8] = {
159 'S', 'u', 'b', 't', 'y', 'p', 'e', 0 };
160 static WCHAR const sourcefilter_valuename[14] = {
161 'S', 'o', 'u', 'r', 'c', 'e', ' ', 'F', 'i', 'l', 't', 'e', 'r', 0 };
162 static WCHAR const extensions_keyname[11] = {
163 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', 0 };
165 /***********************************************************************
166 * static helper functions
168 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
169 static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
171 static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
173 static LONG register_progid(WCHAR const *clsid,
174 char const *progid, char const *curver_progid,
175 char const *name, char const *extra);
177 /***********************************************************************
178 * register_interfaces
180 static HRESULT register_interfaces(struct regsvr_interface const *list)
182 LONG res = ERROR_SUCCESS;
185 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
186 KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
187 if (res != ERROR_SUCCESS) goto error_return;
189 for (; res == ERROR_SUCCESS && list->iid; ++list) {
193 StringFromGUID2(list->iid, buf, 39);
194 res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
195 KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
196 if (res != ERROR_SUCCESS) goto error_close_interface_key;
199 res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
200 (CONST BYTE*)(list->name),
201 strlen(list->name) + 1);
202 if (res != ERROR_SUCCESS) goto error_close_iid_key;
205 if (list->base_iid) {
206 res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
207 if (res != ERROR_SUCCESS) goto error_close_iid_key;
210 if (0 <= list->num_methods) {
211 static WCHAR const fmt[3] = { '%', 'd', 0 };
214 res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
215 KEY_READ | KEY_WRITE, NULL, &key, NULL);
216 if (res != ERROR_SUCCESS) goto error_close_iid_key;
218 wsprintfW(buf, fmt, list->num_methods);
219 res = RegSetValueExW(key, NULL, 0, REG_SZ,
221 (lstrlenW(buf) + 1) * sizeof(WCHAR));
224 if (res != ERROR_SUCCESS) goto error_close_iid_key;
227 if (list->ps_clsid) {
228 res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
229 if (res != ERROR_SUCCESS) goto error_close_iid_key;
232 if (list->ps_clsid32) {
233 res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
234 if (res != ERROR_SUCCESS) goto error_close_iid_key;
238 RegCloseKey(iid_key);
241 error_close_interface_key:
242 RegCloseKey(interface_key);
244 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
247 /***********************************************************************
248 * unregister_interfaces
250 static HRESULT unregister_interfaces(struct regsvr_interface const *list)
252 LONG res = ERROR_SUCCESS;
255 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
256 KEY_READ | KEY_WRITE, &interface_key);
257 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
258 if (res != ERROR_SUCCESS) goto error_return;
260 for (; res == ERROR_SUCCESS && list->iid; ++list) {
263 StringFromGUID2(list->iid, buf, 39);
264 res = RegDeleteTreeW(interface_key, buf);
265 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
268 RegCloseKey(interface_key);
270 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
273 /***********************************************************************
276 static HRESULT register_coclasses(struct regsvr_coclass const *list)
278 LONG res = ERROR_SUCCESS;
281 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
282 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
283 if (res != ERROR_SUCCESS) goto error_return;
285 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
289 StringFromGUID2(list->clsid, buf, 39);
290 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
291 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
292 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
295 res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
296 (CONST BYTE*)(list->name),
297 strlen(list->name) + 1);
298 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
302 res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
303 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
309 res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
310 KEY_READ | KEY_WRITE, NULL,
312 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
314 res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
315 (CONST BYTE*)list->ips32,
316 lstrlenA(list->ips32) + 1);
317 if (res == ERROR_SUCCESS && list->ips32_tmodel)
318 res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
319 (CONST BYTE*)list->ips32_tmodel,
320 strlen(list->ips32_tmodel) + 1);
321 RegCloseKey(ips32_key);
322 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
326 res = register_key_defvalueA(clsid_key, progid_keyname,
328 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
330 res = register_progid(buf, list->progid, NULL,
331 list->name, list->progid_extra);
332 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
335 if (list->viprogid) {
336 res = register_key_defvalueA(clsid_key, viprogid_keyname,
338 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
340 res = register_progid(buf, list->viprogid, list->progid,
341 list->name, list->progid_extra);
342 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
345 error_close_clsid_key:
346 RegCloseKey(clsid_key);
349 error_close_coclass_key:
350 RegCloseKey(coclass_key);
352 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
355 /***********************************************************************
356 * unregister_coclasses
358 static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
360 LONG res = ERROR_SUCCESS;
363 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
364 KEY_READ | KEY_WRITE, &coclass_key);
365 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
366 if (res != ERROR_SUCCESS) goto error_return;
368 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
371 StringFromGUID2(list->clsid, buf, 39);
372 res = RegDeleteTreeW(coclass_key, buf);
373 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
374 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
377 res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
378 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
379 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
382 if (list->viprogid) {
383 res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
384 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
385 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
389 error_close_coclass_key:
390 RegCloseKey(coclass_key);
392 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
395 /***********************************************************************
396 * register_mediatypes_parsing
398 static HRESULT register_mediatypes_parsing(struct regsvr_mediatype_parsing const *list)
400 LONG res = ERROR_SUCCESS;
405 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0, NULL, 0,
406 KEY_READ | KEY_WRITE, NULL, &mediatype_key, NULL);
407 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
409 for (; res == ERROR_SUCCESS && list->majortype; ++list) {
410 HKEY majortype_key = NULL;
411 HKEY subtype_key = NULL;
413 StringFromGUID2(list->majortype, buf, 39);
414 res = RegCreateKeyExW(mediatype_key, buf, 0, NULL, 0,
415 KEY_READ | KEY_WRITE, NULL, &majortype_key, NULL);
416 if (res != ERROR_SUCCESS) goto error_close_keys;
418 StringFromGUID2(list->subtype, buf, 39);
419 res = RegCreateKeyExW(majortype_key, buf, 0, NULL, 0,
420 KEY_READ | KEY_WRITE, NULL, &subtype_key, NULL);
421 if (res != ERROR_SUCCESS) goto error_close_keys;
423 StringFromGUID2(&CLSID_AsyncReader, buf, 39);
424 res = RegSetValueExW(subtype_key, sourcefilter_valuename, 0, REG_SZ, (CONST BYTE*)buf,
425 (lstrlenW(buf) + 1) * sizeof(WCHAR));
426 if (res != ERROR_SUCCESS) goto error_close_keys;
428 for(i = 0; list->line[i]; i++) {
430 wsprintfA(buffer, "%d", i);
431 res = RegSetValueExA(subtype_key, buffer, 0, REG_SZ, (CONST BYTE*)list->line[i],
432 lstrlenA(list->line[i]));
433 if (res != ERROR_SUCCESS) goto error_close_keys;
438 RegCloseKey(majortype_key);
440 RegCloseKey(subtype_key);
443 RegCloseKey(mediatype_key);
445 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
448 /***********************************************************************
449 * register_mediatypes_extension
451 static HRESULT register_mediatypes_extension(struct regsvr_mediatype_extension const *list)
453 LONG res = ERROR_SUCCESS;
455 HKEY extensions_root_key = NULL;
458 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0, NULL, 0,
459 KEY_READ | KEY_WRITE, NULL, &mediatype_key, NULL);
460 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
462 res = RegCreateKeyExW(mediatype_key, extensions_keyname, 0, NULL, 0,
463 KEY_READ | KEY_WRITE, NULL, &extensions_root_key, NULL);
464 if (res != ERROR_SUCCESS) goto error_return;
466 for (; res == ERROR_SUCCESS && list->majortype; ++list) {
469 res = RegCreateKeyExA(extensions_root_key, list->extension, 0, NULL, 0,
470 KEY_READ | KEY_WRITE, NULL, &extension_key, NULL);
471 if (res != ERROR_SUCCESS) break;
473 StringFromGUID2(list->majortype, buf, 39);
474 res = RegSetValueExW(extension_key, mediatype_name, 0, REG_SZ, (CONST BYTE*)buf,
475 (lstrlenW(buf) + 1) * sizeof(WCHAR));
476 if (res != ERROR_SUCCESS) goto error_close_key;
478 StringFromGUID2(list->subtype, buf, 39);
479 res = RegSetValueExW(extension_key, subtype_valuename, 0, REG_SZ, (CONST BYTE*)buf,
480 (lstrlenW(buf) + 1) * sizeof(WCHAR));
481 if (res != ERROR_SUCCESS) goto error_close_key;
483 StringFromGUID2(&CLSID_AsyncReader, buf, 39);
484 res = RegSetValueExW(extension_key, sourcefilter_valuename, 0, REG_SZ, (CONST BYTE*)buf,
485 (lstrlenW(buf) + 1) * sizeof(WCHAR));
486 if (res != ERROR_SUCCESS) goto error_close_key;
489 RegCloseKey(extension_key);
493 RegCloseKey(mediatype_key);
494 if (extensions_root_key)
495 RegCloseKey(extensions_root_key);
497 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
500 /***********************************************************************
501 * unregister_mediatypes_parsing
503 static HRESULT unregister_mediatypes_parsing(struct regsvr_mediatype_parsing const *list)
510 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0,
511 KEY_READ | KEY_WRITE, &mediatype_key);
512 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
513 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
515 for (; res == ERROR_SUCCESS && list->majortype; ++list) {
516 StringFromGUID2(list->majortype, buf, 39);
517 res = RegOpenKeyExW(mediatype_key, buf, 0,
518 KEY_READ | KEY_WRITE, &majortype_key);
519 if (res == ERROR_FILE_NOT_FOUND) {
523 if (res != ERROR_SUCCESS) break;
525 StringFromGUID2(list->subtype, buf, 39);
526 res = RegDeleteTreeW(majortype_key, buf);
527 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
529 /* Removed majortype key if there is no more subtype key */
530 res = RegDeleteKeyW(majortype_key, 0);
531 if (res == ERROR_ACCESS_DENIED) res = ERROR_SUCCESS;
533 RegCloseKey(majortype_key);
536 RegCloseKey(mediatype_key);
538 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
541 /***********************************************************************
542 * unregister_mediatypes_extension
544 static HRESULT unregister_mediatypes_extension(struct regsvr_mediatype_extension const *list)
548 HKEY extensions_root_key = NULL;
550 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0,
551 KEY_READ | KEY_WRITE, &mediatype_key);
552 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
553 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
555 res = RegOpenKeyExW(mediatype_key, extensions_keyname, 0,
556 KEY_READ | KEY_WRITE, &extensions_root_key);
557 if (res == ERROR_FILE_NOT_FOUND)
559 else if (res == ERROR_SUCCESS)
560 for (; res == ERROR_SUCCESS && list->majortype; ++list) {
561 res = RegDeleteTreeA(extensions_root_key, list->extension);
562 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
565 RegCloseKey(mediatype_key);
566 if (extensions_root_key)
567 RegCloseKey(extensions_root_key);
569 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
572 /***********************************************************************
575 static HRESULT register_filters(struct regsvr_filter const *list)
578 IFilterMapper2* pFM2 = NULL;
581 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&pFM2);
584 for (; SUCCEEDED(hr) && list->clsid; ++list) {
586 REGFILTERPINS2* prfp2;
589 for (i = 0; list->pins[i].flags != 0xFFFFFFFF; i++) ;
591 rf2.dwMerit = list->merit;
593 rf2.u.s1.rgPins2 = prfp2 = CoTaskMemAlloc(i*sizeof(REGFILTERPINS2));
598 for (i = 0; list->pins[i].flags != 0xFFFFFFFF; i++) {
599 REGPINTYPES* lpMediatype;
603 for (nbmt = 0; list->pins[i].mediatypes[nbmt].majortype; nbmt++) ;
604 /* Allocate a single buffer for regpintypes struct and clsids */
605 lpMediatype = CoTaskMemAlloc(nbmt*(sizeof(REGPINTYPES) + 2*sizeof(CLSID)));
610 lpClsid = (CLSID*) (lpMediatype + nbmt);
611 for (j = 0; j < nbmt; j++) {
612 (lpMediatype + j)->clsMajorType = lpClsid + j*2;
613 memcpy(lpClsid + j*2, list->pins[i].mediatypes[j].majortype, sizeof(CLSID));
614 (lpMediatype + j)->clsMinorType = lpClsid + j*2 + 1;
615 if (list->pins[i].mediatypes[j].subtype)
616 memcpy(lpClsid + j*2 + 1, list->pins[i].mediatypes[j].subtype, sizeof(CLSID));
618 /* Subtype are often a combination of major type + fourcc/tag */
619 memcpy(lpClsid + j*2 + 1, list->pins[i].mediatypes[j].majortype, sizeof(CLSID));
620 *(DWORD*)(lpClsid + j*2 + 1) = list->pins[i].mediatypes[j].fourcc;
623 prfp2[i].dwFlags = list->pins[i].flags;
624 prfp2[i].cInstances = 0;
625 prfp2[i].nMediaTypes = j;
626 prfp2[i].lpMediaType = lpMediatype;
627 prfp2[i].nMediums = 0;
628 prfp2[i].lpMedium = NULL;
629 prfp2[i].clsPinCategory = NULL;
633 ERR("failed to register with hresult 0x%x\n", hr);
634 CoTaskMemFree(prfp2);
638 hr = IFilterMapper2_RegisterFilter(pFM2, list->clsid, list->name, NULL, list->category, NULL, &rf2);
641 CoTaskMemFree((REGPINTYPES*)prfp2[i-1].lpMediaType);
644 CoTaskMemFree(prfp2);
649 IFilterMapper2_Release(pFM2);
656 /***********************************************************************
659 static HRESULT unregister_filters(struct regsvr_filter const *list)
662 IFilterMapper2* pFM2;
666 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&pFM2);
669 for (; SUCCEEDED(hr) && list->clsid; ++list)
670 hr = IFilterMapper2_UnregisterFilter(pFM2, list->category, NULL, list->clsid);
671 IFilterMapper2_Release(pFM2);
679 /***********************************************************************
682 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
686 StringFromGUID2(guid, buf, 39);
687 return register_key_defvalueW(base, name, buf);
690 /***********************************************************************
691 * regsvr_key_defvalueW
693 static LONG register_key_defvalueW(
701 res = RegCreateKeyExW(base, name, 0, NULL, 0,
702 KEY_READ | KEY_WRITE, NULL, &key, NULL);
703 if (res != ERROR_SUCCESS) return res;
704 res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
705 (lstrlenW(value) + 1) * sizeof(WCHAR));
710 /***********************************************************************
711 * regsvr_key_defvalueA
713 static LONG register_key_defvalueA(
721 res = RegCreateKeyExW(base, name, 0, NULL, 0,
722 KEY_READ | KEY_WRITE, NULL, &key, NULL);
723 if (res != ERROR_SUCCESS) return res;
724 res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
725 lstrlenA(value) + 1);
730 /***********************************************************************
733 static LONG register_progid(
736 char const *curver_progid,
743 res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
744 NULL, 0, KEY_READ | KEY_WRITE, NULL,
746 if (res != ERROR_SUCCESS) return res;
749 res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
750 (CONST BYTE*)name, strlen(name) + 1);
751 if (res != ERROR_SUCCESS) goto error_close_progid_key;
755 res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
756 if (res != ERROR_SUCCESS) goto error_close_progid_key;
760 res = register_key_defvalueA(progid_key, curver_keyname,
762 if (res != ERROR_SUCCESS) goto error_close_progid_key;
768 res = RegCreateKeyExA(progid_key, extra, 0,
769 NULL, 0, KEY_READ | KEY_WRITE, NULL,
771 if (res == ERROR_SUCCESS)
772 RegCloseKey(extra_key);
775 error_close_progid_key:
776 RegCloseKey(progid_key);
780 static GUID const CLSID_PSFactoryBuffer = {
781 0x92a3a302, 0xda7c, 0x4a1f, {0xba,0x7e,0x18,0x02,0xbb,0x5d,0x2d,0x02} };
783 /***********************************************************************
786 static struct regsvr_coclass const coclass_list[] = {
787 { &CLSID_FilterGraph,
793 { &CLSID_FilterGraphNoThread,
799 { &CLSID_FilterMapper,
805 { &CLSID_FilterMapper2,
811 { &CLSID_SystemClock,
817 { &CLSID_MemoryAllocator,
823 { &CLSID_SeekingPassThru,
829 { &CLSID_AsyncReader,
830 "File Source Filter",
835 { &CLSID_AviSplitter,
841 { &CLSID_MPEG1Splitter,
842 "MPEG-I Stream Splitter",
853 { &CLSID_DSoundRender,
854 "DirectSound Audio Renderer",
859 { &CLSID_AudioRender,
860 "Wave Audio Renderer",
865 { &CLSID_NullRenderer,
871 { &CLSID_VideoRenderer,
877 { &CLSID_VideoRendererDefault,
878 "Default Video Renderer",
895 { NULL } /* list terminator */
898 /***********************************************************************
902 static struct regsvr_interface const interface_list[] = {
908 &CLSID_PSFactoryBuffer
910 { &IID_IFilterGraph2,
915 &CLSID_PSFactoryBuffer
917 { &IID_IFilterMapper,
922 &CLSID_PSFactoryBuffer
924 { &IID_IFilterMapper2,
929 &CLSID_PSFactoryBuffer
932 { &IID_SeekingPassThru,
937 &CLSID_PSFactoryBuffer
944 &CLSID_PSFactoryBuffer
951 &CLSID_PSFactoryBuffer
953 { NULL } /* list terminator */
956 /***********************************************************************
960 static struct regsvr_mediatype_parsing const mediatype_parsing_list[] = {
963 { "0,4,,52494646,8,4,,41564920",
967 &MEDIASUBTYPE_MPEG1System,
968 { "0, 16, FFFFFFFFF100010001800001FFFFFFFF, 000001BA2100010001800001000001BB",
972 &MEDIASUBTYPE_MPEG1VideoCD,
973 { "0, 4, , 52494646, 8, 8, , 43445841666D7420, 36, 20, FFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFF, 646174610000000000FFFFFFFFFFFFFFFFFFFF00",
977 &MEDIASUBTYPE_MPEG1Video,
978 { "0, 4, , 000001B3",
982 &MEDIASUBTYPE_MPEG1Audio,
983 { "0, 2, FFE0, FFE0",
984 "0, 10, FFFFFF00000080808080, 494433000000000000",
988 &MEDIASUBTYPE_QTMovie,
989 { "4, 4, , 6d646174",
995 { "0,4,,52494646,8,4,,57415645",
1003 { &MEDIATYPE_Stream,
1005 { "0,4,,464f524d,8,4,,41494646",
1006 "0,4,,464f524d,8,4,,41494643",
1009 { &MEDIATYPE_Stream,
1015 { &MEDIATYPE_Stream,
1017 { "0,4,,52494646,8,4,,524D4944",
1021 { NULL } /* list terminator */
1024 /***********************************************************************
1028 static struct regsvr_mediatype_extension const mediatype_extension_list[] = {
1029 { &MEDIATYPE_Stream,
1030 &MEDIASUBTYPE_MPEG1Audio,
1033 { NULL } /* list terminator */
1036 /***********************************************************************
1040 static struct regsvr_filter const filter_list[] = {
1041 { &CLSID_AviSplitter,
1042 &CLSID_LegacyAmFilterCategory,
1043 {'A','V','I',' ','S','p','l','i','t','t','e','r',0},
1046 { { &MEDIATYPE_Stream, &MEDIASUBTYPE_Avi },
1050 { REG_PINFLAG_B_OUTPUT,
1051 { { &MEDIATYPE_Video, &GUID_NULL },
1058 { &CLSID_MPEG1Splitter,
1059 &CLSID_LegacyAmFilterCategory,
1060 {'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0},
1063 { { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio },
1064 { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Video },
1065 { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System },
1066 { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1VideoCD },
1070 { REG_PINFLAG_B_OUTPUT,
1071 { { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet },
1072 { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload },
1076 { REG_PINFLAG_B_OUTPUT,
1077 { { &MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Packet },
1078 { &MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Payload },
1085 { &CLSID_NullRenderer,
1086 &CLSID_LegacyAmFilterCategory,
1087 {'N','u','l','l',' ','R','e','n','d','e','r','e','r',0},
1089 { { REG_PINFLAG_B_RENDERER,
1090 { { &MEDIATYPE_NULL, &GUID_NULL },
1097 { &CLSID_VideoRenderer,
1098 &CLSID_LegacyAmFilterCategory,
1099 {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0},
1101 { { REG_PINFLAG_B_RENDERER,
1102 { { &MEDIATYPE_Video, &GUID_NULL },
1109 { &CLSID_VideoRendererDefault,
1110 &CLSID_LegacyAmFilterCategory,
1111 {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0},
1113 { { REG_PINFLAG_B_RENDERER,
1114 { { &MEDIATYPE_Video, &GUID_NULL },
1121 { &CLSID_DSoundRender,
1122 &CLSID_LegacyAmFilterCategory,
1123 {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0},
1125 { { REG_PINFLAG_B_RENDERER,
1126 { { &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM },
1127 /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */
1134 { &CLSID_AudioRender,
1135 &CLSID_LegacyAmFilterCategory,
1136 {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0},
1138 { { REG_PINFLAG_B_RENDERER,
1139 { { &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM },
1140 /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */
1148 &CLSID_LegacyAmFilterCategory,
1149 {'A','V','I',' ','D','e','c','o','m','p','r','e','s','s','o','r',0},
1152 { { &MEDIATYPE_Video, &GUID_NULL },
1156 { REG_PINFLAG_B_OUTPUT,
1157 { { &MEDIATYPE_Video, &GUID_NULL },
1164 { &CLSID_AsyncReader,
1165 &CLSID_LegacyAmFilterCategory,
1166 {'F','i','l','e',' ','S','o','u','r','c','e',' ','(','A','s','y','n','c','.',')',0},
1168 { { REG_PINFLAG_B_OUTPUT,
1169 { { &MEDIATYPE_Stream, &GUID_NULL },
1176 { &CLSID_ACMWrapper,
1177 &CLSID_LegacyAmFilterCategory,
1178 {'A','C','M',' ','W','r','a','p','p','e','r',0},
1181 { { &MEDIATYPE_Audio, &GUID_NULL },
1185 { REG_PINFLAG_B_OUTPUT,
1186 { { &MEDIATYPE_Audio, &GUID_NULL },
1193 { &CLSID_WAVEParser,
1194 &CLSID_LegacyAmFilterCategory,
1195 {'W','a','v','e',' ','P','a','r','s','e','r',0},
1198 { { &MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE },
1199 { &MEDIATYPE_Stream, &MEDIASUBTYPE_AU },
1200 { &MEDIATYPE_Stream, &MEDIASUBTYPE_AIFF },
1204 { REG_PINFLAG_B_OUTPUT,
1205 { { &MEDIATYPE_Audio, &GUID_NULL },
1212 { NULL } /* list terminator */
1215 /***********************************************************************
1216 * DllRegisterServer (QUARTZ.@)
1218 HRESULT WINAPI DllRegisterServer(void)
1224 hr = register_coclasses(coclass_list);
1226 hr = register_interfaces(interface_list);
1228 hr = register_mediatypes_parsing(mediatype_parsing_list);
1230 hr = register_mediatypes_extension(mediatype_extension_list);
1232 hr = register_filters(filter_list);
1236 /***********************************************************************
1237 * DllUnregisterServer (QUARTZ.@)
1239 HRESULT WINAPI DllUnregisterServer(void)
1245 hr = unregister_filters(filter_list);
1247 hr = unregister_coclasses(coclass_list);
1249 hr = unregister_interfaces(interface_list);
1251 hr = unregister_mediatypes_parsing(mediatype_parsing_list);
1253 hr = unregister_mediatypes_extension(mediatype_extension_list);