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
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
42 * Near the bottom of this file are the exported DllRegisterServer and
43 * DllUnregisterServer, which make all this worthwhile.
46 /***********************************************************************
47 * interface for self-registering
49 struct regsvr_interface
51 IID
const *iid
; /* NULL for end of list */
52 LPCSTR name
; /* can be NULL to omit */
53 IID
const *base_iid
; /* can be NULL to omit */
54 int num_methods
; /* can be <0 to omit */
55 CLSID
const *ps_clsid
; /* can be NULL to omit */
56 CLSID
const *ps_clsid32
; /* can be NULL to omit */
59 static HRESULT
register_interfaces(struct regsvr_interface
const *list
);
60 static HRESULT
unregister_interfaces(struct regsvr_interface
const *list
);
64 CLSID
const *clsid
; /* NULL for end of list */
65 LPCSTR name
; /* can be NULL to omit */
66 LPCSTR ips
; /* can be NULL to omit */
67 LPCSTR ips32
; /* can be NULL to omit */
68 LPCSTR ips32_tmodel
; /* can be NULL to omit */
69 LPCSTR progid
; /* can be NULL to omit */
70 LPCSTR viprogid
; /* can be NULL to omit */
71 LPCSTR progid_extra
; /* can be NULL to omit */
74 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
);
75 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
);
77 struct regsvr_mediatype_parsing
79 CLSID
const *majortype
; /* NULL for end of list */
81 LPCSTR line
[11]; /* NULL for end of list */
84 static HRESULT
register_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
);
85 static HRESULT
unregister_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
);
87 struct regsvr_mediatype_extension
89 CLSID
const *majortype
; /* NULL for end of list */
96 CLSID
const *majortype
; /* NULL for end of list */
103 DWORD flags
; /* 0xFFFFFFFF for end of list */
104 struct mediatype mediatypes
[11];
109 CLSID
const *clsid
; /* NULL for end of list */
110 CLSID
const *category
;
116 static HRESULT
register_mediatypes_extension(struct regsvr_mediatype_extension
const *list
);
117 static HRESULT
unregister_mediatypes_extension(struct regsvr_mediatype_extension
const *list
);
119 static HRESULT
register_filters(struct regsvr_filter
const *list
);
120 static HRESULT
unregister_filters(struct regsvr_filter
const *list
);
122 /***********************************************************************
123 * static string constants
125 static WCHAR
const interface_keyname
[10] = {
126 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
127 static WCHAR
const base_ifa_keyname
[14] = {
128 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
130 static WCHAR
const num_methods_keyname
[11] = {
131 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
132 static WCHAR
const ps_clsid_keyname
[15] = {
133 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
135 static WCHAR
const ps_clsid32_keyname
[17] = {
136 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
137 'i', 'd', '3', '2', 0 };
138 static WCHAR
const clsid_keyname
[6] = {
139 'C', 'L', 'S', 'I', 'D', 0 };
140 static WCHAR
const curver_keyname
[7] = {
141 'C', 'u', 'r', 'V', 'e', 'r', 0 };
142 static WCHAR
const ips_keyname
[13] = {
143 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
145 static WCHAR
const ips32_keyname
[15] = {
146 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
148 static WCHAR
const progid_keyname
[7] = {
149 'P', 'r', 'o', 'g', 'I', 'D', 0 };
150 static WCHAR
const viprogid_keyname
[25] = {
151 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
152 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
154 static char const tmodel_valuename
[] = "ThreadingModel";
155 static WCHAR
const mediatype_name
[11] = {
156 'M', 'e', 'd', 'i', 'a', ' ', 'T', 'y', 'p', 'e', 0 };
157 static WCHAR
const subtype_valuename
[8] = {
158 'S', 'u', 'b', 't', 'y', 'p', 'e', 0 };
159 static WCHAR
const sourcefilter_valuename
[14] = {
160 'S', 'o', 'u', 'r', 'c', 'e', ' ', 'F', 'i', 'l', 't', 'e', 'r', 0 };
161 static WCHAR
const extensions_keyname
[11] = {
162 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', 0 };
164 /***********************************************************************
165 * static helper functions
167 static LONG
register_key_guid(HKEY base
, WCHAR
const *name
, GUID
const *guid
);
168 static LONG
register_key_defvalueW(HKEY base
, WCHAR
const *name
,
170 static LONG
register_key_defvalueA(HKEY base
, WCHAR
const *name
,
172 static LONG
register_progid(WCHAR
const *clsid
,
173 char const *progid
, char const *curver_progid
,
174 char const *name
, char const *extra
);
176 /***********************************************************************
177 * register_interfaces
179 static HRESULT
register_interfaces(struct regsvr_interface
const *list
)
181 LONG res
= ERROR_SUCCESS
;
184 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, interface_keyname
, 0, NULL
, 0,
185 KEY_READ
| KEY_WRITE
, NULL
, &interface_key
, NULL
);
186 if (res
!= ERROR_SUCCESS
) goto error_return
;
188 for (; res
== ERROR_SUCCESS
&& list
->iid
; ++list
) {
192 StringFromGUID2(list
->iid
, buf
, 39);
193 res
= RegCreateKeyExW(interface_key
, buf
, 0, NULL
, 0,
194 KEY_READ
| KEY_WRITE
, NULL
, &iid_key
, NULL
);
195 if (res
!= ERROR_SUCCESS
) goto error_close_interface_key
;
198 res
= RegSetValueExA(iid_key
, NULL
, 0, REG_SZ
,
199 (CONST BYTE
*)(list
->name
),
200 strlen(list
->name
) + 1);
201 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
204 if (list
->base_iid
) {
205 res
= register_key_guid(iid_key
, base_ifa_keyname
, list
->base_iid
);
206 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
209 if (0 <= list
->num_methods
) {
210 static WCHAR
const fmt
[3] = { '%', 'd', 0 };
213 res
= RegCreateKeyExW(iid_key
, num_methods_keyname
, 0, NULL
, 0,
214 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
215 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
217 wsprintfW(buf
, fmt
, list
->num_methods
);
218 res
= RegSetValueExW(key
, NULL
, 0, REG_SZ
,
220 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
223 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
226 if (list
->ps_clsid
) {
227 res
= register_key_guid(iid_key
, ps_clsid_keyname
, list
->ps_clsid
);
228 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
231 if (list
->ps_clsid32
) {
232 res
= register_key_guid(iid_key
, ps_clsid32_keyname
, list
->ps_clsid32
);
233 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
237 RegCloseKey(iid_key
);
240 error_close_interface_key
:
241 RegCloseKey(interface_key
);
243 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
246 /***********************************************************************
247 * unregister_interfaces
249 static HRESULT
unregister_interfaces(struct regsvr_interface
const *list
)
251 LONG res
= ERROR_SUCCESS
;
254 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, interface_keyname
, 0,
255 KEY_READ
| KEY_WRITE
, &interface_key
);
256 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
257 if (res
!= ERROR_SUCCESS
) goto error_return
;
259 for (; res
== ERROR_SUCCESS
&& list
->iid
; ++list
) {
262 StringFromGUID2(list
->iid
, buf
, 39);
263 res
= RegDeleteTreeW(interface_key
, buf
);
264 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
267 RegCloseKey(interface_key
);
269 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
272 /***********************************************************************
275 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
)
277 LONG res
= ERROR_SUCCESS
;
280 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
281 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
282 if (res
!= ERROR_SUCCESS
) goto error_return
;
284 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
288 StringFromGUID2(list
->clsid
, buf
, 39);
289 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
290 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
291 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
294 res
= RegSetValueExA(clsid_key
, NULL
, 0, REG_SZ
,
295 (CONST BYTE
*)(list
->name
),
296 strlen(list
->name
) + 1);
297 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
301 res
= register_key_defvalueA(clsid_key
, ips_keyname
, list
->ips
);
302 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
308 res
= RegCreateKeyExW(clsid_key
, ips32_keyname
, 0, NULL
, 0,
309 KEY_READ
| KEY_WRITE
, NULL
,
311 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
313 res
= RegSetValueExA(ips32_key
, NULL
, 0, REG_SZ
,
314 (CONST BYTE
*)list
->ips32
,
315 lstrlenA(list
->ips32
) + 1);
316 if (res
== ERROR_SUCCESS
&& list
->ips32_tmodel
)
317 res
= RegSetValueExA(ips32_key
, tmodel_valuename
, 0, REG_SZ
,
318 (CONST BYTE
*)list
->ips32_tmodel
,
319 strlen(list
->ips32_tmodel
) + 1);
320 RegCloseKey(ips32_key
);
321 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
325 res
= register_key_defvalueA(clsid_key
, progid_keyname
,
327 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
329 res
= register_progid(buf
, list
->progid
, NULL
,
330 list
->name
, list
->progid_extra
);
331 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
334 if (list
->viprogid
) {
335 res
= register_key_defvalueA(clsid_key
, viprogid_keyname
,
337 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
339 res
= register_progid(buf
, list
->viprogid
, list
->progid
,
340 list
->name
, list
->progid_extra
);
341 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
344 error_close_clsid_key
:
345 RegCloseKey(clsid_key
);
348 error_close_coclass_key
:
349 RegCloseKey(coclass_key
);
351 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
354 /***********************************************************************
355 * unregister_coclasses
357 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
)
359 LONG res
= ERROR_SUCCESS
;
362 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
363 KEY_READ
| KEY_WRITE
, &coclass_key
);
364 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
365 if (res
!= ERROR_SUCCESS
) goto error_return
;
367 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
370 StringFromGUID2(list
->clsid
, buf
, 39);
371 res
= RegDeleteTreeW(coclass_key
, buf
);
372 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
373 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
376 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->progid
);
377 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
378 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
381 if (list
->viprogid
) {
382 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->viprogid
);
383 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
384 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
388 error_close_coclass_key
:
389 RegCloseKey(coclass_key
);
391 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
394 /***********************************************************************
395 * register_mediatypes_parsing
397 static HRESULT
register_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
)
399 LONG res
= ERROR_SUCCESS
;
404 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0, NULL
, 0,
405 KEY_READ
| KEY_WRITE
, NULL
, &mediatype_key
, NULL
);
406 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
408 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
409 HKEY majortype_key
= NULL
;
410 HKEY subtype_key
= NULL
;
412 StringFromGUID2(list
->majortype
, buf
, 39);
413 res
= RegCreateKeyExW(mediatype_key
, buf
, 0, NULL
, 0,
414 KEY_READ
| KEY_WRITE
, NULL
, &majortype_key
, NULL
);
415 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
417 StringFromGUID2(list
->subtype
, buf
, 39);
418 res
= RegCreateKeyExW(majortype_key
, buf
, 0, NULL
, 0,
419 KEY_READ
| KEY_WRITE
, NULL
, &subtype_key
, NULL
);
420 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
422 StringFromGUID2(&CLSID_AsyncReader
, buf
, 39);
423 res
= RegSetValueExW(subtype_key
, sourcefilter_valuename
, 0, REG_SZ
, (CONST BYTE
*)buf
,
424 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
425 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
427 for(i
= 0; list
->line
[i
]; i
++) {
429 wsprintfA(buffer
, "%d", i
);
430 res
= RegSetValueExA(subtype_key
, buffer
, 0, REG_SZ
, (CONST BYTE
*)list
->line
[i
],
431 lstrlenA(list
->line
[i
]));
432 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
437 RegCloseKey(majortype_key
);
439 RegCloseKey(subtype_key
);
442 RegCloseKey(mediatype_key
);
444 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
447 /***********************************************************************
448 * register_mediatypes_extension
450 static HRESULT
register_mediatypes_extension(struct regsvr_mediatype_extension
const *list
)
452 LONG res
= ERROR_SUCCESS
;
454 HKEY extensions_root_key
= NULL
;
457 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0, NULL
, 0,
458 KEY_READ
| KEY_WRITE
, NULL
, &mediatype_key
, NULL
);
459 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
461 res
= RegCreateKeyExW(mediatype_key
, extensions_keyname
, 0, NULL
, 0,
462 KEY_READ
| KEY_WRITE
, NULL
, &extensions_root_key
, NULL
);
463 if (res
!= ERROR_SUCCESS
) goto error_return
;
465 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
468 res
= RegCreateKeyExA(extensions_root_key
, list
->extension
, 0, NULL
, 0,
469 KEY_READ
| KEY_WRITE
, NULL
, &extension_key
, NULL
);
470 if (res
!= ERROR_SUCCESS
) break;
472 StringFromGUID2(list
->majortype
, buf
, 39);
473 res
= RegSetValueExW(extension_key
, mediatype_name
, 0, REG_SZ
, (CONST BYTE
*)buf
,
474 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
475 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
477 StringFromGUID2(list
->subtype
, buf
, 39);
478 res
= RegSetValueExW(extension_key
, subtype_valuename
, 0, REG_SZ
, (CONST BYTE
*)buf
,
479 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
480 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
482 StringFromGUID2(&CLSID_AsyncReader
, buf
, 39);
483 res
= RegSetValueExW(extension_key
, sourcefilter_valuename
, 0, REG_SZ
, (CONST BYTE
*)buf
,
484 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
485 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
488 RegCloseKey(extension_key
);
492 RegCloseKey(mediatype_key
);
493 if (extensions_root_key
)
494 RegCloseKey(extensions_root_key
);
496 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
499 /***********************************************************************
500 * unregister_mediatypes_parsing
502 static HRESULT
unregister_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
)
509 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0,
510 KEY_READ
| KEY_WRITE
, &mediatype_key
);
511 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
512 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
514 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
515 StringFromGUID2(list
->majortype
, buf
, 39);
516 res
= RegOpenKeyExW(mediatype_key
, buf
, 0,
517 KEY_READ
| KEY_WRITE
, &majortype_key
);
518 if (res
== ERROR_FILE_NOT_FOUND
) {
522 if (res
!= ERROR_SUCCESS
) break;
524 StringFromGUID2(list
->subtype
, buf
, 39);
525 res
= RegDeleteTreeW(majortype_key
, buf
);
526 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
528 /* Removed majortype key if there is no more subtype key */
529 res
= RegDeleteKeyW(majortype_key
, 0);
530 if (res
== ERROR_ACCESS_DENIED
) res
= ERROR_SUCCESS
;
532 RegCloseKey(majortype_key
);
535 RegCloseKey(mediatype_key
);
537 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
540 /***********************************************************************
541 * unregister_mediatypes_extension
543 static HRESULT
unregister_mediatypes_extension(struct regsvr_mediatype_extension
const *list
)
547 HKEY extensions_root_key
= NULL
;
549 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0,
550 KEY_READ
| KEY_WRITE
, &mediatype_key
);
551 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
552 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
554 res
= RegOpenKeyExW(mediatype_key
, extensions_keyname
, 0,
555 KEY_READ
| KEY_WRITE
, &extensions_root_key
);
556 if (res
== ERROR_FILE_NOT_FOUND
)
558 else if (res
== ERROR_SUCCESS
)
559 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
560 res
= RegDeleteTreeA(extensions_root_key
, list
->extension
);
561 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
564 RegCloseKey(mediatype_key
);
565 if (extensions_root_key
)
566 RegCloseKey(extensions_root_key
);
568 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
571 /***********************************************************************
574 static HRESULT
register_filters(struct regsvr_filter
const *list
)
577 IFilterMapper2
* pFM2
= NULL
;
580 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pFM2
);
583 for (; SUCCEEDED(hr
) && list
->clsid
; ++list
) {
585 REGFILTERPINS2
* prfp2
;
588 for (i
= 0; list
->pins
[i
].flags
!= 0xFFFFFFFF; i
++) ;
590 rf2
.dwMerit
= list
->merit
;
592 rf2
.u
.s1
.rgPins2
= prfp2
= CoTaskMemAlloc(i
*sizeof(REGFILTERPINS2
));
597 for (i
= 0; list
->pins
[i
].flags
!= 0xFFFFFFFF; i
++) {
598 REGPINTYPES
* lpMediatype
;
602 for (nbmt
= 0; list
->pins
[i
].mediatypes
[nbmt
].majortype
; nbmt
++) ;
603 /* Allocate a single buffer for regpintypes struct and clsids */
604 lpMediatype
= CoTaskMemAlloc(nbmt
*(sizeof(REGPINTYPES
) + 2*sizeof(CLSID
)));
609 lpClsid
= (CLSID
*) (lpMediatype
+ nbmt
);
610 for (j
= 0; j
< nbmt
; j
++) {
611 (lpMediatype
+ j
)->clsMajorType
= lpClsid
+ j
*2;
612 memcpy(lpClsid
+ j
*2, list
->pins
[i
].mediatypes
[j
].majortype
, sizeof(CLSID
));
613 (lpMediatype
+ j
)->clsMinorType
= lpClsid
+ j
*2 + 1;
614 if (list
->pins
[i
].mediatypes
[j
].subtype
)
615 memcpy(lpClsid
+ j
*2 + 1, list
->pins
[i
].mediatypes
[j
].subtype
, sizeof(CLSID
));
617 /* Subtype are often a combination of major type + fourcc/tag */
618 memcpy(lpClsid
+ j
*2 + 1, list
->pins
[i
].mediatypes
[j
].majortype
, sizeof(CLSID
));
619 *(DWORD
*)(lpClsid
+ j
*2 + 1) = list
->pins
[i
].mediatypes
[j
].fourcc
;
622 prfp2
[i
].dwFlags
= list
->pins
[i
].flags
;
623 prfp2
[i
].cInstances
= 0;
624 prfp2
[i
].nMediaTypes
= j
;
625 prfp2
[i
].lpMediaType
= lpMediatype
;
626 prfp2
[i
].nMediums
= 0;
627 prfp2
[i
].lpMedium
= NULL
;
628 prfp2
[i
].clsPinCategory
= NULL
;
632 ERR("failed to register with hresult 0x%x\n", hr
);
633 CoTaskMemFree(prfp2
);
637 hr
= IFilterMapper2_RegisterFilter(pFM2
, list
->clsid
, list
->name
, NULL
, list
->category
, NULL
, &rf2
);
640 CoTaskMemFree((REGPINTYPES
*)prfp2
[i
-1].lpMediaType
);
643 CoTaskMemFree(prfp2
);
648 IFilterMapper2_Release(pFM2
);
655 /***********************************************************************
658 static HRESULT
unregister_filters(struct regsvr_filter
const *list
)
661 IFilterMapper2
* pFM2
;
665 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pFM2
);
668 for (; SUCCEEDED(hr
) && list
->clsid
; ++list
)
669 hr
= IFilterMapper2_UnregisterFilter(pFM2
, list
->category
, NULL
, list
->clsid
);
670 IFilterMapper2_Release(pFM2
);
678 /***********************************************************************
681 static LONG
register_key_guid(HKEY base
, WCHAR
const *name
, GUID
const *guid
)
685 StringFromGUID2(guid
, buf
, 39);
686 return register_key_defvalueW(base
, name
, buf
);
689 /***********************************************************************
690 * regsvr_key_defvalueW
692 static LONG
register_key_defvalueW(
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
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (CONST BYTE
*)value
,
704 (lstrlenW(value
) + 1) * sizeof(WCHAR
));
709 /***********************************************************************
710 * regsvr_key_defvalueA
712 static LONG
register_key_defvalueA(
720 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
721 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
722 if (res
!= ERROR_SUCCESS
) return res
;
723 res
= RegSetValueExA(key
, NULL
, 0, REG_SZ
, (CONST BYTE
*)value
,
724 lstrlenA(value
) + 1);
729 /***********************************************************************
732 static LONG
register_progid(
735 char const *curver_progid
,
742 res
= RegCreateKeyExA(HKEY_CLASSES_ROOT
, progid
, 0,
743 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
745 if (res
!= ERROR_SUCCESS
) return res
;
748 res
= RegSetValueExA(progid_key
, NULL
, 0, REG_SZ
,
749 (CONST BYTE
*)name
, strlen(name
) + 1);
750 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
754 res
= register_key_defvalueW(progid_key
, clsid_keyname
, clsid
);
755 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
759 res
= register_key_defvalueA(progid_key
, curver_keyname
,
761 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
767 res
= RegCreateKeyExA(progid_key
, extra
, 0,
768 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
770 if (res
== ERROR_SUCCESS
)
771 RegCloseKey(extra_key
);
774 error_close_progid_key
:
775 RegCloseKey(progid_key
);
779 static GUID
const CLSID_PSFactoryBuffer
= {
780 0x92a3a302, 0xda7c, 0x4a1f, {0xba,0x7e,0x18,0x02,0xbb,0x5d,0x2d,0x02} };
782 /***********************************************************************
785 static struct regsvr_coclass
const coclass_list
[] = {
786 { &CLSID_FilterGraph
,
792 { &CLSID_FilterGraphNoThread
,
798 { &CLSID_FilterMapper
,
804 { &CLSID_FilterMapper2
,
810 { &CLSID_SystemClock
,
816 { &CLSID_MemoryAllocator
,
822 { &CLSID_SeekingPassThru
,
828 { &CLSID_AsyncReader
,
829 "File Source Filter",
834 { &CLSID_AviSplitter
,
840 { &CLSID_MPEG1Splitter
,
841 "MPEG-I Stream Splitter",
852 { &CLSID_DSoundRender
,
853 "DirectSound Audio Renderer",
858 { &CLSID_NullRenderer
,
864 { &CLSID_VideoRenderer
,
870 { &CLSID_VideoRendererDefault
,
871 "Default Video Renderer",
888 { NULL
} /* list terminator */
891 /***********************************************************************
895 static struct regsvr_interface
const interface_list
[] = {
901 &CLSID_PSFactoryBuffer
903 { &IID_IFilterGraph2
,
908 &CLSID_PSFactoryBuffer
910 { &IID_IFilterMapper
,
915 &CLSID_PSFactoryBuffer
917 { &IID_IFilterMapper2
,
922 &CLSID_PSFactoryBuffer
925 { &IID_SeekingPassThru,
930 &CLSID_PSFactoryBuffer
937 &CLSID_PSFactoryBuffer
944 &CLSID_PSFactoryBuffer
946 { NULL
} /* list terminator */
949 /***********************************************************************
953 static struct regsvr_mediatype_parsing
const mediatype_parsing_list
[] = {
956 { "0,4,,52494646,8,4,,41564920",
960 &MEDIASUBTYPE_MPEG1System
,
961 { "0, 16, FFFFFFFFF100010001800001FFFFFFFF, 000001BA2100010001800001000001BB",
965 &MEDIASUBTYPE_MPEG1VideoCD
,
966 { "0, 4, , 52494646, 8, 8, , 43445841666D7420, 36, 20, FFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFF, 646174610000000000FFFFFFFFFFFFFFFFFFFF00",
970 &MEDIASUBTYPE_MPEG1Video
,
971 { "0, 4, , 000001B3",
975 &MEDIASUBTYPE_MPEG1Audio
,
976 { "0, 2, FFE0, FFE0",
977 "0, 10, FFFFFF00000080808080, 494433000000000000",
981 &MEDIASUBTYPE_QTMovie
,
982 { "4, 4, , 6d646174",
988 { "0,4,,52494646,8,4,,57415645",
998 { "0,4,,464f524d,8,4,,41494646",
999 "0,4,,464f524d,8,4,,41494643",
1002 { &MEDIATYPE_Stream
,
1008 { &MEDIATYPE_Stream
,
1010 { "0,4,,52494646,8,4,,524D4944",
1014 { NULL
} /* list terminator */
1017 /***********************************************************************
1021 static struct regsvr_mediatype_extension
const mediatype_extension_list
[] = {
1022 { &MEDIATYPE_Stream
,
1023 &MEDIASUBTYPE_MPEG1Audio
,
1026 { NULL
} /* list terminator */
1029 /***********************************************************************
1033 static struct regsvr_filter
const filter_list
[] = {
1034 { &CLSID_AviSplitter
,
1035 &CLSID_LegacyAmFilterCategory
,
1036 {'A','V','I',' ','S','p','l','i','t','t','e','r',0},
1039 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_Avi
},
1043 { REG_PINFLAG_B_OUTPUT
,
1044 { { &MEDIATYPE_Video
, &GUID_NULL
},
1051 { &CLSID_MPEG1Splitter
,
1052 &CLSID_LegacyAmFilterCategory
,
1053 {'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0},
1056 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Audio
},
1057 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Video
},
1058 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1System
},
1059 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1VideoCD
},
1063 { REG_PINFLAG_B_OUTPUT
,
1064 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1Packet
},
1065 { &MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1AudioPayload
},
1069 { REG_PINFLAG_B_OUTPUT
,
1070 { { &MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Packet
},
1071 { &MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Payload
},
1078 { &CLSID_NullRenderer
,
1079 &CLSID_LegacyAmFilterCategory
,
1080 {'N','u','l','l',' ','R','e','n','d','e','r','e','r',0},
1082 { { REG_PINFLAG_B_RENDERER
,
1083 { { &MEDIATYPE_NULL
, &GUID_NULL
},
1090 { &CLSID_VideoRenderer
,
1091 &CLSID_LegacyAmFilterCategory
,
1092 {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0},
1094 { { REG_PINFLAG_B_RENDERER
,
1095 { { &MEDIATYPE_Video
, &GUID_NULL
},
1102 { &CLSID_VideoRendererDefault
,
1103 &CLSID_LegacyAmFilterCategory
,
1104 {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0},
1106 { { REG_PINFLAG_B_RENDERER
,
1107 { { &MEDIATYPE_Video
, &GUID_NULL
},
1114 { &CLSID_DSoundRender
,
1115 &CLSID_LegacyAmFilterCategory
,
1116 {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0},
1118 { { REG_PINFLAG_B_RENDERER
,
1119 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_PCM
},
1120 /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */
1128 &CLSID_LegacyAmFilterCategory
,
1129 {'A','V','I',' ','D','e','c','o','m','p','r','e','s','s','o','r',0},
1132 { { &MEDIATYPE_Video
, &GUID_NULL
},
1136 { REG_PINFLAG_B_OUTPUT
,
1137 { { &MEDIATYPE_Video
, &GUID_NULL
},
1144 { &CLSID_AsyncReader
,
1145 &CLSID_LegacyAmFilterCategory
,
1146 {'F','i','l','e',' ','S','o','u','r','c','e',' ','(','A','s','y','n','c','.',')',0},
1148 { { REG_PINFLAG_B_OUTPUT
,
1149 { { &MEDIATYPE_Stream
, &GUID_NULL
},
1156 { &CLSID_ACMWrapper
,
1157 &CLSID_LegacyAmFilterCategory
,
1158 {'A','C','M',' ','W','r','a','p','p','e','r',0},
1161 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1165 { REG_PINFLAG_B_OUTPUT
,
1166 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1173 { &CLSID_WAVEParser
,
1174 &CLSID_LegacyAmFilterCategory
,
1175 {'W','a','v','e',' ','P','a','r','s','e','r',0},
1178 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_WAVE
},
1179 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_AU
},
1180 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_AIFF
},
1184 { REG_PINFLAG_B_OUTPUT
,
1185 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1192 { NULL
} /* list terminator */
1195 /***********************************************************************
1196 * DllRegisterServer (QUARTZ.@)
1198 HRESULT WINAPI
DllRegisterServer(void)
1204 hr
= register_coclasses(coclass_list
);
1206 hr
= register_interfaces(interface_list
);
1208 hr
= register_mediatypes_parsing(mediatype_parsing_list
);
1210 hr
= register_mediatypes_extension(mediatype_extension_list
);
1212 hr
= register_filters(filter_list
);
1216 /***********************************************************************
1217 * DllUnregisterServer (QUARTZ.@)
1219 HRESULT WINAPI
DllUnregisterServer(void)
1225 hr
= unregister_filters(filter_list
);
1227 hr
= unregister_coclasses(coclass_list
);
1229 hr
= unregister_interfaces(interface_list
);
1231 hr
= unregister_mediatypes_parsing(mediatype_parsing_list
);
1233 hr
= unregister_mediatypes_extension(mediatype_extension_list
);