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

registrar.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**)&registrar);
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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.