~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/dsound/regsvr.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  *      self-registerable dll functions for dsound.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
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include <stdarg.h>
 22 
 23 #define NONAMELESSSTRUCT
 24 #define NONAMELESSUNION
 25 #include "windef.h"
 26 #include "winbase.h"
 27 #include "winuser.h"
 28 #include "winreg.h"
 29 
 30 #include "mmsystem.h"
 31 #include "dsound.h"
 32 
 33 #include "wine/debug.h"
 34 #include "wine/unicode.h"
 35 
 36 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
 37 
 38 static LSTATUS (WINAPI *pRegDeleteTreeW)(HKEY,LPCWSTR);
 39 static LSTATUS (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
 40 
 41 /*
 42  * Near the bottom of this file are the exported DllRegisterServer and
 43  * DllUnregisterServer, which make all this worthwhile.
 44  */
 45 
 46 /***********************************************************************
 47  *              interface for self-registering
 48  */
 49 struct regsvr_interface
 50 {
 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 */
 57 };
 58 
 59 static HRESULT register_interfaces(struct regsvr_interface const *list);
 60 static HRESULT unregister_interfaces(struct regsvr_interface const *list);
 61 
 62 struct regsvr_coclass
 63 {
 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 */
 72 };
 73 
 74 static HRESULT register_coclasses(struct regsvr_coclass const *list);
 75 static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
 76 
 77 /***********************************************************************
 78  *              static string constants
 79  */
 80 static WCHAR const interface_keyname[10] = {
 81     'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
 82 static WCHAR const base_ifa_keyname[14] = {
 83     'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
 84     'e', 0 };
 85 static WCHAR const num_methods_keyname[11] = {
 86     'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
 87 static WCHAR const ps_clsid_keyname[15] = {
 88     'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
 89     'i', 'd', 0 };
 90 static WCHAR const ps_clsid32_keyname[17] = {
 91     'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
 92     'i', 'd', '3', '2', 0 };
 93 static WCHAR const clsid_keyname[6] = {
 94     'C', 'L', 'S', 'I', 'D', 0 };
 95 static WCHAR const curver_keyname[7] = {
 96     'C', 'u', 'r', 'V', 'e', 'r', 0 };
 97 static WCHAR const ips_keyname[13] = {
 98     'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
 99     0 };
100 static WCHAR const ips32_keyname[15] = {
101     'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
102     '3', '2', 0 };
103 static WCHAR const progid_keyname[7] = {
104     'P', 'r', 'o', 'g', 'I', 'D', 0 };
105 static WCHAR const viprogid_keyname[25] = {
106     'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
107     'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
108     0 };
109 static char const tmodel_valuename[] = "ThreadingModel";
110 
111 /***********************************************************************
112  *              static helper functions
113  */
114 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
115 static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
116                                    WCHAR const *value);
117 static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
118                                    char const *value);
119 static LONG register_progid(WCHAR const *clsid,
120                             char const *progid, char const *curver_progid,
121                             char const *name, char const *extra);
122 
123 /***********************************************************************
124  *              register_interfaces
125  */
126 static HRESULT register_interfaces(struct regsvr_interface const *list)
127 {
128     LONG res = ERROR_SUCCESS;
129     HKEY interface_key;
130 
131     res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
132                           KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
133     if (res != ERROR_SUCCESS) goto error_return;
134 
135     for (; res == ERROR_SUCCESS && list->iid; ++list) {
136         WCHAR buf[39];
137         HKEY iid_key;
138 
139         StringFromGUID2(list->iid, buf, 39);
140         res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
141                               KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
142         if (res != ERROR_SUCCESS) goto error_close_interface_key;
143 
144         if (list->name) {
145             res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
146                                  (CONST BYTE*)(list->name),
147                                  strlen(list->name) + 1);
148             if (res != ERROR_SUCCESS) goto error_close_iid_key;
149         }
150 
151         if (list->base_iid) {
152             res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
153             if (res != ERROR_SUCCESS) goto error_close_iid_key;
154         }
155 
156         if (0 <= list->num_methods) {
157             static WCHAR const fmt[3] = { '%', 'd', 0 };
158             HKEY key;
159 
160             res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
161                                   KEY_READ | KEY_WRITE, NULL, &key, NULL);
162             if (res != ERROR_SUCCESS) goto error_close_iid_key;
163 
164             sprintfW(buf, fmt, list->num_methods);
165             res = RegSetValueExW(key, NULL, 0, REG_SZ,
166                                  (CONST BYTE*)buf,
167                                  (lstrlenW(buf) + 1) * sizeof(WCHAR));
168             RegCloseKey(key);
169 
170             if (res != ERROR_SUCCESS) goto error_close_iid_key;
171         }
172 
173         if (list->ps_clsid) {
174             res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
175             if (res != ERROR_SUCCESS) goto error_close_iid_key;
176         }
177 
178         if (list->ps_clsid32) {
179             res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
180             if (res != ERROR_SUCCESS) goto error_close_iid_key;
181         }
182 
183     error_close_iid_key:
184         RegCloseKey(iid_key);
185     }
186 
187 error_close_interface_key:
188     RegCloseKey(interface_key);
189 error_return:
190     return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
191 }
192 
193 /***********************************************************************
194  *              unregister_interfaces
195  */
196 static HRESULT unregister_interfaces(struct regsvr_interface const *list)
197 {
198     LONG res = ERROR_SUCCESS;
199     HKEY interface_key;
200 
201     res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
202                         KEY_READ | KEY_WRITE, &interface_key);
203     if (res == ERROR_FILE_NOT_FOUND) return S_OK;
204     if (res != ERROR_SUCCESS) goto error_return;
205 
206     for (; res == ERROR_SUCCESS && list->iid; ++list) {
207         WCHAR buf[39];
208 
209         StringFromGUID2(list->iid, buf, 39);
210         res = pRegDeleteTreeW(interface_key, buf);
211         if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
212     }
213 
214     RegCloseKey(interface_key);
215 error_return:
216     return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
217 }
218 
219 /***********************************************************************
220  *              register_coclasses
221  */
222 static HRESULT register_coclasses(struct regsvr_coclass const *list)
223 {
224     LONG res = ERROR_SUCCESS;
225     HKEY coclass_key;
226 
227     res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
228                           KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
229     if (res != ERROR_SUCCESS) goto error_return;
230 
231     for (; res == ERROR_SUCCESS && list->clsid; ++list) {
232         WCHAR buf[39];
233         HKEY clsid_key;
234 
235         StringFromGUID2(list->clsid, buf, 39);
236         res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
237                               KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
238         if (res != ERROR_SUCCESS) goto error_close_coclass_key;
239 
240         if (list->name) {
241             res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
242                                  (CONST BYTE*)(list->name),
243                                  strlen(list->name) + 1);
244             if (res != ERROR_SUCCESS) goto error_close_clsid_key;
245         }
246 
247         if (list->ips) {
248             res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
249             if (res != ERROR_SUCCESS) goto error_close_clsid_key;
250         }
251 
252         if (list->ips32) {
253             HKEY ips32_key;
254 
255             res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
256                                   KEY_READ | KEY_WRITE, NULL,
257                                   &ips32_key, NULL);
258             if (res != ERROR_SUCCESS) goto error_close_clsid_key;
259 
260             res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
261                                  (CONST BYTE*)list->ips32,
262                                  lstrlenA(list->ips32) + 1);
263             if (res == ERROR_SUCCESS && list->ips32_tmodel)
264                 res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
265                                      (CONST BYTE*)list->ips32_tmodel,
266                                      strlen(list->ips32_tmodel) + 1);
267             RegCloseKey(ips32_key);
268             if (res != ERROR_SUCCESS) goto error_close_clsid_key;
269         }
270 
271         if (list->progid) {
272             res = register_key_defvalueA(clsid_key, progid_keyname,
273                                          list->progid);
274             if (res != ERROR_SUCCESS) goto error_close_clsid_key;
275 
276             res = register_progid(buf, list->progid, NULL,
277                                   list->name, list->progid_extra);
278             if (res != ERROR_SUCCESS) goto error_close_clsid_key;
279         }
280 
281         if (list->viprogid) {
282             res = register_key_defvalueA(clsid_key, viprogid_keyname,
283                                          list->viprogid);
284             if (res != ERROR_SUCCESS) goto error_close_clsid_key;
285 
286             res = register_progid(buf, list->viprogid, list->progid,
287                                   list->name, list->progid_extra);
288             if (res != ERROR_SUCCESS) goto error_close_clsid_key;
289         }
290 
291     error_close_clsid_key:
292         RegCloseKey(clsid_key);
293     }
294 
295 error_close_coclass_key:
296     RegCloseKey(coclass_key);
297 error_return:
298     return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
299 }
300 
301 /***********************************************************************
302  *              unregister_coclasses
303  */
304 static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
305 {
306     LONG res = ERROR_SUCCESS;
307     HKEY coclass_key;
308 
309     res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
310                         KEY_READ | KEY_WRITE, &coclass_key);
311     if (res == ERROR_FILE_NOT_FOUND) return S_OK;
312     if (res != ERROR_SUCCESS) goto error_return;
313 
314     for (; res == ERROR_SUCCESS && list->clsid; ++list) {
315         WCHAR buf[39];
316 
317         StringFromGUID2(list->clsid, buf, 39);
318         res = pRegDeleteTreeW(coclass_key, buf);
319         if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
320         if (res != ERROR_SUCCESS) goto error_close_coclass_key;
321 
322         if (list->progid) {
323             res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
324             if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
325             if (res != ERROR_SUCCESS) goto error_close_coclass_key;
326         }
327 
328         if (list->viprogid) {
329             res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
330             if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
331             if (res != ERROR_SUCCESS) goto error_close_coclass_key;
332         }
333     }
334 
335 error_close_coclass_key:
336     RegCloseKey(coclass_key);
337 error_return:
338     return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
339 }
340 
341 /***********************************************************************
342  *              regsvr_key_guid
343  */
344 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
345 {
346     WCHAR buf[39];
347 
348     StringFromGUID2(guid, buf, 39);
349     return register_key_defvalueW(base, name, buf);
350 }
351 
352 /***********************************************************************
353  *              regsvr_key_defvalueW
354  */
355 static LONG register_key_defvalueW(
356     HKEY base,
357     WCHAR const *name,
358     WCHAR const *value)
359 {
360     LONG res;
361     HKEY key;
362 
363     res = RegCreateKeyExW(base, name, 0, NULL, 0,
364                           KEY_READ | KEY_WRITE, NULL, &key, NULL);
365     if (res != ERROR_SUCCESS) return res;
366     res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
367                          (lstrlenW(value) + 1) * sizeof(WCHAR));
368     RegCloseKey(key);
369     return res;
370 }
371 
372 /***********************************************************************
373  *              regsvr_key_defvalueA
374  */
375 static LONG register_key_defvalueA(
376     HKEY base,
377     WCHAR const *name,
378     char const *value)
379 {
380     LONG res;
381     HKEY key;
382 
383     res = RegCreateKeyExW(base, name, 0, NULL, 0,
384                           KEY_READ | KEY_WRITE, NULL, &key, NULL);
385     if (res != ERROR_SUCCESS) return res;
386     res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
387                          lstrlenA(value) + 1);
388     RegCloseKey(key);
389     return res;
390 }
391 
392 /***********************************************************************
393  *              regsvr_progid
394  */
395 static LONG register_progid(
396     WCHAR const *clsid,
397     char const *progid,
398     char const *curver_progid,
399     char const *name,
400     char const *extra)
401 {
402     LONG res;
403     HKEY progid_key;
404 
405     res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
406                           NULL, 0, KEY_READ | KEY_WRITE, NULL,
407                           &progid_key, NULL);
408     if (res != ERROR_SUCCESS) return res;
409 
410     if (name) {
411         res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
412                              (CONST BYTE*)name, strlen(name) + 1);
413         if (res != ERROR_SUCCESS) goto error_close_progid_key;
414     }
415 
416     if (clsid) {
417         res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
418         if (res != ERROR_SUCCESS) goto error_close_progid_key;
419     }
420 
421     if (curver_progid) {
422         res = register_key_defvalueA(progid_key, curver_keyname,
423                                      curver_progid);
424         if (res != ERROR_SUCCESS) goto error_close_progid_key;
425     }
426 
427     if (extra) {
428         HKEY extra_key;
429 
430         res = RegCreateKeyExA(progid_key, extra, 0,
431                               NULL, 0, KEY_READ | KEY_WRITE, NULL,
432                               &extra_key, NULL);
433         if (res == ERROR_SUCCESS)
434             RegCloseKey(extra_key);
435     }
436 
437 error_close_progid_key:
438     RegCloseKey(progid_key);
439     return res;
440 }
441 
442 /***********************************************************************
443  *              coclass list
444  */
445 static GUID const CLSID_DirectSoundBufferConfig = {
446     0xB2F586D4, 0x5558, 0x49D1, {0xA0,0x7B,0x32,0x49,0xDB,0xBB,0x33,0xC2} };
447 
448 static struct regsvr_coclass const coclass_list[] = {
449     {   &CLSID_DirectSound,
450         "DirectSound Object",
451         NULL,
452         "dsound.dll",
453         "Both"
454     },
455     {   &CLSID_DirectSound8,
456         "DirectSound 8.0 Object",
457         NULL,
458         "dsound.dll",
459         "Both"
460     },
461     {   &CLSID_DirectSoundBufferConfig,
462         "DirectSoundBufferConfig Object",
463         NULL,
464         "dsound.dll",
465         "Both"
466     },
467     {   &CLSID_DirectSoundCapture,
468         "DirectSoundCapture Object",
469         NULL,
470         "dsound.dll",
471         "Both"
472     },
473     {   &CLSID_DirectSoundCapture8,
474         "DirectSoundCapture 8.0 Object",
475         NULL,
476         "dsound.dll",
477         "Both"
478     },
479     {   &CLSID_DirectSoundFullDuplex,
480         "DirectSoundFullDuplex Object",
481         NULL,
482         "dsound.dll",
483         "Both"
484     },
485     { NULL }                    /* list terminator */
486 };
487 
488 /***********************************************************************
489  *              interface list
490  */
491 
492 static struct regsvr_interface const interface_list[] = {
493     { NULL }                    /* list terminator */
494 };
495 
496 /***********************************************************************
497  *              DllRegisterServer (DSOUND.@)
498  */
499 HRESULT WINAPI DllRegisterServer(void)
500 {
501     HRESULT hr;
502 
503     TRACE("\n");
504 
505     hr = register_coclasses(coclass_list);
506     if (SUCCEEDED(hr))
507         hr = register_interfaces(interface_list);
508     return hr;
509 }
510 
511 /***********************************************************************
512  *              DllUnregisterServer (DSOUND.@)
513  */
514 HRESULT WINAPI DllUnregisterServer(void)
515 {
516     HRESULT hr;
517 
518     HMODULE advapi32 = GetModuleHandleA("advapi32");
519     if (!advapi32) return E_FAIL;
520     pRegDeleteTreeA = (void *) GetProcAddress(advapi32, "RegDeleteTreeA");
521     pRegDeleteTreeW = (void *) GetProcAddress(advapi32, "RegDeleteTreeW");
522     if (!pRegDeleteTreeA || !pRegDeleteTreeW) return E_FAIL;
523 
524     TRACE("\n");
525 
526     hr = unregister_coclasses(coclass_list);
527     if (SUCCEEDED(hr))
528         hr = unregister_interfaces(interface_list);
529     return hr;
530 }
531 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.