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"
24 * Near the bottom of this file are the exported DllRegisterServer and
25 * DllUnregisterServer, which make all this worthwhile.
28 /***********************************************************************
29 * interface for self-registering
31 struct regsvr_interface
33 IID
const *iid
; /* NULL for end of list */
34 LPCSTR name
; /* can be NULL to omit */
35 IID
const *base_iid
; /* can be NULL to omit */
36 int num_methods
; /* can be <0 to omit */
37 CLSID
const *ps_clsid
; /* can be NULL to omit */
38 CLSID
const *ps_clsid32
; /* can be NULL to omit */
41 static HRESULT
register_interfaces(struct regsvr_interface
const *list
);
42 static HRESULT
unregister_interfaces(struct regsvr_interface
const *list
);
46 CLSID
const *clsid
; /* NULL for end of list */
47 LPCSTR name
; /* can be NULL to omit */
48 LPCSTR ips
; /* can be NULL to omit */
49 LPCSTR ips32
; /* can be NULL to omit */
50 LPCSTR ips32_tmodel
; /* can be NULL to omit */
51 LPCSTR progid
; /* can be NULL to omit */
52 LPCSTR viprogid
; /* can be NULL to omit */
53 LPCSTR progid_extra
; /* can be NULL to omit */
56 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
);
57 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
);
59 struct regsvr_mediatype_parsing
61 CLSID
const *majortype
; /* NULL for end of list */
63 LPCSTR line
[11]; /* NULL for end of list */
66 static HRESULT
register_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
);
67 static HRESULT
unregister_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
);
69 struct regsvr_mediatype_extension
71 CLSID
const *majortype
; /* NULL for end of list */
78 CLSID
const *majortype
; /* NULL for end of list */
85 DWORD flags
; /* 0xFFFFFFFF for end of list */
86 struct mediatype mediatypes
[11];
91 CLSID
const *clsid
; /* NULL for end of list */
92 CLSID
const *category
;
98 static HRESULT
register_mediatypes_extension(struct regsvr_mediatype_extension
const *list
);
99 static HRESULT
unregister_mediatypes_extension(struct regsvr_mediatype_extension
const *list
);
101 static HRESULT
register_filters(struct regsvr_filter
const *list
);
102 static HRESULT
unregister_filters(struct regsvr_filter
const *list
);
104 /***********************************************************************
105 * static string constants
107 static const WCHAR interface_keyname
[] = {
108 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
109 static const WCHAR base_ifa_keyname
[] = {
110 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
112 static const WCHAR num_methods_keyname
[] = {
113 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
114 static const WCHAR ps_clsid_keyname
[] = {
115 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
117 static const WCHAR ps_clsid32_keyname
[] = {
118 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
119 'i', 'd', '3', '2', 0 };
120 static const WCHAR clsid_keyname
[] = {
121 'C', 'L', 'S', 'I', 'D', 0 };
122 static const WCHAR curver_keyname
[] = {
123 'C', 'u', 'r', 'V', 'e', 'r', 0 };
124 static const WCHAR ips_keyname
[] = {
125 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
127 static const WCHAR ips32_keyname
[] = {
128 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
130 static const WCHAR progid_keyname
[] = {
131 'P', 'r', 'o', 'g', 'I', 'D', 0 };
132 static const WCHAR viprogid_keyname
[] = {
133 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
134 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
136 static const char tmodel_valuename
[] = "ThreadingModel";
137 static const WCHAR mediatype_name
[] = {
138 'M', 'e', 'd', 'i', 'a', ' ', 'T', 'y', 'p', 'e', 0 };
139 static const WCHAR subtype_valuename
[] = {
140 'S', 'u', 'b', 't', 'y', 'p', 'e', 0 };
141 static const WCHAR sourcefilter_valuename
[] = {
142 'S', 'o', 'u', 'r', 'c', 'e', ' ', 'F', 'i', 'l', 't', 'e', 'r', 0 };
143 static const WCHAR extensions_keyname
[] = {
144 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', 0 };
146 /***********************************************************************
147 * static helper functions
149 static LONG
register_key_guid(HKEY base
, WCHAR
const *name
, GUID
const *guid
);
150 static LONG
register_key_defvalueW(HKEY base
, WCHAR
const *name
,
152 static LONG
register_key_defvalueA(HKEY base
, WCHAR
const *name
,
154 static LONG
register_progid(WCHAR
const *clsid
,
155 char const *progid
, char const *curver_progid
,
156 char const *name
, char const *extra
);
158 /***********************************************************************
159 * register_interfaces
161 static HRESULT
register_interfaces(struct regsvr_interface
const *list
)
163 LONG res
= ERROR_SUCCESS
;
166 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, interface_keyname
, 0, NULL
, 0,
167 KEY_READ
| KEY_WRITE
, NULL
, &interface_key
, NULL
);
168 if (res
!= ERROR_SUCCESS
) goto error_return
;
170 for (; res
== ERROR_SUCCESS
&& list
->iid
; ++list
) {
174 StringFromGUID2(list
->iid
, buf
, 39);
175 res
= RegCreateKeyExW(interface_key
, buf
, 0, NULL
, 0,
176 KEY_READ
| KEY_WRITE
, NULL
, &iid_key
, NULL
);
177 if (res
!= ERROR_SUCCESS
) goto error_close_interface_key
;
180 res
= RegSetValueExA(iid_key
, NULL
, 0, REG_SZ
, (const BYTE
*)list
->name
,
181 strlen(list
->name
) + 1);
182 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
185 if (list
->base_iid
) {
186 res
= register_key_guid(iid_key
, base_ifa_keyname
, list
->base_iid
);
187 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
190 if (0 <= list
->num_methods
) {
191 static const WCHAR fmt
[] = { '%', 'd', 0 };
194 res
= RegCreateKeyExW(iid_key
, num_methods_keyname
, 0, NULL
, 0,
195 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
196 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
198 sprintfW(buf
, fmt
, list
->num_methods
);
199 res
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (const BYTE
*)buf
,
200 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
203 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
206 if (list
->ps_clsid
) {
207 res
= register_key_guid(iid_key
, ps_clsid_keyname
, list
->ps_clsid
);
208 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
211 if (list
->ps_clsid32
) {
212 res
= register_key_guid(iid_key
, ps_clsid32_keyname
, list
->ps_clsid32
);
213 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
217 RegCloseKey(iid_key
);
220 error_close_interface_key
:
221 RegCloseKey(interface_key
);
223 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
226 /***********************************************************************
227 * unregister_interfaces
229 static HRESULT
unregister_interfaces(struct regsvr_interface
const *list
)
231 LONG res
= ERROR_SUCCESS
;
234 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, interface_keyname
, 0,
235 KEY_READ
| KEY_WRITE
, &interface_key
);
236 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
237 if (res
!= ERROR_SUCCESS
) goto error_return
;
239 for (; res
== ERROR_SUCCESS
&& list
->iid
; ++list
) {
242 StringFromGUID2(list
->iid
, buf
, 39);
243 res
= RegDeleteTreeW(interface_key
, buf
);
244 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
247 RegCloseKey(interface_key
);
249 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
252 /***********************************************************************
255 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
)
257 LONG res
= ERROR_SUCCESS
;
260 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
261 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
262 if (res
!= ERROR_SUCCESS
) goto error_return
;
264 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
268 StringFromGUID2(list
->clsid
, buf
, 39);
269 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
270 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
271 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
274 res
= RegSetValueExA(clsid_key
, NULL
, 0, REG_SZ
, (const BYTE
*)list
->name
,
275 strlen(list
->name
) + 1);
276 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
280 res
= register_key_defvalueA(clsid_key
, ips_keyname
, list
->ips
);
281 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
287 res
= RegCreateKeyExW(clsid_key
, ips32_keyname
, 0, NULL
, 0,
288 KEY_READ
| KEY_WRITE
, NULL
,
290 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
292 res
= RegSetValueExA(ips32_key
, NULL
, 0, REG_SZ
, (const BYTE
*)list
->ips32
,
293 lstrlenA(list
->ips32
) + 1);
294 if (res
== ERROR_SUCCESS
&& list
->ips32_tmodel
)
295 res
= RegSetValueExA(ips32_key
, tmodel_valuename
, 0, REG_SZ
,
296 (const BYTE
*)list
->ips32_tmodel
,
297 strlen(list
->ips32_tmodel
) + 1);
298 RegCloseKey(ips32_key
);
299 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
303 res
= register_key_defvalueA(clsid_key
, progid_keyname
,
305 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
307 res
= register_progid(buf
, list
->progid
, NULL
,
308 list
->name
, list
->progid_extra
);
309 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
312 if (list
->viprogid
) {
313 res
= register_key_defvalueA(clsid_key
, viprogid_keyname
,
315 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
317 res
= register_progid(buf
, list
->viprogid
, list
->progid
,
318 list
->name
, list
->progid_extra
);
319 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
322 error_close_clsid_key
:
323 RegCloseKey(clsid_key
);
326 error_close_coclass_key
:
327 RegCloseKey(coclass_key
);
329 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
332 /***********************************************************************
333 * unregister_coclasses
335 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
)
337 LONG res
= ERROR_SUCCESS
;
340 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
341 KEY_READ
| KEY_WRITE
, &coclass_key
);
342 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
343 if (res
!= ERROR_SUCCESS
) goto error_return
;
345 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
348 StringFromGUID2(list
->clsid
, buf
, 39);
349 res
= RegDeleteTreeW(coclass_key
, buf
);
350 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
351 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
354 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->progid
);
355 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
356 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
359 if (list
->viprogid
) {
360 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->viprogid
);
361 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
362 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
366 error_close_coclass_key
:
367 RegCloseKey(coclass_key
);
369 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
372 /***********************************************************************
373 * register_mediatypes_parsing
375 static HRESULT
register_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
)
377 LONG res
= ERROR_SUCCESS
;
382 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0, NULL
, 0,
383 KEY_READ
| KEY_WRITE
, NULL
, &mediatype_key
, NULL
);
384 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
386 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
387 HKEY majortype_key
= NULL
;
388 HKEY subtype_key
= NULL
;
390 StringFromGUID2(list
->majortype
, buf
, 39);
391 res
= RegCreateKeyExW(mediatype_key
, buf
, 0, NULL
, 0,
392 KEY_READ
| KEY_WRITE
, NULL
, &majortype_key
, NULL
);
393 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
395 StringFromGUID2(list
->subtype
, buf
, 39);
396 res
= RegCreateKeyExW(majortype_key
, buf
, 0, NULL
, 0,
397 KEY_READ
| KEY_WRITE
, NULL
, &subtype_key
, NULL
);
398 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
400 StringFromGUID2(&CLSID_AsyncReader
, buf
, 39);
401 res
= RegSetValueExW(subtype_key
, sourcefilter_valuename
, 0, REG_SZ
, (const BYTE
*)buf
,
402 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
403 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
405 for(i
= 0; list
->line
[i
]; i
++) {
407 wsprintfA(buffer
, "%d", i
);
408 res
= RegSetValueExA(subtype_key
, buffer
, 0, REG_SZ
, (const BYTE
*)list
->line
[i
],
409 lstrlenA(list
->line
[i
]));
410 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
415 RegCloseKey(majortype_key
);
417 RegCloseKey(subtype_key
);
420 RegCloseKey(mediatype_key
);
422 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
425 /***********************************************************************
426 * register_mediatypes_extension
428 static HRESULT
register_mediatypes_extension(struct regsvr_mediatype_extension
const *list
)
430 LONG res
= ERROR_SUCCESS
;
432 HKEY extensions_root_key
= NULL
;
435 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0, NULL
, 0,
436 KEY_READ
| KEY_WRITE
, NULL
, &mediatype_key
, NULL
);
437 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
439 res
= RegCreateKeyExW(mediatype_key
, extensions_keyname
, 0, NULL
, 0,
440 KEY_READ
| KEY_WRITE
, NULL
, &extensions_root_key
, NULL
);
441 if (res
!= ERROR_SUCCESS
) goto error_return
;
443 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
446 res
= RegCreateKeyExA(extensions_root_key
, list
->extension
, 0, NULL
, 0,
447 KEY_READ
| KEY_WRITE
, NULL
, &extension_key
, NULL
);
448 if (res
!= ERROR_SUCCESS
) break;
450 StringFromGUID2(list
->majortype
, buf
, 39);
451 res
= RegSetValueExW(extension_key
, mediatype_name
, 0, REG_SZ
, (const BYTE
*)buf
,
452 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
453 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
455 StringFromGUID2(list
->subtype
, buf
, 39);
456 res
= RegSetValueExW(extension_key
, subtype_valuename
, 0, REG_SZ
, (const BYTE
*)buf
,
457 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
458 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
460 StringFromGUID2(&CLSID_AsyncReader
, buf
, 39);
461 res
= RegSetValueExW(extension_key
, sourcefilter_valuename
, 0, REG_SZ
, (const BYTE
*)buf
,
462 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
463 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
466 RegCloseKey(extension_key
);
470 RegCloseKey(mediatype_key
);
471 if (extensions_root_key
)
472 RegCloseKey(extensions_root_key
);
474 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
477 /***********************************************************************
478 * unregister_mediatypes_parsing
480 static HRESULT
unregister_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
)
487 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0,
488 KEY_READ
| KEY_WRITE
, &mediatype_key
);
489 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
490 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
492 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
493 StringFromGUID2(list
->majortype
, buf
, 39);
494 res
= RegOpenKeyExW(mediatype_key
, buf
, 0,
495 KEY_READ
| KEY_WRITE
, &majortype_key
);
496 if (res
== ERROR_FILE_NOT_FOUND
) {
500 if (res
!= ERROR_SUCCESS
) break;
502 StringFromGUID2(list
->subtype
, buf
, 39);
503 res
= RegDeleteTreeW(majortype_key
, buf
);
504 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
506 /* Removed majortype key if there is no more subtype key */
507 res
= RegDeleteKeyW(majortype_key
, 0);
508 if (res
== ERROR_ACCESS_DENIED
) res
= ERROR_SUCCESS
;
510 RegCloseKey(majortype_key
);
513 RegCloseKey(mediatype_key
);
515 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
518 /***********************************************************************
519 * unregister_mediatypes_extension
521 static HRESULT
unregister_mediatypes_extension(struct regsvr_mediatype_extension
const *list
)
525 HKEY extensions_root_key
= NULL
;
527 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0,
528 KEY_READ
| KEY_WRITE
, &mediatype_key
);
529 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
530 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
532 res
= RegOpenKeyExW(mediatype_key
, extensions_keyname
, 0,
533 KEY_READ
| KEY_WRITE
, &extensions_root_key
);
534 if (res
== ERROR_FILE_NOT_FOUND
)
536 else if (res
== ERROR_SUCCESS
)
537 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
538 res
= RegDeleteTreeA(extensions_root_key
, list
->extension
);
539 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
542 RegCloseKey(mediatype_key
);
543 if (extensions_root_key
)
544 RegCloseKey(extensions_root_key
);
546 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
549 /***********************************************************************
552 static HRESULT
register_filters(struct regsvr_filter
const *list
)
555 IFilterMapper2
* pFM2
= NULL
;
558 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pFM2
);
561 for (; SUCCEEDED(hr
) && list
->clsid
; ++list
) {
563 REGFILTERPINS2
* prfp2
;
566 for (i
= 0; list
->pins
[i
].flags
!= 0xFFFFFFFF; i
++) ;
568 rf2
.dwMerit
= list
->merit
;
570 rf2
.u
.s2
.rgPins2
= prfp2
= CoTaskMemAlloc(i
*sizeof(REGFILTERPINS2
));
575 for (i
= 0; list
->pins
[i
].flags
!= 0xFFFFFFFF; i
++) {
576 REGPINTYPES
* lpMediatype
;
580 for (nbmt
= 0; list
->pins
[i
].mediatypes
[nbmt
].majortype
; nbmt
++) ;
581 /* Allocate a single buffer for regpintypes struct and clsids */
582 lpMediatype
= CoTaskMemAlloc(nbmt
*(sizeof(REGPINTYPES
) + 2*sizeof(CLSID
)));
587 lpClsid
= (CLSID
*) (lpMediatype
+ nbmt
);
588 for (j
= 0; j
< nbmt
; j
++) {
589 (lpMediatype
+ j
)->clsMajorType
= lpClsid
+ j
*2;
590 memcpy(lpClsid
+ j
*2, list
->pins
[i
].mediatypes
[j
].majortype
, sizeof(CLSID
));
591 (lpMediatype
+ j
)->clsMinorType
= lpClsid
+ j
*2 + 1;
592 if (list
->pins
[i
].mediatypes
[j
].subtype
)
593 memcpy(lpClsid
+ j
*2 + 1, list
->pins
[i
].mediatypes
[j
].subtype
, sizeof(CLSID
));
595 /* Subtype are often a combination of major type + fourcc/tag */
596 memcpy(lpClsid
+ j
*2 + 1, list
->pins
[i
].mediatypes
[j
].majortype
, sizeof(CLSID
));
597 *(DWORD
*)(lpClsid
+ j
*2 + 1) = list
->pins
[i
].mediatypes
[j
].fourcc
;
600 prfp2
[i
].dwFlags
= list
->pins
[i
].flags
;
601 prfp2
[i
].cInstances
= 0;
602 prfp2
[i
].nMediaTypes
= j
;
603 prfp2
[i
].lpMediaType
= lpMediatype
;
604 prfp2
[i
].nMediums
= 0;
605 prfp2
[i
].lpMedium
= NULL
;
606 prfp2
[i
].clsPinCategory
= NULL
;
610 ERR("failed to register with hresult 0x%x\n", hr
);
611 CoTaskMemFree(prfp2
);
615 hr
= IFilterMapper2_RegisterFilter(pFM2
, list
->clsid
, list
->name
, NULL
, list
->category
, NULL
, &rf2
);
618 CoTaskMemFree((REGPINTYPES
*)prfp2
[i
-1].lpMediaType
);
621 CoTaskMemFree(prfp2
);
626 IFilterMapper2_Release(pFM2
);
633 /***********************************************************************
636 static HRESULT
unregister_filters(struct regsvr_filter
const *list
)
639 IFilterMapper2
* pFM2
;
643 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pFM2
);
646 for (; SUCCEEDED(hr
) && list
->clsid
; ++list
)
647 hr
= IFilterMapper2_UnregisterFilter(pFM2
, list
->category
, NULL
, list
->clsid
);
648 IFilterMapper2_Release(pFM2
);
656 /***********************************************************************
659 static LONG
register_key_guid(HKEY base
, WCHAR
const *name
, GUID
const *guid
)
663 StringFromGUID2(guid
, buf
, 39);
664 return register_key_defvalueW(base
, name
, buf
);
667 /***********************************************************************
668 * regsvr_key_defvalueW
670 static LONG
register_key_defvalueW(
678 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
679 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
680 if (res
!= ERROR_SUCCESS
) return res
;
681 res
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (const BYTE
*)value
,
682 (lstrlenW(value
) + 1) * sizeof(WCHAR
));
687 /***********************************************************************
688 * regsvr_key_defvalueA
690 static LONG
register_key_defvalueA(
698 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
699 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
700 if (res
!= ERROR_SUCCESS
) return res
;
701 res
= RegSetValueExA(key
, NULL
, 0, REG_SZ
, (const BYTE
*)value
, lstrlenA(value
) + 1);
706 /***********************************************************************
709 static LONG
register_progid(
712 char const *curver_progid
,
719 res
= RegCreateKeyExA(HKEY_CLASSES_ROOT
, progid
, 0,
720 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
722 if (res
!= ERROR_SUCCESS
) return res
;
725 res
= RegSetValueExA(progid_key
, NULL
, 0, REG_SZ
, (const BYTE
*)name
, strlen(name
) + 1);
726 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
730 res
= register_key_defvalueW(progid_key
, clsid_keyname
, clsid
);
731 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
735 res
= register_key_defvalueA(progid_key
, curver_keyname
,
737 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
743 res
= RegCreateKeyExA(progid_key
, extra
, 0,
744 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
746 if (res
== ERROR_SUCCESS
)
747 RegCloseKey(extra_key
);
750 error_close_progid_key
:
751 RegCloseKey(progid_key
);
755 /***********************************************************************
758 static struct regsvr_coclass
const coclass_list
[] = {
759 { NULL
} /* list terminator */
762 /***********************************************************************
766 static struct regsvr_interface
const interface_list
[] = {
767 { NULL
} /* list terminator */
770 /***********************************************************************
774 static struct regsvr_mediatype_parsing
const mediatype_parsing_list
[] = {
777 { "0,4,,52494646,8,4,,41564920",
781 &MEDIASUBTYPE_MPEG1System
,
782 { "0, 16, FFFFFFFFF100010001800001FFFFFFFF, 000001BA2100010001800001000001BB",
786 &MEDIASUBTYPE_MPEG1VideoCD
,
787 { "0, 4, , 52494646, 8, 8, , 43445841666D7420, 36, 20, FFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFF, 646174610000000000FFFFFFFFFFFFFFFFFFFF00",
791 &MEDIASUBTYPE_MPEG1Video
,
792 { "0, 4, , 000001B3",
796 &MEDIASUBTYPE_MPEG1Audio
,
797 { "0, 2, FFE0, FFE0",
798 "0, 10, FFFFFF00000080808080, 494433000000000000",
802 &MEDIASUBTYPE_QTMovie
,
803 { "4, 4, , 6d646174",
809 { "0,4,,52494646,8,4,,57415645",
819 { "0,4,,464f524d,8,4,,41494646",
820 "0,4,,464f524d,8,4,,41494643",
831 { "0,4,,52494646,8,4,,524D4944",
835 { NULL
} /* list terminator */
838 /***********************************************************************
842 static struct regsvr_mediatype_extension
const mediatype_extension_list
[] = {
844 &MEDIASUBTYPE_MPEG1Audio
,
847 { NULL
} /* list terminator */
850 /***********************************************************************
854 static struct regsvr_filter
const filter_list
[] = {
855 { &CLSID_AviSplitter
,
856 &CLSID_LegacyAmFilterCategory
,
857 {'A','V','I',' ','S','p','l','i','t','t','e','r',0},
860 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_Avi
},
864 { REG_PINFLAG_B_OUTPUT
,
865 { { &MEDIATYPE_Video
, &GUID_NULL
},
872 { &CLSID_MPEG1Splitter
,
873 &CLSID_LegacyAmFilterCategory
,
874 {'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0},
877 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Audio
},
878 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Video
},
879 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1System
},
880 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1VideoCD
},
884 { REG_PINFLAG_B_OUTPUT
,
885 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1Packet
},
886 { &MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1AudioPayload
},
890 { REG_PINFLAG_B_OUTPUT
,
891 { { &MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Packet
},
892 { &MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Payload
},
899 { &CLSID_NullRenderer
,
900 &CLSID_LegacyAmFilterCategory
,
901 {'N','u','l','l',' ','R','e','n','d','e','r','e','r',0},
903 { { REG_PINFLAG_B_RENDERER
,
904 { { &MEDIATYPE_NULL
, &GUID_NULL
},
911 { &CLSID_VideoRenderer
,
912 &CLSID_LegacyAmFilterCategory
,
913 {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0},
915 { { REG_PINFLAG_B_RENDERER
,
916 { { &MEDIATYPE_Video
, &GUID_NULL
},
923 { &CLSID_VideoRendererDefault
,
924 &CLSID_LegacyAmFilterCategory
,
925 {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0},
927 { { REG_PINFLAG_B_RENDERER
,
928 { { &MEDIATYPE_Video
, &GUID_NULL
},
935 { &CLSID_VideoMixingRenderer
,
936 &CLSID_LegacyAmFilterCategory
,
937 {'V','i','d','e','o',' ','M','i','x','i','n','g',' ','R','e','n','d','e','r','e','r',0},
939 { { REG_PINFLAG_B_RENDERER
,
940 { { &MEDIATYPE_Video
, &GUID_NULL
},
947 { &CLSID_VideoMixingRenderer9
,
948 &CLSID_LegacyAmFilterCategory
,
949 {'V','i','d','e','o',' ','M','i','x','i','n','g',' ','R','e','n','d','e','r','e','r',' ','9',0},
951 { { REG_PINFLAG_B_RENDERER
,
952 { { &MEDIATYPE_Video
, &GUID_NULL
},
959 { &CLSID_DSoundRender
,
960 &CLSID_LegacyAmFilterCategory
,
961 {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0},
963 { { REG_PINFLAG_B_RENDERER
,
964 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_PCM
},
965 /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */
972 { &CLSID_AudioRender
,
973 &CLSID_LegacyAmFilterCategory
,
974 {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0},
976 { { REG_PINFLAG_B_RENDERER
,
977 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_PCM
},
978 /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */
986 &CLSID_LegacyAmFilterCategory
,
987 {'A','V','I',' ','D','e','c','o','m','p','r','e','s','s','o','r',0},
990 { { &MEDIATYPE_Video
, &GUID_NULL
},
994 { REG_PINFLAG_B_OUTPUT
,
995 { { &MEDIATYPE_Video
, &GUID_NULL
},
1002 { &CLSID_AsyncReader
,
1003 &CLSID_LegacyAmFilterCategory
,
1004 {'F','i','l','e',' ','S','o','u','r','c','e',' ','(','A','s','y','n','c','.',')',0},
1006 { { REG_PINFLAG_B_OUTPUT
,
1007 { { &MEDIATYPE_Stream
, &GUID_NULL
},
1014 { &CLSID_ACMWrapper
,
1015 &CLSID_LegacyAmFilterCategory
,
1016 {'A','C','M',' ','W','r','a','p','p','e','r',0},
1019 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1023 { REG_PINFLAG_B_OUTPUT
,
1024 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1031 { &CLSID_WAVEParser
,
1032 &CLSID_LegacyAmFilterCategory
,
1033 {'W','a','v','e',' ','P','a','r','s','e','r',0},
1036 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_WAVE
},
1037 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_AU
},
1038 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_AIFF
},
1042 { REG_PINFLAG_B_OUTPUT
,
1043 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1050 { NULL
} /* list terminator */
1053 extern HRESULT WINAPI
QUARTZ_DllRegisterServer(void) DECLSPEC_HIDDEN
;
1054 extern HRESULT WINAPI
QUARTZ_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
1056 /***********************************************************************
1057 * DllRegisterServer (QUARTZ.@)
1059 HRESULT WINAPI
DllRegisterServer(void)
1065 hr
= QUARTZ_DllRegisterServer();
1067 hr
= register_coclasses(coclass_list
);
1069 hr
= register_interfaces(interface_list
);
1071 hr
= register_mediatypes_parsing(mediatype_parsing_list
);
1073 hr
= register_mediatypes_extension(mediatype_extension_list
);
1075 hr
= register_filters(filter_list
);
1079 /***********************************************************************
1080 * DllUnregisterServer (QUARTZ.@)
1082 HRESULT WINAPI
DllUnregisterServer(void)
1088 hr
= unregister_filters(filter_list
);
1090 hr
= unregister_coclasses(coclass_list
);
1092 hr
= unregister_interfaces(interface_list
);
1094 hr
= unregister_mediatypes_parsing(mediatype_parsing_list
);
1096 hr
= unregister_mediatypes_extension(mediatype_extension_list
);
1098 hr
= QUARTZ_DllUnregisterServer();