Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenregsvr.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
1.7.6.1
|