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

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.