Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenregsvr.c
Go to the documentation of this file.
00001 /* 00002 * self-registerable dll functions for dsound.dll 00003 * 00004 * Copyright (C) 2003 John K. Hohm 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "precomp.h" 00022 00023 static LSTATUS (WINAPI *pRegDeleteTreeW)(HKEY,LPCWSTR); 00024 static LSTATUS (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR); 00025 00026 /* 00027 * Near the bottom of this file are the exported DllRegisterServer and 00028 * DllUnregisterServer, which make all this worthwhile. 00029 */ 00030 00031 /*********************************************************************** 00032 * interface for self-registering 00033 */ 00034 struct regsvr_interface 00035 { 00036 IID const *iid; /* NULL for end of list */ 00037 LPCSTR name; /* can be NULL to omit */ 00038 IID const *base_iid; /* can be NULL to omit */ 00039 int num_methods; /* can be <0 to omit */ 00040 CLSID const *ps_clsid; /* can be NULL to omit */ 00041 CLSID const *ps_clsid32; /* can be NULL to omit */ 00042 }; 00043 00044 static HRESULT register_interfaces(struct regsvr_interface const *list); 00045 static HRESULT unregister_interfaces(struct regsvr_interface const *list); 00046 00047 struct regsvr_coclass 00048 { 00049 CLSID const *clsid; /* NULL for end of list */ 00050 LPCSTR name; /* can be NULL to omit */ 00051 LPCSTR ips; /* can be NULL to omit */ 00052 LPCSTR ips32; /* can be NULL to omit */ 00053 LPCSTR ips32_tmodel; /* can be NULL to omit */ 00054 LPCSTR progid; /* can be NULL to omit */ 00055 LPCSTR viprogid; /* can be NULL to omit */ 00056 LPCSTR progid_extra; /* can be NULL to omit */ 00057 }; 00058 00059 static HRESULT register_coclasses(struct regsvr_coclass const *list); 00060 static HRESULT unregister_coclasses(struct regsvr_coclass const *list); 00061 00062 /*********************************************************************** 00063 * static string constants 00064 */ 00065 static WCHAR const interface_keyname[10] = { 00066 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 }; 00067 static WCHAR const base_ifa_keyname[14] = { 00068 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 00069 'e', 0 }; 00070 static WCHAR const num_methods_keyname[11] = { 00071 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 }; 00072 static WCHAR const ps_clsid_keyname[15] = { 00073 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', 00074 'i', 'd', 0 }; 00075 static WCHAR const ps_clsid32_keyname[17] = { 00076 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', 00077 'i', 'd', '3', '2', 0 }; 00078 static WCHAR const clsid_keyname[6] = { 00079 'C', 'L', 'S', 'I', 'D', 0 }; 00080 static WCHAR const curver_keyname[7] = { 00081 'C', 'u', 'r', 'V', 'e', 'r', 0 }; 00082 static WCHAR const ips_keyname[13] = { 00083 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', 00084 0 }; 00085 static WCHAR const ips32_keyname[15] = { 00086 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', 00087 '3', '2', 0 }; 00088 static WCHAR const progid_keyname[7] = { 00089 'P', 'r', 'o', 'g', 'I', 'D', 0 }; 00090 static WCHAR const viprogid_keyname[25] = { 00091 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p', 00092 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D', 00093 0 }; 00094 static char const tmodel_valuename[] = "ThreadingModel"; 00095 00096 /*********************************************************************** 00097 * static helper functions 00098 */ 00099 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid); 00100 static LONG register_key_defvalueW(HKEY base, WCHAR const *name, 00101 WCHAR const *value); 00102 static LONG register_key_defvalueA(HKEY base, WCHAR const *name, 00103 char const *value); 00104 static LONG register_progid(WCHAR const *clsid, 00105 char const *progid, char const *curver_progid, 00106 char const *name, char const *extra); 00107 00108 /*********************************************************************** 00109 * register_interfaces 00110 */ 00111 static HRESULT register_interfaces(struct regsvr_interface const *list) 00112 { 00113 LONG res = ERROR_SUCCESS; 00114 HKEY interface_key; 00115 00116 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0, 00117 KEY_READ | KEY_WRITE, NULL, &interface_key, NULL); 00118 if (res != ERROR_SUCCESS) goto error_return; 00119 00120 for (; res == ERROR_SUCCESS && list->iid; ++list) { 00121 WCHAR buf[39]; 00122 HKEY iid_key; 00123 00124 StringFromGUID2(list->iid, buf, 39); 00125 res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0, 00126 KEY_READ | KEY_WRITE, NULL, &iid_key, NULL); 00127 if (res != ERROR_SUCCESS) goto error_close_interface_key; 00128 00129 if (list->name) { 00130 res = RegSetValueExA(iid_key, NULL, 0, REG_SZ, 00131 (CONST BYTE*)(list->name), 00132 strlen(list->name) + 1); 00133 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00134 } 00135 00136 if (list->base_iid) { 00137 res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid); 00138 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00139 } 00140 00141 if (0 <= list->num_methods) { 00142 static WCHAR const fmt[3] = { '%', 'd', 0 }; 00143 HKEY key; 00144 00145 res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0, 00146 KEY_READ | KEY_WRITE, NULL, &key, NULL); 00147 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00148 00149 swprintf(buf, fmt, list->num_methods); 00150 res = RegSetValueExW(key, NULL, 0, REG_SZ, 00151 (CONST BYTE*)buf, 00152 (lstrlenW(buf) + 1) * sizeof(WCHAR)); 00153 RegCloseKey(key); 00154 00155 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00156 } 00157 00158 if (list->ps_clsid) { 00159 res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid); 00160 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00161 } 00162 00163 if (list->ps_clsid32) { 00164 res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32); 00165 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00166 } 00167 00168 error_close_iid_key: 00169 RegCloseKey(iid_key); 00170 } 00171 00172 error_close_interface_key: 00173 RegCloseKey(interface_key); 00174 error_return: 00175 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 00176 } 00177 00178 /*********************************************************************** 00179 * unregister_interfaces 00180 */ 00181 static HRESULT unregister_interfaces(struct regsvr_interface const *list) 00182 { 00183 LONG res = ERROR_SUCCESS; 00184 HKEY interface_key; 00185 00186 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, 00187 KEY_READ | KEY_WRITE, &interface_key); 00188 if (res == ERROR_FILE_NOT_FOUND) return S_OK; 00189 if (res != ERROR_SUCCESS) goto error_return; 00190 00191 for (; res == ERROR_SUCCESS && list->iid; ++list) { 00192 WCHAR buf[39]; 00193 00194 StringFromGUID2(list->iid, buf, 39); 00195 res = pRegDeleteTreeW(interface_key, buf); 00196 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 00197 } 00198 00199 RegCloseKey(interface_key); 00200 error_return: 00201 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 00202 } 00203 00204 /*********************************************************************** 00205 * register_coclasses 00206 */ 00207 static HRESULT register_coclasses(struct regsvr_coclass const *list) 00208 { 00209 LONG res = ERROR_SUCCESS; 00210 HKEY coclass_key; 00211 00212 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 00213 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 00214 if (res != ERROR_SUCCESS) goto error_return; 00215 00216 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 00217 WCHAR buf[39]; 00218 HKEY clsid_key; 00219 00220 StringFromGUID2(list->clsid, buf, 39); 00221 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 00222 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); 00223 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 00224 00225 if (list->name) { 00226 res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ, 00227 (CONST BYTE*)(list->name), 00228 strlen(list->name) + 1); 00229 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00230 } 00231 00232 if (list->ips) { 00233 res = register_key_defvalueA(clsid_key, ips_keyname, list->ips); 00234 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00235 } 00236 00237 if (list->ips32) { 00238 HKEY ips32_key; 00239 00240 res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0, 00241 KEY_READ | KEY_WRITE, NULL, 00242 &ips32_key, NULL); 00243 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00244 00245 res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ, 00246 (CONST BYTE*)list->ips32, 00247 lstrlenA(list->ips32) + 1); 00248 if (res == ERROR_SUCCESS && list->ips32_tmodel) 00249 res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ, 00250 (CONST BYTE*)list->ips32_tmodel, 00251 strlen(list->ips32_tmodel) + 1); 00252 RegCloseKey(ips32_key); 00253 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00254 } 00255 00256 if (list->progid) { 00257 res = register_key_defvalueA(clsid_key, progid_keyname, 00258 list->progid); 00259 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00260 00261 res = register_progid(buf, list->progid, NULL, 00262 list->name, list->progid_extra); 00263 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00264 } 00265 00266 if (list->viprogid) { 00267 res = register_key_defvalueA(clsid_key, viprogid_keyname, 00268 list->viprogid); 00269 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00270 00271 res = register_progid(buf, list->viprogid, list->progid, 00272 list->name, list->progid_extra); 00273 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00274 } 00275 00276 error_close_clsid_key: 00277 RegCloseKey(clsid_key); 00278 } 00279 00280 error_close_coclass_key: 00281 RegCloseKey(coclass_key); 00282 error_return: 00283 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 00284 } 00285 00286 /*********************************************************************** 00287 * unregister_coclasses 00288 */ 00289 static HRESULT unregister_coclasses(struct regsvr_coclass const *list) 00290 { 00291 LONG res = ERROR_SUCCESS; 00292 HKEY coclass_key; 00293 00294 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 00295 KEY_READ | KEY_WRITE, &coclass_key); 00296 if (res == ERROR_FILE_NOT_FOUND) return S_OK; 00297 if (res != ERROR_SUCCESS) goto error_return; 00298 00299 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 00300 WCHAR buf[39]; 00301 00302 StringFromGUID2(list->clsid, buf, 39); 00303 res = pRegDeleteTreeW(coclass_key, buf); 00304 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 00305 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 00306 00307 if (list->progid) { 00308 res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); 00309 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 00310 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 00311 } 00312 00313 if (list->viprogid) { 00314 res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid); 00315 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 00316 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 00317 } 00318 } 00319 00320 error_close_coclass_key: 00321 RegCloseKey(coclass_key); 00322 error_return: 00323 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 00324 } 00325 00326 /*********************************************************************** 00327 * regsvr_key_guid 00328 */ 00329 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid) 00330 { 00331 WCHAR buf[39]; 00332 00333 StringFromGUID2(guid, buf, 39); 00334 return register_key_defvalueW(base, name, buf); 00335 } 00336 00337 /*********************************************************************** 00338 * regsvr_key_defvalueW 00339 */ 00340 static LONG register_key_defvalueW( 00341 HKEY base, 00342 WCHAR const *name, 00343 WCHAR const *value) 00344 { 00345 LONG res; 00346 HKEY key; 00347 00348 res = RegCreateKeyExW(base, name, 0, NULL, 0, 00349 KEY_READ | KEY_WRITE, NULL, &key, NULL); 00350 if (res != ERROR_SUCCESS) return res; 00351 res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value, 00352 (lstrlenW(value) + 1) * sizeof(WCHAR)); 00353 RegCloseKey(key); 00354 return res; 00355 } 00356 00357 /*********************************************************************** 00358 * regsvr_key_defvalueA 00359 */ 00360 static LONG register_key_defvalueA( 00361 HKEY base, 00362 WCHAR const *name, 00363 char const *value) 00364 { 00365 LONG res; 00366 HKEY key; 00367 00368 res = RegCreateKeyExW(base, name, 0, NULL, 0, 00369 KEY_READ | KEY_WRITE, NULL, &key, NULL); 00370 if (res != ERROR_SUCCESS) return res; 00371 res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value, 00372 lstrlenA(value) + 1); 00373 RegCloseKey(key); 00374 return res; 00375 } 00376 00377 /*********************************************************************** 00378 * regsvr_progid 00379 */ 00380 static LONG register_progid( 00381 WCHAR const *clsid, 00382 char const *progid, 00383 char const *curver_progid, 00384 char const *name, 00385 char const *extra) 00386 { 00387 LONG res; 00388 HKEY progid_key; 00389 00390 res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0, 00391 NULL, 0, KEY_READ | KEY_WRITE, NULL, 00392 &progid_key, NULL); 00393 if (res != ERROR_SUCCESS) return res; 00394 00395 if (name) { 00396 res = RegSetValueExA(progid_key, NULL, 0, REG_SZ, 00397 (CONST BYTE*)name, strlen(name) + 1); 00398 if (res != ERROR_SUCCESS) goto error_close_progid_key; 00399 } 00400 00401 if (clsid) { 00402 res = register_key_defvalueW(progid_key, clsid_keyname, clsid); 00403 if (res != ERROR_SUCCESS) goto error_close_progid_key; 00404 } 00405 00406 if (curver_progid) { 00407 res = register_key_defvalueA(progid_key, curver_keyname, 00408 curver_progid); 00409 if (res != ERROR_SUCCESS) goto error_close_progid_key; 00410 } 00411 00412 if (extra) { 00413 HKEY extra_key; 00414 00415 res = RegCreateKeyExA(progid_key, extra, 0, 00416 NULL, 0, KEY_READ | KEY_WRITE, NULL, 00417 &extra_key, NULL); 00418 if (res == ERROR_SUCCESS) 00419 RegCloseKey(extra_key); 00420 } 00421 00422 error_close_progid_key: 00423 RegCloseKey(progid_key); 00424 return res; 00425 } 00426 00427 /*********************************************************************** 00428 * coclass list 00429 */ 00430 static GUID const CLSID_DirectSoundBufferConfig = { 00431 0xB2F586D4, 0x5558, 0x49D1, {0xA0,0x7B,0x32,0x49,0xDB,0xBB,0x33,0xC2} }; 00432 00433 static struct regsvr_coclass const coclass_list[] = { 00434 { &CLSID_DirectSound, 00435 "DirectSound Object", 00436 NULL, 00437 "dsound.dll", 00438 "Both" 00439 }, 00440 { &CLSID_DirectSound8, 00441 "DirectSound 8.0 Object", 00442 NULL, 00443 "dsound.dll", 00444 "Both" 00445 }, 00446 { &CLSID_DirectSoundBufferConfig, 00447 "DirectSoundBufferConfig Object", 00448 NULL, 00449 "dsound.dll", 00450 "Both" 00451 }, 00452 { &CLSID_DirectSoundCapture, 00453 "DirectSoundCapture Object", 00454 NULL, 00455 "dsound.dll", 00456 "Both" 00457 }, 00458 { &CLSID_DirectSoundCapture8, 00459 "DirectSoundCapture 8.0 Object", 00460 NULL, 00461 "dsound.dll", 00462 "Both" 00463 }, 00464 { &CLSID_DirectSoundFullDuplex, 00465 "DirectSoundFullDuplex Object", 00466 NULL, 00467 "dsound.dll", 00468 "Both" 00469 }, 00470 { NULL } /* list terminator */ 00471 }; 00472 00473 /*********************************************************************** 00474 * interface list 00475 */ 00476 00477 static struct regsvr_interface const interface_list[] = { 00478 { NULL } /* list terminator */ 00479 }; 00480 00481 /*********************************************************************** 00482 * DllRegisterServer (DSOUND.@) 00483 */ 00484 HRESULT WINAPI DllRegisterServer(void) 00485 { 00486 HRESULT hr; 00487 00488 hr = register_coclasses(coclass_list); 00489 if (SUCCEEDED(hr)) 00490 hr = register_interfaces(interface_list); 00491 return hr; 00492 } 00493 00494 /*********************************************************************** 00495 * DllUnregisterServer (DSOUND.@) 00496 */ 00497 HRESULT WINAPI DllUnregisterServer(void) 00498 { 00499 HRESULT hr; 00500 00501 HMODULE advapi32 = GetModuleHandleA("advapi32"); 00502 if (!advapi32) return E_FAIL; 00503 pRegDeleteTreeA = (void *) GetProcAddress(advapi32, "RegDeleteTreeA"); 00504 pRegDeleteTreeW = (void *) GetProcAddress(advapi32, "RegDeleteTreeW"); 00505 if (!pRegDeleteTreeA || !pRegDeleteTreeW) return E_FAIL; 00506 00507 hr = unregister_coclasses(coclass_list); 00508 if (SUCCEEDED(hr)) 00509 hr = unregister_interfaces(interface_list); 00510 return hr; 00511 } Generated on Sat May 26 2012 04:20:04 for ReactOS by
1.7.6.1
|