Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenregistrar.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2005 Jacek Caban 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 00020 #include <stdarg.h> 00021 00022 #define COBJMACROS 00023 00024 #include "windef.h" 00025 #include "winbase.h" 00026 #include "winuser.h" 00027 #include "winreg.h" 00028 #include "objbase.h" 00029 #include "oaidl.h" 00030 #include "rpcproxy.h" 00031 #include "atliface.h" 00032 #include "atlbase.h" 00033 00034 #include "wine/debug.h" 00035 #include "wine/unicode.h" 00036 00037 WINE_DEFAULT_DEBUG_CHANNEL(atl); 00038 00039 static LONG dll_count; 00040 00041 /************************************************************** 00042 * ATLRegistrar implementation 00043 */ 00044 00045 static const struct { 00046 WCHAR name[22]; 00047 HKEY key; 00048 } root_keys[] = { 00049 {{'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T',0}, 00050 HKEY_CLASSES_ROOT}, 00051 {{'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R',0}, 00052 HKEY_CURRENT_USER}, 00053 {{'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',0}, 00054 HKEY_LOCAL_MACHINE}, 00055 {{'H','K','E','Y','_','U','S','E','R','S',0}, 00056 HKEY_USERS}, 00057 {{'H','K','E','Y','_','P','E','R','F','O','R','M','A','N','C','E','_','D','A','T','A',0}, 00058 HKEY_PERFORMANCE_DATA}, 00059 {{'H','K','E','Y','_','D','Y','N','_','D','A','T','A',0}, 00060 HKEY_DYN_DATA}, 00061 {{'H','K','E','Y','_','C','U','R','R','E','N','T','_','C','O','N','F','I','G',0}, 00062 HKEY_CURRENT_CONFIG}, 00063 {{'H','K','C','R',0}, HKEY_CLASSES_ROOT}, 00064 {{'H','K','C','U',0}, HKEY_CURRENT_USER}, 00065 {{'H','K','L','M',0}, HKEY_LOCAL_MACHINE}, 00066 {{'H','K','U',0}, HKEY_USERS}, 00067 {{'H','K','P','D',0}, HKEY_PERFORMANCE_DATA}, 00068 {{'H','K','D','D',0}, HKEY_DYN_DATA}, 00069 {{'H','K','C','C',0}, HKEY_CURRENT_CONFIG} 00070 }; 00071 00072 typedef struct rep_list_str { 00073 LPOLESTR key; 00074 LPOLESTR item; 00075 int key_len; 00076 struct rep_list_str *next; 00077 } rep_list; 00078 00079 typedef struct { 00080 IRegistrar IRegistrar_iface; 00081 LONG ref; 00082 rep_list *rep; 00083 } Registrar; 00084 00085 typedef struct { 00086 LPOLESTR str; 00087 DWORD alloc; 00088 DWORD len; 00089 } strbuf; 00090 00091 static inline Registrar *impl_from_IRegistrar(IRegistrar *iface) 00092 { 00093 return CONTAINING_RECORD(iface, Registrar, IRegistrar_iface); 00094 } 00095 00096 static void strbuf_init(strbuf *buf) 00097 { 00098 buf->str = HeapAlloc(GetProcessHeap(), 0, 128*sizeof(WCHAR)); 00099 buf->alloc = 128; 00100 buf->len = 0; 00101 } 00102 00103 static void strbuf_write(LPCOLESTR str, strbuf *buf, int len) 00104 { 00105 if(len == -1) 00106 len = lstrlenW(str); 00107 if(buf->len+len+1 >= buf->alloc) { 00108 buf->alloc = (buf->len+len)<<1; 00109 buf->str = HeapReAlloc(GetProcessHeap(), 0, buf->str, buf->alloc*sizeof(WCHAR)); 00110 } 00111 memcpy(buf->str+buf->len, str, len*sizeof(OLECHAR)); 00112 buf->len += len; 00113 buf->str[buf->len] = '\0'; 00114 } 00115 00116 static HRESULT get_word(LPCOLESTR *str, strbuf *buf) 00117 { 00118 LPCOLESTR iter, iter2 = *str; 00119 00120 buf->len = 0; 00121 buf->str[0] = '\0'; 00122 00123 while(isspaceW(*iter2)) 00124 iter2++; 00125 iter = iter2; 00126 if(!*iter) { 00127 *str = iter; 00128 return S_OK; 00129 } 00130 00131 if(*iter == '}' || *iter == '=') { 00132 strbuf_write(iter++, buf, 1); 00133 }else if(*iter == '\'') { 00134 iter2 = ++iter; 00135 iter = strchrW(iter, '\''); 00136 if(!iter) { 00137 WARN("Unexpected end of script\n"); 00138 *str = iter; 00139 return DISP_E_EXCEPTION; 00140 } 00141 strbuf_write(iter2, buf, iter-iter2); 00142 iter++; 00143 }else { 00144 while(*iter && !isspaceW(*iter)) 00145 iter++; 00146 strbuf_write(iter2, buf, iter-iter2); 00147 } 00148 00149 while(isspaceW(*iter)) 00150 iter++; 00151 *str = iter; 00152 return S_OK; 00153 } 00154 00155 static HRESULT do_preprocess(const Registrar *This, LPCOLESTR data, strbuf *buf) 00156 { 00157 LPCOLESTR iter, iter2 = data; 00158 rep_list *rep_iter; 00159 static const WCHAR wstr[] = {'%',0}; 00160 00161 iter = strchrW(data, '%'); 00162 while(iter) { 00163 strbuf_write(iter2, buf, iter-iter2); 00164 00165 iter2 = ++iter; 00166 if(!*iter2) 00167 return DISP_E_EXCEPTION; 00168 iter = strchrW(iter2, '%'); 00169 if(!iter) 00170 return DISP_E_EXCEPTION; 00171 00172 if(iter == iter2) { 00173 strbuf_write(wstr, buf, 1); 00174 }else { 00175 for(rep_iter = This->rep; rep_iter; rep_iter = rep_iter->next) { 00176 if(rep_iter->key_len == iter-iter2 00177 && !memicmpW(iter2, rep_iter->key, rep_iter->key_len)) 00178 break; 00179 } 00180 if(!rep_iter) { 00181 WARN("Could not find replacement: %s\n", debugstr_wn(iter2, iter-iter2)); 00182 return DISP_E_EXCEPTION; 00183 } 00184 00185 strbuf_write(rep_iter->item, buf, -1); 00186 } 00187 00188 iter2 = ++iter; 00189 iter = strchrW(iter, '%'); 00190 } 00191 00192 strbuf_write(iter2, buf, -1); 00193 TRACE("%s\n", debugstr_w(buf->str)); 00194 00195 return S_OK; 00196 } 00197 00198 static HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOOL do_register) 00199 { 00200 LPCOLESTR iter = *pstr; 00201 HRESULT hres; 00202 LONG lres; 00203 HKEY hkey = 0; 00204 strbuf name; 00205 00206 enum { 00207 NORMAL, 00208 NO_REMOVE, 00209 IS_VAL, 00210 FORCE_REMOVE, 00211 DO_DELETE 00212 } key_type = NORMAL; 00213 00214 static const WCHAR wstrNoRemove[] = {'N','o','R','e','m','o','v','e',0}; 00215 static const WCHAR wstrForceRemove[] = {'F','o','r','c','e','R','e','m','o','v','e',0}; 00216 static const WCHAR wstrDelete[] = {'D','e','l','e','t','e',0}; 00217 static const WCHAR wstrval[] = {'v','a','l',0}; 00218 00219 iter = *pstr; 00220 hres = get_word(&iter, buf); 00221 if(FAILED(hres)) 00222 return hres; 00223 strbuf_init(&name); 00224 00225 while(buf->str[1] || buf->str[0] != '}') { 00226 key_type = NORMAL; 00227 if(!lstrcmpiW(buf->str, wstrNoRemove)) 00228 key_type = NO_REMOVE; 00229 else if(!lstrcmpiW(buf->str, wstrForceRemove)) 00230 key_type = FORCE_REMOVE; 00231 else if(!lstrcmpiW(buf->str, wstrval)) 00232 key_type = IS_VAL; 00233 else if(!lstrcmpiW(buf->str, wstrDelete)) 00234 key_type = DO_DELETE; 00235 00236 if(key_type != NORMAL) { 00237 hres = get_word(&iter, buf); 00238 if(FAILED(hres)) 00239 break; 00240 } 00241 TRACE("name = %s\n", debugstr_w(buf->str)); 00242 00243 if(do_register) { 00244 if(key_type == IS_VAL) { 00245 hkey = parent_key; 00246 strbuf_write(buf->str, &name, -1); 00247 }else if(key_type == DO_DELETE) { 00248 TRACE("Deleting %s\n", debugstr_w(buf->str)); 00249 RegDeleteTreeW(parent_key, buf->str); 00250 }else { 00251 if(key_type == FORCE_REMOVE) 00252 RegDeleteTreeW(parent_key, buf->str); 00253 lres = RegCreateKeyW(parent_key, buf->str, &hkey); 00254 if(lres != ERROR_SUCCESS) { 00255 WARN("Could not create(open) key: %08x\n", lres); 00256 hres = HRESULT_FROM_WIN32(lres); 00257 break; 00258 } 00259 } 00260 }else if(key_type != IS_VAL && key_type != DO_DELETE) { 00261 strbuf_write(buf->str, &name, -1); 00262 lres = RegOpenKeyW(parent_key, buf->str, &hkey); 00263 if(lres != ERROR_SUCCESS) 00264 WARN("Could not open key %s: %08x\n", debugstr_w(name.str), lres); 00265 } 00266 00267 if(key_type != DO_DELETE && *iter == '=') { 00268 iter++; 00269 hres = get_word(&iter, buf); 00270 if(FAILED(hres)) 00271 break; 00272 if(buf->len != 1) { 00273 WARN("Wrong registry type: %s\n", debugstr_w(buf->str)); 00274 hres = DISP_E_EXCEPTION; 00275 break; 00276 } 00277 if(do_register) { 00278 switch(buf->str[0]) { 00279 case 's': 00280 hres = get_word(&iter, buf); 00281 if(FAILED(hres)) 00282 break; 00283 lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_SZ, (PBYTE)buf->str, 00284 (lstrlenW(buf->str)+1)*sizeof(WCHAR)); 00285 if(lres != ERROR_SUCCESS) { 00286 WARN("Could set value of key: %08x\n", lres); 00287 hres = HRESULT_FROM_WIN32(lres); 00288 break; 00289 } 00290 break; 00291 case 'd': { 00292 DWORD dw; 00293 hres = get_word(&iter, buf); 00294 if(FAILED(hres)) 00295 break; 00296 dw = atoiW(buf->str); 00297 lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_DWORD, 00298 (PBYTE)&dw, sizeof(dw)); 00299 if(lres != ERROR_SUCCESS) { 00300 WARN("Could set value of key: %08x\n", lres); 00301 hres = HRESULT_FROM_WIN32(lres); 00302 break; 00303 } 00304 break; 00305 } 00306 case 'b': { 00307 BYTE *bytes; 00308 DWORD count; 00309 DWORD i; 00310 hres = get_word(&iter, buf); 00311 if(FAILED(hres)) 00312 break; 00313 count = (lstrlenW(buf->str) + 1) / 2; 00314 bytes = HeapAlloc(GetProcessHeap(), 0, count); 00315 if(bytes == NULL) { 00316 hres = E_OUTOFMEMORY; 00317 break; 00318 } 00319 for(i = 0; i < count && buf->str[2*i]; i++) { 00320 WCHAR digits[3]; 00321 if(!isxdigitW(buf->str[2*i]) || !isxdigitW(buf->str[2*i + 1])) { 00322 hres = E_FAIL; 00323 break; 00324 } 00325 digits[0] = buf->str[2*i]; 00326 digits[1] = buf->str[2*i + 1]; 00327 digits[2] = 0; 00328 bytes[i] = (BYTE) strtoulW(digits, NULL, 16); 00329 } 00330 if(SUCCEEDED(hres)) { 00331 lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_BINARY, 00332 bytes, count); 00333 if(lres != ERROR_SUCCESS) { 00334 WARN("Could not set value of key: 0x%08x\n", lres); 00335 hres = HRESULT_FROM_WIN32(lres); 00336 } 00337 } 00338 HeapFree(GetProcessHeap(), 0, bytes); 00339 break; 00340 } 00341 default: 00342 WARN("Wrong resource type: %s\n", debugstr_w(buf->str)); 00343 hres = DISP_E_EXCEPTION; 00344 }; 00345 if(FAILED(hres)) 00346 break; 00347 }else { 00348 if(*iter == '-') 00349 iter++; 00350 hres = get_word(&iter, buf); 00351 if(FAILED(hres)) 00352 break; 00353 } 00354 }else if(key_type == IS_VAL) { 00355 WARN("value not set!\n"); 00356 hres = DISP_E_EXCEPTION; 00357 break; 00358 } 00359 00360 if(key_type != IS_VAL && key_type != DO_DELETE && *iter == '{' && isspaceW(iter[1])) { 00361 hres = get_word(&iter, buf); 00362 if(FAILED(hres)) 00363 break; 00364 hres = do_process_key(&iter, hkey, buf, do_register); 00365 if(FAILED(hres)) 00366 break; 00367 } 00368 00369 TRACE("%x %x\n", do_register, key_type); 00370 if(!do_register && (key_type == NORMAL || key_type == FORCE_REMOVE)) { 00371 TRACE("Deleting %s\n", debugstr_w(name.str)); 00372 RegDeleteKeyW(parent_key, name.str); 00373 } 00374 00375 if(hkey && key_type != IS_VAL) 00376 RegCloseKey(hkey); 00377 hkey = 0; 00378 name.len = 0; 00379 00380 hres = get_word(&iter, buf); 00381 if(FAILED(hres)) 00382 break; 00383 } 00384 00385 HeapFree(GetProcessHeap(), 0, name.str); 00386 if(hkey && key_type != IS_VAL) 00387 RegCloseKey(hkey); 00388 *pstr = iter; 00389 return hres; 00390 } 00391 00392 static HRESULT do_process_root_key(LPCOLESTR data, BOOL do_register) 00393 { 00394 LPCOLESTR iter = data; 00395 strbuf buf; 00396 HRESULT hres = S_OK; 00397 unsigned int i; 00398 00399 strbuf_init(&buf); 00400 hres = get_word(&iter, &buf); 00401 if(FAILED(hres)) 00402 return hres; 00403 00404 while(*iter) { 00405 if(!buf.len) { 00406 WARN("ward.len == 0, failed\n"); 00407 hres = DISP_E_EXCEPTION; 00408 break; 00409 } 00410 for(i=0; i<sizeof(root_keys)/sizeof(root_keys[0]); i++) { 00411 if(!lstrcmpiW(buf.str, root_keys[i].name)) 00412 break; 00413 } 00414 if(i == sizeof(root_keys)/sizeof(root_keys[0])) { 00415 WARN("Wrong root key name: %s\n", debugstr_w(buf.str)); 00416 hres = DISP_E_EXCEPTION; 00417 break; 00418 } 00419 hres = get_word(&iter, &buf); 00420 if(FAILED(hres)) 00421 break; 00422 if(buf.str[1] || buf.str[0] != '{') { 00423 WARN("Failed, expected '{', got %s\n", debugstr_w(buf.str)); 00424 hres = DISP_E_EXCEPTION; 00425 break; 00426 } 00427 hres = do_process_key(&iter, root_keys[i].key, &buf, do_register); 00428 if(FAILED(hres)) { 00429 WARN("Processing key failed: %08x\n", hres); 00430 break; 00431 } 00432 hres = get_word(&iter, &buf); 00433 if(FAILED(hres)) 00434 break; 00435 } 00436 HeapFree(GetProcessHeap(), 0, buf.str); 00437 return hres; 00438 } 00439 00440 static HRESULT string_register(Registrar *This, LPCOLESTR data, BOOL do_register) 00441 { 00442 strbuf buf; 00443 HRESULT hres; 00444 00445 TRACE("(%p %s %x)\n", This, debugstr_w(data), do_register); 00446 00447 strbuf_init(&buf); 00448 hres = do_preprocess(This, data, &buf); 00449 if(FAILED(hres)) { 00450 WARN("preprocessing failed!\n"); 00451 HeapFree(GetProcessHeap(), 0, buf.str); 00452 return hres; 00453 } 00454 00455 hres = do_process_root_key(buf.str, do_register); 00456 if(FAILED(hres) && do_register) 00457 do_process_root_key(buf.str, FALSE); 00458 00459 HeapFree(GetProcessHeap(), 0, buf.str); 00460 return hres; 00461 } 00462 00463 static HRESULT resource_register(Registrar *This, LPCOLESTR resFileName, 00464 LPCOLESTR szID, LPCOLESTR szType, BOOL do_register) 00465 { 00466 HINSTANCE hins; 00467 HRSRC src; 00468 LPSTR regstra; 00469 LPWSTR regstrw; 00470 DWORD len, reslen; 00471 HRESULT hres; 00472 00473 hins = LoadLibraryExW(resFileName, NULL, LOAD_LIBRARY_AS_DATAFILE); 00474 if(hins) { 00475 src = FindResourceW(hins, szID, szType); 00476 if(src) { 00477 regstra = LoadResource(hins, src); 00478 reslen = SizeofResource(hins, src); 00479 if(regstra) { 00480 len = MultiByteToWideChar(CP_ACP, 0, regstra, reslen, NULL, 0)+1; 00481 regstrw = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(WCHAR)); 00482 MultiByteToWideChar(CP_ACP, 0, regstra, reslen, regstrw, len); 00483 regstrw[len-1] = '\0'; 00484 00485 hres = string_register(This, regstrw, do_register); 00486 00487 HeapFree(GetProcessHeap(), 0, regstrw); 00488 }else { 00489 WARN("could not load resource\n"); 00490 hres = HRESULT_FROM_WIN32(GetLastError()); 00491 } 00492 }else { 00493 WARN("Could not find source\n"); 00494 hres = HRESULT_FROM_WIN32(GetLastError()); 00495 } 00496 FreeLibrary(hins); 00497 }else { 00498 WARN("Could not load resource file\n"); 00499 hres = HRESULT_FROM_WIN32(GetLastError()); 00500 } 00501 00502 return hres; 00503 } 00504 00505 static HRESULT file_register(Registrar *This, LPCOLESTR fileName, BOOL do_register) 00506 { 00507 HANDLE file; 00508 DWORD filelen, len; 00509 LPWSTR regstrw; 00510 LPSTR regstra; 00511 LRESULT lres; 00512 HRESULT hres; 00513 00514 file = CreateFileW(fileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); 00515 if(file != INVALID_HANDLE_VALUE) { 00516 filelen = GetFileSize(file, NULL); 00517 regstra = HeapAlloc(GetProcessHeap(), 0, filelen); 00518 lres = ReadFile(file, regstra, filelen, NULL, NULL); 00519 if(lres == ERROR_SUCCESS) { 00520 len = MultiByteToWideChar(CP_ACP, 0, regstra, filelen, NULL, 0)+1; 00521 regstrw = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(WCHAR)); 00522 MultiByteToWideChar(CP_ACP, 0, regstra, filelen, regstrw, len); 00523 regstrw[len-1] = '\0'; 00524 00525 hres = string_register(This, regstrw, do_register); 00526 00527 HeapFree(GetProcessHeap(), 0, regstrw); 00528 }else { 00529 WARN("Failed to read faile\n"); 00530 hres = HRESULT_FROM_WIN32(lres); 00531 } 00532 HeapFree(GetProcessHeap(), 0, regstra); 00533 CloseHandle(file); 00534 }else { 00535 WARN("Could not open file\n"); 00536 hres = HRESULT_FROM_WIN32(GetLastError()); 00537 } 00538 00539 return hres; 00540 } 00541 00542 static HRESULT WINAPI Registrar_QueryInterface(IRegistrar *iface, REFIID riid, void **ppvObject) 00543 { 00544 TRACE("(%p)->(%s %p\n", iface, debugstr_guid(riid), ppvObject); 00545 00546 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRegistrar, riid)) { 00547 IRegistrar_AddRef(iface); 00548 *ppvObject = iface; 00549 return S_OK; 00550 } 00551 return E_NOINTERFACE; 00552 } 00553 00554 static ULONG WINAPI Registrar_AddRef(IRegistrar *iface) 00555 { 00556 Registrar *This = impl_from_IRegistrar(iface); 00557 ULONG ref = InterlockedIncrement(&This->ref); 00558 TRACE("(%p) ->%d\n", This, ref); 00559 return ref; 00560 } 00561 00562 static ULONG WINAPI Registrar_Release(IRegistrar *iface) 00563 { 00564 Registrar *This = impl_from_IRegistrar(iface); 00565 ULONG ref = InterlockedDecrement(&This->ref); 00566 00567 TRACE("(%p) ->%d\n", This, ref); 00568 if(!ref) { 00569 IRegistrar_ClearReplacements(iface); 00570 HeapFree(GetProcessHeap(), 0, This); 00571 InterlockedDecrement(&dll_count); 00572 } 00573 return ref; 00574 } 00575 00576 static HRESULT WINAPI Registrar_AddReplacement(IRegistrar *iface, LPCOLESTR Key, LPCOLESTR item) 00577 { 00578 Registrar *This = impl_from_IRegistrar(iface); 00579 int len; 00580 rep_list *new_rep; 00581 00582 TRACE("(%p)->(%s %s)\n", This, debugstr_w(Key), debugstr_w(item)); 00583 00584 new_rep = HeapAlloc(GetProcessHeap(), 0, sizeof(rep_list)); 00585 00586 new_rep->key_len = lstrlenW(Key); 00587 new_rep->key = HeapAlloc(GetProcessHeap(), 0, (new_rep->key_len + 1) * sizeof(OLECHAR)); 00588 memcpy(new_rep->key, Key, (new_rep->key_len+1)*sizeof(OLECHAR)); 00589 00590 len = lstrlenW(item)+1; 00591 new_rep->item = HeapAlloc(GetProcessHeap(), 0, len*sizeof(OLECHAR)); 00592 memcpy(new_rep->item, item, len*sizeof(OLECHAR)); 00593 00594 new_rep->next = This->rep; 00595 This->rep = new_rep; 00596 00597 return S_OK; 00598 } 00599 00600 static HRESULT WINAPI Registrar_ClearReplacements(IRegistrar *iface) 00601 { 00602 Registrar *This = impl_from_IRegistrar(iface); 00603 rep_list *iter, *iter2; 00604 00605 TRACE("(%p)\n", This); 00606 00607 if(!This->rep) 00608 return S_OK; 00609 00610 iter = This->rep; 00611 while(iter) { 00612 iter2 = iter->next; 00613 HeapFree(GetProcessHeap(), 0, iter->key); 00614 HeapFree(GetProcessHeap(), 0, iter->item); 00615 HeapFree(GetProcessHeap(), 0, iter); 00616 iter = iter2; 00617 } 00618 00619 This->rep = NULL; 00620 return S_OK; 00621 } 00622 00623 static HRESULT WINAPI Registrar_ResourceRegisterSz(IRegistrar* iface, LPCOLESTR resFileName, 00624 LPCOLESTR szID, LPCOLESTR szType) 00625 { 00626 Registrar *This = impl_from_IRegistrar(iface); 00627 TRACE("(%p)->(%s %s %s)\n", This, debugstr_w(resFileName), debugstr_w(szID), debugstr_w(szType)); 00628 return resource_register(This, resFileName, szID, szType, TRUE); 00629 } 00630 00631 static HRESULT WINAPI Registrar_ResourceUnregisterSz(IRegistrar* iface, LPCOLESTR resFileName, 00632 LPCOLESTR szID, LPCOLESTR szType) 00633 { 00634 Registrar *This = impl_from_IRegistrar(iface); 00635 TRACE("(%p)->(%s %s %s)\n", This, debugstr_w(resFileName), debugstr_w(szID), debugstr_w(szType)); 00636 return resource_register(This, resFileName, szID, szType, FALSE); 00637 } 00638 00639 static HRESULT WINAPI Registrar_FileRegister(IRegistrar* iface, LPCOLESTR fileName) 00640 { 00641 Registrar *This = impl_from_IRegistrar(iface); 00642 TRACE("(%p)->(%s)\n", This, debugstr_w(fileName)); 00643 return file_register(This, fileName, TRUE); 00644 } 00645 00646 static HRESULT WINAPI Registrar_FileUnregister(IRegistrar* iface, LPCOLESTR fileName) 00647 { 00648 Registrar *This = impl_from_IRegistrar(iface); 00649 FIXME("(%p)->(%s)\n", This, debugstr_w(fileName)); 00650 return file_register(This, fileName, FALSE); 00651 } 00652 00653 static HRESULT WINAPI Registrar_StringRegister(IRegistrar* iface, LPCOLESTR data) 00654 { 00655 Registrar *This = impl_from_IRegistrar(iface); 00656 TRACE("(%p)->(%s)\n", This, debugstr_w(data)); 00657 return string_register(This, data, TRUE); 00658 } 00659 00660 static HRESULT WINAPI Registrar_StringUnregister(IRegistrar* iface, LPCOLESTR data) 00661 { 00662 Registrar *This = impl_from_IRegistrar(iface); 00663 TRACE("(%p)->(%s)\n", This, debugstr_w(data)); 00664 return string_register(This, data, FALSE); 00665 } 00666 00667 static HRESULT WINAPI Registrar_ResourceRegister(IRegistrar* iface, LPCOLESTR resFileName, 00668 UINT nID, LPCOLESTR szType) 00669 { 00670 Registrar *This = impl_from_IRegistrar(iface); 00671 TRACE("(%p)->(%s %d %s)\n", iface, debugstr_w(resFileName), nID, debugstr_w(szType)); 00672 return resource_register(This, resFileName, MAKEINTRESOURCEW(nID), szType, TRUE); 00673 } 00674 00675 static HRESULT WINAPI Registrar_ResourceUnregister(IRegistrar* iface, LPCOLESTR resFileName, 00676 UINT nID, LPCOLESTR szType) 00677 { 00678 Registrar *This = impl_from_IRegistrar(iface); 00679 TRACE("(%p)->(%s %d %s)\n", This, debugstr_w(resFileName), nID, debugstr_w(szType)); 00680 return resource_register(This, resFileName, MAKEINTRESOURCEW(nID), szType, FALSE); 00681 } 00682 00683 static const IRegistrarVtbl RegistrarVtbl = { 00684 Registrar_QueryInterface, 00685 Registrar_AddRef, 00686 Registrar_Release, 00687 Registrar_AddReplacement, 00688 Registrar_ClearReplacements, 00689 Registrar_ResourceRegisterSz, 00690 Registrar_ResourceUnregisterSz, 00691 Registrar_FileRegister, 00692 Registrar_FileUnregister, 00693 Registrar_StringRegister, 00694 Registrar_StringUnregister, 00695 Registrar_ResourceRegister, 00696 Registrar_ResourceUnregister, 00697 }; 00698 00699 static HRESULT Registrar_create(const IUnknown *pUnkOuter, REFIID riid, void **ppvObject) 00700 { 00701 Registrar *ret; 00702 00703 if(!IsEqualGUID(&IID_IUnknown, riid) && !IsEqualGUID(&IID_IRegistrar, riid)) 00704 return E_NOINTERFACE; 00705 00706 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(Registrar)); 00707 ret->IRegistrar_iface.lpVtbl = &RegistrarVtbl; 00708 ret->ref = 1; 00709 ret->rep = NULL; 00710 *ppvObject = ret; 00711 00712 InterlockedIncrement(&dll_count); 00713 00714 return S_OK; 00715 } 00716 00717 /************************************************************** 00718 * ClassFactory implementation 00719 */ 00720 00721 static HRESULT WINAPI RegistrarCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppvObject) 00722 { 00723 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject); 00724 00725 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) { 00726 *ppvObject = iface; 00727 IClassFactory_AddRef( iface ); 00728 return S_OK; 00729 } 00730 00731 return E_NOINTERFACE; 00732 } 00733 00734 static ULONG WINAPI RegistrarCF_AddRef(IClassFactory *iface) 00735 { 00736 InterlockedIncrement(&dll_count); 00737 return 2; 00738 } 00739 00740 static ULONG WINAPI RegistrarCF_Release(IClassFactory *iface) 00741 { 00742 InterlockedDecrement(&dll_count); 00743 return 1; 00744 } 00745 00746 static HRESULT WINAPI RegistrarCF_CreateInstance(IClassFactory *iface, LPUNKNOWN pUnkOuter, 00747 REFIID riid, void **ppvObject) 00748 { 00749 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject); 00750 return Registrar_create(pUnkOuter, riid, ppvObject); 00751 } 00752 00753 static HRESULT WINAPI RegistrarCF_LockServer(IClassFactory *iface, BOOL lock) 00754 { 00755 TRACE("(%p)->(%x)\n", iface, lock); 00756 00757 if(lock) 00758 InterlockedIncrement(&dll_count); 00759 else 00760 InterlockedDecrement(&dll_count); 00761 00762 return S_OK; 00763 } 00764 00765 static const IClassFactoryVtbl IRegistrarCFVtbl = { 00766 RegistrarCF_QueryInterface, 00767 RegistrarCF_AddRef, 00768 RegistrarCF_Release, 00769 RegistrarCF_CreateInstance, 00770 RegistrarCF_LockServer 00771 }; 00772 00773 static IClassFactory RegistrarCF = { &IRegistrarCFVtbl }; 00774 00775 /************************************************************** 00776 * DllGetClassObject (ATL.2) 00777 */ 00778 HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, LPVOID *ppvObject) 00779 { 00780 TRACE("(%s %s %p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppvObject); 00781 00782 if(IsEqualGUID(&CLSID_Registrar, clsid)) 00783 return IClassFactory_QueryInterface( &RegistrarCF, riid, ppvObject ); 00784 00785 FIXME("Not supported class %s\n", debugstr_guid(clsid)); 00786 return CLASS_E_CLASSNOTAVAILABLE; 00787 } 00788 00789 extern HINSTANCE hInst; 00790 00791 static HRESULT do_register_dll_server(IRegistrar *pRegistrar, LPCOLESTR wszDll, 00792 LPCOLESTR wszId, BOOL do_register, 00793 const struct _ATL_REGMAP_ENTRY* pMapEntries) 00794 { 00795 IRegistrar *registrar; 00796 HRESULT hres; 00797 const struct _ATL_REGMAP_ENTRY *pMapEntry; 00798 00799 static const WCHAR wszModule[] = {'M','O','D','U','L','E',0}; 00800 static const WCHAR wszRegistry[] = {'R','E','G','I','S','T','R','Y',0}; 00801 00802 if (pRegistrar) 00803 registrar = pRegistrar; 00804 else 00805 Registrar_create(NULL, &IID_IRegistrar, (void**)®istrar); 00806 00807 IRegistrar_AddReplacement(registrar, wszModule, wszDll); 00808 00809 for (pMapEntry = pMapEntries; pMapEntry && pMapEntry->szKey; pMapEntry++) 00810 IRegistrar_AddReplacement(registrar, pMapEntry->szKey, pMapEntry->szData); 00811 00812 if(do_register) 00813 hres = IRegistrar_ResourceRegisterSz(registrar, wszDll, wszId, wszRegistry); 00814 else 00815 hres = IRegistrar_ResourceUnregisterSz(registrar, wszDll, wszId, wszRegistry); 00816 00817 if(registrar != pRegistrar) 00818 IRegistrar_Release(registrar); 00819 return hres; 00820 } 00821 00822 static HRESULT do_register_server(BOOL do_register) 00823 { 00824 static const WCHAR CLSID_RegistrarW[] = 00825 {'C','L','S','I','D','_','R','e','g','i','s','t','r','a','r',0}; 00826 static const WCHAR atl_dllW[] = {'a','t','l','.','d','l','l',0}; 00827 00828 WCHAR clsid_str[40]; 00829 const struct _ATL_REGMAP_ENTRY reg_map[] = {{CLSID_RegistrarW, clsid_str}, {NULL,NULL}}; 00830 00831 StringFromGUID2(&CLSID_Registrar, clsid_str, sizeof(clsid_str)/sizeof(WCHAR)); 00832 return do_register_dll_server(NULL, atl_dllW, MAKEINTRESOURCEW(101), do_register, reg_map); 00833 } 00834 00835 /*********************************************************************** 00836 * AtlModuleUpdateRegistryFromResourceD [ATL.@] 00837 * 00838 */ 00839 HRESULT WINAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULEW* pM, LPCOLESTR lpszRes, 00840 BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg) 00841 { 00842 HINSTANCE lhInst = pM->m_hInst; 00843 /* everything inside this function below this point 00844 * should go into atl71.AtlUpdateRegistryFromResourceD 00845 */ 00846 WCHAR module_name[MAX_PATH]; 00847 00848 if(!GetModuleFileNameW(lhInst, module_name, MAX_PATH)) { 00849 FIXME("hinst %p: did not get module name\n", 00850 lhInst); 00851 return E_FAIL; 00852 } 00853 00854 TRACE("%p (%s), %s, %d, %p, %p\n", hInst, debugstr_w(module_name), 00855 debugstr_w(lpszRes), bRegister, pMapEntries, pReg); 00856 00857 return do_register_dll_server(pReg, module_name, lpszRes, bRegister, pMapEntries); 00858 } 00859 00860 /*********************************************************************** 00861 * DllRegisterServer (ATL.@) 00862 */ 00863 HRESULT WINAPI DllRegisterServer(void) 00864 { 00865 /* Note: we can't use __wine_register_server here because it uses CLSID_Registrar which isn't registred yet */ 00866 return do_register_server(TRUE); 00867 } 00868 00869 /*********************************************************************** 00870 * DllUnRegisterServer (ATL.@) 00871 */ 00872 HRESULT WINAPI DllUnregisterServer(void) 00873 { 00874 return do_register_server(FALSE); 00875 } 00876 00877 /*********************************************************************** 00878 * DllCanUnloadNow (ATL.@) 00879 */ 00880 HRESULT WINAPI DllCanUnloadNow(void) 00881 { 00882 TRACE("dll_count = %u\n", dll_count); 00883 return dll_count ? S_FALSE : S_OK; 00884 } Generated on Sat May 26 2012 04:21:22 for ReactOS by
1.7.6.1
|