Commit | Line | Data |
---|---|---|
2c296648 JH |
1 | /* |
2 | * self-registerable dll functions for quartz.dll | |
3 | * | |
4 | * Copyright (C) 2003 John K. Hohm | |
5 | * | |
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. | |
10 | * | |
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. | |
15 | * | |
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 | |
360a3f91 | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
2c296648 JH |
19 | */ |
20 | ||
617dc088 CC |
21 | #define NONAMELESSUNION |
22 | #define NONAMELESSSTRUCT | |
23 | #define COBJMACROS | |
e37c6e18 | 24 | #include <stdarg.h> |
2c296648 JH |
25 | #include <string.h> |
26 | ||
27 | #include "windef.h" | |
28 | #include "winbase.h" | |
61ba32c0 | 29 | #include "wingdi.h" |
2c296648 JH |
30 | #include "winuser.h" |
31 | #include "winreg.h" | |
32 | #include "winerror.h" | |
33 | ||
34 | #include "ole2.h" | |
35 | #include "uuids.h" | |
617dc088 | 36 | #include "strmif.h" |
2c296648 JH |
37 | |
38 | #include "wine/debug.h" | |
8bd9a3aa | 39 | #include "wine/unicode.h" |
2c296648 JH |
40 | |
41 | WINE_DEFAULT_DEBUG_CHANNEL(quartz); | |
42 | ||
43 | /* | |
44 | * Near the bottom of this file are the exported DllRegisterServer and | |
45 | * DllUnregisterServer, which make all this worthwhile. | |
46 | */ | |
47 | ||
48 | /*********************************************************************** | |
49 | * interface for self-registering | |
50 | */ | |
51 | struct regsvr_interface | |
52 | { | |
53 | IID const *iid; /* NULL for end of list */ | |
54 | LPCSTR name; /* can be NULL to omit */ | |
55 | IID const *base_iid; /* can be NULL to omit */ | |
56 | int num_methods; /* can be <0 to omit */ | |
57 | CLSID const *ps_clsid; /* can be NULL to omit */ | |
58 | CLSID const *ps_clsid32; /* can be NULL to omit */ | |
59 | }; | |
60 | ||
61 | static HRESULT register_interfaces(struct regsvr_interface const *list); | |
62 | static HRESULT unregister_interfaces(struct regsvr_interface const *list); | |
63 | ||
64 | struct regsvr_coclass | |
65 | { | |
66 | CLSID const *clsid; /* NULL for end of list */ | |
67 | LPCSTR name; /* can be NULL to omit */ | |
68 | LPCSTR ips; /* can be NULL to omit */ | |
69 | LPCSTR ips32; /* can be NULL to omit */ | |
70 | LPCSTR ips32_tmodel; /* can be NULL to omit */ | |
71 | LPCSTR progid; /* can be NULL to omit */ | |
72 | LPCSTR viprogid; /* can be NULL to omit */ | |
73 | LPCSTR progid_extra; /* can be NULL to omit */ | |
74 | }; | |
75 | ||
76 | static HRESULT register_coclasses(struct regsvr_coclass const *list); | |
77 | static HRESULT unregister_coclasses(struct regsvr_coclass const *list); | |
78 | ||
18511a38 CC |
79 | struct regsvr_mediatype_parsing |
80 | { | |
81 | CLSID const *majortype; /* NULL for end of list */ | |
82 | CLSID const *subtype; | |
83 | LPCSTR line[11]; /* NULL for end of list */ | |
84 | }; | |
85 | ||
86 | static HRESULT register_mediatypes_parsing(struct regsvr_mediatype_parsing const *list); | |
87 | static HRESULT unregister_mediatypes_parsing(struct regsvr_mediatype_parsing const *list); | |
88 | ||
89 | struct regsvr_mediatype_extension | |
90 | { | |
91 | CLSID const *majortype; /* NULL for end of list */ | |
92 | CLSID const *subtype; | |
93 | LPCSTR extension; | |
94 | }; | |
95 | ||
617dc088 CC |
96 | struct mediatype |
97 | { | |
98 | CLSID const *majortype; /* NULL for end of list */ | |
99 | CLSID const *subtype; | |
100 | DWORD fourcc; | |
101 | }; | |
102 | ||
103 | struct pin | |
104 | { | |
105 | DWORD flags; /* 0xFFFFFFFF for end of list */ | |
106 | struct mediatype mediatypes[11]; | |
107 | }; | |
108 | ||
109 | struct regsvr_filter | |
110 | { | |
111 | CLSID const *clsid; /* NULL for end of list */ | |
112 | CLSID const *category; | |
113 | WCHAR name[50]; | |
114 | DWORD merit; | |
115 | struct pin pins[11]; | |
116 | }; | |
117 | ||
18511a38 CC |
118 | static HRESULT register_mediatypes_extension(struct regsvr_mediatype_extension const *list); |
119 | static HRESULT unregister_mediatypes_extension(struct regsvr_mediatype_extension const *list); | |
120 | ||
617dc088 CC |
121 | static HRESULT register_filters(struct regsvr_filter const *list); |
122 | static HRESULT unregister_filters(struct regsvr_filter const *list); | |
123 | ||
2c296648 JH |
124 | /*********************************************************************** |
125 | * static string constants | |
126 | */ | |
127 | static WCHAR const interface_keyname[10] = { | |
128 | 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 }; | |
129 | static WCHAR const base_ifa_keyname[14] = { | |
130 | 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', | |
131 | 'e', 0 }; | |
132 | static WCHAR const num_methods_keyname[11] = { | |
133 | 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 }; | |
134 | static WCHAR const ps_clsid_keyname[15] = { | |
135 | 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', | |
136 | 'i', 'd', 0 }; | |
137 | static WCHAR const ps_clsid32_keyname[17] = { | |
138 | 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', | |
139 | 'i', 'd', '3', '2', 0 }; | |
140 | static WCHAR const clsid_keyname[6] = { | |
141 | 'C', 'L', 'S', 'I', 'D', 0 }; | |
142 | static WCHAR const curver_keyname[7] = { | |
143 | 'C', 'u', 'r', 'V', 'e', 'r', 0 }; | |
144 | static WCHAR const ips_keyname[13] = { | |
145 | 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', | |
146 | 0 }; | |
147 | static WCHAR const ips32_keyname[15] = { | |
148 | 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', | |
149 | '3', '2', 0 }; | |
150 | static WCHAR const progid_keyname[7] = { | |
151 | 'P', 'r', 'o', 'g', 'I', 'D', 0 }; | |
152 | static WCHAR const viprogid_keyname[25] = { | |
153 | 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p', | |
154 | 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D', | |
155 | 0 }; | |
156 | static char const tmodel_valuename[] = "ThreadingModel"; | |
18511a38 CC |
157 | static WCHAR const mediatype_name[11] = { |
158 | 'M', 'e', 'd', 'i', 'a', ' ', 'T', 'y', 'p', 'e', 0 }; | |
159 | static WCHAR const subtype_valuename[8] = { | |
160 | 'S', 'u', 'b', 't', 'y', 'p', 'e', 0 }; | |
1e0aaaf2 PV |
161 | static WCHAR const sourcefilter_valuename[14] = { |
162 | 'S', 'o', 'u', 'r', 'c', 'e', ' ', 'F', 'i', 'l', 't', 'e', 'r', 0 }; | |
18511a38 CC |
163 | static WCHAR const extensions_keyname[11] = { |
164 | 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', 0 }; | |
2c296648 JH |
165 | |
166 | /*********************************************************************** | |
167 | * static helper functions | |
168 | */ | |
169 | static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid); | |
170 | static LONG register_key_defvalueW(HKEY base, WCHAR const *name, | |
171 | WCHAR const *value); | |
172 | static LONG register_key_defvalueA(HKEY base, WCHAR const *name, | |
173 | char const *value); | |
174 | static LONG register_progid(WCHAR const *clsid, | |
175 | char const *progid, char const *curver_progid, | |
176 | char const *name, char const *extra); | |
2c296648 JH |
177 | |
178 | /*********************************************************************** | |
179 | * register_interfaces | |
180 | */ | |
181 | static HRESULT register_interfaces(struct regsvr_interface const *list) | |
182 | { | |
183 | LONG res = ERROR_SUCCESS; | |
184 | HKEY interface_key; | |
185 | ||
186 | res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0, | |
187 | KEY_READ | KEY_WRITE, NULL, &interface_key, NULL); | |
188 | if (res != ERROR_SUCCESS) goto error_return; | |
189 | ||
190 | for (; res == ERROR_SUCCESS && list->iid; ++list) { | |
191 | WCHAR buf[39]; | |
192 | HKEY iid_key; | |
193 | ||
194 | StringFromGUID2(list->iid, buf, 39); | |
195 | res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0, | |
196 | KEY_READ | KEY_WRITE, NULL, &iid_key, NULL); | |
197 | if (res != ERROR_SUCCESS) goto error_close_interface_key; | |
198 | ||
199 | if (list->name) { | |
200 | res = RegSetValueExA(iid_key, NULL, 0, REG_SZ, | |
201 | (CONST BYTE*)(list->name), | |
202 | strlen(list->name) + 1); | |
203 | if (res != ERROR_SUCCESS) goto error_close_iid_key; | |
204 | } | |
205 | ||
206 | if (list->base_iid) { | |
74407105 | 207 | res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid); |
2c296648 JH |
208 | if (res != ERROR_SUCCESS) goto error_close_iid_key; |
209 | } | |
210 | ||
211 | if (0 <= list->num_methods) { | |
212 | static WCHAR const fmt[3] = { '%', 'd', 0 }; | |
213 | HKEY key; | |
214 | ||
215 | res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0, | |
216 | KEY_READ | KEY_WRITE, NULL, &key, NULL); | |
217 | if (res != ERROR_SUCCESS) goto error_close_iid_key; | |
218 | ||
8bd9a3aa | 219 | sprintfW(buf, fmt, list->num_methods); |
2c296648 JH |
220 | res = RegSetValueExW(key, NULL, 0, REG_SZ, |
221 | (CONST BYTE*)buf, | |
222 | (lstrlenW(buf) + 1) * sizeof(WCHAR)); | |
223 | RegCloseKey(key); | |
224 | ||
225 | if (res != ERROR_SUCCESS) goto error_close_iid_key; | |
226 | } | |
227 | ||
228 | if (list->ps_clsid) { | |
e5f009e0 | 229 | res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid); |
2c296648 JH |
230 | if (res != ERROR_SUCCESS) goto error_close_iid_key; |
231 | } | |
232 | ||
233 | if (list->ps_clsid32) { | |
e5f009e0 | 234 | res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32); |
2c296648 JH |
235 | if (res != ERROR_SUCCESS) goto error_close_iid_key; |
236 | } | |
237 | ||
238 | error_close_iid_key: | |
239 | RegCloseKey(iid_key); | |
240 | } | |
241 | ||
242 | error_close_interface_key: | |
243 | RegCloseKey(interface_key); | |
244 | error_return: | |
245 | return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; | |
246 | } | |
247 | ||
248 | /*********************************************************************** | |
249 | * unregister_interfaces | |
250 | */ | |
251 | static HRESULT unregister_interfaces(struct regsvr_interface const *list) | |
252 | { | |
253 | LONG res = ERROR_SUCCESS; | |
254 | HKEY interface_key; | |
255 | ||
256 | res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, | |
257 | KEY_READ | KEY_WRITE, &interface_key); | |
258 | if (res == ERROR_FILE_NOT_FOUND) return S_OK; | |
259 | if (res != ERROR_SUCCESS) goto error_return; | |
260 | ||
261 | for (; res == ERROR_SUCCESS && list->iid; ++list) { | |
262 | WCHAR buf[39]; | |
263 | ||
264 | StringFromGUID2(list->iid, buf, 39); | |
c13c9e38 SL |
265 | res = RegDeleteTreeW(interface_key, buf); |
266 | if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; | |
2c296648 JH |
267 | } |
268 | ||
269 | RegCloseKey(interface_key); | |
270 | error_return: | |
271 | return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; | |
272 | } | |
273 | ||
274 | /*********************************************************************** | |
275 | * register_coclasses | |
276 | */ | |
277 | static HRESULT register_coclasses(struct regsvr_coclass const *list) | |
278 | { | |
279 | LONG res = ERROR_SUCCESS; | |
280 | HKEY coclass_key; | |
281 | ||
282 | res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, | |
283 | KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); | |
284 | if (res != ERROR_SUCCESS) goto error_return; | |
285 | ||
286 | for (; res == ERROR_SUCCESS && list->clsid; ++list) { | |
287 | WCHAR buf[39]; | |
288 | HKEY clsid_key; | |
289 | ||
290 | StringFromGUID2(list->clsid, buf, 39); | |
291 | res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, | |
292 | KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); | |
293 | if (res != ERROR_SUCCESS) goto error_close_coclass_key; | |
294 | ||
295 | if (list->name) { | |
296 | res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ, | |
297 | (CONST BYTE*)(list->name), | |
298 | strlen(list->name) + 1); | |
299 | if (res != ERROR_SUCCESS) goto error_close_clsid_key; | |
300 | } | |
301 | ||
302 | if (list->ips) { | |
303 | res = register_key_defvalueA(clsid_key, ips_keyname, list->ips); | |
304 | if (res != ERROR_SUCCESS) goto error_close_clsid_key; | |
305 | } | |
306 | ||
307 | if (list->ips32) { | |
308 | HKEY ips32_key; | |
309 | ||
310 | res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0, | |
311 | KEY_READ | KEY_WRITE, NULL, | |
312 | &ips32_key, NULL); | |
313 | if (res != ERROR_SUCCESS) goto error_close_clsid_key; | |
314 | ||
315 | res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ, | |
316 | (CONST BYTE*)list->ips32, | |
317 | lstrlenA(list->ips32) + 1); | |
318 | if (res == ERROR_SUCCESS && list->ips32_tmodel) | |
319 | res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ, | |
320 | (CONST BYTE*)list->ips32_tmodel, | |
321 | strlen(list->ips32_tmodel) + 1); | |
322 | RegCloseKey(ips32_key); | |
323 | if (res != ERROR_SUCCESS) goto error_close_clsid_key; | |
324 | } | |
325 | ||
326 | if (list->progid) { | |
327 | res = register_key_defvalueA(clsid_key, progid_keyname, | |
328 | list->progid); | |
329 | if (res != ERROR_SUCCESS) goto error_close_clsid_key; | |
330 | ||
331 | res = register_progid(buf, list->progid, NULL, | |
332 | list->name, list->progid_extra); | |
333 | if (res != ERROR_SUCCESS) goto error_close_clsid_key; | |
334 | } | |
335 | ||
336 | if (list->viprogid) { | |
337 | res = register_key_defvalueA(clsid_key, viprogid_keyname, | |
338 | list->viprogid); | |
339 | if (res != ERROR_SUCCESS) goto error_close_clsid_key; | |
340 | ||
341 | res = register_progid(buf, list->viprogid, list->progid, | |
342 | list->name, list->progid_extra); | |
343 | if (res != ERROR_SUCCESS) goto error_close_clsid_key; | |
344 | } | |
345 | ||
346 | error_close_clsid_key: | |
347 | RegCloseKey(clsid_key); | |
348 | } | |
349 | ||
350 | error_close_coclass_key: | |
351 | RegCloseKey(coclass_key); | |
352 | error_return: | |
353 | return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; | |
354 | } | |
355 | ||
356 | /*********************************************************************** | |
357 | * unregister_coclasses | |
358 | */ | |
359 | static HRESULT unregister_coclasses(struct regsvr_coclass const *list) | |
360 | { | |
361 | LONG res = ERROR_SUCCESS; | |
362 | HKEY coclass_key; | |
363 | ||
364 | res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, | |
365 | KEY_READ | KEY_WRITE, &coclass_key); | |
366 | if (res == ERROR_FILE_NOT_FOUND) return S_OK; | |
367 | if (res != ERROR_SUCCESS) goto error_return; | |
368 | ||
369 | for (; res == ERROR_SUCCESS && list->clsid; ++list) { | |
370 | WCHAR buf[39]; | |
371 | ||
372 | StringFromGUID2(list->clsid, buf, 39); | |
c13c9e38 SL |
373 | res = RegDeleteTreeW(coclass_key, buf); |
374 | if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; | |
2c296648 JH |
375 | if (res != ERROR_SUCCESS) goto error_close_coclass_key; |
376 | ||
377 | if (list->progid) { | |
c13c9e38 SL |
378 | res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); |
379 | if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; | |
2c296648 JH |
380 | if (res != ERROR_SUCCESS) goto error_close_coclass_key; |
381 | } | |
382 | ||
383 | if (list->viprogid) { | |
c13c9e38 SL |
384 | res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid); |
385 | if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; | |
2c296648 JH |
386 | if (res != ERROR_SUCCESS) goto error_close_coclass_key; |
387 | } | |
388 | } | |
389 | ||
390 | error_close_coclass_key: | |
391 | RegCloseKey(coclass_key); | |
392 | error_return: | |
393 | return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; | |
394 | } | |
395 | ||
18511a38 CC |
396 | /*********************************************************************** |
397 | * register_mediatypes_parsing | |
398 | */ | |
399 | static HRESULT register_mediatypes_parsing(struct regsvr_mediatype_parsing const *list) | |
400 | { | |
401 | LONG res = ERROR_SUCCESS; | |
402 | HKEY mediatype_key; | |
403 | WCHAR buf[39]; | |
404 | int i; | |
405 | ||
406 | res = RegCreateKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0, NULL, 0, | |
407 | KEY_READ | KEY_WRITE, NULL, &mediatype_key, NULL); | |
408 | if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); | |
409 | ||
410 | for (; res == ERROR_SUCCESS && list->majortype; ++list) { | |
411 | HKEY majortype_key = NULL; | |
412 | HKEY subtype_key = NULL; | |
413 | ||
414 | StringFromGUID2(list->majortype, buf, 39); | |
415 | res = RegCreateKeyExW(mediatype_key, buf, 0, NULL, 0, | |
416 | KEY_READ | KEY_WRITE, NULL, &majortype_key, NULL); | |
417 | if (res != ERROR_SUCCESS) goto error_close_keys; | |
418 | ||
419 | StringFromGUID2(list->subtype, buf, 39); | |
420 | res = RegCreateKeyExW(majortype_key, buf, 0, NULL, 0, | |
421 | KEY_READ | KEY_WRITE, NULL, &subtype_key, NULL); | |
422 | if (res != ERROR_SUCCESS) goto error_close_keys; | |
423 | ||
424 | StringFromGUID2(&CLSID_AsyncReader, buf, 39); | |
1e0aaaf2 | 425 | res = RegSetValueExW(subtype_key, sourcefilter_valuename, 0, REG_SZ, (CONST BYTE*)buf, |
18511a38 CC |
426 | (lstrlenW(buf) + 1) * sizeof(WCHAR)); |
427 | if (res != ERROR_SUCCESS) goto error_close_keys; | |
428 | ||
429 | for(i = 0; list->line[i]; i++) { | |
430 | char buffer[3]; | |
431 | wsprintfA(buffer, "%d", i); | |
432 | res = RegSetValueExA(subtype_key, buffer, 0, REG_SZ, (CONST BYTE*)list->line[i], | |
433 | lstrlenA(list->line[i])); | |
434 | if (res != ERROR_SUCCESS) goto error_close_keys; | |
435 | } | |
436 | ||
437 | error_close_keys: | |
438 | if (majortype_key) | |
439 | RegCloseKey(majortype_key); | |
440 | if (subtype_key) | |
441 | RegCloseKey(subtype_key); | |
442 | } | |
443 | ||
444 | RegCloseKey(mediatype_key); | |
445 | ||
446 | return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; | |
447 | } | |
448 | ||
449 | /*********************************************************************** | |
450 | * register_mediatypes_extension | |
451 | */ | |
452 | static HRESULT register_mediatypes_extension(struct regsvr_mediatype_extension const *list) | |
453 | { | |
454 | LONG res = ERROR_SUCCESS; | |
455 | HKEY mediatype_key; | |
456 | HKEY extensions_root_key = NULL; | |
457 | WCHAR buf[39]; | |
458 | ||
459 | res = RegCreateKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0, NULL, 0, | |
460 | KEY_READ | KEY_WRITE, NULL, &mediatype_key, NULL); | |
461 | if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); | |
462 | ||
463 | res = RegCreateKeyExW(mediatype_key, extensions_keyname, 0, NULL, 0, | |
464 | KEY_READ | KEY_WRITE, NULL, &extensions_root_key, NULL); | |
465 | if (res != ERROR_SUCCESS) goto error_return; | |
466 | ||
467 | for (; res == ERROR_SUCCESS && list->majortype; ++list) { | |
468 | HKEY extension_key; | |
469 | ||
470 | res = RegCreateKeyExA(extensions_root_key, list->extension, 0, NULL, 0, | |
471 | KEY_READ | KEY_WRITE, NULL, &extension_key, NULL); | |
472 | if (res != ERROR_SUCCESS) break; | |
473 | ||
474 | StringFromGUID2(list->majortype, buf, 39); | |
475 | res = RegSetValueExW(extension_key, mediatype_name, 0, REG_SZ, (CONST BYTE*)buf, | |
476 | (lstrlenW(buf) + 1) * sizeof(WCHAR)); | |
477 | if (res != ERROR_SUCCESS) goto error_close_key; | |
478 | ||
479 | StringFromGUID2(list->subtype, buf, 39); | |
480 | res = RegSetValueExW(extension_key, subtype_valuename, 0, REG_SZ, (CONST BYTE*)buf, | |
481 | (lstrlenW(buf) + 1) * sizeof(WCHAR)); | |
482 | if (res != ERROR_SUCCESS) goto error_close_key; | |
483 | ||
484 | StringFromGUID2(&CLSID_AsyncReader, buf, 39); | |
1e0aaaf2 | 485 | res = RegSetValueExW(extension_key, sourcefilter_valuename, 0, REG_SZ, (CONST BYTE*)buf, |
18511a38 CC |
486 | (lstrlenW(buf) + 1) * sizeof(WCHAR)); |
487 | if (res != ERROR_SUCCESS) goto error_close_key; | |
488 | ||
489 | error_close_key: | |
490 | RegCloseKey(extension_key); | |
491 | } | |
492 | ||
493 | error_return: | |
494 | RegCloseKey(mediatype_key); | |
495 | if (extensions_root_key) | |
496 | RegCloseKey(extensions_root_key); | |
497 | ||
498 | return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; | |
499 | } | |
500 | ||
501 | /*********************************************************************** | |
502 | * unregister_mediatypes_parsing | |
503 | */ | |
504 | static HRESULT unregister_mediatypes_parsing(struct regsvr_mediatype_parsing const *list) | |
505 | { | |
506 | LONG res; | |
507 | HKEY mediatype_key; | |
508 | HKEY majortype_key; | |
509 | WCHAR buf[39]; | |
510 | ||
511 | res = RegOpenKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0, | |
512 | KEY_READ | KEY_WRITE, &mediatype_key); | |
513 | if (res == ERROR_FILE_NOT_FOUND) return S_OK; | |
514 | if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); | |
515 | ||
516 | for (; res == ERROR_SUCCESS && list->majortype; ++list) { | |
517 | StringFromGUID2(list->majortype, buf, 39); | |
518 | res = RegOpenKeyExW(mediatype_key, buf, 0, | |
519 | KEY_READ | KEY_WRITE, &majortype_key); | |
520 | if (res == ERROR_FILE_NOT_FOUND) { | |
521 | res = ERROR_SUCCESS; | |
522 | continue; | |
523 | } | |
524 | if (res != ERROR_SUCCESS) break; | |
525 | ||
526 | StringFromGUID2(list->subtype, buf, 39); | |
c13c9e38 | 527 | res = RegDeleteTreeW(majortype_key, buf); |
18511a38 CC |
528 | if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; |
529 | ||
530 | /* Removed majortype key if there is no more subtype key */ | |
531 | res = RegDeleteKeyW(majortype_key, 0); | |
532 | if (res == ERROR_ACCESS_DENIED) res = ERROR_SUCCESS; | |
533 | ||
534 | RegCloseKey(majortype_key); | |
535 | } | |
536 | ||
537 | RegCloseKey(mediatype_key); | |
538 | ||
539 | return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; | |
540 | } | |
541 | ||
542 | /*********************************************************************** | |
543 | * unregister_mediatypes_extension | |
544 | */ | |
545 | static HRESULT unregister_mediatypes_extension(struct regsvr_mediatype_extension const *list) | |
546 | { | |
547 | LONG res; | |
548 | HKEY mediatype_key; | |
549 | HKEY extensions_root_key = NULL; | |
550 | ||
551 | res = RegOpenKeyExW(HKEY_CLASSES_ROOT, mediatype_name, 0, | |
552 | KEY_READ | KEY_WRITE, &mediatype_key); | |
553 | if (res == ERROR_FILE_NOT_FOUND) return S_OK; | |
554 | if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); | |
555 | ||
556 | res = RegOpenKeyExW(mediatype_key, extensions_keyname, 0, | |
557 | KEY_READ | KEY_WRITE, &extensions_root_key); | |
558 | if (res == ERROR_FILE_NOT_FOUND) | |
559 | res = ERROR_SUCCESS; | |
560 | else if (res == ERROR_SUCCESS) | |
561 | for (; res == ERROR_SUCCESS && list->majortype; ++list) { | |
c13c9e38 | 562 | res = RegDeleteTreeA(extensions_root_key, list->extension); |
18511a38 CC |
563 | if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; |
564 | } | |
565 | ||
566 | RegCloseKey(mediatype_key); | |
567 | if (extensions_root_key) | |
568 | RegCloseKey(extensions_root_key); | |
569 | ||
570 | return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; | |
571 | } | |
572 | ||
617dc088 CC |
573 | /*********************************************************************** |
574 | * register_filters | |
575 | */ | |
576 | static HRESULT register_filters(struct regsvr_filter const *list) | |
577 | { | |
578 | HRESULT hr; | |
579 | IFilterMapper2* pFM2 = NULL; | |
580 | ||
581 | CoInitialize(NULL); | |
617dc088 CC |
582 | hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&pFM2); |
583 | ||
584 | if (SUCCEEDED(hr)) { | |
585 | for (; SUCCEEDED(hr) && list->clsid; ++list) { | |
586 | REGFILTER2 rf2; | |
587 | REGFILTERPINS2* prfp2; | |
588 | int i; | |
2cfcf1c3 | 589 | |
617dc088 CC |
590 | for (i = 0; list->pins[i].flags != 0xFFFFFFFF; i++) ; |
591 | rf2.dwVersion = 2; | |
592 | rf2.dwMerit = list->merit; | |
593 | rf2.u.s1.cPins2 = i; | |
f10e6d7e | 594 | rf2.u.s1.rgPins2 = prfp2 = CoTaskMemAlloc(i*sizeof(REGFILTERPINS2)); |
617dc088 CC |
595 | if (!prfp2) { |
596 | hr = E_OUTOFMEMORY; | |
597 | break; | |
598 | } | |
599 | for (i = 0; list->pins[i].flags != 0xFFFFFFFF; i++) { | |
600 | REGPINTYPES* lpMediatype; | |
601 | CLSID* lpClsid; | |
602 | int j, nbmt; | |
2cfcf1c3 | 603 | |
617dc088 CC |
604 | for (nbmt = 0; list->pins[i].mediatypes[nbmt].majortype; nbmt++) ; |
605 | /* Allocate a single buffer for regpintypes struct and clsids */ | |
f10e6d7e | 606 | lpMediatype = CoTaskMemAlloc(nbmt*(sizeof(REGPINTYPES) + 2*sizeof(CLSID))); |
617dc088 CC |
607 | if (!lpMediatype) { |
608 | hr = E_OUTOFMEMORY; | |
609 | break; | |
610 | } | |
611 | lpClsid = (CLSID*) (lpMediatype + nbmt); | |
612 | for (j = 0; j < nbmt; j++) { | |
613 | (lpMediatype + j)->clsMajorType = lpClsid + j*2; | |
614 | memcpy(lpClsid + j*2, list->pins[i].mediatypes[j].majortype, sizeof(CLSID)); | |
615 | (lpMediatype + j)->clsMinorType = lpClsid + j*2 + 1; | |
616 | if (list->pins[i].mediatypes[j].subtype) | |
617 | memcpy(lpClsid + j*2 + 1, list->pins[i].mediatypes[j].subtype, sizeof(CLSID)); | |
618 | else { | |
619 | /* Subtype are often a combination of major type + fourcc/tag */ | |
620 | memcpy(lpClsid + j*2 + 1, list->pins[i].mediatypes[j].majortype, sizeof(CLSID)); | |
621 | *(DWORD*)(lpClsid + j*2 + 1) = list->pins[i].mediatypes[j].fourcc; | |
622 | } | |
623 | } | |
624 | prfp2[i].dwFlags = list->pins[i].flags; | |
625 | prfp2[i].cInstances = 0; | |
626 | prfp2[i].nMediaTypes = j; | |
627 | prfp2[i].lpMediaType = lpMediatype; | |
628 | prfp2[i].nMediums = 0; | |
629 | prfp2[i].lpMedium = NULL; | |
630 | prfp2[i].clsPinCategory = NULL; | |
631 | } | |
632 | ||
2cfcf1c3 | 633 | if (FAILED(hr)) { |
cfbb859f | 634 | ERR("failed to register with hresult 0x%x\n", hr); |
b0241781 | 635 | CoTaskMemFree(prfp2); |
2cfcf1c3 MH |
636 | break; |
637 | } | |
638 | ||
617dc088 CC |
639 | hr = IFilterMapper2_RegisterFilter(pFM2, list->clsid, list->name, NULL, list->category, NULL, &rf2); |
640 | ||
2cfcf1c3 | 641 | while (i) { |
617dc088 | 642 | CoTaskMemFree((REGPINTYPES*)prfp2[i-1].lpMediaType); |
2cfcf1c3 MH |
643 | i--; |
644 | } | |
617dc088 CC |
645 | CoTaskMemFree(prfp2); |
646 | } | |
647 | } | |
648 | ||
649 | if (pFM2) | |
650 | IFilterMapper2_Release(pFM2); | |
651 | ||
652 | CoUninitialize(); | |
653 | ||
654 | return hr; | |
655 | } | |
656 | ||
657 | /*********************************************************************** | |
658 | * unregister_filters | |
659 | */ | |
660 | static HRESULT unregister_filters(struct regsvr_filter const *list) | |
661 | { | |
662 | HRESULT hr; | |
663 | IFilterMapper2* pFM2; | |
664 | ||
665 | CoInitialize(NULL); | |
666 | ||
667 | hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&pFM2); | |
668 | ||
669 | if (SUCCEEDED(hr)) { | |
670 | for (; SUCCEEDED(hr) && list->clsid; ++list) | |
671 | hr = IFilterMapper2_UnregisterFilter(pFM2, list->category, NULL, list->clsid); | |
672 | IFilterMapper2_Release(pFM2); | |
673 | } | |
674 | ||
675 | CoUninitialize(); | |
676 | ||
677 | return hr; | |
678 | } | |
679 | ||
2c296648 JH |
680 | /*********************************************************************** |
681 | * regsvr_key_guid | |
682 | */ | |
683 | static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid) | |
684 | { | |
685 | WCHAR buf[39]; | |
686 | ||
687 | StringFromGUID2(guid, buf, 39); | |
688 | return register_key_defvalueW(base, name, buf); | |
689 | } | |
690 | ||
691 | /*********************************************************************** | |
692 | * regsvr_key_defvalueW | |
693 | */ | |
694 | static LONG register_key_defvalueW( | |
695 | HKEY base, | |
696 | WCHAR const *name, | |
697 | WCHAR const *value) | |
698 | { | |
699 | LONG res; | |
700 | HKEY key; | |
701 | ||
702 | res = RegCreateKeyExW(base, name, 0, NULL, 0, | |
703 | KEY_READ | KEY_WRITE, NULL, &key, NULL); | |
704 | if (res != ERROR_SUCCESS) return res; | |
705 | res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value, | |
706 | (lstrlenW(value) + 1) * sizeof(WCHAR)); | |
707 | RegCloseKey(key); | |
708 | return res; | |
709 | } | |
710 | ||
711 | /*********************************************************************** | |
712 | * regsvr_key_defvalueA | |
713 | */ | |
714 | static LONG register_key_defvalueA( | |
715 | HKEY base, | |
716 | WCHAR const *name, | |
717 | char const *value) | |
718 | { | |
719 | LONG res; | |
720 | HKEY key; | |
721 | ||
722 | res = RegCreateKeyExW(base, name, 0, NULL, 0, | |
723 | KEY_READ | KEY_WRITE, NULL, &key, NULL); | |
724 | if (res != ERROR_SUCCESS) return res; | |
725 | res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value, | |
726 | lstrlenA(value) + 1); | |
727 | RegCloseKey(key); | |
728 | return res; | |
729 | } | |
730 | ||
731 | /*********************************************************************** | |
732 | * regsvr_progid | |
733 | */ | |
734 | static LONG register_progid( | |
735 | WCHAR const *clsid, | |
736 | char const *progid, | |
737 | char const *curver_progid, | |
738 | char const *name, | |
739 | char const *extra) | |
740 | { | |
741 | LONG res; | |
742 | HKEY progid_key; | |
743 | ||
744 | res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0, | |
745 | NULL, 0, KEY_READ | KEY_WRITE, NULL, | |
746 | &progid_key, NULL); | |
747 | if (res != ERROR_SUCCESS) return res; | |
748 | ||
749 | if (name) { | |
750 | res = RegSetValueExA(progid_key, NULL, 0, REG_SZ, | |
751 | (CONST BYTE*)name, strlen(name) + 1); | |
752 | if (res != ERROR_SUCCESS) goto error_close_progid_key; | |
753 | } | |
754 | ||
755 | if (clsid) { | |
756 | res = register_key_defvalueW(progid_key, clsid_keyname, clsid); | |
757 | if (res != ERROR_SUCCESS) goto error_close_progid_key; | |
758 | } | |
759 | ||
760 | if (curver_progid) { | |
761 | res = register_key_defvalueA(progid_key, curver_keyname, | |
762 | curver_progid); | |
763 | if (res != ERROR_SUCCESS) goto error_close_progid_key; | |
764 | } | |
765 | ||
766 | if (extra) { | |
767 | HKEY extra_key; | |
768 | ||
769 | res = RegCreateKeyExA(progid_key, extra, 0, | |
770 | NULL, 0, KEY_READ | KEY_WRITE, NULL, | |
771 | &extra_key, NULL); | |
772 | if (res == ERROR_SUCCESS) | |
773 | RegCloseKey(extra_key); | |
774 | } | |
775 | ||
776 | error_close_progid_key: | |
777 | RegCloseKey(progid_key); | |
778 | return res; | |
779 | } | |
780 | ||
2c296648 JH |
781 | /*********************************************************************** |
782 | * coclass list | |
783 | */ | |
784 | static struct regsvr_coclass const coclass_list[] = { | |
2c296648 JH |
785 | { NULL } /* list terminator */ |
786 | }; | |
787 | ||
788 | /*********************************************************************** | |
789 | * interface list | |
790 | */ | |
791 | ||
792 | static struct regsvr_interface const interface_list[] = { | |
793 | { NULL } /* list terminator */ | |
794 | }; | |
795 | ||
18511a38 CC |
796 | /*********************************************************************** |
797 | * mediatype list | |
798 | */ | |
799 | ||
800 | static struct regsvr_mediatype_parsing const mediatype_parsing_list[] = { | |
801 | { &MEDIATYPE_Stream, | |
802 | &MEDIASUBTYPE_Avi, | |
803 | { "0,4,,52494646,8,4,,41564920", | |
804 | NULL } | |
805 | }, | |
806 | { &MEDIATYPE_Stream, | |
807 | &MEDIASUBTYPE_MPEG1System, | |
1e0aaaf2 | 808 | { "0, 16, FFFFFFFFF100010001800001FFFFFFFF, 000001BA2100010001800001000001BB", |
18511a38 CC |
809 | NULL } |
810 | }, | |
811 | { &MEDIATYPE_Stream, | |
812 | &MEDIASUBTYPE_MPEG1VideoCD, | |
813 | { "0, 4, , 52494646, 8, 8, , 43445841666D7420, 36, 20, FFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFF, 646174610000000000FFFFFFFFFFFFFFFFFFFF00", | |
814 | NULL } | |
815 | }, | |
816 | { &MEDIATYPE_Stream, | |
817 | &MEDIASUBTYPE_MPEG1Video, | |
818 | { "0, 4, , 000001B3", | |
819 | NULL } | |
820 | }, | |
821 | { &MEDIATYPE_Stream, | |
822 | &MEDIASUBTYPE_MPEG1Audio, | |
823 | { "0, 2, FFE0, FFE0", | |
24708e4e | 824 | "0, 10, FFFFFF00000080808080, 494433000000000000", |
18511a38 CC |
825 | NULL } |
826 | }, | |
827 | { &MEDIATYPE_Stream, | |
828 | &MEDIASUBTYPE_QTMovie, | |
829 | { "4, 4, , 6d646174", | |
830 | "4, 4, , 6d6f6f76", | |
831 | NULL } | |
832 | }, | |
833 | { &MEDIATYPE_Stream, | |
834 | &MEDIASUBTYPE_WAVE, | |
835 | { "0,4,,52494646,8,4,,57415645", | |
836 | NULL } | |
837 | }, | |
838 | { &MEDIATYPE_Stream, | |
839 | &MEDIASUBTYPE_AU, | |
840 | { "0,4,,2e736e64", | |
841 | NULL } | |
842 | }, | |
843 | { &MEDIATYPE_Stream, | |
844 | &MEDIASUBTYPE_AIFF, | |
845 | { "0,4,,464f524d,8,4,,41494646", | |
846 | "0,4,,464f524d,8,4,,41494643", | |
847 | NULL } | |
848 | }, | |
849 | { &MEDIATYPE_Stream, | |
850 | &MEDIATYPE_Text, | |
851 | { "0,4,,4C595249", | |
852 | "0,4,,6C797269", | |
853 | NULL } | |
854 | }, | |
855 | { &MEDIATYPE_Stream, | |
856 | &MEDIATYPE_Midi, | |
857 | { "0,4,,52494646,8,4,,524D4944", | |
858 | "0,4,,4D546864", | |
859 | NULL } | |
860 | }, | |
861 | { NULL } /* list terminator */ | |
862 | }; | |
863 | ||
864 | /*********************************************************************** | |
865 | * mediatype list | |
866 | */ | |
867 | ||
868 | static struct regsvr_mediatype_extension const mediatype_extension_list[] = { | |
869 | { &MEDIATYPE_Stream, | |
870 | &MEDIASUBTYPE_MPEG1Audio, | |
871 | ".mp3" | |
872 | }, | |
873 | { NULL } /* list terminator */ | |
874 | }; | |
875 | ||
617dc088 CC |
876 | /*********************************************************************** |
877 | * filter list | |
878 | */ | |
879 | ||
880 | static struct regsvr_filter const filter_list[] = { | |
881 | { &CLSID_AviSplitter, | |
882 | &CLSID_LegacyAmFilterCategory, | |
883 | {'A','V','I',' ','S','p','l','i','t','t','e','r',0}, | |
884 | 0x600000, | |
885 | { { 0, | |
886 | { { &MEDIATYPE_Stream, &MEDIASUBTYPE_Avi }, | |
887 | { NULL } | |
888 | }, | |
889 | }, | |
890 | { REG_PINFLAG_B_OUTPUT, | |
891 | { { &MEDIATYPE_Video, &GUID_NULL }, | |
892 | { NULL } | |
893 | }, | |
894 | }, | |
895 | { 0xFFFFFFFF }, | |
896 | } | |
897 | }, | |
b3fab140 CR |
898 | { &CLSID_MPEG1Splitter, |
899 | &CLSID_LegacyAmFilterCategory, | |
900 | {'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0}, | |
901 | 0x600000, | |
902 | { { 0, | |
903 | { { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio }, | |
904 | { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Video }, | |
905 | { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1System }, | |
906 | { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1VideoCD }, | |
907 | { NULL } | |
908 | }, | |
909 | }, | |
910 | { REG_PINFLAG_B_OUTPUT, | |
911 | { { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1Packet }, | |
912 | { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload }, | |
913 | { NULL } | |
914 | }, | |
915 | }, | |
916 | { REG_PINFLAG_B_OUTPUT, | |
917 | { { &MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Packet }, | |
918 | { &MEDIATYPE_Video, &MEDIASUBTYPE_MPEG1Payload }, | |
919 | { NULL } | |
920 | }, | |
921 | }, | |
922 | { 0xFFFFFFFF }, | |
923 | } | |
924 | }, | |
e1867dac ML |
925 | { &CLSID_NullRenderer, |
926 | &CLSID_LegacyAmFilterCategory, | |
927 | {'N','u','l','l',' ','R','e','n','d','e','r','e','r',0}, | |
928 | 0x200000, | |
929 | { { REG_PINFLAG_B_RENDERER, | |
930 | { { &MEDIATYPE_NULL, &GUID_NULL }, | |
931 | { NULL } | |
932 | }, | |
933 | }, | |
934 | { 0xFFFFFFFF }, | |
935 | } | |
936 | }, | |
617dc088 CC |
937 | { &CLSID_VideoRenderer, |
938 | &CLSID_LegacyAmFilterCategory, | |
939 | {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0}, | |
940 | 0x800000, | |
941 | { { REG_PINFLAG_B_RENDERER, | |
942 | { { &MEDIATYPE_Video, &GUID_NULL }, | |
943 | { NULL } | |
944 | }, | |
945 | }, | |
946 | { 0xFFFFFFFF }, | |
947 | } | |
948 | }, | |
9742724a LZ |
949 | { &CLSID_VideoRendererDefault, |
950 | &CLSID_LegacyAmFilterCategory, | |
951 | {'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0}, | |
952 | 0x800000, | |
953 | { { REG_PINFLAG_B_RENDERER, | |
954 | { { &MEDIATYPE_Video, &GUID_NULL }, | |
955 | { NULL } | |
956 | }, | |
957 | }, | |
958 | { 0xFFFFFFFF }, | |
959 | } | |
960 | }, | |
4c09284c ML |
961 | { &CLSID_DSoundRender, |
962 | &CLSID_LegacyAmFilterCategory, | |
963 | {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0}, | |
964 | 0x800000, | |
965 | { { REG_PINFLAG_B_RENDERER, | |
966 | { { &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM }, | |
8b65914c ML |
967 | /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */ |
968 | { NULL } | |
969 | }, | |
970 | }, | |
971 | { 0xFFFFFFFF }, | |
972 | } | |
973 | }, | |
974 | { &CLSID_AudioRender, | |
975 | &CLSID_LegacyAmFilterCategory, | |
976 | {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0}, | |
977 | 0x800000, | |
978 | { { REG_PINFLAG_B_RENDERER, | |
979 | { { &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM }, | |
4c09284c ML |
980 | /* { &MEDIATYPE_Audio, &MEDIASUBTYPE_IEEE_FLOAT }, */ |
981 | { NULL } | |
982 | }, | |
983 | }, | |
984 | { 0xFFFFFFFF }, | |
985 | } | |
986 | }, | |
617dc088 CC |
987 | { &CLSID_AVIDec, |
988 | &CLSID_LegacyAmFilterCategory, | |
989 | {'A','V','I',' ','D','e','c','o','m','p','r','e','s','s','o','r',0}, | |
990 | 0x600000, | |
991 | { { 0, | |
992 | { { &MEDIATYPE_Video, &GUID_NULL }, | |
993 | { NULL } | |
994 | }, | |
995 | }, | |
996 | { REG_PINFLAG_B_OUTPUT, | |
997 | { { &MEDIATYPE_Video, &GUID_NULL }, | |
998 | { NULL } | |
999 | }, | |
1000 | }, | |
1001 | { 0xFFFFFFFF }, | |
1002 | } | |
1003 | }, | |
1004 | { &CLSID_AsyncReader, | |
1005 | &CLSID_LegacyAmFilterCategory, | |
1006 | {'F','i','l','e',' ','S','o','u','r','c','e',' ','(','A','s','y','n','c','.',')',0}, | |
1007 | 0x400000, | |
1008 | { { REG_PINFLAG_B_OUTPUT, | |
1009 | { { &MEDIATYPE_Stream, &GUID_NULL }, | |
1010 | { NULL } | |
1011 | }, | |
1012 | }, | |
1013 | { 0xFFFFFFFF }, | |
1014 | } | |
1015 | }, | |
72213b18 CC |
1016 | { &CLSID_ACMWrapper, |
1017 | &CLSID_LegacyAmFilterCategory, | |
1018 | {'A','C','M',' ','W','r','a','p','p','e','r',0}, | |
1019 | 0x600000, | |
1020 | { { 0, | |
1021 | { { &MEDIATYPE_Audio, &GUID_NULL }, | |
1022 | { NULL } | |
1023 | }, | |
1024 | }, | |
1025 | { REG_PINFLAG_B_OUTPUT, | |
1026 | { { &MEDIATYPE_Audio, &GUID_NULL }, | |
1027 | { NULL } | |
1028 | }, | |
1029 | }, | |
1030 | { 0xFFFFFFFF }, | |
1031 | } | |
1032 | }, | |
80a2e6e9 CC |
1033 | { &CLSID_WAVEParser, |
1034 | &CLSID_LegacyAmFilterCategory, | |
1035 | {'W','a','v','e',' ','P','a','r','s','e','r',0}, | |
1036 | 0x400000, | |
1037 | { { 0, | |
1038 | { { &MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE }, | |
1039 | { &MEDIATYPE_Stream, &MEDIASUBTYPE_AU }, | |
1040 | { &MEDIATYPE_Stream, &MEDIASUBTYPE_AIFF }, | |
1041 | { NULL } | |
1042 | }, | |
1043 | }, | |
1044 | { REG_PINFLAG_B_OUTPUT, | |
1045 | { { &MEDIATYPE_Audio, &GUID_NULL }, | |
1046 | { NULL } | |
1047 | }, | |
1048 | }, | |
1049 | { 0xFFFFFFFF }, | |
1050 | } | |
1051 | }, | |
617dc088 CC |
1052 | { NULL } /* list terminator */ |
1053 | }; | |
1054 | ||
c81ac66d AJ |
1055 | extern HRESULT WINAPI QUARTZ_DllRegisterServer(void) DECLSPEC_HIDDEN; |
1056 | extern HRESULT WINAPI QUARTZ_DllUnregisterServer(void) DECLSPEC_HIDDEN; | |
1057 | ||
2c296648 JH |
1058 | /*********************************************************************** |
1059 | * DllRegisterServer (QUARTZ.@) | |
1060 | */ | |
54160222 | 1061 | HRESULT WINAPI DllRegisterServer(void) |
2c296648 JH |
1062 | { |
1063 | HRESULT hr; | |
1064 | ||
1065 | TRACE("\n"); | |
1066 | ||
c81ac66d AJ |
1067 | hr = QUARTZ_DllRegisterServer(); |
1068 | if (SUCCEEDED(hr)) | |
1069 | hr = register_coclasses(coclass_list); | |
2c296648 JH |
1070 | if (SUCCEEDED(hr)) |
1071 | hr = register_interfaces(interface_list); | |
18511a38 CC |
1072 | if (SUCCEEDED(hr)) |
1073 | hr = register_mediatypes_parsing(mediatype_parsing_list); | |
1074 | if (SUCCEEDED(hr)) | |
1075 | hr = register_mediatypes_extension(mediatype_extension_list); | |
617dc088 CC |
1076 | if (SUCCEEDED(hr)) |
1077 | hr = register_filters(filter_list); | |
2c296648 JH |
1078 | return hr; |
1079 | } | |
1080 | ||
1081 | /*********************************************************************** | |
1082 | * DllUnregisterServer (QUARTZ.@) | |
1083 | */ | |
54160222 | 1084 | HRESULT WINAPI DllUnregisterServer(void) |
2c296648 JH |
1085 | { |
1086 | HRESULT hr; | |
1087 | ||
1088 | TRACE("\n"); | |
1089 | ||
617dc088 CC |
1090 | hr = unregister_filters(filter_list); |
1091 | if (SUCCEEDED(hr)) | |
1092 | hr = unregister_coclasses(coclass_list); | |
2c296648 JH |
1093 | if (SUCCEEDED(hr)) |
1094 | hr = unregister_interfaces(interface_list); | |
18511a38 CC |
1095 | if (SUCCEEDED(hr)) |
1096 | hr = unregister_mediatypes_parsing(mediatype_parsing_list); | |
1097 | if (SUCCEEDED(hr)) | |
1098 | hr = unregister_mediatypes_extension(mediatype_extension_list); | |
c81ac66d AJ |
1099 | if (SUCCEEDED(hr)) |
1100 | hr = QUARTZ_DllUnregisterServer(); | |
2c296648 JH |
1101 | return hr; |
1102 | } |