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 wuapi.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 00022 #include <stdarg.h> 00023 #include <string.h> 00024 00025 #include "windef.h" 00026 #include "winbase.h" 00027 #include "winuser.h" 00028 #include "winreg.h" 00029 #include "winerror.h" 00030 #include "objbase.h" 00031 #include "wuapi.h" 00032 00033 #include "wine/debug.h" 00034 #include "wine/unicode.h" 00035 00036 WINE_DEFAULT_DEBUG_CHANNEL(wuapi); 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 clsid_str; /* can be NULL to omit */ 00067 LPCSTR progid; /* can be NULL to omit */ 00068 }; 00069 00070 static HRESULT register_coclasses(struct regsvr_coclass const *list); 00071 static HRESULT unregister_coclasses(struct regsvr_coclass const *list); 00072 00073 /*********************************************************************** 00074 * static string constants 00075 */ 00076 static WCHAR const interface_keyname[10] = { 00077 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 }; 00078 static WCHAR const base_ifa_keyname[14] = { 00079 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 00080 'e', 0 }; 00081 static WCHAR const num_methods_keyname[11] = { 00082 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 }; 00083 static WCHAR const ps_clsid_keyname[15] = { 00084 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', 00085 'i', 'd', 0 }; 00086 static WCHAR const ps_clsid32_keyname[17] = { 00087 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', 00088 'i', 'd', '3', '2', 0 }; 00089 static WCHAR const clsid_keyname[6] = { 00090 'C', 'L', 'S', 'I', 'D', 0 }; 00091 static WCHAR const ips_keyname[13] = { 00092 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', 00093 0 }; 00094 static WCHAR const ips32_keyname[15] = { 00095 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', 00096 '3', '2', 0 }; 00097 static WCHAR const progid_keyname[7] = { 00098 'P', 'r', 'o', 'g', 'I', 'D', 0 }; 00099 static char const tmodel_valuename[] = "ThreadingModel"; 00100 00101 /*********************************************************************** 00102 * static helper functions 00103 */ 00104 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid); 00105 static LONG register_key_defvalueW(HKEY base, WCHAR const *name, 00106 WCHAR const *value); 00107 static LONG register_key_defvalueA(HKEY base, WCHAR const *name, 00108 char const *value); 00109 00110 /*********************************************************************** 00111 * register_interfaces 00112 */ 00113 static HRESULT register_interfaces(struct regsvr_interface const *list) 00114 { 00115 LONG res = ERROR_SUCCESS; 00116 HKEY interface_key; 00117 00118 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0, 00119 KEY_READ | KEY_WRITE, NULL, &interface_key, NULL); 00120 if (res != ERROR_SUCCESS) goto error_return; 00121 00122 for (; res == ERROR_SUCCESS && list->iid; ++list) { 00123 WCHAR buf[39]; 00124 HKEY iid_key; 00125 00126 StringFromGUID2(list->iid, buf, 39); 00127 res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0, 00128 KEY_READ | KEY_WRITE, NULL, &iid_key, NULL); 00129 if (res != ERROR_SUCCESS) goto error_close_interface_key; 00130 00131 if (list->name) { 00132 res = RegSetValueExA(iid_key, NULL, 0, REG_SZ, 00133 (CONST BYTE*)(list->name), 00134 strlen(list->name) + 1); 00135 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00136 } 00137 00138 if (list->base_iid) { 00139 res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid); 00140 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00141 } 00142 00143 if (0 <= list->num_methods) { 00144 static WCHAR const fmt[3] = { '%', 'd', 0 }; 00145 HKEY key; 00146 00147 res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0, 00148 KEY_READ | KEY_WRITE, NULL, &key, NULL); 00149 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00150 00151 sprintfW(buf, fmt, list->num_methods); 00152 res = RegSetValueExW(key, NULL, 0, REG_SZ, 00153 (CONST BYTE*)buf, 00154 (lstrlenW(buf) + 1) * sizeof(WCHAR)); 00155 RegCloseKey(key); 00156 00157 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00158 } 00159 00160 if (list->ps_clsid) { 00161 res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid); 00162 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00163 } 00164 00165 if (list->ps_clsid32) { 00166 res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32); 00167 if (res != ERROR_SUCCESS) goto error_close_iid_key; 00168 } 00169 00170 error_close_iid_key: 00171 RegCloseKey(iid_key); 00172 } 00173 00174 error_close_interface_key: 00175 RegCloseKey(interface_key); 00176 error_return: 00177 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 00178 } 00179 00180 /*********************************************************************** 00181 * unregister_interfaces 00182 */ 00183 static HRESULT unregister_interfaces(struct regsvr_interface const *list) 00184 { 00185 LONG res = ERROR_SUCCESS; 00186 HKEY interface_key; 00187 00188 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, 00189 KEY_READ | KEY_WRITE, &interface_key); 00190 if (res == ERROR_FILE_NOT_FOUND) return S_OK; 00191 if (res != ERROR_SUCCESS) goto error_return; 00192 00193 for (; res == ERROR_SUCCESS && list->iid; ++list) { 00194 WCHAR buf[39]; 00195 00196 StringFromGUID2(list->iid, buf, 39); 00197 res = RegDeleteTreeW(interface_key, buf); 00198 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 00199 } 00200 00201 RegCloseKey(interface_key); 00202 error_return: 00203 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 00204 } 00205 00206 /*********************************************************************** 00207 * register_coclasses 00208 */ 00209 static HRESULT register_coclasses(struct regsvr_coclass const *list) 00210 { 00211 LONG res = ERROR_SUCCESS; 00212 HKEY coclass_key; 00213 00214 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 00215 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 00216 if (res != ERROR_SUCCESS) goto error_return; 00217 00218 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 00219 WCHAR buf[39]; 00220 HKEY clsid_key; 00221 00222 StringFromGUID2(list->clsid, buf, 39); 00223 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 00224 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); 00225 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 00226 00227 if (list->name) { 00228 res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ, 00229 (CONST BYTE*)(list->name), 00230 strlen(list->name) + 1); 00231 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00232 } 00233 00234 if (list->ips) { 00235 res = register_key_defvalueA(clsid_key, ips_keyname, list->ips); 00236 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00237 } 00238 00239 if (list->ips32) { 00240 HKEY ips32_key; 00241 00242 res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0, 00243 KEY_READ | KEY_WRITE, NULL, 00244 &ips32_key, NULL); 00245 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00246 00247 res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ, 00248 (CONST BYTE*)list->ips32, 00249 lstrlenA(list->ips32) + 1); 00250 if (res == ERROR_SUCCESS && list->ips32_tmodel) 00251 res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ, 00252 (CONST BYTE*)list->ips32_tmodel, 00253 strlen(list->ips32_tmodel) + 1); 00254 RegCloseKey(ips32_key); 00255 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00256 } 00257 00258 if (list->clsid_str) { 00259 res = register_key_defvalueA(clsid_key, clsid_keyname, 00260 list->clsid_str); 00261 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00262 } 00263 00264 if (list->progid) { 00265 HKEY progid_key; 00266 00267 res = register_key_defvalueA(clsid_key, progid_keyname, 00268 list->progid); 00269 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00270 00271 res = RegCreateKeyExA(HKEY_CLASSES_ROOT, list->progid, 0, 00272 NULL, 0, KEY_READ | KEY_WRITE, NULL, 00273 &progid_key, NULL); 00274 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00275 00276 res = register_key_defvalueW(progid_key, clsid_keyname, buf); 00277 RegCloseKey(progid_key); 00278 if (res != ERROR_SUCCESS) goto error_close_clsid_key; 00279 } 00280 00281 error_close_clsid_key: 00282 RegCloseKey(clsid_key); 00283 } 00284 00285 error_close_coclass_key: 00286 RegCloseKey(coclass_key); 00287 error_return: 00288 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 00289 } 00290 00291 /*********************************************************************** 00292 * unregister_coclasses 00293 */ 00294 static HRESULT unregister_coclasses(struct regsvr_coclass const *list) 00295 { 00296 LONG res = ERROR_SUCCESS; 00297 HKEY coclass_key; 00298 00299 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 00300 KEY_READ | KEY_WRITE, &coclass_key); 00301 if (res == ERROR_FILE_NOT_FOUND) return S_OK; 00302 if (res != ERROR_SUCCESS) goto error_return; 00303 00304 for (; res == ERROR_SUCCESS && list->clsid; ++list) { 00305 WCHAR buf[39]; 00306 00307 StringFromGUID2(list->clsid, buf, 39); 00308 res = RegDeleteTreeW(coclass_key, buf); 00309 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 00310 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 00311 00312 if (list->progid) { 00313 res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); 00314 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 00315 if (res != ERROR_SUCCESS) goto error_close_coclass_key; 00316 } 00317 } 00318 00319 error_close_coclass_key: 00320 RegCloseKey(coclass_key); 00321 error_return: 00322 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 00323 } 00324 00325 /*********************************************************************** 00326 * regsvr_key_guid 00327 */ 00328 static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid) 00329 { 00330 WCHAR buf[39]; 00331 00332 StringFromGUID2(guid, buf, 39); 00333 return register_key_defvalueW(base, name, buf); 00334 } 00335 00336 /*********************************************************************** 00337 * regsvr_key_defvalueW 00338 */ 00339 static LONG register_key_defvalueW( 00340 HKEY base, 00341 WCHAR const *name, 00342 WCHAR const *value) 00343 { 00344 LONG res; 00345 HKEY key; 00346 00347 res = RegCreateKeyExW(base, name, 0, NULL, 0, 00348 KEY_READ | KEY_WRITE, NULL, &key, NULL); 00349 if (res != ERROR_SUCCESS) return res; 00350 res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value, 00351 (lstrlenW(value) + 1) * sizeof(WCHAR)); 00352 RegCloseKey(key); 00353 return res; 00354 } 00355 00356 /*********************************************************************** 00357 * regsvr_key_defvalueA 00358 */ 00359 static LONG register_key_defvalueA( 00360 HKEY base, 00361 WCHAR const *name, 00362 char const *value) 00363 { 00364 LONG res; 00365 HKEY key; 00366 00367 res = RegCreateKeyExW(base, name, 0, NULL, 0, 00368 KEY_READ | KEY_WRITE, NULL, &key, NULL); 00369 if (res != ERROR_SUCCESS) return res; 00370 res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value, 00371 lstrlenA(value) + 1); 00372 RegCloseKey(key); 00373 return res; 00374 } 00375 00376 /*********************************************************************** 00377 * coclass list 00378 */ 00379 static struct regsvr_coclass const coclass_list[] = { 00380 { &CLSID_UpdateSession, 00381 "CLSID_UpdateSession", 00382 NULL, 00383 "wuapi.dll", 00384 "Both" 00385 }, 00386 { &CLSID_AutomaticUpdates, 00387 "CLSID_AutomaticUpdates", 00388 NULL, 00389 "wuapi.dll", 00390 "Both" 00391 }, 00392 { NULL } /* list terminator */ 00393 }; 00394 00395 /*********************************************************************** 00396 * interface list 00397 */ 00398 static struct regsvr_interface const interface_list[] = { 00399 { NULL } /* list terminator */ 00400 }; 00401 00402 /*********************************************************************** 00403 * DllRegisterServer (WUAPI.@) 00404 */ 00405 HRESULT WINAPI DllRegisterServer(void) 00406 { 00407 HRESULT hr; 00408 00409 TRACE("\n"); 00410 00411 hr = register_coclasses(coclass_list); 00412 if (SUCCEEDED(hr)) 00413 hr = register_interfaces(interface_list); 00414 return hr; 00415 } 00416 00417 /*********************************************************************** 00418 * DllUnregisterServer (WUAPI.@) 00419 */ 00420 HRESULT WINAPI DllUnregisterServer(void) 00421 { 00422 HRESULT hr; 00423 00424 TRACE("\n"); 00425 00426 hr = unregister_coclasses(coclass_list); 00427 if (SUCCEEDED(hr)) 00428 hr = unregister_interfaces(interface_list); 00429 return hr; 00430 } Generated on Fri May 25 2012 04:19:29 for ReactOS by
1.7.6.1
|