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 msctf
00003  *
00004  * Copyright (C) 2004 Stefan Leichter
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 "winuser.h"
00027 #include "wingdi.h"
00028 #include "winreg.h"
00029 #include "winerror.h"
00030 
00031 #include "ole2.h"
00032 #include "shlguid.h"
00033 #include "msctf.h"
00034 
00035 #include "wine/debug.h"
00036 
00037 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
00038 
00039 /*
00040  * Near the bottom of this file are the exported DllRegisterServer and
00041  * DllUnregisterServer, which make all this worthwhile.
00042  */
00043 
00044 /***********************************************************************
00045  *      interface for self-registering
00046  */
00047 struct regsvr_interface
00048 {
00049     IID const *iid;     /* NULL for end of list */
00050     LPCSTR name;        /* can be NULL to omit */
00051     IID const *base_iid;    /* can be NULL to omit */
00052     int num_methods;        /* can be <0 to omit */
00053     CLSID const *ps_clsid;  /* can be NULL to omit */
00054     CLSID const *ps_clsid32;    /* can be NULL to omit */
00055 };
00056 
00057 static HRESULT register_interfaces(struct regsvr_interface const *list);
00058 static HRESULT unregister_interfaces(struct regsvr_interface const *list);
00059 
00060 struct regsvr_coclass
00061 {
00062     CLSID const *clsid;     /* NULL for end of list */
00063     LPCSTR name;        /* can be NULL to omit */
00064     LPCSTR ips;         /* can be NULL to omit */
00065     LPCSTR ips32;       /* can be NULL to omit */
00066     LPCSTR ips32_tmodel;    /* can be NULL to omit */
00067     LPCSTR progid;      /* can be NULL to omit */
00068     LPCSTR viprogid;        /* can be NULL to omit */
00069     LPCSTR progid_extra;    /* can be NULL to omit */
00070 };
00071 
00072 static HRESULT register_coclasses(struct regsvr_coclass const *list);
00073 static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
00074 
00075 /***********************************************************************
00076  *      static string constants
00077  */
00078 static WCHAR const interface_keyname[10] = {
00079     'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
00080 static WCHAR const base_ifa_keyname[14] = {
00081     'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
00082     'e', 0 };
00083 static WCHAR const num_methods_keyname[11] = {
00084     'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
00085 static WCHAR const ps_clsid_keyname[15] = {
00086     'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
00087     'i', 'd', 0 };
00088 static WCHAR const ps_clsid32_keyname[17] = {
00089     'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
00090     'i', 'd', '3', '2', 0 };
00091 static WCHAR const clsid_keyname[6] = {
00092     'C', 'L', 'S', 'I', 'D', 0 };
00093 static WCHAR const curver_keyname[7] = {
00094     'C', 'u', 'r', 'V', 'e', 'r', 0 };
00095 static WCHAR const ips_keyname[13] = {
00096     'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
00097     0 };
00098 static WCHAR const ips32_keyname[15] = {
00099     'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
00100     '3', '2', 0 };
00101 static WCHAR const progid_keyname[7] = {
00102     'P', 'r', 'o', 'g', 'I', 'D', 0 };
00103 static WCHAR const viprogid_keyname[25] = {
00104     'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
00105     'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
00106     0 };
00107 static char const tmodel_valuename[] = "ThreadingModel";
00108 
00109 /***********************************************************************
00110  *      static helper functions
00111  */
00112 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
00113 static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
00114                    WCHAR const *value);
00115 static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
00116                    char const *value);
00117 static LONG register_progid(WCHAR const *clsid,
00118                 char const *progid, char const *curver_progid,
00119                 char const *name, char const *extra);
00120 
00121 /***********************************************************************
00122  *      register_interfaces
00123  */
00124 static HRESULT register_interfaces(struct regsvr_interface const *list)
00125 {
00126     LONG res = ERROR_SUCCESS;
00127     HKEY interface_key;
00128 
00129     res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
00130               KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
00131     if (res != ERROR_SUCCESS) goto error_return;
00132 
00133     for (; res == ERROR_SUCCESS && list->iid; ++list) {
00134     WCHAR buf[39];
00135     HKEY iid_key;
00136 
00137     StringFromGUID2(list->iid, buf, 39);
00138     res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
00139                   KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
00140     if (res != ERROR_SUCCESS) goto error_close_interface_key;
00141 
00142     if (list->name) {
00143         res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
00144                  (CONST BYTE*)(list->name),
00145                  strlen(list->name) + 1);
00146         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00147     }
00148 
00149     if (list->base_iid) {
00150         res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
00151         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00152     }
00153 
00154     if (0 <= list->num_methods) {
00155         static WCHAR const fmt[3] = { '%', 'd', 0 };
00156         HKEY key;
00157 
00158         res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
00159                   KEY_READ | KEY_WRITE, NULL, &key, NULL);
00160         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00161 
00162         wsprintfW(buf, fmt, list->num_methods);
00163         res = RegSetValueExW(key, NULL, 0, REG_SZ,
00164                  (CONST BYTE*)buf,
00165                  (lstrlenW(buf) + 1) * sizeof(WCHAR));
00166         RegCloseKey(key);
00167 
00168         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00169     }
00170 
00171     if (list->ps_clsid) {
00172         res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
00173         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00174     }
00175 
00176     if (list->ps_clsid32) {
00177         res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
00178         if (res != ERROR_SUCCESS) goto error_close_iid_key;
00179     }
00180 
00181     error_close_iid_key:
00182     RegCloseKey(iid_key);
00183     }
00184 
00185 error_close_interface_key:
00186     RegCloseKey(interface_key);
00187 error_return:
00188     return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
00189 }
00190 
00191 /***********************************************************************
00192  *      unregister_interfaces
00193  */
00194 static HRESULT unregister_interfaces(struct regsvr_interface const *list)
00195 {
00196     LONG res = ERROR_SUCCESS;
00197     HKEY interface_key;
00198 
00199     res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
00200             KEY_READ | KEY_WRITE, &interface_key);
00201     if (res == ERROR_FILE_NOT_FOUND) return S_OK;
00202     if (res != ERROR_SUCCESS) goto error_return;
00203 
00204     for (; res == ERROR_SUCCESS && list->iid; ++list) {
00205     WCHAR buf[39];
00206 
00207     StringFromGUID2(list->iid, buf, 39);
00208     res = RegDeleteTreeW(interface_key, buf);
00209     if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
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 = RegDeleteTreeW(coclass_key, buf);
00317     if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
00318     if (res != ERROR_SUCCESS) goto error_close_coclass_key;
00319 
00320     if (list->progid) {
00321         res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
00322         if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
00323         if (res != ERROR_SUCCESS) goto error_close_coclass_key;
00324     }
00325 
00326     if (list->viprogid) {
00327         res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
00328         if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
00329         if (res != ERROR_SUCCESS) goto error_close_coclass_key;
00330     }
00331     }
00332 
00333 error_close_coclass_key:
00334     RegCloseKey(coclass_key);
00335 error_return:
00336     return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
00337 }
00338 
00339 /***********************************************************************
00340  *      regsvr_key_guid
00341  */
00342 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
00343 {
00344     WCHAR buf[39];
00345 
00346     StringFromGUID2(guid, buf, 39);
00347     return register_key_defvalueW(base, name, buf);
00348 }
00349 
00350 /***********************************************************************
00351  *      regsvr_key_defvalueW
00352  */
00353 static LONG register_key_defvalueW(
00354     HKEY base,
00355     WCHAR const *name,
00356     WCHAR const *value)
00357 {
00358     LONG res;
00359     HKEY key;
00360 
00361     res = RegCreateKeyExW(base, name, 0, NULL, 0,
00362               KEY_READ | KEY_WRITE, NULL, &key, NULL);
00363     if (res != ERROR_SUCCESS) return res;
00364     res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
00365              (lstrlenW(value) + 1) * sizeof(WCHAR));
00366     RegCloseKey(key);
00367     return res;
00368 }
00369 
00370 /***********************************************************************
00371  *      regsvr_key_defvalueA
00372  */
00373 static LONG register_key_defvalueA(
00374     HKEY base,
00375     WCHAR const *name,
00376     char const *value)
00377 {
00378     LONG res;
00379     HKEY key;
00380 
00381     res = RegCreateKeyExW(base, name, 0, NULL, 0,
00382               KEY_READ | KEY_WRITE, NULL, &key, NULL);
00383     if (res != ERROR_SUCCESS) return res;
00384     res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
00385              lstrlenA(value) + 1);
00386     RegCloseKey(key);
00387     return res;
00388 }
00389 
00390 /***********************************************************************
00391  *      regsvr_progid
00392  */
00393 static LONG register_progid(
00394     WCHAR const *clsid,
00395     char const *progid,
00396     char const *curver_progid,
00397     char const *name,
00398     char const *extra)
00399 {
00400     LONG res;
00401     HKEY progid_key;
00402 
00403     res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
00404               NULL, 0, KEY_READ | KEY_WRITE, NULL,
00405               &progid_key, NULL);
00406     if (res != ERROR_SUCCESS) return res;
00407 
00408     if (name) {
00409     res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
00410                  (CONST BYTE*)name, strlen(name) + 1);
00411     if (res != ERROR_SUCCESS) goto error_close_progid_key;
00412     }
00413 
00414     if (clsid) {
00415     res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
00416     if (res != ERROR_SUCCESS) goto error_close_progid_key;
00417     }
00418 
00419     if (curver_progid) {
00420     res = register_key_defvalueA(progid_key, curver_keyname,
00421                      curver_progid);
00422     if (res != ERROR_SUCCESS) goto error_close_progid_key;
00423     }
00424 
00425     if (extra) {
00426     HKEY extra_key;
00427 
00428     res = RegCreateKeyExA(progid_key, extra, 0,
00429                   NULL, 0, KEY_READ | KEY_WRITE, NULL,
00430                   &extra_key, NULL);
00431     if (res == ERROR_SUCCESS)
00432         RegCloseKey(extra_key);
00433     }
00434 
00435 error_close_progid_key:
00436     RegCloseKey(progid_key);
00437     return res;
00438 }
00439 
00440 /***********************************************************************
00441  *      coclass list
00442  */
00443 static struct regsvr_coclass const coclass_list[] = {
00444     {
00445         &CLSID_TF_ThreadMgr,
00446         "TF_ThreadMgr",
00447         NULL,
00448         "msctf.dll",
00449         "Apartment"
00450     },
00451     {
00452         &CLSID_TF_InputProcessorProfiles,
00453         "TF_InputProcessorProfiles",
00454         NULL,
00455         "msctf.dll",
00456         "Apartment"
00457     },
00458     {
00459         &CLSID_TF_CategoryMgr,
00460         "TF_CategoryMgr",
00461         NULL,
00462         "msctf.dll",
00463         "Apartment"
00464     },
00465     {
00466         &CLSID_TF_LangBarMgr,
00467         "TF_LangBarMgr",
00468         NULL,
00469         "msctf.dll",
00470         "Apartment"
00471     },
00472     {
00473         &CLSID_TF_DisplayAttributeMgr,
00474         "TF_DisplayAttributeMgr",
00475         NULL,
00476         "msctf.dll",
00477         "Apartment"
00478     },
00479     { NULL }            /* list terminator */
00480 };
00481 
00482 /***********************************************************************
00483  *      interface list
00484  */
00485 
00486 static struct regsvr_interface const interface_list[] = {
00487     { NULL }            /* list terminator */
00488 };
00489 
00490 /***********************************************************************
00491  *      DllRegisterServer (MSCTF.@)
00492  */
00493 HRESULT WINAPI DllRegisterServer(void)
00494 {
00495     HRESULT hr;
00496 
00497     TRACE("\n");
00498 
00499     hr = register_coclasses(coclass_list);
00500     if (SUCCEEDED(hr))
00501     hr = register_interfaces(interface_list);
00502     return hr;
00503 }
00504 
00505 /***********************************************************************
00506  *      DllUnregisterServer (MSCTF.@)
00507  */
00508 HRESULT WINAPI DllUnregisterServer(void)
00509 {
00510     HRESULT hr;
00511 
00512     TRACE("\n");
00513 
00514     hr = unregister_coclasses(coclass_list);
00515     if (SUCCEEDED(hr))
00516     hr = unregister_interfaces(interface_list);
00517     return hr;
00518 }

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