ReactOS  0.4.14-dev-49-gfb4591c
regsvr.c
Go to the documentation of this file.
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 "precomp.h"
22 
23 static LSTATUS (WINAPI *pRegDeleteTreeW)(HKEY,LPCWSTR);
24 static LSTATUS (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
25 
26 /*
27  * Near the bottom of this file are the exported DllRegisterServer and
28  * DllUnregisterServer, which make all this worthwhile.
29  */
30 
31 /***********************************************************************
32  * interface for self-registering
33  */
35 {
36  IID const *iid; /* NULL for end of list */
37  LPCSTR name; /* can be NULL to omit */
38  IID const *base_iid; /* can be NULL to omit */
39  int num_methods; /* can be <0 to omit */
40  CLSID const *ps_clsid; /* can be NULL to omit */
41  CLSID const *ps_clsid32; /* can be NULL to omit */
42 };
43 
44 static HRESULT register_interfaces(struct regsvr_interface const *list);
46 
48 {
49  CLSID const *clsid; /* NULL for end of list */
50  LPCSTR name; /* can be NULL to omit */
51  LPCSTR ips; /* can be NULL to omit */
52  LPCSTR ips32; /* can be NULL to omit */
53  LPCSTR ips32_tmodel; /* can be NULL to omit */
54  LPCSTR progid; /* can be NULL to omit */
55  LPCSTR viprogid; /* can be NULL to omit */
56  LPCSTR progid_extra; /* can be NULL to omit */
57 };
58 
59 static HRESULT register_coclasses(struct regsvr_coclass const *list);
60 static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
61 
62 /***********************************************************************
63  * static string constants
64  */
65 static WCHAR const interface_keyname[10] = {
66  'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
67 static WCHAR const base_ifa_keyname[14] = {
68  'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
69  'e', 0 };
70 static WCHAR const num_methods_keyname[11] = {
71  'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
72 static WCHAR const ps_clsid_keyname[15] = {
73  'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
74  'i', 'd', 0 };
75 static WCHAR const ps_clsid32_keyname[17] = {
76  'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
77  'i', 'd', '3', '2', 0 };
78 static WCHAR const clsid_keyname[6] = {
79  'C', 'L', 'S', 'I', 'D', 0 };
80 static WCHAR const curver_keyname[7] = {
81  'C', 'u', 'r', 'V', 'e', 'r', 0 };
82 static WCHAR const ips_keyname[13] = {
83  'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
84  0 };
85 static WCHAR const ips32_keyname[15] = {
86  'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
87  '3', '2', 0 };
88 static WCHAR const progid_keyname[7] = {
89  'P', 'r', 'o', 'g', 'I', 'D', 0 };
90 static WCHAR const viprogid_keyname[25] = {
91  'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
92  'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
93  0 };
94 static char const tmodel_valuename[] = "ThreadingModel";
95 
96 /***********************************************************************
97  * static helper functions
98  */
99 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
101  WCHAR const *value);
103  char const *value);
104 static LONG register_progid(WCHAR const *clsid,
105  char const *progid, char const *curver_progid,
106  char const *name, char const *extra);
107 
108 /***********************************************************************
109  * register_interfaces
110  */
112 {
114  HKEY interface_key;
115 
117  KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
118  if (res != ERROR_SUCCESS) goto error_return;
119 
120  for (; res == ERROR_SUCCESS && list->iid; ++list) {
121  WCHAR buf[39];
122  HKEY iid_key;
123 
124  StringFromGUID2(list->iid, buf, 39);
125  res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
126  KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
127  if (res != ERROR_SUCCESS) goto error_close_interface_key;
128 
129  if (list->name) {
130  res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
131  (CONST BYTE*)(list->name),
132  strlen(list->name) + 1);
133  if (res != ERROR_SUCCESS) goto error_close_iid_key;
134  }
135 
136  if (list->base_iid) {
137  res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
138  if (res != ERROR_SUCCESS) goto error_close_iid_key;
139  }
140 
141  if (0 <= list->num_methods) {
142  static WCHAR const fmt[3] = { '%', 'd', 0 };
143  HKEY key;
144 
145  res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
146  KEY_READ | KEY_WRITE, NULL, &key, NULL);
147  if (res != ERROR_SUCCESS) goto error_close_iid_key;
148 
149  swprintf(buf, fmt, list->num_methods);
151  (CONST BYTE*)buf,
152  (lstrlenW(buf) + 1) * sizeof(WCHAR));
153  RegCloseKey(key);
154 
155  if (res != ERROR_SUCCESS) goto error_close_iid_key;
156  }
157 
158  if (list->ps_clsid) {
159  res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
160  if (res != ERROR_SUCCESS) goto error_close_iid_key;
161  }
162 
163  if (list->ps_clsid32) {
164  res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
165  if (res != ERROR_SUCCESS) goto error_close_iid_key;
166  }
167 
168  error_close_iid_key:
169  RegCloseKey(iid_key);
170  }
171 
172 error_close_interface_key:
173  RegCloseKey(interface_key);
174 error_return:
176 }
177 
178 /***********************************************************************
179  * unregister_interfaces
180  */
182 {
184  HKEY interface_key;
185 
187  KEY_READ | KEY_WRITE, &interface_key);
188  if (res == ERROR_FILE_NOT_FOUND) return S_OK;
189  if (res != ERROR_SUCCESS) goto error_return;
190 
191  for (; res == ERROR_SUCCESS && list->iid; ++list) {
192  WCHAR buf[39];
193 
194  StringFromGUID2(list->iid, buf, 39);
195  res = pRegDeleteTreeW(interface_key, buf);
197  }
198 
199  RegCloseKey(interface_key);
200 error_return:
202 }
203 
204 /***********************************************************************
205  * register_coclasses
206  */
208 {
210  HKEY coclass_key;
211 
213  KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
214  if (res != ERROR_SUCCESS) goto error_return;
215 
216  for (; res == ERROR_SUCCESS && list->clsid; ++list) {
217  WCHAR buf[39];
218  HKEY clsid_key;
219 
220  StringFromGUID2(list->clsid, buf, 39);
221  res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
222  KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
223  if (res != ERROR_SUCCESS) goto error_close_coclass_key;
224 
225  if (list->name) {
226  res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
227  (CONST BYTE*)(list->name),
228  strlen(list->name) + 1);
229  if (res != ERROR_SUCCESS) goto error_close_clsid_key;
230  }
231 
232  if (list->ips) {
233  res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
234  if (res != ERROR_SUCCESS) goto error_close_clsid_key;
235  }
236 
237  if (list->ips32) {
238  HKEY ips32_key;
239 
240  res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
242  &ips32_key, NULL);
243  if (res != ERROR_SUCCESS) goto error_close_clsid_key;
244 
245  res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
246  (CONST BYTE*)list->ips32,
247  lstrlenA(list->ips32) + 1);
248  if (res == ERROR_SUCCESS && list->ips32_tmodel)
249  res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
250  (CONST BYTE*)list->ips32_tmodel,
251  strlen(list->ips32_tmodel) + 1);
252  RegCloseKey(ips32_key);
253  if (res != ERROR_SUCCESS) goto error_close_clsid_key;
254  }
255 
256  if (list->progid) {
258  list->progid);
259  if (res != ERROR_SUCCESS) goto error_close_clsid_key;
260 
261  res = register_progid(buf, list->progid, NULL,
262  list->name, list->progid_extra);
263  if (res != ERROR_SUCCESS) goto error_close_clsid_key;
264  }
265 
266  if (list->viprogid) {
268  list->viprogid);
269  if (res != ERROR_SUCCESS) goto error_close_clsid_key;
270 
271  res = register_progid(buf, list->viprogid, list->progid,
272  list->name, list->progid_extra);
273  if (res != ERROR_SUCCESS) goto error_close_clsid_key;
274  }
275 
276  error_close_clsid_key:
277  RegCloseKey(clsid_key);
278  }
279 
280 error_close_coclass_key:
281  RegCloseKey(coclass_key);
282 error_return:
284 }
285 
286 /***********************************************************************
287  * unregister_coclasses
288  */
290 {
292  HKEY coclass_key;
293 
295  KEY_READ | KEY_WRITE, &coclass_key);
296  if (res == ERROR_FILE_NOT_FOUND) return S_OK;
297  if (res != ERROR_SUCCESS) goto error_return;
298 
299  for (; res == ERROR_SUCCESS && list->clsid; ++list) {
300  WCHAR buf[39];
301 
302  StringFromGUID2(list->clsid, buf, 39);
303  res = pRegDeleteTreeW(coclass_key, buf);
305  if (res != ERROR_SUCCESS) goto error_close_coclass_key;
306 
307  if (list->progid) {
308  res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
310  if (res != ERROR_SUCCESS) goto error_close_coclass_key;
311  }
312 
313  if (list->viprogid) {
314  res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
316  if (res != ERROR_SUCCESS) goto error_close_coclass_key;
317  }
318  }
319 
320 error_close_coclass_key:
321  RegCloseKey(coclass_key);
322 error_return:
324 }
325 
326 /***********************************************************************
327  * regsvr_key_guid
328  */
330 {
331  WCHAR buf[39];
332 
333  StringFromGUID2(guid, buf, 39);
335 }
336 
337 /***********************************************************************
338  * regsvr_key_defvalueW
339  */
341  HKEY base,
342  WCHAR const *name,
343  WCHAR const *value)
344 {
345  LONG res;
346  HKEY key;
347 
348  res = RegCreateKeyExW(base, name, 0, NULL, 0,
349  KEY_READ | KEY_WRITE, NULL, &key, NULL);
350  if (res != ERROR_SUCCESS) return res;
352  (lstrlenW(value) + 1) * sizeof(WCHAR));
353  RegCloseKey(key);
354  return res;
355 }
356 
357 /***********************************************************************
358  * regsvr_key_defvalueA
359  */
361  HKEY base,
362  WCHAR const *name,
363  char const *value)
364 {
365  LONG res;
366  HKEY key;
367 
368  res = RegCreateKeyExW(base, name, 0, NULL, 0,
369  KEY_READ | KEY_WRITE, NULL, &key, NULL);
370  if (res != ERROR_SUCCESS) return res;
372  lstrlenA(value) + 1);
373  RegCloseKey(key);
374  return res;
375 }
376 
377 /***********************************************************************
378  * regsvr_progid
379  */
381  WCHAR const *clsid,
382  char const *progid,
383  char const *curver_progid,
384  char const *name,
385  char const *extra)
386 {
387  LONG res;
388  HKEY progid_key;
389 
391  NULL, 0, KEY_READ | KEY_WRITE, NULL,
392  &progid_key, NULL);
393  if (res != ERROR_SUCCESS) return res;
394 
395  if (name) {
396  res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
397  (CONST BYTE*)name, strlen(name) + 1);
398  if (res != ERROR_SUCCESS) goto error_close_progid_key;
399  }
400 
401  if (clsid) {
403  if (res != ERROR_SUCCESS) goto error_close_progid_key;
404  }
405 
406  if (curver_progid) {
408  curver_progid);
409  if (res != ERROR_SUCCESS) goto error_close_progid_key;
410  }
411 
412  if (extra) {
413  HKEY extra_key;
414 
415  res = RegCreateKeyExA(progid_key, extra, 0,
416  NULL, 0, KEY_READ | KEY_WRITE, NULL,
417  &extra_key, NULL);
418  if (res == ERROR_SUCCESS)
419  RegCloseKey(extra_key);
420  }
421 
422 error_close_progid_key:
423  RegCloseKey(progid_key);
424  return res;
425 }
426 
427 /***********************************************************************
428  * coclass list
429  */
431  0xB2F586D4, 0x5558, 0x49D1, {0xA0,0x7B,0x32,0x49,0xDB,0xBB,0x33,0xC2} };
432 
433 static struct regsvr_coclass const coclass_list[] = {
434  { &CLSID_DirectSound,
435  "DirectSound Object",
436  NULL,
437  "dsound.dll",
438  "Both"
439  },
440  { &CLSID_DirectSound8,
441  "DirectSound 8.0 Object",
442  NULL,
443  "dsound.dll",
444  "Both"
445  },
447  "DirectSoundBufferConfig Object",
448  NULL,
449  "dsound.dll",
450  "Both"
451  },
452  { &CLSID_DirectSoundCapture,
453  "DirectSoundCapture Object",
454  NULL,
455  "dsound.dll",
456  "Both"
457  },
458  { &CLSID_DirectSoundCapture8,
459  "DirectSoundCapture 8.0 Object",
460  NULL,
461  "dsound.dll",
462  "Both"
463  },
464  { &CLSID_DirectSoundFullDuplex,
465  "DirectSoundFullDuplex Object",
466  NULL,
467  "dsound.dll",
468  "Both"
469  },
470  { NULL } /* list terminator */
471 };
472 
473 /***********************************************************************
474  * interface list
475  */
476 
478  { NULL } /* list terminator */
479 };
480 
481 /***********************************************************************
482  * DllRegisterServer (DSOUND.@)
483  */
485 {
486  HRESULT hr;
487 
489  if (SUCCEEDED(hr))
491  return hr;
492 }
493 
494 /***********************************************************************
495  * DllUnregisterServer (DSOUND.@)
496  */
498 {
499  HRESULT hr;
500 
501  HMODULE advapi32 = GetModuleHandleA("advapi32");
502  if (!advapi32) return E_FAIL;
503  pRegDeleteTreeA = (void *) GetProcAddress(advapi32, "RegDeleteTreeA");
504  pRegDeleteTreeW = (void *) GetProcAddress(advapi32, "RegDeleteTreeW");
505  if (!pRegDeleteTreeA || !pRegDeleteTreeW) return E_FAIL;
506 
508  if (SUCCEEDED(hr))
510  return hr;
511 }
LPCSTR name
Definition: regsvr.c:37
static WCHAR const curver_keyname[7]
Definition: regsvr.c:80
IID const * iid
Definition: regsvr.c:36
CLSID const * ps_clsid32
Definition: regsvr.c:41
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define ERROR_SUCCESS
Definition: deptool.c:10
static WCHAR const ips32_keyname[15]
Definition: regsvr.c:85
HRESULT hr
Definition: shlfolder.c:183
HRESULT WINAPI DllRegisterServer(void)
Definition: regsvr.c:484
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
int num_methods
Definition: regsvr.c:39
#define KEY_READ
Definition: nt_native.h:1023
static struct regsvr_interface const interface_list[]
Definition: regsvr.c:477
CLSID const * ps_clsid
Definition: regsvr.c:40
static WCHAR const clsid_keyname[6]
Definition: regsvr.c:78
LPCSTR ips32
Definition: regsvr.c:52
#define lstrlenW
Definition: compat.h:407
#define E_FAIL
Definition: ddrawi.h:102
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
Definition: regsvr.c:329
const GUID * guid
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
long LONG
Definition: pedump.c:60
HRESULT WINAPI DllUnregisterServer(void)
Definition: regsvr.c:497
static LONG register_progid(WCHAR const *clsid, char const *progid, char const *curver_progid, char const *name, char const *extra)
Definition: regsvr.c:380
smooth NULL
Definition: ftsmooth.c:416
static WCHAR const progid_keyname[7]
Definition: regsvr.c:88
static WCHAR const interface_keyname[10]
Definition: regsvr.c:65
static WCHAR const ips_keyname[13]
Definition: regsvr.c:82
const char * LPCSTR
Definition: xmlstorage.h:183
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
LPCSTR progid
Definition: regsvr.c:54
CLSID const * clsid
Definition: regsvr.c:49
#define KEY_WRITE
Definition: nt_native.h:1031
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
static LONG register_key_defvalueA(HKEY base, WCHAR const *name, char const *value)
Definition: regsvr.c:360
LPCSTR progid_extra
Definition: regsvr.c:56
Definition: id3.c:18
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
static WCHAR const ps_clsid_keyname[15]
Definition: regsvr.c:72
static struct regsvr_coclass const coclass_list[]
Definition: regsvr.c:433
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define WINAPI
Definition: msvc.h:8
LPCSTR viprogid
Definition: regsvr.c:55
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2343
static HRESULT register_interfaces(struct regsvr_interface const *list)
Definition: regsvr.c:111
static LPCSTR
Definition: regsvr.c:24
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
LPCSTR name
Definition: regsvr.c:50
static HRESULT unregister_interfaces(struct regsvr_interface const *list)
Definition: regsvr.c:181
REFCLSID clsid
Definition: msctf.c:84
HKEY key
Definition: reg.c:42
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
unsigned char BYTE
Definition: mem.h:68
Definition: _list.h:228
static GUID const CLSID_DirectSoundBufferConfig
Definition: regsvr.c:430
IID const * base_iid
Definition: regsvr.c:38
static LONG register_key_defvalueW(HKEY base, WCHAR const *name, WCHAR const *value)
Definition: regsvr.c:340
static WCHAR const viprogid_keyname[25]
Definition: regsvr.c:90
#define S_OK
Definition: intsafe.h:59
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
static WCHAR const num_methods_keyname[11]
Definition: regsvr.c:70
#define list
Definition: rosglue.h:35
static HRESULT register_coclasses(struct regsvr_coclass const *list)
Definition: regsvr.c:207
static WCHAR const base_ifa_keyname[14]
Definition: regsvr.c:67
LPCSTR ips
Definition: regsvr.c:51
static WCHAR const ps_clsid32_keyname[17]
Definition: regsvr.c:75
Definition: name.c:36
GLuint res
Definition: glext.h:9613
static LPCWSTR
Definition: regsvr.c:23
HANDLE HKEY
Definition: registry.h:24
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define const
Definition: zconf.h:230
#define progid(str)
Definition: exdisp.idl:31
#define GetProcAddress(x, y)
Definition: compat.h:410
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
static char const tmodel_valuename[]
Definition: regsvr.c:94
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4812
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1029
LPCSTR ips32_tmodel
Definition: regsvr.c:53
static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
Definition: regsvr.c:289
Definition: dsound.c:943
#define CONST
Definition: pedump.c:81
#define SUCCEEDED(hr)
Definition: intsafe.h:57
Definition: path.c:42
#define REG_SZ
Definition: layer.c:22