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 #include "quartz_private.h"
26 * Near the bottom of this file are the exported DllRegisterServer and
27 * DllUnregisterServer, which make all this worthwhile.
30 /***********************************************************************
31 * interface for self-registering
33 struct regsvr_interface
35 IID
const *iid
; /* NULL for end of list */
36 LPCSTR name
; /* can be NULL to omit */
37 IID
const *base_iid
; /* can be NULL to omit */
38 int num_methods
; /* can be <0 to omit */
39 CLSID
const *ps_clsid
; /* can be NULL to omit */
40 CLSID
const *ps_clsid32
; /* can be NULL to omit */
43 static HRESULT
register_interfaces(struct regsvr_interface
const *list
);
44 static HRESULT
unregister_interfaces(struct regsvr_interface
const *list
);
48 CLSID
const *clsid
; /* NULL for end of list */
49 LPCSTR name
; /* can be NULL to omit */
50 LPCSTR ips
; /* can be NULL to omit */
51 LPCSTR ips32
; /* can be NULL to omit */
52 LPCSTR ips32_tmodel
; /* can be NULL to omit */
53 LPCSTR progid
; /* can be NULL to omit */
54 LPCSTR viprogid
; /* can be NULL to omit */
55 LPCSTR progid_extra
; /* can be NULL to omit */
58 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
);
59 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
);
61 struct regsvr_mediatype_parsing
63 CLSID
const *majortype
; /* NULL for end of list */
65 LPCSTR line
[11]; /* NULL for end of list */
68 static HRESULT
register_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
);
69 static HRESULT
unregister_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
);
71 struct regsvr_mediatype_extension
73 CLSID
const *majortype
; /* NULL for end of list */
80 CLSID
const *majortype
; /* NULL for end of list */
87 DWORD flags
; /* 0xFFFFFFFF for end of list */
88 struct mediatype mediatypes
[11];
93 CLSID
const *clsid
; /* NULL for end of list */
94 CLSID
const *category
;
100 static HRESULT
register_mediatypes_extension(struct regsvr_mediatype_extension
const *list
);
101 static HRESULT
unregister_mediatypes_extension(struct regsvr_mediatype_extension
const *list
);
103 static HRESULT
register_filters(struct regsvr_filter
const *list
);
104 static HRESULT
unregister_filters(struct regsvr_filter
const *list
);
106 /***********************************************************************
107 * static string constants
109 static const WCHAR interface_keyname
[] = {
110 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
111 static const WCHAR base_ifa_keyname
[] = {
112 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
114 static const WCHAR num_methods_keyname
[] = {
115 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
116 static const WCHAR ps_clsid_keyname
[] = {
117 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
119 static const WCHAR ps_clsid32_keyname
[] = {
120 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
121 'i', 'd', '3', '2', 0 };
122 static const WCHAR clsid_keyname
[] = {
123 'C', 'L', 'S', 'I', 'D', 0 };
124 static const WCHAR curver_keyname
[] = {
125 'C', 'u', 'r', 'V', 'e', 'r', 0 };
126 static const WCHAR ips_keyname
[] = {
127 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
129 static const WCHAR ips32_keyname
[] = {
130 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
132 static const WCHAR progid_keyname
[] = {
133 'P', 'r', 'o', 'g', 'I', 'D', 0 };
134 static const WCHAR viprogid_keyname
[] = {
135 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
136 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
138 static const char tmodel_valuename
[] = "ThreadingModel";
139 static const WCHAR mediatype_name
[] = {
140 'M', 'e', 'd', 'i', 'a', ' ', 'T', 'y', 'p', 'e', 0 };
141 static const WCHAR subtype_valuename
[] = {
142 'S', 'u', 'b', 't', 'y', 'p', 'e', 0 };
143 static const WCHAR sourcefilter_valuename
[] = {
144 'S', 'o', 'u', 'r', 'c', 'e', ' ', 'F', 'i', 'l', 't', 'e', 'r', 0 };
145 static const WCHAR extensions_keyname
[] = {
146 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', 0 };
148 /***********************************************************************
149 * static helper functions
151 static LONG
register_key_guid(HKEY base
, WCHAR
const *name
, GUID
const *guid
);
152 static LONG
register_key_defvalueW(HKEY base
, WCHAR
const *name
,
154 static LONG
register_key_defvalueA(HKEY base
, WCHAR
const *name
,
156 static LONG
register_progid(WCHAR
const *clsid
,
157 char const *progid
, char const *curver_progid
,
158 char const *name
, char const *extra
);
160 /***********************************************************************
161 * register_interfaces
163 static HRESULT
register_interfaces(struct regsvr_interface
const *list
)
165 LONG res
= ERROR_SUCCESS
;
168 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, interface_keyname
, 0, NULL
, 0,
169 KEY_READ
| KEY_WRITE
, NULL
, &interface_key
, NULL
);
170 if (res
!= ERROR_SUCCESS
) goto error_return
;
172 for (; res
== ERROR_SUCCESS
&& list
->iid
; ++list
) {
176 StringFromGUID2(list
->iid
, buf
, 39);
177 res
= RegCreateKeyExW(interface_key
, buf
, 0, NULL
, 0,
178 KEY_READ
| KEY_WRITE
, NULL
, &iid_key
, NULL
);
179 if (res
!= ERROR_SUCCESS
) goto error_close_interface_key
;
182 res
= RegSetValueExA(iid_key
, NULL
, 0, REG_SZ
, (const BYTE
*)list
->name
,
183 strlen(list
->name
) + 1);
184 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
187 if (list
->base_iid
) {
188 res
= register_key_guid(iid_key
, base_ifa_keyname
, list
->base_iid
);
189 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
192 if (0 <= list
->num_methods
) {
193 static const WCHAR fmt
[] = { '%', 'd', 0 };
196 res
= RegCreateKeyExW(iid_key
, num_methods_keyname
, 0, NULL
, 0,
197 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
198 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
200 sprintfW(buf
, fmt
, list
->num_methods
);
201 res
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (const BYTE
*)buf
,
202 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
205 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
208 if (list
->ps_clsid
) {
209 res
= register_key_guid(iid_key
, ps_clsid_keyname
, list
->ps_clsid
);
210 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
213 if (list
->ps_clsid32
) {
214 res
= register_key_guid(iid_key
, ps_clsid32_keyname
, list
->ps_clsid32
);
215 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
219 RegCloseKey(iid_key
);
222 error_close_interface_key
:
223 RegCloseKey(interface_key
);
225 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
228 /***********************************************************************
229 * unregister_interfaces
231 static HRESULT
unregister_interfaces(struct regsvr_interface
const *list
)
233 LONG res
= ERROR_SUCCESS
;
236 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, interface_keyname
, 0,
237 KEY_READ
| KEY_WRITE
, &interface_key
);
238 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
239 if (res
!= ERROR_SUCCESS
) goto error_return
;
241 for (; res
== ERROR_SUCCESS
&& list
->iid
; ++list
) {
244 StringFromGUID2(list
->iid
, buf
, 39);
245 res
= RegDeleteTreeW(interface_key
, buf
);
246 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
249 RegCloseKey(interface_key
);
251 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
254 /***********************************************************************
257 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
)
259 LONG res
= ERROR_SUCCESS
;
262 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
263 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
264 if (res
!= ERROR_SUCCESS
) goto error_return
;
266 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
270 StringFromGUID2(list
->clsid
, buf
, 39);
271 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
272 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
273 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
276 res
= RegSetValueExA(clsid_key
, NULL
, 0, REG_SZ
, (const BYTE
*)list
->name
,
277 strlen(list
->name
) + 1);
278 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
282 res
= register_key_defvalueA(clsid_key
, ips_keyname
, list
->ips
);
283 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
289 res
= RegCreateKeyExW(clsid_key
, ips32_keyname
, 0, NULL
, 0,
290 KEY_READ
| KEY_WRITE
, NULL
,
292 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
294 res
= RegSetValueExA(ips32_key
, NULL
, 0, REG_SZ
, (const BYTE
*)list
->ips32
,
295 lstrlenA(list
->ips32
) + 1);
296 if (res
== ERROR_SUCCESS
&& list
->ips32_tmodel
)
297 res
= RegSetValueExA(ips32_key
, tmodel_valuename
, 0, REG_SZ
,
298 (const BYTE
*)list
->ips32_tmodel
,
299 strlen(list
->ips32_tmodel
) + 1);
300 RegCloseKey(ips32_key
);
301 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
305 res
= register_key_defvalueA(clsid_key
, progid_keyname
,
307 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
309 res
= register_progid(buf
, list
->progid
, NULL
,
310 list
->name
, list
->progid_extra
);
311 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
314 if (list
->viprogid
) {
315 res
= register_key_defvalueA(clsid_key
, viprogid_keyname
,
317 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
319 res
= register_progid(buf
, list
->viprogid
, list
->progid
,
320 list
->name
, list
->progid_extra
);
321 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
324 error_close_clsid_key
:
325 RegCloseKey(clsid_key
);
328 error_close_coclass_key
:
329 RegCloseKey(coclass_key
);
331 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
334 /***********************************************************************
335 * unregister_coclasses
337 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
)
339 LONG res
= ERROR_SUCCESS
;
342 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
343 KEY_READ
| KEY_WRITE
, &coclass_key
);
344 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
345 if (res
!= ERROR_SUCCESS
) goto error_return
;
347 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
350 StringFromGUID2(list
->clsid
, buf
, 39);
351 res
= RegDeleteTreeW(coclass_key
, buf
);
352 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
353 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
356 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->progid
);
357 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
358 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
361 if (list
->viprogid
) {
362 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->viprogid
);
363 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
364 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
368 error_close_coclass_key
:
369 RegCloseKey(coclass_key
);
371 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
374 /***********************************************************************
375 * register_mediatypes_parsing
377 static HRESULT
register_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
)
379 LONG res
= ERROR_SUCCESS
;
384 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0, NULL
, 0,
385 KEY_READ
| KEY_WRITE
, NULL
, &mediatype_key
, NULL
);
386 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
388 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
389 HKEY majortype_key
= NULL
;
390 HKEY subtype_key
= NULL
;
392 StringFromGUID2(list
->majortype
, buf
, 39);
393 res
= RegCreateKeyExW(mediatype_key
, buf
, 0, NULL
, 0,
394 KEY_READ
| KEY_WRITE
, NULL
, &majortype_key
, NULL
);
395 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
397 StringFromGUID2(list
->subtype
, buf
, 39);
398 res
= RegCreateKeyExW(majortype_key
, buf
, 0, NULL
, 0,
399 KEY_READ
| KEY_WRITE
, NULL
, &subtype_key
, NULL
);
400 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
402 StringFromGUID2(&CLSID_AsyncReader
, buf
, 39);
403 res
= RegSetValueExW(subtype_key
, sourcefilter_valuename
, 0, REG_SZ
, (const BYTE
*)buf
,
404 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
405 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
407 for(i
= 0; list
->line
[i
]; i
++) {
409 wsprintfA(buffer
, "%d", i
);
410 res
= RegSetValueExA(subtype_key
, buffer
, 0, REG_SZ
, (const BYTE
*)list
->line
[i
],
411 lstrlenA(list
->line
[i
]));
412 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
417 RegCloseKey(majortype_key
);
419 RegCloseKey(subtype_key
);
422 RegCloseKey(mediatype_key
);
424 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
427 /***********************************************************************
428 * register_mediatypes_extension
430 static HRESULT
register_mediatypes_extension(struct regsvr_mediatype_extension
const *list
)
432 LONG res
= ERROR_SUCCESS
;
434 HKEY extensions_root_key
= NULL
;
437 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0, NULL
, 0,
438 KEY_READ
| KEY_WRITE
, NULL
, &mediatype_key
, NULL
);
439 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
441 res
= RegCreateKeyExW(mediatype_key
, extensions_keyname
, 0, NULL
, 0,
442 KEY_READ
| KEY_WRITE
, NULL
, &extensions_root_key
, NULL
);
443 if (res
!= ERROR_SUCCESS
) goto error_return
;
445 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
448 res
= RegCreateKeyExA(extensions_root_key
, list
->extension
, 0, NULL
, 0,
449 KEY_READ
| KEY_WRITE
, NULL
, &extension_key
, NULL
);
450 if (res
!= ERROR_SUCCESS
) break;
452 StringFromGUID2(list
->majortype
, buf
, 39);
453 res
= RegSetValueExW(extension_key
, mediatype_name
, 0, REG_SZ
, (const BYTE
*)buf
,
454 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
455 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
457 StringFromGUID2(list
->subtype
, buf
, 39);
458 res
= RegSetValueExW(extension_key
, subtype_valuename
, 0, REG_SZ
, (const BYTE
*)buf
,
459 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
460 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
462 StringFromGUID2(&CLSID_AsyncReader
, buf
, 39);
463 res
= RegSetValueExW(extension_key
, sourcefilter_valuename
, 0, REG_SZ
, (const BYTE
*)buf
,
464 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
465 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
468 RegCloseKey(extension_key
);
472 RegCloseKey(mediatype_key
);
473 if (extensions_root_key
)
474 RegCloseKey(extensions_root_key
);
476 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
479 /***********************************************************************
480 * unregister_mediatypes_parsing
482 static HRESULT
unregister_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
)
489 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0,
490 KEY_READ
| KEY_WRITE
, &mediatype_key
);
491 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
492 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
494 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
495 StringFromGUID2(list
->majortype
, buf
, 39);
496 res
= RegOpenKeyExW(mediatype_key
, buf
, 0,
497 KEY_READ
| KEY_WRITE
, &majortype_key
);
498 if (res
== ERROR_FILE_NOT_FOUND
) {
502 if (res
!= ERROR_SUCCESS
) break;
504 StringFromGUID2(list
->subtype
, buf
, 39);
505 res
= RegDeleteTreeW(majortype_key
, buf
);
506 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
508 /* Removed majortype key if there is no more subtype key */
509 res
= RegDeleteKeyW(majortype_key
, 0);
510 if (res
== ERROR_ACCESS_DENIED
) res
= ERROR_SUCCESS
;
512 RegCloseKey(majortype_key
);
515 RegCloseKey(mediatype_key
);
517 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
520 /***********************************************************************
521 * unregister_mediatypes_extension
523 static HRESULT
unregister_mediatypes_extension(struct regsvr_mediatype_extension
const *list
)
527 HKEY extensions_root_key
= NULL
;
529 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0,
530 KEY_READ
| KEY_WRITE
, &mediatype_key
);
531 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
532 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
534 res
= RegOpenKeyExW(mediatype_key
, extensions_keyname
, 0,
535 KEY_READ
| KEY_WRITE
, &extensions_root_key
);
536 if (res
== ERROR_FILE_NOT_FOUND
)
538 else if (res
== ERROR_SUCCESS
)
539 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
540 res
= RegDeleteTreeA(extensions_root_key
, list
->extension
);
541 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
544 RegCloseKey(mediatype_key
);
545 if (extensions_root_key
)
546 RegCloseKey(extensions_root_key
);
548 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
551 /***********************************************************************
554 static HRESULT
register_filters(struct regsvr_filter
const *list
)
557 IFilterMapper2
* pFM2
= NULL
;
560 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pFM2
);
563 for (; SUCCEEDED(hr
) && list
->clsid
; ++list
) {
565 REGFILTERPINS2
* prfp2
;
568 for (i
= 0; list
->pins
[i
].flags
!= 0xFFFFFFFF; i
++) ;
570 rf2
.dwMerit
= list
->merit
;
572 rf2
.u
.s2
.rgPins2
= prfp2
= CoTaskMemAlloc(i
*sizeof(REGFILTERPINS2
));
577 for (i
= 0; list
->pins
[i
].flags
!= 0xFFFFFFFF; i
++) {
578 REGPINTYPES
* lpMediatype
;
582 for (nbmt
= 0; list
->pins
[i
].mediatypes
[nbmt
].majortype
; nbmt
++) ;
583 /* Allocate a single buffer for regpintypes struct and clsids */
584 lpMediatype
= CoTaskMemAlloc(nbmt
*(sizeof(REGPINTYPES
) + 2*sizeof(CLSID
)));
589 lpClsid
= (CLSID
*) (lpMediatype
+ nbmt
);
590 for (j
= 0; j
< nbmt
; j
++) {
591 (lpMediatype
+ j
)->clsMajorType
= lpClsid
+ j
*2;
592 memcpy(lpClsid
+ j
*2, list
->pins
[i
].mediatypes
[j
].majortype
, sizeof(CLSID
));
593 (lpMediatype
+ j
)->clsMinorType
= lpClsid
+ j
*2 + 1;
594 if (list
->pins
[i
].mediatypes
[j
].subtype
)
595 memcpy(lpClsid
+ j
*2 + 1, list
->pins
[i
].mediatypes
[j
].subtype
, sizeof(CLSID
));
597 /* Subtypes are often a combination of major type + fourcc/tag */
598 memcpy(lpClsid
+ j
*2 + 1, list
->pins
[i
].mediatypes
[j
].majortype
, sizeof(CLSID
));
599 *(DWORD
*)(lpClsid
+ j
*2 + 1) = list
->pins
[i
].mediatypes
[j
].fourcc
;
602 prfp2
[i
].dwFlags
= list
->pins
[i
].flags
;
603 prfp2
[i
].cInstances
= 0;
604 prfp2
[i
].nMediaTypes
= j
;
605 prfp2
[i
].lpMediaType
= lpMediatype
;
606 prfp2
[i
].nMediums
= 0;
607 prfp2
[i
].lpMedium
= NULL
;
608 prfp2
[i
].clsPinCategory
= NULL
;
612 ERR("failed to register with hresult 0x%x\n", hr
);
613 CoTaskMemFree(prfp2
);
617 hr
= IFilterMapper2_RegisterFilter(pFM2
, list
->clsid
, list
->name
, NULL
, list
->category
, NULL
, &rf2
);
620 CoTaskMemFree((REGPINTYPES
*)prfp2
[i
-1].lpMediaType
);
623 CoTaskMemFree(prfp2
);
628 IFilterMapper2_Release(pFM2
);
635 /***********************************************************************
638 static HRESULT
unregister_filters(struct regsvr_filter
const *list
)
641 IFilterMapper2
* pFM2
;
645 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pFM2
);
648 for (; SUCCEEDED(hr
) && list
->clsid
; ++list
)
649 hr
= IFilterMapper2_UnregisterFilter(pFM2
, list
->category
, NULL
, list
->clsid
);
650 IFilterMapper2_Release(pFM2
);
658 /***********************************************************************
661 static LONG
register_key_guid(HKEY base
, WCHAR
const *name
, GUID
const *guid
)
665 StringFromGUID2(guid
, buf
, 39);
666 return register_key_defvalueW(base
, name
, buf
);
669 /***********************************************************************
670 * regsvr_key_defvalueW
672 static LONG
register_key_defvalueW(
680 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
681 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
682 if (res
!= ERROR_SUCCESS
) return res
;
683 res
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (const BYTE
*)value
,
684 (lstrlenW(value
) + 1) * sizeof(WCHAR
));
689 /***********************************************************************
690 * regsvr_key_defvalueA
692 static LONG
register_key_defvalueA(
700 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
701 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
702 if (res
!= ERROR_SUCCESS
) return res
;
703 res
= RegSetValueExA(key
, NULL
, 0, REG_SZ
, (const BYTE
*)value
, lstrlenA(value
) + 1);
708 /***********************************************************************
711 static LONG
register_progid(
714 char const *curver_progid
,
721 res
= RegCreateKeyExA(HKEY_CLASSES_ROOT
, progid
, 0,
722 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
724 if (res
!= ERROR_SUCCESS
) return res
;
727 res
= RegSetValueExA(progid_key
, NULL
, 0, REG_SZ
, (const BYTE
*)name
, strlen(name
) + 1);
728 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
732 res
= register_key_defvalueW(progid_key
, clsid_keyname
, clsid
);
733 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
737 res
= register_key_defvalueA(progid_key
, curver_keyname
,
739 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
745 res
= RegCreateKeyExA(progid_key
, extra
, 0,
746 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
748 if (res
== ERROR_SUCCESS
)
749 RegCloseKey(extra_key
);
752 error_close_progid_key
:
753 RegCloseKey(progid_key
);
757 /***********************************************************************
760 static struct regsvr_coclass
const coclass_list
[] = {
761 { NULL
} /* list terminator */
764 /***********************************************************************
768 static struct regsvr_interface
const interface_list
[] = {
769 { NULL
} /* list terminator */
772 /***********************************************************************
776 static struct regsvr_mediatype_parsing
const mediatype_parsing_list
[] = {
779 { "0,4,,52494646,8,4,,41564920",
783 &MEDIASUBTYPE_MPEG1System
,
784 { "0, 16, FFFFFFFFF100010001800001FFFFFFFF, 000001BA2100010001800001000001BB",
788 &MEDIASUBTYPE_MPEG1VideoCD
,
789 { "0, 4, , 52494646, 8, 8, , 43445841666D7420, 36, 20, FFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFF, 646174610000000000FFFFFFFFFFFFFFFFFFFF00",
793 &MEDIASUBTYPE_MPEG1Video
,
794 { "0, 4, , 000001B3",
798 &MEDIASUBTYPE_MPEG1Audio
,
799 { "0, 2, FFE0, FFE0",
800 "0, 10, FFFFFF00000080808080, 494433000000000000",
804 &MEDIASUBTYPE_MPEG2_PROGRAM
,
805 { "0, 5, FFFFFFFFC0, 000001BA40",
809 &MEDIASUBTYPE_QTMovie
,
810 { "4, 4, , 6d646174",
816 { "0,4,,52494646,8,4,,57415645",
826 { "0,4,,464f524d,8,4,,41494646",
827 "0,4,,464f524d,8,4,,41494643",
838 { "0,4,,52494646,8,4,,524D4944",
842 { NULL
} /* list terminator */
845 /***********************************************************************
849 static struct regsvr_mediatype_extension
const mediatype_extension_list
[] = {
851 &MEDIASUBTYPE_MPEG1Audio
,
854 { NULL
} /* list terminator */
857 /***********************************************************************
861 static struct regsvr_filter
const filter_list
[] = {
862 { &CLSID_AviSplitter
,
863 &CLSID_LegacyAmFilterCategory
,
864 {'A','V','I',' ','S','p','l','i','t','t','e','r',0},
867 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_Avi
},
871 { REG_PINFLAG_B_OUTPUT
,
872 { { &MEDIATYPE_Video
, &GUID_NULL
},
879 { &CLSID_MPEG1Splitter
,
880 &CLSID_LegacyAmFilterCategory
,
881 {'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0},
884 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Audio
},
885 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Video
},
886 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1System
},
887 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1VideoCD
},
891 { REG_PINFLAG_B_OUTPUT
,
892 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1Packet
},
893 { &MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1AudioPayload
},
897 { REG_PINFLAG_B_OUTPUT
,
898 { { &MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Packet
},
899 { &MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Payload
},
906 { &CLSID_NullRenderer
,
907 &CLSID_LegacyAmFilterCategory
,
908 {'N','u','l','l',' ','R','e','n','d','e','r','e','r',0},
910 { { REG_PINFLAG_B_RENDERER
,
911 { { &MEDIATYPE_NULL
, &GUID_NULL
},
918 { &CLSID_VideoRenderer
,
919 &CLSID_LegacyAmFilterCategory
,
920 {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0},
922 { { REG_PINFLAG_B_RENDERER
,
923 { { &MEDIATYPE_Video
, &GUID_NULL
},
930 { &CLSID_VideoRendererDefault
,
931 &CLSID_LegacyAmFilterCategory
,
932 {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0},
934 { { REG_PINFLAG_B_RENDERER
,
935 { { &MEDIATYPE_Video
, &GUID_NULL
},
942 { &CLSID_VideoMixingRenderer
,
943 &CLSID_LegacyAmFilterCategory
,
944 {'V','i','d','e','o',' ','M','i','x','i','n','g',' ','R','e','n','d','e','r','e','r',0},
946 { { REG_PINFLAG_B_RENDERER
,
947 { { &MEDIATYPE_Video
, &GUID_NULL
},
954 { &CLSID_VideoMixingRenderer9
,
955 &CLSID_LegacyAmFilterCategory
,
956 {'V','i','d','e','o',' ','M','i','x','i','n','g',' ','R','e','n','d','e','r','e','r',' ','9',0},
958 { { REG_PINFLAG_B_RENDERER
,
959 { { &MEDIATYPE_Video
, &GUID_NULL
},
966 { &CLSID_DSoundRender
,
967 &CLSID_LegacyAmFilterCategory
,
968 {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0},
970 { { REG_PINFLAG_B_RENDERER
,
971 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_PCM
},
972 /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */
979 { &CLSID_AudioRender
,
980 &CLSID_LegacyAmFilterCategory
,
981 {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0},
983 { { REG_PINFLAG_B_RENDERER
,
984 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_PCM
},
985 /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */
993 &CLSID_LegacyAmFilterCategory
,
994 {'A','V','I',' ','D','e','c','o','m','p','r','e','s','s','o','r',0},
997 { { &MEDIATYPE_Video
, &GUID_NULL
},
1001 { REG_PINFLAG_B_OUTPUT
,
1002 { { &MEDIATYPE_Video
, &GUID_NULL
},
1009 { &CLSID_AsyncReader
,
1010 &CLSID_LegacyAmFilterCategory
,
1011 {'F','i','l','e',' ','S','o','u','r','c','e',' ','(','A','s','y','n','c','.',')',0},
1013 { { REG_PINFLAG_B_OUTPUT
,
1014 { { &MEDIATYPE_Stream
, &GUID_NULL
},
1021 { &CLSID_ACMWrapper
,
1022 &CLSID_LegacyAmFilterCategory
,
1023 {'A','C','M',' ','W','r','a','p','p','e','r',0},
1026 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1030 { REG_PINFLAG_B_OUTPUT
,
1031 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1038 { &CLSID_WAVEParser
,
1039 &CLSID_LegacyAmFilterCategory
,
1040 {'W','a','v','e',' ','P','a','r','s','e','r',0},
1043 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_WAVE
},
1044 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_AU
},
1045 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_AIFF
},
1049 { REG_PINFLAG_B_OUTPUT
,
1050 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1057 { NULL
} /* list terminator */
1060 extern HRESULT WINAPI
QUARTZ_DllRegisterServer(void) DECLSPEC_HIDDEN
;
1061 extern HRESULT WINAPI
QUARTZ_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
1063 /***********************************************************************
1064 * DllRegisterServer (QUARTZ.@)
1066 HRESULT WINAPI
DllRegisterServer(void)
1072 hr
= QUARTZ_DllRegisterServer();
1074 hr
= register_coclasses(coclass_list
);
1076 hr
= register_interfaces(interface_list
);
1078 hr
= register_mediatypes_parsing(mediatype_parsing_list
);
1080 hr
= register_mediatypes_extension(mediatype_extension_list
);
1082 hr
= register_filters(filter_list
);
1086 /***********************************************************************
1087 * DllUnregisterServer (QUARTZ.@)
1089 HRESULT WINAPI
DllUnregisterServer(void)
1095 hr
= unregister_filters(filter_list
);
1097 hr
= unregister_coclasses(coclass_list
);
1099 hr
= unregister_interfaces(interface_list
);
1101 hr
= unregister_mediatypes_parsing(mediatype_parsing_list
);
1103 hr
= unregister_mediatypes_extension(mediatype_extension_list
);
1105 hr
= QUARTZ_DllUnregisterServer();