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 WIN32_NO_STATUS
23 #define COM_NO_WINDOWS_H
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
36 //#include "winerror.h"
43 #include <wine/debug.h>
44 #include <wine/unicode.h>
46 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
49 * Near the bottom of this file are the exported DllRegisterServer and
50 * DllUnregisterServer, which make all this worthwhile.
53 /***********************************************************************
54 * interface for self-registering
56 struct regsvr_interface
58 IID
const *iid
; /* NULL for end of list */
59 LPCSTR name
; /* can be NULL to omit */
60 IID
const *base_iid
; /* can be NULL to omit */
61 int num_methods
; /* can be <0 to omit */
62 CLSID
const *ps_clsid
; /* can be NULL to omit */
63 CLSID
const *ps_clsid32
; /* can be NULL to omit */
66 static HRESULT
register_interfaces(struct regsvr_interface
const *list
);
67 static HRESULT
unregister_interfaces(struct regsvr_interface
const *list
);
71 CLSID
const *clsid
; /* NULL for end of list */
72 LPCSTR name
; /* can be NULL to omit */
73 LPCSTR ips
; /* can be NULL to omit */
74 LPCSTR ips32
; /* can be NULL to omit */
75 LPCSTR ips32_tmodel
; /* can be NULL to omit */
76 LPCSTR progid
; /* can be NULL to omit */
77 LPCSTR viprogid
; /* can be NULL to omit */
78 LPCSTR progid_extra
; /* can be NULL to omit */
81 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
);
82 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
);
84 struct regsvr_mediatype_parsing
86 CLSID
const *majortype
; /* NULL for end of list */
88 LPCSTR line
[11]; /* NULL for end of list */
91 static HRESULT
register_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
);
92 static HRESULT
unregister_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
);
94 struct regsvr_mediatype_extension
96 CLSID
const *majortype
; /* NULL for end of list */
103 CLSID
const *majortype
; /* NULL for end of list */
104 CLSID
const *subtype
;
110 DWORD flags
; /* 0xFFFFFFFF for end of list */
111 struct mediatype mediatypes
[11];
116 CLSID
const *clsid
; /* NULL for end of list */
117 CLSID
const *category
;
123 static HRESULT
register_mediatypes_extension(struct regsvr_mediatype_extension
const *list
);
124 static HRESULT
unregister_mediatypes_extension(struct regsvr_mediatype_extension
const *list
);
126 static HRESULT
register_filters(struct regsvr_filter
const *list
);
127 static HRESULT
unregister_filters(struct regsvr_filter
const *list
);
129 /***********************************************************************
130 * static string constants
132 static const WCHAR interface_keyname
[] = {
133 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
134 static const WCHAR base_ifa_keyname
[] = {
135 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
137 static const WCHAR num_methods_keyname
[] = {
138 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
139 static const WCHAR ps_clsid_keyname
[] = {
140 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
142 static const WCHAR ps_clsid32_keyname
[] = {
143 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
144 'i', 'd', '3', '2', 0 };
145 static const WCHAR clsid_keyname
[] = {
146 'C', 'L', 'S', 'I', 'D', 0 };
147 static const WCHAR curver_keyname
[] = {
148 'C', 'u', 'r', 'V', 'e', 'r', 0 };
149 static const WCHAR ips_keyname
[] = {
150 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
152 static const WCHAR ips32_keyname
[] = {
153 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
155 static const WCHAR progid_keyname
[] = {
156 'P', 'r', 'o', 'g', 'I', 'D', 0 };
157 static const WCHAR viprogid_keyname
[] = {
158 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
159 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
161 static const char tmodel_valuename
[] = "ThreadingModel";
162 static const WCHAR mediatype_name
[] = {
163 'M', 'e', 'd', 'i', 'a', ' ', 'T', 'y', 'p', 'e', 0 };
164 static const WCHAR subtype_valuename
[] = {
165 'S', 'u', 'b', 't', 'y', 'p', 'e', 0 };
166 static const WCHAR sourcefilter_valuename
[] = {
167 'S', 'o', 'u', 'r', 'c', 'e', ' ', 'F', 'i', 'l', 't', 'e', 'r', 0 };
168 static const WCHAR extensions_keyname
[] = {
169 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', 0 };
171 /***********************************************************************
172 * static helper functions
174 static LONG
register_key_guid(HKEY base
, WCHAR
const *name
, GUID
const *guid
);
175 static LONG
register_key_defvalueW(HKEY base
, WCHAR
const *name
,
177 static LONG
register_key_defvalueA(HKEY base
, WCHAR
const *name
,
179 static LONG
register_progid(WCHAR
const *clsid
,
180 char const *progid
, char const *curver_progid
,
181 char const *name
, char const *extra
);
183 /***********************************************************************
184 * register_interfaces
186 static HRESULT
register_interfaces(struct regsvr_interface
const *list
)
188 LONG res
= ERROR_SUCCESS
;
191 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, interface_keyname
, 0, NULL
, 0,
192 KEY_READ
| KEY_WRITE
, NULL
, &interface_key
, NULL
);
193 if (res
!= ERROR_SUCCESS
) goto error_return
;
195 for (; res
== ERROR_SUCCESS
&& list
->iid
; ++list
) {
199 StringFromGUID2(list
->iid
, buf
, 39);
200 res
= RegCreateKeyExW(interface_key
, buf
, 0, NULL
, 0,
201 KEY_READ
| KEY_WRITE
, NULL
, &iid_key
, NULL
);
202 if (res
!= ERROR_SUCCESS
) goto error_close_interface_key
;
205 res
= RegSetValueExA(iid_key
, NULL
, 0, REG_SZ
,
206 (CONST BYTE
*)(list
->name
),
207 strlen(list
->name
) + 1);
208 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
211 if (list
->base_iid
) {
212 res
= register_key_guid(iid_key
, base_ifa_keyname
, list
->base_iid
);
213 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
216 if (0 <= list
->num_methods
) {
217 static const WCHAR fmt
[] = { '%', 'd', 0 };
220 res
= RegCreateKeyExW(iid_key
, num_methods_keyname
, 0, NULL
, 0,
221 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
222 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
224 sprintfW(buf
, fmt
, list
->num_methods
);
225 res
= RegSetValueExW(key
, NULL
, 0, REG_SZ
,
227 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
230 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
233 if (list
->ps_clsid
) {
234 res
= register_key_guid(iid_key
, ps_clsid_keyname
, list
->ps_clsid
);
235 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
238 if (list
->ps_clsid32
) {
239 res
= register_key_guid(iid_key
, ps_clsid32_keyname
, list
->ps_clsid32
);
240 if (res
!= ERROR_SUCCESS
) goto error_close_iid_key
;
244 RegCloseKey(iid_key
);
247 error_close_interface_key
:
248 RegCloseKey(interface_key
);
250 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
253 /***********************************************************************
254 * unregister_interfaces
256 static HRESULT
unregister_interfaces(struct regsvr_interface
const *list
)
258 LONG res
= ERROR_SUCCESS
;
261 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, interface_keyname
, 0,
262 KEY_READ
| KEY_WRITE
, &interface_key
);
263 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
264 if (res
!= ERROR_SUCCESS
) goto error_return
;
266 for (; res
== ERROR_SUCCESS
&& list
->iid
; ++list
) {
269 StringFromGUID2(list
->iid
, buf
, 39);
270 res
= RegDeleteTreeW(interface_key
, buf
);
271 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
274 RegCloseKey(interface_key
);
276 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
279 /***********************************************************************
282 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
)
284 LONG res
= ERROR_SUCCESS
;
287 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
288 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
289 if (res
!= ERROR_SUCCESS
) goto error_return
;
291 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
295 StringFromGUID2(list
->clsid
, buf
, 39);
296 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
297 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
298 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
301 res
= RegSetValueExA(clsid_key
, NULL
, 0, REG_SZ
,
302 (CONST BYTE
*)(list
->name
),
303 strlen(list
->name
) + 1);
304 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
308 res
= register_key_defvalueA(clsid_key
, ips_keyname
, list
->ips
);
309 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
315 res
= RegCreateKeyExW(clsid_key
, ips32_keyname
, 0, NULL
, 0,
316 KEY_READ
| KEY_WRITE
, NULL
,
318 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
320 res
= RegSetValueExA(ips32_key
, NULL
, 0, REG_SZ
,
321 (CONST BYTE
*)list
->ips32
,
322 lstrlenA(list
->ips32
) + 1);
323 if (res
== ERROR_SUCCESS
&& list
->ips32_tmodel
)
324 res
= RegSetValueExA(ips32_key
, tmodel_valuename
, 0, REG_SZ
,
325 (CONST BYTE
*)list
->ips32_tmodel
,
326 strlen(list
->ips32_tmodel
) + 1);
327 RegCloseKey(ips32_key
);
328 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
332 res
= register_key_defvalueA(clsid_key
, progid_keyname
,
334 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
336 res
= register_progid(buf
, list
->progid
, NULL
,
337 list
->name
, list
->progid_extra
);
338 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
341 if (list
->viprogid
) {
342 res
= register_key_defvalueA(clsid_key
, viprogid_keyname
,
344 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
346 res
= register_progid(buf
, list
->viprogid
, list
->progid
,
347 list
->name
, list
->progid_extra
);
348 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
351 error_close_clsid_key
:
352 RegCloseKey(clsid_key
);
355 error_close_coclass_key
:
356 RegCloseKey(coclass_key
);
358 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
361 /***********************************************************************
362 * unregister_coclasses
364 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
)
366 LONG res
= ERROR_SUCCESS
;
369 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
370 KEY_READ
| KEY_WRITE
, &coclass_key
);
371 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
372 if (res
!= ERROR_SUCCESS
) goto error_return
;
374 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
377 StringFromGUID2(list
->clsid
, buf
, 39);
378 res
= RegDeleteTreeW(coclass_key
, buf
);
379 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
380 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
383 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->progid
);
384 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
385 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
388 if (list
->viprogid
) {
389 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->viprogid
);
390 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
391 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
395 error_close_coclass_key
:
396 RegCloseKey(coclass_key
);
398 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
401 /***********************************************************************
402 * register_mediatypes_parsing
404 static HRESULT
register_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
)
406 LONG res
= ERROR_SUCCESS
;
411 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0, NULL
, 0,
412 KEY_READ
| KEY_WRITE
, NULL
, &mediatype_key
, NULL
);
413 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
415 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
416 HKEY majortype_key
= NULL
;
417 HKEY subtype_key
= NULL
;
419 StringFromGUID2(list
->majortype
, buf
, 39);
420 res
= RegCreateKeyExW(mediatype_key
, buf
, 0, NULL
, 0,
421 KEY_READ
| KEY_WRITE
, NULL
, &majortype_key
, NULL
);
422 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
424 StringFromGUID2(list
->subtype
, buf
, 39);
425 res
= RegCreateKeyExW(majortype_key
, buf
, 0, NULL
, 0,
426 KEY_READ
| KEY_WRITE
, NULL
, &subtype_key
, NULL
);
427 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
429 StringFromGUID2(&CLSID_AsyncReader
, buf
, 39);
430 res
= RegSetValueExW(subtype_key
, sourcefilter_valuename
, 0, REG_SZ
, (CONST BYTE
*)buf
,
431 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
432 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
434 for(i
= 0; list
->line
[i
]; i
++) {
436 wsprintfA(buffer
, "%d", i
);
437 res
= RegSetValueExA(subtype_key
, buffer
, 0, REG_SZ
, (CONST BYTE
*)list
->line
[i
],
438 lstrlenA(list
->line
[i
]));
439 if (res
!= ERROR_SUCCESS
) goto error_close_keys
;
444 RegCloseKey(majortype_key
);
446 RegCloseKey(subtype_key
);
449 RegCloseKey(mediatype_key
);
451 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
454 /***********************************************************************
455 * register_mediatypes_extension
457 static HRESULT
register_mediatypes_extension(struct regsvr_mediatype_extension
const *list
)
459 LONG res
= ERROR_SUCCESS
;
461 HKEY extensions_root_key
= NULL
;
464 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0, NULL
, 0,
465 KEY_READ
| KEY_WRITE
, NULL
, &mediatype_key
, NULL
);
466 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
468 res
= RegCreateKeyExW(mediatype_key
, extensions_keyname
, 0, NULL
, 0,
469 KEY_READ
| KEY_WRITE
, NULL
, &extensions_root_key
, NULL
);
470 if (res
!= ERROR_SUCCESS
) goto error_return
;
472 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
475 res
= RegCreateKeyExA(extensions_root_key
, list
->extension
, 0, NULL
, 0,
476 KEY_READ
| KEY_WRITE
, NULL
, &extension_key
, NULL
);
477 if (res
!= ERROR_SUCCESS
) break;
479 StringFromGUID2(list
->majortype
, buf
, 39);
480 res
= RegSetValueExW(extension_key
, mediatype_name
, 0, REG_SZ
, (CONST BYTE
*)buf
,
481 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
482 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
484 StringFromGUID2(list
->subtype
, buf
, 39);
485 res
= RegSetValueExW(extension_key
, subtype_valuename
, 0, REG_SZ
, (CONST BYTE
*)buf
,
486 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
487 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
489 StringFromGUID2(&CLSID_AsyncReader
, buf
, 39);
490 res
= RegSetValueExW(extension_key
, sourcefilter_valuename
, 0, REG_SZ
, (CONST BYTE
*)buf
,
491 (lstrlenW(buf
) + 1) * sizeof(WCHAR
));
492 if (res
!= ERROR_SUCCESS
) goto error_close_key
;
495 RegCloseKey(extension_key
);
499 RegCloseKey(mediatype_key
);
500 if (extensions_root_key
)
501 RegCloseKey(extensions_root_key
);
503 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
506 /***********************************************************************
507 * unregister_mediatypes_parsing
509 static HRESULT
unregister_mediatypes_parsing(struct regsvr_mediatype_parsing
const *list
)
516 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0,
517 KEY_READ
| KEY_WRITE
, &mediatype_key
);
518 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
519 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
521 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
522 StringFromGUID2(list
->majortype
, buf
, 39);
523 res
= RegOpenKeyExW(mediatype_key
, buf
, 0,
524 KEY_READ
| KEY_WRITE
, &majortype_key
);
525 if (res
== ERROR_FILE_NOT_FOUND
) {
529 if (res
!= ERROR_SUCCESS
) break;
531 StringFromGUID2(list
->subtype
, buf
, 39);
532 res
= RegDeleteTreeW(majortype_key
, buf
);
533 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
535 /* Removed majortype key if there is no more subtype key */
536 res
= RegDeleteKeyW(majortype_key
, 0);
537 if (res
== ERROR_ACCESS_DENIED
) res
= ERROR_SUCCESS
;
539 RegCloseKey(majortype_key
);
542 RegCloseKey(mediatype_key
);
544 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
547 /***********************************************************************
548 * unregister_mediatypes_extension
550 static HRESULT
unregister_mediatypes_extension(struct regsvr_mediatype_extension
const *list
)
554 HKEY extensions_root_key
= NULL
;
556 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, mediatype_name
, 0,
557 KEY_READ
| KEY_WRITE
, &mediatype_key
);
558 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
559 if (res
!= ERROR_SUCCESS
) return HRESULT_FROM_WIN32(res
);
561 res
= RegOpenKeyExW(mediatype_key
, extensions_keyname
, 0,
562 KEY_READ
| KEY_WRITE
, &extensions_root_key
);
563 if (res
== ERROR_FILE_NOT_FOUND
)
565 else if (res
== ERROR_SUCCESS
)
566 for (; res
== ERROR_SUCCESS
&& list
->majortype
; ++list
) {
567 res
= RegDeleteTreeA(extensions_root_key
, list
->extension
);
568 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
571 RegCloseKey(mediatype_key
);
572 if (extensions_root_key
)
573 RegCloseKey(extensions_root_key
);
575 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
578 /***********************************************************************
581 static HRESULT
register_filters(struct regsvr_filter
const *list
)
584 IFilterMapper2
* pFM2
= NULL
;
587 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pFM2
);
590 for (; SUCCEEDED(hr
) && list
->clsid
; ++list
) {
592 REGFILTERPINS2
* prfp2
;
595 for (i
= 0; list
->pins
[i
].flags
!= 0xFFFFFFFF; i
++) ;
597 rf2
.dwMerit
= list
->merit
;
599 rf2
.u
.s2
.rgPins2
= prfp2
= CoTaskMemAlloc(i
*sizeof(REGFILTERPINS2
));
604 for (i
= 0; list
->pins
[i
].flags
!= 0xFFFFFFFF; i
++) {
605 REGPINTYPES
* lpMediatype
;
609 for (nbmt
= 0; list
->pins
[i
].mediatypes
[nbmt
].majortype
; nbmt
++) ;
610 /* Allocate a single buffer for regpintypes struct and clsids */
611 lpMediatype
= CoTaskMemAlloc(nbmt
*(sizeof(REGPINTYPES
) + 2*sizeof(CLSID
)));
616 lpClsid
= (CLSID
*) (lpMediatype
+ nbmt
);
617 for (j
= 0; j
< nbmt
; j
++) {
618 (lpMediatype
+ j
)->clsMajorType
= lpClsid
+ j
*2;
619 memcpy(lpClsid
+ j
*2, list
->pins
[i
].mediatypes
[j
].majortype
, sizeof(CLSID
));
620 (lpMediatype
+ j
)->clsMinorType
= lpClsid
+ j
*2 + 1;
621 if (list
->pins
[i
].mediatypes
[j
].subtype
)
622 memcpy(lpClsid
+ j
*2 + 1, list
->pins
[i
].mediatypes
[j
].subtype
, sizeof(CLSID
));
624 /* Subtype are often a combination of major type + fourcc/tag */
625 memcpy(lpClsid
+ j
*2 + 1, list
->pins
[i
].mediatypes
[j
].majortype
, sizeof(CLSID
));
626 *(DWORD
*)(lpClsid
+ j
*2 + 1) = list
->pins
[i
].mediatypes
[j
].fourcc
;
629 prfp2
[i
].dwFlags
= list
->pins
[i
].flags
;
630 prfp2
[i
].cInstances
= 0;
631 prfp2
[i
].nMediaTypes
= j
;
632 prfp2
[i
].lpMediaType
= lpMediatype
;
633 prfp2
[i
].nMediums
= 0;
634 prfp2
[i
].lpMedium
= NULL
;
635 prfp2
[i
].clsPinCategory
= NULL
;
639 ERR("failed to register with hresult 0x%x\n", hr
);
640 CoTaskMemFree(prfp2
);
644 hr
= IFilterMapper2_RegisterFilter(pFM2
, list
->clsid
, list
->name
, NULL
, list
->category
, NULL
, &rf2
);
647 CoTaskMemFree((REGPINTYPES
*)prfp2
[i
-1].lpMediaType
);
650 CoTaskMemFree(prfp2
);
655 IFilterMapper2_Release(pFM2
);
662 /***********************************************************************
665 static HRESULT
unregister_filters(struct regsvr_filter
const *list
)
668 IFilterMapper2
* pFM2
;
672 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pFM2
);
675 for (; SUCCEEDED(hr
) && list
->clsid
; ++list
)
676 hr
= IFilterMapper2_UnregisterFilter(pFM2
, list
->category
, NULL
, list
->clsid
);
677 IFilterMapper2_Release(pFM2
);
685 /***********************************************************************
688 static LONG
register_key_guid(HKEY base
, WCHAR
const *name
, GUID
const *guid
)
692 StringFromGUID2(guid
, buf
, 39);
693 return register_key_defvalueW(base
, name
, buf
);
696 /***********************************************************************
697 * regsvr_key_defvalueW
699 static LONG
register_key_defvalueW(
707 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
708 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
709 if (res
!= ERROR_SUCCESS
) return res
;
710 res
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (CONST BYTE
*)value
,
711 (lstrlenW(value
) + 1) * sizeof(WCHAR
));
716 /***********************************************************************
717 * regsvr_key_defvalueA
719 static LONG
register_key_defvalueA(
727 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
728 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
729 if (res
!= ERROR_SUCCESS
) return res
;
730 res
= RegSetValueExA(key
, NULL
, 0, REG_SZ
, (CONST BYTE
*)value
,
731 lstrlenA(value
) + 1);
736 /***********************************************************************
739 static LONG
register_progid(
742 char const *curver_progid
,
749 res
= RegCreateKeyExA(HKEY_CLASSES_ROOT
, progid
, 0,
750 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
752 if (res
!= ERROR_SUCCESS
) return res
;
755 res
= RegSetValueExA(progid_key
, NULL
, 0, REG_SZ
,
756 (CONST BYTE
*)name
, strlen(name
) + 1);
757 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
761 res
= register_key_defvalueW(progid_key
, clsid_keyname
, clsid
);
762 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
766 res
= register_key_defvalueA(progid_key
, curver_keyname
,
768 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
774 res
= RegCreateKeyExA(progid_key
, extra
, 0,
775 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
777 if (res
== ERROR_SUCCESS
)
778 RegCloseKey(extra_key
);
781 error_close_progid_key
:
782 RegCloseKey(progid_key
);
786 /***********************************************************************
789 static struct regsvr_coclass
const coclass_list
[] = {
790 { NULL
} /* list terminator */
793 /***********************************************************************
797 static struct regsvr_interface
const interface_list
[] = {
798 { NULL
} /* list terminator */
801 /***********************************************************************
805 static struct regsvr_mediatype_parsing
const mediatype_parsing_list
[] = {
808 { "0,4,,52494646,8,4,,41564920",
812 &MEDIASUBTYPE_MPEG1System
,
813 { "0, 16, FFFFFFFFF100010001800001FFFFFFFF, 000001BA2100010001800001000001BB",
817 &MEDIASUBTYPE_MPEG1VideoCD
,
818 { "0, 4, , 52494646, 8, 8, , 43445841666D7420, 36, 20, FFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFF, 646174610000000000FFFFFFFFFFFFFFFFFFFF00",
822 &MEDIASUBTYPE_MPEG1Video
,
823 { "0, 4, , 000001B3",
827 &MEDIASUBTYPE_MPEG1Audio
,
828 { "0, 2, FFE0, FFE0",
829 "0, 10, FFFFFF00000080808080, 494433000000000000",
833 &MEDIASUBTYPE_QTMovie
,
834 { "4, 4, , 6d646174",
840 { "0,4,,52494646,8,4,,57415645",
850 { "0,4,,464f524d,8,4,,41494646",
851 "0,4,,464f524d,8,4,,41494643",
862 { "0,4,,52494646,8,4,,524D4944",
866 { NULL
} /* list terminator */
869 /***********************************************************************
873 static struct regsvr_mediatype_extension
const mediatype_extension_list
[] = {
875 &MEDIASUBTYPE_MPEG1Audio
,
878 { NULL
} /* list terminator */
881 /***********************************************************************
885 static struct regsvr_filter
const filter_list
[] = {
886 { &CLSID_AviSplitter
,
887 &CLSID_LegacyAmFilterCategory
,
888 {'A','V','I',' ','S','p','l','i','t','t','e','r',0},
891 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_Avi
},
895 { REG_PINFLAG_B_OUTPUT
,
896 { { &MEDIATYPE_Video
, &GUID_NULL
},
903 { &CLSID_MPEG1Splitter
,
904 &CLSID_LegacyAmFilterCategory
,
905 {'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0},
908 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Audio
},
909 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1Video
},
910 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1System
},
911 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_MPEG1VideoCD
},
915 { REG_PINFLAG_B_OUTPUT
,
916 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1Packet
},
917 { &MEDIATYPE_Audio
, &MEDIASUBTYPE_MPEG1AudioPayload
},
921 { REG_PINFLAG_B_OUTPUT
,
922 { { &MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Packet
},
923 { &MEDIATYPE_Video
, &MEDIASUBTYPE_MPEG1Payload
},
930 { &CLSID_NullRenderer
,
931 &CLSID_LegacyAmFilterCategory
,
932 {'N','u','l','l',' ','R','e','n','d','e','r','e','r',0},
934 { { REG_PINFLAG_B_RENDERER
,
935 { { &MEDIATYPE_NULL
, &GUID_NULL
},
942 { &CLSID_VideoRenderer
,
943 &CLSID_LegacyAmFilterCategory
,
944 {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0},
946 { { REG_PINFLAG_B_RENDERER
,
947 { { &MEDIATYPE_Video
, &GUID_NULL
},
954 { &CLSID_VideoRendererDefault
,
955 &CLSID_LegacyAmFilterCategory
,
956 {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0},
958 { { REG_PINFLAG_B_RENDERER
,
959 { { &MEDIATYPE_Video
, &GUID_NULL
},
966 { &CLSID_VideoMixingRenderer9
,
967 &CLSID_LegacyAmFilterCategory
,
968 {'V','i','d','e','o',' ','M','i','x','i','n','g',' ','R','e','n','d','e','r','e','r',' ','9',0},
970 { { REG_PINFLAG_B_RENDERER
,
971 { { &MEDIATYPE_Video
, &GUID_NULL
},
978 { &CLSID_DSoundRender
,
979 &CLSID_LegacyAmFilterCategory
,
980 {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0},
982 { { REG_PINFLAG_B_RENDERER
,
983 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_PCM
},
984 /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */
991 { &CLSID_AudioRender
,
992 &CLSID_LegacyAmFilterCategory
,
993 {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0},
995 { { REG_PINFLAG_B_RENDERER
,
996 { { &MEDIATYPE_Audio
, &MEDIASUBTYPE_PCM
},
997 /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */
1005 &CLSID_LegacyAmFilterCategory
,
1006 {'A','V','I',' ','D','e','c','o','m','p','r','e','s','s','o','r',0},
1009 { { &MEDIATYPE_Video
, &GUID_NULL
},
1013 { REG_PINFLAG_B_OUTPUT
,
1014 { { &MEDIATYPE_Video
, &GUID_NULL
},
1021 { &CLSID_AsyncReader
,
1022 &CLSID_LegacyAmFilterCategory
,
1023 {'F','i','l','e',' ','S','o','u','r','c','e',' ','(','A','s','y','n','c','.',')',0},
1025 { { REG_PINFLAG_B_OUTPUT
,
1026 { { &MEDIATYPE_Stream
, &GUID_NULL
},
1033 { &CLSID_ACMWrapper
,
1034 &CLSID_LegacyAmFilterCategory
,
1035 {'A','C','M',' ','W','r','a','p','p','e','r',0},
1038 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1042 { REG_PINFLAG_B_OUTPUT
,
1043 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1050 { &CLSID_WAVEParser
,
1051 &CLSID_LegacyAmFilterCategory
,
1052 {'W','a','v','e',' ','P','a','r','s','e','r',0},
1055 { { &MEDIATYPE_Stream
, &MEDIASUBTYPE_WAVE
},
1056 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_AU
},
1057 { &MEDIATYPE_Stream
, &MEDIASUBTYPE_AIFF
},
1061 { REG_PINFLAG_B_OUTPUT
,
1062 { { &MEDIATYPE_Audio
, &GUID_NULL
},
1069 { NULL
} /* list terminator */
1072 extern HRESULT WINAPI
QUARTZ_DllRegisterServer(void) DECLSPEC_HIDDEN
;
1073 extern HRESULT WINAPI
QUARTZ_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
1075 /***********************************************************************
1076 * DllRegisterServer (QUARTZ.@)
1078 HRESULT WINAPI
DllRegisterServer(void)
1084 hr
= QUARTZ_DllRegisterServer();
1086 hr
= register_coclasses(coclass_list
);
1088 hr
= register_interfaces(interface_list
);
1090 hr
= register_mediatypes_parsing(mediatype_parsing_list
);
1092 hr
= register_mediatypes_extension(mediatype_extension_list
);
1094 hr
= register_filters(filter_list
);
1098 /***********************************************************************
1099 * DllUnregisterServer (QUARTZ.@)
1101 HRESULT WINAPI
DllUnregisterServer(void)
1107 hr
= unregister_filters(filter_list
);
1109 hr
= unregister_coclasses(coclass_list
);
1111 hr
= unregister_interfaces(interface_list
);
1113 hr
= unregister_mediatypes_parsing(mediatype_parsing_list
);
1115 hr
= unregister_mediatypes_extension(mediatype_extension_list
);
1117 hr
= QUARTZ_DllUnregisterServer();