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

Generated on Sat May 26 2012 04:20:05 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.