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 dinput.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 #include <string.h>
00023 
00024 #include "windef.h"
00025 #include "winbase.h"
00026 #include "wingdi.h"
00027 #include "winuser.h"
00028 #include "winreg.h"
00029 #include "winerror.h"
00030 
00031 #include "dinput.h"
00032 
00033 #include "wine/debug.h"
00034 #include "wine/unicode.h"
00035 
00036 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
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 
00120 /***********************************************************************
00121  *      register_interfaces
00122  */
00123 static HRESULT register_interfaces(struct regsvr_interface const *list)
00124 {
00125     LONG res = ERROR_SUCCESS;
00126     HKEY interface_key;
00127 
00128     res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
00129               KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
00130     if (res != ERROR_SUCCESS) goto error_return;
00131 
00132     for (; res == ERROR_SUCCESS && list->iid; ++list) {
00133     WCHAR buf[39];
00134     HKEY iid_key;
00135 
00136     StringFromGUID2(list->iid, buf, 39);
00137     res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
00138                   KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
00139     if (res != ERROR_SUCCESS) goto error_close_interface_key;
00140 
00141     if (list->name) {
00142         res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
00143                  (CONST BYTE*)(list->name),
00144                  strlen(list->name) + 1);
00145         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00146     }
00147 
00148     if (list->base_iid) {
00149         res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
00150         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00151     }
00152 
00153     if (0 <= list->num_methods) {
00154         static WCHAR const fmt[3] = { '%', 'd', 0 };
00155         HKEY key;
00156 
00157         res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
00158                   KEY_READ | KEY_WRITE, NULL, &key, NULL);
00159         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00160 
00161         sprintfW(buf, fmt, list->num_methods);
00162         res = RegSetValueExW(key, NULL, 0, REG_SZ,
00163                  (CONST BYTE*)buf,
00164                  (lstrlenW(buf) + 1) * sizeof(WCHAR));
00165         RegCloseKey(key);
00166 
00167         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00168     }
00169 
00170     if (list->ps_clsid) {
00171         res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
00172         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00173     }
00174 
00175     if (list->ps_clsid32) {
00176         res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
00177         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00178     }
00179 
00180     error_close_iid_key:
00181     RegCloseKey(iid_key);
00182     }
00183 
00184 error_close_interface_key:
00185     RegCloseKey(interface_key);
00186 error_return:
00187     return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
00188 }
00189 
00190 /***********************************************************************
00191  *      unregister_interfaces
00192  */
00193 static HRESULT unregister_interfaces(struct regsvr_interface const *list)
00194 {
00195     LONG res = ERROR_SUCCESS;
00196     HKEY interface_key;
00197 
00198     res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
00199             KEY_READ | KEY_WRITE, &interface_key);
00200     if (res == ERROR_FILE_NOT_FOUND) return S_OK;
00201     if (res != ERROR_SUCCESS) goto error_return;
00202 
00203     for (; res == ERROR_SUCCESS && list->iid; ++list) {
00204     WCHAR buf[39];
00205 
00206     StringFromGUID2(list->iid, buf, 39);
00207     res = RegDeleteTreeW(interface_key, buf);
00208     if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
00209     }
00210 
00211     RegCloseKey(interface_key);
00212 error_return:
00213     return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
00214 }
00215 
00216 /***********************************************************************
00217  *      register_coclasses
00218  */
00219 static HRESULT register_coclasses(struct regsvr_coclass const *list)
00220 {
00221     LONG res = ERROR_SUCCESS;
00222     HKEY coclass_key;
00223 
00224     res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
00225               KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
00226     if (res != ERROR_SUCCESS) goto error_return;
00227 
00228     for (; res == ERROR_SUCCESS && list->clsid; ++list) {
00229     WCHAR buf[39];
00230     HKEY clsid_key;
00231 
00232     StringFromGUID2(list->clsid, buf, 39);
00233     res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
00234                   KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
00235     if (res != ERROR_SUCCESS) goto error_close_coclass_key;
00236 
00237     if (list->name) {
00238         res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
00239                  (CONST BYTE*)(list->name),
00240                  strlen(list->name) + 1);
00241         if (res != ERROR_SUCCESS) goto error_close_clsid_key;
00242     }
00243 
00244     if (list->ips) {
00245         res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
00246         if (res != ERROR_SUCCESS) goto error_close_clsid_key;
00247     }
00248 
00249     if (list->ips32) {
00250         HKEY ips32_key;
00251 
00252         res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
00253                   KEY_READ | KEY_WRITE, NULL,
00254                   &ips32_key, NULL);
00255         if (res != ERROR_SUCCESS) goto error_close_clsid_key;
00256 
00257         res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
00258                  (CONST BYTE*)list->ips32,
00259                  lstrlenA(list->ips32) + 1);
00260         if (res == ERROR_SUCCESS && list->ips32_tmodel)
00261         res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
00262                      (CONST BYTE*)list->ips32_tmodel,
00263                      strlen(list->ips32_tmodel) + 1);
00264         RegCloseKey(ips32_key);
00265         if (res != ERROR_SUCCESS) goto error_close_clsid_key;
00266     }
00267 
00268     if (list->progid) {
00269         res = register_key_defvalueA(clsid_key, progid_keyname,
00270                      list->progid);
00271         if (res != ERROR_SUCCESS) goto error_close_clsid_key;
00272 
00273         res = register_progid(buf, list->progid, NULL,
00274                   list->name, list->progid_extra);
00275         if (res != ERROR_SUCCESS) goto error_close_clsid_key;
00276     }
00277 
00278     if (list->viprogid) {
00279         res = register_key_defvalueA(clsid_key, viprogid_keyname,
00280                      list->viprogid);
00281         if (res != ERROR_SUCCESS) goto error_close_clsid_key;
00282 
00283         res = register_progid(buf, list->viprogid, list->progid,
00284                   list->name, list->progid_extra);
00285         if (res != ERROR_SUCCESS) goto error_close_clsid_key;
00286     }
00287 
00288     error_close_clsid_key:
00289     RegCloseKey(clsid_key);
00290     }
00291 
00292 error_close_coclass_key:
00293     RegCloseKey(coclass_key);
00294 error_return:
00295     return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
00296 }
00297 
00298 /***********************************************************************
00299  *      unregister_coclasses
00300  */
00301 static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
00302 {
00303     LONG res = ERROR_SUCCESS;
00304     HKEY coclass_key;
00305 
00306     res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
00307             KEY_READ | KEY_WRITE, &coclass_key);
00308     if (res == ERROR_FILE_NOT_FOUND) return S_OK;
00309     if (res != ERROR_SUCCESS) goto error_return;
00310 
00311     for (; res == ERROR_SUCCESS && list->clsid; ++list) {
00312     WCHAR buf[39];
00313 
00314     StringFromGUID2(list->clsid, buf, 39);
00315     res = RegDeleteTreeW(coclass_key, buf);
00316     if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
00317     if (res != ERROR_SUCCESS) goto error_close_coclass_key;
00318 
00319     if (list->progid) {
00320         res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
00321         if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
00322         if (res != ERROR_SUCCESS) goto error_close_coclass_key;
00323     }
00324 
00325     if (list->viprogid) {
00326         res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
00327         if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
00328         if (res != ERROR_SUCCESS) goto error_close_coclass_key;
00329     }
00330     }
00331 
00332 error_close_coclass_key:
00333     RegCloseKey(coclass_key);
00334 error_return:
00335     return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
00336 }
00337 
00338 /***********************************************************************
00339  *      regsvr_key_guid
00340  */
00341 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
00342 {
00343     WCHAR buf[39];
00344 
00345     StringFromGUID2(guid, buf, 39);
00346     return register_key_defvalueW(base, name, buf);
00347 }
00348 
00349 /***********************************************************************
00350  *      regsvr_key_defvalueW
00351  */
00352 static LONG register_key_defvalueW(
00353     HKEY base,
00354     WCHAR const *name,
00355     WCHAR const *value)
00356 {
00357     LONG res;
00358     HKEY key;
00359 
00360     res = RegCreateKeyExW(base, name, 0, NULL, 0,
00361               KEY_READ | KEY_WRITE, NULL, &key, NULL);
00362     if (res != ERROR_SUCCESS) return res;
00363     res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
00364              (lstrlenW(value) + 1) * sizeof(WCHAR));
00365     RegCloseKey(key);
00366     return res;
00367 }
00368 
00369 /***********************************************************************
00370  *      regsvr_key_defvalueA
00371  */
00372 static LONG register_key_defvalueA(
00373     HKEY base,
00374     WCHAR const *name,
00375     char const *value)
00376 {
00377     LONG res;
00378     HKEY key;
00379 
00380     res = RegCreateKeyExW(base, name, 0, NULL, 0,
00381               KEY_READ | KEY_WRITE, NULL, &key, NULL);
00382     if (res != ERROR_SUCCESS) return res;
00383     res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
00384              lstrlenA(value) + 1);
00385     RegCloseKey(key);
00386     return res;
00387 }
00388 
00389 /***********************************************************************
00390  *      regsvr_progid
00391  */
00392 static LONG register_progid(
00393     WCHAR const *clsid,
00394     char const *progid,
00395     char const *curver_progid,
00396     char const *name,
00397     char const *extra)
00398 {
00399     LONG res;
00400     HKEY progid_key;
00401 
00402     res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
00403               NULL, 0, KEY_READ | KEY_WRITE, NULL,
00404               &progid_key, NULL);
00405     if (res != ERROR_SUCCESS) return res;
00406 
00407     if (name) {
00408     res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
00409                  (CONST BYTE*)name, strlen(name) + 1);
00410     if (res != ERROR_SUCCESS) goto error_close_progid_key;
00411     }
00412 
00413     if (clsid) {
00414     res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
00415     if (res != ERROR_SUCCESS) goto error_close_progid_key;
00416     }
00417 
00418     if (curver_progid) {
00419     res = register_key_defvalueA(progid_key, curver_keyname,
00420                      curver_progid);
00421     if (res != ERROR_SUCCESS) goto error_close_progid_key;
00422     }
00423 
00424     if (extra) {
00425     HKEY extra_key;
00426 
00427     res = RegCreateKeyExA(progid_key, extra, 0,
00428                   NULL, 0, KEY_READ | KEY_WRITE, NULL,
00429                   &extra_key, NULL);
00430     if (res == ERROR_SUCCESS)
00431         RegCloseKey(extra_key);
00432     }
00433 
00434 error_close_progid_key:
00435     RegCloseKey(progid_key);
00436     return res;
00437 }
00438 
00439 /***********************************************************************
00440  *      coclass list
00441  */
00442 static struct regsvr_coclass const coclass_list[] = {
00443     {
00444     &CLSID_DirectInput,
00445     "DirectInput Object",
00446     NULL,
00447     "dinput.dll",
00448     "Both"
00449     },
00450     {
00451     &CLSID_DirectInputDevice,
00452     "DirectInputDevice Object",
00453     NULL,
00454     "dinput.dll",
00455     "Both"
00456     },
00457     { NULL }            /* list terminator */
00458 };
00459 
00460 /***********************************************************************
00461  *      interface list
00462  */
00463 
00464 static struct regsvr_interface const interface_list[] = {
00465     { NULL }            /* list terminator */
00466 };
00467 
00468 /***********************************************************************
00469  *      DllRegisterServer (DINPUT.@)
00470  */
00471 HRESULT WINAPI DllRegisterServer(void)
00472 {
00473     HRESULT hr;
00474 
00475     TRACE("\n");
00476 
00477     hr = register_coclasses(coclass_list);
00478     if (SUCCEEDED(hr))
00479     hr = register_interfaces(interface_list);
00480     return hr;
00481 }
00482 
00483 /***********************************************************************
00484  *      DllUnregisterServer (DINPUT.@)
00485  */
00486 HRESULT WINAPI DllUnregisterServer(void)
00487 {
00488     HRESULT hr;
00489 
00490     TRACE("\n");
00491 
00492     hr = unregister_coclasses(coclass_list);
00493     if (SUCCEEDED(hr))
00494     hr = unregister_interfaces(interface_list);
00495     return hr;
00496 }

Generated on Sun May 27 2012 04:21:32 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.