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

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.