ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

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

Generated on Sat May 26 2012 04:20:03 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.