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 "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 doxygen 1.7.6.1

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