Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/atl/registrar.c
4388 views
1
/*
2
* Copyright 2005 Jacek Caban
3
*
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) any later version.
8
*
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
13
*
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17
*/
18
19
#define COBJMACROS
20
21
#include "atlbase.h"
22
23
#include "wine/debug.h"
24
25
WINE_DEFAULT_DEBUG_CHANNEL(atl);
26
27
/**************************************************************
28
* ATLRegistrar implementation
29
*/
30
31
static const struct {
32
WCHAR name[22];
33
HKEY key;
34
} root_keys[] = {
35
{L"HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT},
36
{L"HKEY_CURRENT_USER", HKEY_CURRENT_USER},
37
{L"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE},
38
{L"HKEY_USERS", HKEY_USERS},
39
{L"HKEY_PERFORMANCE_DATA", HKEY_PERFORMANCE_DATA},
40
{L"HKEY_DYN_DATA", HKEY_DYN_DATA},
41
{L"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG},
42
{L"HKCR", HKEY_CLASSES_ROOT},
43
{L"HKCU", HKEY_CURRENT_USER},
44
{L"HKLM", HKEY_LOCAL_MACHINE},
45
{L"HKU", HKEY_USERS},
46
{L"HKPD", HKEY_PERFORMANCE_DATA},
47
{L"HKDD", HKEY_DYN_DATA},
48
{L"HKCC", HKEY_CURRENT_CONFIG}
49
};
50
51
typedef struct rep_list_str {
52
LPOLESTR key;
53
LPOLESTR item;
54
int key_len;
55
struct rep_list_str *next;
56
} rep_list;
57
58
typedef struct {
59
IRegistrar IRegistrar_iface;
60
LONG ref;
61
rep_list *rep;
62
} Registrar;
63
64
typedef struct {
65
LPOLESTR str;
66
DWORD alloc;
67
DWORD len;
68
} strbuf;
69
70
static inline Registrar *impl_from_IRegistrar(IRegistrar *iface)
71
{
72
return CONTAINING_RECORD(iface, Registrar, IRegistrar_iface);
73
}
74
75
static void strbuf_init(strbuf *buf)
76
{
77
buf->str = malloc(128*sizeof(WCHAR));
78
buf->alloc = 128;
79
buf->len = 0;
80
}
81
82
static void strbuf_write(LPCOLESTR str, strbuf *buf, int len)
83
{
84
if(len == -1)
85
len = lstrlenW(str);
86
if(buf->len+len+1 >= buf->alloc) {
87
buf->alloc = (buf->len+len)<<1;
88
buf->str = realloc(buf->str, buf->alloc*sizeof(WCHAR));
89
}
90
memcpy(buf->str+buf->len, str, len*sizeof(OLECHAR));
91
buf->len += len;
92
buf->str[buf->len] = '\0';
93
}
94
95
static int xdigit_to_int(WCHAR c)
96
{
97
if('0' <= c && c <= '9') return c - '0';
98
if('a' <= c && c <= 'f') return c - 'a' + 10;
99
if('A' <= c && c <= 'F') return c - 'A' + 10;
100
return -1;
101
}
102
103
static HRESULT get_word(LPCOLESTR *str, strbuf *buf)
104
{
105
LPCOLESTR iter, iter2 = *str;
106
107
buf->len = 0;
108
buf->str[0] = '\0';
109
110
while(iswspace(*iter2))
111
iter2++;
112
iter = iter2;
113
if(!*iter) {
114
*str = iter;
115
return S_OK;
116
}
117
118
if(*iter == '}' || *iter == '=') {
119
strbuf_write(iter++, buf, 1);
120
}else if(*iter == '\'') {
121
for (;;)
122
{
123
iter2 = ++iter;
124
iter = wcschr(iter, '\'');
125
if(!iter) {
126
WARN("Unexpected end of script\n");
127
*str = iter;
128
return DISP_E_EXCEPTION;
129
}
130
if (iter[1] != '\'') break;
131
iter++;
132
strbuf_write(iter2, buf, iter-iter2);
133
}
134
strbuf_write(iter2, buf, iter-iter2);
135
iter++;
136
}else {
137
while(*iter && !iswspace(*iter))
138
iter++;
139
strbuf_write(iter2, buf, iter-iter2);
140
}
141
142
while(iswspace(*iter))
143
iter++;
144
*str = iter;
145
return S_OK;
146
}
147
148
static HRESULT do_preprocess(const Registrar *This, LPCOLESTR data, strbuf *buf)
149
{
150
LPCOLESTR iter, iter2 = data;
151
rep_list *rep_iter;
152
153
iter = wcschr(data, '%');
154
while(iter) {
155
strbuf_write(iter2, buf, iter-iter2);
156
157
iter2 = ++iter;
158
if(!*iter2)
159
return DISP_E_EXCEPTION;
160
iter = wcschr(iter2, '%');
161
if(!iter)
162
return DISP_E_EXCEPTION;
163
164
if(iter == iter2) {
165
strbuf_write(L"%", buf, 1);
166
}else {
167
for(rep_iter = This->rep; rep_iter; rep_iter = rep_iter->next) {
168
if(rep_iter->key_len == iter-iter2
169
&& !wcsnicmp(iter2, rep_iter->key, rep_iter->key_len))
170
break;
171
}
172
if(!rep_iter) {
173
WARN("Could not find replacement: %s\n", debugstr_wn(iter2, iter-iter2));
174
return DISP_E_EXCEPTION;
175
}
176
177
strbuf_write(rep_iter->item, buf, -1);
178
}
179
180
iter2 = ++iter;
181
iter = wcschr(iter, '%');
182
}
183
184
strbuf_write(iter2, buf, -1);
185
TRACE("%s\n", debugstr_w(buf->str));
186
187
return S_OK;
188
}
189
190
static HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOOL do_register)
191
{
192
LPCOLESTR iter;
193
HRESULT hres;
194
LONG lres;
195
HKEY hkey = 0;
196
strbuf name;
197
198
enum {
199
NORMAL,
200
NO_REMOVE,
201
IS_VAL,
202
FORCE_REMOVE,
203
DO_DELETE
204
} key_type = NORMAL;
205
206
iter = *pstr;
207
hres = get_word(&iter, buf);
208
if(FAILED(hres))
209
return hres;
210
strbuf_init(&name);
211
212
while(buf->str[1] || buf->str[0] != '}') {
213
key_type = NORMAL;
214
if(!lstrcmpiW(buf->str, L"NoRemove"))
215
key_type = NO_REMOVE;
216
else if(!lstrcmpiW(buf->str, L"ForceRemove"))
217
key_type = FORCE_REMOVE;
218
else if(!lstrcmpiW(buf->str, L"val"))
219
key_type = IS_VAL;
220
else if(!lstrcmpiW(buf->str, L"Delete"))
221
key_type = DO_DELETE;
222
223
if(key_type != NORMAL) {
224
hres = get_word(&iter, buf);
225
if(FAILED(hres))
226
break;
227
}
228
TRACE("name = %s\n", debugstr_w(buf->str));
229
230
if(do_register) {
231
if(key_type == IS_VAL) {
232
hkey = parent_key;
233
strbuf_write(buf->str, &name, -1);
234
}else if(key_type == DO_DELETE) {
235
TRACE("Deleting %s\n", debugstr_w(buf->str));
236
RegDeleteTreeW(parent_key, buf->str);
237
}else {
238
if(key_type == FORCE_REMOVE)
239
RegDeleteTreeW(parent_key, buf->str);
240
lres = RegCreateKeyW(parent_key, buf->str, &hkey);
241
if(lres != ERROR_SUCCESS) {
242
WARN("Could not create(open) key: %08lx\n", lres);
243
hres = HRESULT_FROM_WIN32(lres);
244
break;
245
}
246
}
247
}else if(key_type != IS_VAL && key_type != DO_DELETE) {
248
strbuf_write(buf->str, &name, -1);
249
lres = RegOpenKeyW(parent_key, buf->str, &hkey);
250
if(lres != ERROR_SUCCESS)
251
WARN("Could not open key %s: %08lx\n", debugstr_w(name.str), lres);
252
}
253
254
if(key_type != DO_DELETE && *iter == '=') {
255
iter++;
256
hres = get_word(&iter, buf);
257
if(FAILED(hres))
258
break;
259
if(buf->len != 1) {
260
WARN("Wrong registry type: %s\n", debugstr_w(buf->str));
261
hres = DISP_E_EXCEPTION;
262
break;
263
}
264
if(do_register) {
265
switch(buf->str[0]) {
266
case 's':
267
hres = get_word(&iter, buf);
268
if(FAILED(hres))
269
break;
270
lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_SZ, (PBYTE)buf->str,
271
(lstrlenW(buf->str)+1)*sizeof(WCHAR));
272
if(lres != ERROR_SUCCESS) {
273
WARN("Could set value of key: %08lx\n", lres);
274
hres = HRESULT_FROM_WIN32(lres);
275
break;
276
}
277
break;
278
case 'd': {
279
DWORD dw;
280
hres = get_word(&iter, buf);
281
if(FAILED(hres))
282
break;
283
dw = wcstoul(buf->str, NULL, 10);
284
lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_DWORD,
285
(PBYTE)&dw, sizeof(dw));
286
if(lres != ERROR_SUCCESS) {
287
WARN("Could set value of key: %08lx\n", lres);
288
hres = HRESULT_FROM_WIN32(lres);
289
break;
290
}
291
break;
292
}
293
case 'b': {
294
BYTE *bytes;
295
DWORD count;
296
DWORD i;
297
hres = get_word(&iter, buf);
298
if(FAILED(hres))
299
break;
300
count = (lstrlenW(buf->str) + 1) / 2;
301
bytes = malloc(count);
302
if(bytes == NULL) {
303
hres = E_OUTOFMEMORY;
304
break;
305
}
306
for(i = 0; i < count && buf->str[2*i]; i++) {
307
int d1, d2;
308
if((d1 = xdigit_to_int(buf->str[2*i])) == -1 || (d2 = xdigit_to_int(buf->str[2*i + 1])) == -1) {
309
hres = E_FAIL;
310
break;
311
}
312
bytes[i] = (d1 << 4) | d2;
313
}
314
if(SUCCEEDED(hres)) {
315
lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_BINARY,
316
bytes, count);
317
if(lres != ERROR_SUCCESS) {
318
WARN("Could not set value of key: 0x%08lx\n", lres);
319
hres = HRESULT_FROM_WIN32(lres);
320
}
321
}
322
free(bytes);
323
break;
324
}
325
default:
326
WARN("Wrong resource type: %s\n", debugstr_w(buf->str));
327
hres = DISP_E_EXCEPTION;
328
};
329
if(FAILED(hres))
330
break;
331
}else {
332
if(*iter == '-')
333
iter++;
334
hres = get_word(&iter, buf);
335
if(FAILED(hres))
336
break;
337
}
338
}else if(key_type == IS_VAL) {
339
WARN("value not set!\n");
340
hres = DISP_E_EXCEPTION;
341
break;
342
}
343
344
if(key_type != IS_VAL && key_type != DO_DELETE && *iter == '{' && iswspace(iter[1])) {
345
hres = get_word(&iter, buf);
346
if(FAILED(hres))
347
break;
348
hres = do_process_key(&iter, hkey, buf, do_register);
349
if(FAILED(hres))
350
break;
351
}
352
353
TRACE("%x %x\n", do_register, key_type);
354
if(!do_register && (key_type == NORMAL || key_type == FORCE_REMOVE)) {
355
TRACE("Deleting %s\n", debugstr_w(name.str));
356
RegDeleteKeyW(parent_key, name.str);
357
}
358
359
if(hkey && key_type != IS_VAL)
360
RegCloseKey(hkey);
361
hkey = 0;
362
name.len = 0;
363
364
hres = get_word(&iter, buf);
365
if(FAILED(hres))
366
break;
367
}
368
369
free(name.str);
370
if(hkey && key_type != IS_VAL)
371
RegCloseKey(hkey);
372
*pstr = iter;
373
return hres;
374
}
375
376
static HRESULT do_process_root_key(LPCOLESTR data, BOOL do_register)
377
{
378
LPCOLESTR iter = data;
379
strbuf buf;
380
HRESULT hres;
381
unsigned int i;
382
383
strbuf_init(&buf);
384
hres = get_word(&iter, &buf);
385
if(FAILED(hres))
386
goto done;
387
388
while(*iter) {
389
if(!buf.len) {
390
WARN("ward.len == 0, failed\n");
391
hres = DISP_E_EXCEPTION;
392
break;
393
}
394
for(i=0; i<ARRAY_SIZE(root_keys); i++) {
395
if(!lstrcmpiW(buf.str, root_keys[i].name))
396
break;
397
}
398
if(i == ARRAY_SIZE(root_keys)) {
399
WARN("Wrong root key name: %s\n", debugstr_w(buf.str));
400
hres = DISP_E_EXCEPTION;
401
break;
402
}
403
hres = get_word(&iter, &buf);
404
if(FAILED(hres))
405
break;
406
if(buf.str[1] || buf.str[0] != '{') {
407
WARN("Failed, expected '{', got %s\n", debugstr_w(buf.str));
408
hres = DISP_E_EXCEPTION;
409
break;
410
}
411
hres = do_process_key(&iter, root_keys[i].key, &buf, do_register);
412
if(FAILED(hres)) {
413
WARN("Processing key failed: %08lx\n", hres);
414
break;
415
}
416
hres = get_word(&iter, &buf);
417
if(FAILED(hres))
418
break;
419
}
420
421
done:
422
free(buf.str);
423
return hres;
424
}
425
426
static HRESULT string_register(Registrar *This, LPCOLESTR data, BOOL do_register)
427
{
428
strbuf buf;
429
HRESULT hres;
430
431
TRACE("(%p %s %x)\n", This, debugstr_w(data), do_register);
432
433
strbuf_init(&buf);
434
hres = do_preprocess(This, data, &buf);
435
if(FAILED(hres)) {
436
WARN("preprocessing failed!\n");
437
free(buf.str);
438
return hres;
439
}
440
441
hres = do_process_root_key(buf.str, do_register);
442
if(FAILED(hres) && do_register)
443
do_process_root_key(buf.str, FALSE);
444
445
free(buf.str);
446
return hres;
447
}
448
449
static HRESULT resource_register(Registrar *This, LPCOLESTR resFileName,
450
LPCOLESTR szID, LPCOLESTR szType, BOOL do_register)
451
{
452
HINSTANCE hins;
453
HRSRC src;
454
LPSTR regstra;
455
LPWSTR regstrw;
456
DWORD len, reslen;
457
HRESULT hres;
458
459
hins = LoadLibraryExW(resFileName, NULL, LOAD_LIBRARY_AS_DATAFILE);
460
if(hins) {
461
src = FindResourceW(hins, szID, szType);
462
if(src) {
463
regstra = LoadResource(hins, src);
464
reslen = SizeofResource(hins, src);
465
if(regstra) {
466
len = MultiByteToWideChar(CP_ACP, 0, regstra, reslen, NULL, 0)+1;
467
regstrw = calloc(len, sizeof(WCHAR));
468
MultiByteToWideChar(CP_ACP, 0, regstra, reslen, regstrw, len);
469
regstrw[len-1] = '\0';
470
471
hres = string_register(This, regstrw, do_register);
472
473
free(regstrw);
474
}else {
475
WARN("could not load resource\n");
476
hres = HRESULT_FROM_WIN32(GetLastError());
477
}
478
}else {
479
WARN("Could not find source\n");
480
hres = HRESULT_FROM_WIN32(GetLastError());
481
}
482
FreeLibrary(hins);
483
}else {
484
WARN("Could not load resource file\n");
485
hres = HRESULT_FROM_WIN32(GetLastError());
486
}
487
488
return hres;
489
}
490
491
static HRESULT file_register(Registrar *This, LPCOLESTR fileName, BOOL do_register)
492
{
493
HANDLE file;
494
DWORD filelen, len;
495
LPWSTR regstrw;
496
LPSTR regstra;
497
HRESULT hres;
498
499
file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
500
if(file != INVALID_HANDLE_VALUE) {
501
filelen = GetFileSize(file, NULL);
502
regstra = malloc(filelen);
503
if(ReadFile(file, regstra, filelen, NULL, NULL)) {
504
len = MultiByteToWideChar(CP_ACP, 0, regstra, filelen, NULL, 0)+1;
505
regstrw = calloc(len, sizeof(WCHAR));
506
MultiByteToWideChar(CP_ACP, 0, regstra, filelen, regstrw, len);
507
regstrw[len-1] = '\0';
508
509
hres = string_register(This, regstrw, do_register);
510
511
free(regstrw);
512
}else {
513
WARN("Failed to read file %s\n", debugstr_w(fileName));
514
hres = HRESULT_FROM_WIN32(GetLastError());
515
}
516
free(regstra);
517
CloseHandle(file);
518
}else {
519
WARN("Could not open file %s\n", debugstr_w(fileName));
520
hres = HRESULT_FROM_WIN32(GetLastError());
521
}
522
523
return hres;
524
}
525
526
static HRESULT WINAPI Registrar_QueryInterface(IRegistrar *iface, REFIID riid, void **ppvObject)
527
{
528
TRACE("(%p)->(%s %p\n", iface, debugstr_guid(riid), ppvObject);
529
530
if(IsEqualGUID(&IID_IUnknown, riid)
531
|| IsEqualGUID(&IID_IRegistrar, riid)
532
|| IsEqualGUID(&IID_IRegistrarBase, riid)) {
533
IRegistrar_AddRef(iface);
534
*ppvObject = iface;
535
return S_OK;
536
}
537
return E_NOINTERFACE;
538
}
539
540
static ULONG WINAPI Registrar_AddRef(IRegistrar *iface)
541
{
542
Registrar *This = impl_from_IRegistrar(iface);
543
ULONG ref = InterlockedIncrement(&This->ref);
544
TRACE("(%p) ->%ld\n", This, ref);
545
return ref;
546
}
547
548
static ULONG WINAPI Registrar_Release(IRegistrar *iface)
549
{
550
Registrar *This = impl_from_IRegistrar(iface);
551
ULONG ref = InterlockedDecrement(&This->ref);
552
553
TRACE("(%p) ->%ld\n", This, ref);
554
if(!ref) {
555
IRegistrar_ClearReplacements(iface);
556
free(This);
557
}
558
return ref;
559
}
560
561
static HRESULT WINAPI Registrar_AddReplacement(IRegistrar *iface, LPCOLESTR Key, LPCOLESTR item)
562
{
563
Registrar *This = impl_from_IRegistrar(iface);
564
int len;
565
rep_list *new_rep;
566
567
TRACE("(%p)->(%s %s)\n", This, debugstr_w(Key), debugstr_w(item));
568
569
new_rep = malloc(sizeof(*new_rep));
570
571
new_rep->key_len = lstrlenW(Key);
572
new_rep->key = malloc((new_rep->key_len + 1) * sizeof(OLECHAR));
573
memcpy(new_rep->key, Key, (new_rep->key_len+1)*sizeof(OLECHAR));
574
575
len = lstrlenW(item)+1;
576
new_rep->item = malloc(len*sizeof(OLECHAR));
577
memcpy(new_rep->item, item, len*sizeof(OLECHAR));
578
579
new_rep->next = This->rep;
580
This->rep = new_rep;
581
582
return S_OK;
583
}
584
585
static HRESULT WINAPI Registrar_ClearReplacements(IRegistrar *iface)
586
{
587
Registrar *This = impl_from_IRegistrar(iface);
588
rep_list *iter, *iter2;
589
590
TRACE("(%p)\n", This);
591
592
if(!This->rep)
593
return S_OK;
594
595
iter = This->rep;
596
while(iter) {
597
iter2 = iter->next;
598
free(iter->key);
599
free(iter->item);
600
free(iter);
601
iter = iter2;
602
}
603
604
This->rep = NULL;
605
return S_OK;
606
}
607
608
static HRESULT WINAPI Registrar_ResourceRegisterSz(IRegistrar* iface, LPCOLESTR resFileName,
609
LPCOLESTR szID, LPCOLESTR szType)
610
{
611
Registrar *This = impl_from_IRegistrar(iface);
612
TRACE("(%p)->(%s %s %s)\n", This, debugstr_w(resFileName), debugstr_w(szID), debugstr_w(szType));
613
return resource_register(This, resFileName, szID, szType, TRUE);
614
}
615
616
static HRESULT WINAPI Registrar_ResourceUnregisterSz(IRegistrar* iface, LPCOLESTR resFileName,
617
LPCOLESTR szID, LPCOLESTR szType)
618
{
619
Registrar *This = impl_from_IRegistrar(iface);
620
TRACE("(%p)->(%s %s %s)\n", This, debugstr_w(resFileName), debugstr_w(szID), debugstr_w(szType));
621
return resource_register(This, resFileName, szID, szType, FALSE);
622
}
623
624
static HRESULT WINAPI Registrar_FileRegister(IRegistrar* iface, LPCOLESTR fileName)
625
{
626
Registrar *This = impl_from_IRegistrar(iface);
627
TRACE("(%p)->(%s)\n", This, debugstr_w(fileName));
628
return file_register(This, fileName, TRUE);
629
}
630
631
static HRESULT WINAPI Registrar_FileUnregister(IRegistrar* iface, LPCOLESTR fileName)
632
{
633
Registrar *This = impl_from_IRegistrar(iface);
634
FIXME("(%p)->(%s)\n", This, debugstr_w(fileName));
635
return file_register(This, fileName, FALSE);
636
}
637
638
static HRESULT WINAPI Registrar_StringRegister(IRegistrar* iface, LPCOLESTR data)
639
{
640
Registrar *This = impl_from_IRegistrar(iface);
641
TRACE("(%p)->(%s)\n", This, debugstr_w(data));
642
return string_register(This, data, TRUE);
643
}
644
645
static HRESULT WINAPI Registrar_StringUnregister(IRegistrar* iface, LPCOLESTR data)
646
{
647
Registrar *This = impl_from_IRegistrar(iface);
648
TRACE("(%p)->(%s)\n", This, debugstr_w(data));
649
return string_register(This, data, FALSE);
650
}
651
652
static HRESULT WINAPI Registrar_ResourceRegister(IRegistrar* iface, LPCOLESTR resFileName,
653
UINT nID, LPCOLESTR szType)
654
{
655
Registrar *This = impl_from_IRegistrar(iface);
656
TRACE("(%p)->(%s %d %s)\n", iface, debugstr_w(resFileName), nID, debugstr_w(szType));
657
return resource_register(This, resFileName, MAKEINTRESOURCEW(nID), szType, TRUE);
658
}
659
660
static HRESULT WINAPI Registrar_ResourceUnregister(IRegistrar* iface, LPCOLESTR resFileName,
661
UINT nID, LPCOLESTR szType)
662
{
663
Registrar *This = impl_from_IRegistrar(iface);
664
TRACE("(%p)->(%s %d %s)\n", This, debugstr_w(resFileName), nID, debugstr_w(szType));
665
return resource_register(This, resFileName, MAKEINTRESOURCEW(nID), szType, FALSE);
666
}
667
668
static const IRegistrarVtbl RegistrarVtbl = {
669
Registrar_QueryInterface,
670
Registrar_AddRef,
671
Registrar_Release,
672
Registrar_AddReplacement,
673
Registrar_ClearReplacements,
674
Registrar_ResourceRegisterSz,
675
Registrar_ResourceUnregisterSz,
676
Registrar_FileRegister,
677
Registrar_FileUnregister,
678
Registrar_StringRegister,
679
Registrar_StringUnregister,
680
Registrar_ResourceRegister,
681
Registrar_ResourceUnregister,
682
};
683
684
/***********************************************************************
685
* AtlCreateRegistrar [atl100.@]
686
*/
687
HRESULT WINAPI AtlCreateRegistrar(IRegistrar **ret)
688
{
689
Registrar *registrar;
690
691
registrar = calloc(1, sizeof(*registrar));
692
if(!registrar)
693
return E_OUTOFMEMORY;
694
695
registrar->IRegistrar_iface.lpVtbl = &RegistrarVtbl;
696
registrar->ref = 1;
697
698
*ret = &registrar->IRegistrar_iface;
699
return S_OK;
700
}
701
702
/***********************************************************************
703
* AtlUpdateRegistryFromResourceD [atl100.@]
704
*/
705
HRESULT WINAPI AtlUpdateRegistryFromResourceD(HINSTANCE inst, LPCOLESTR res,
706
BOOL bRegister, struct _ATL_REGMAP_ENTRY *pMapEntries, IRegistrar *pReg)
707
{
708
const struct _ATL_REGMAP_ENTRY *iter;
709
WCHAR module_name[MAX_PATH];
710
IRegistrar *registrar;
711
HRESULT hres;
712
713
if(!GetModuleFileNameW(inst, module_name, MAX_PATH)) {
714
FIXME("hinst %p: did not get module name\n", inst);
715
return E_FAIL;
716
}
717
718
TRACE("%p (%s), %s, %d, %p, %p\n", inst, debugstr_w(module_name),
719
debugstr_w(res), bRegister, pMapEntries, pReg);
720
721
if(pReg) {
722
registrar = pReg;
723
}else {
724
hres = AtlCreateRegistrar(&registrar);
725
if(FAILED(hres))
726
return hres;
727
}
728
729
IRegistrar_AddReplacement(registrar, L"MODULE", module_name);
730
731
for (iter = pMapEntries; iter && iter->szKey; iter++)
732
IRegistrar_AddReplacement(registrar, iter->szKey, iter->szData);
733
734
if(bRegister)
735
hres = IRegistrar_ResourceRegisterSz(registrar, module_name, res, L"REGISTRY");
736
else
737
hres = IRegistrar_ResourceUnregisterSz(registrar, module_name, res, L"REGISTRY");
738
739
if(registrar != pReg)
740
IRegistrar_Release(registrar);
741
return hres;
742
}
743
744