Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/advpack/reg.c
4389 views
1
/*
2
* Advpack registry functions
3
*
4
* Copyright 2004 Huw D M Davies
5
*
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#include <stdarg.h>
22
#include "windef.h"
23
#include "winbase.h"
24
#include "winreg.h"
25
#include "winnls.h"
26
#include "winerror.h"
27
#include "winuser.h"
28
#include "winternl.h"
29
#include "advpub.h"
30
#include "wine/debug.h"
31
32
WINE_DEFAULT_DEBUG_CHANNEL(advpack);
33
34
static BOOL get_temp_ini_path(LPWSTR name)
35
{
36
WCHAR tmp_dir[MAX_PATH];
37
38
if(!GetTempPathW(ARRAY_SIZE(tmp_dir), tmp_dir))
39
return FALSE;
40
41
if (!GetTempFileNameW(tmp_dir, L"avp", 0, name))
42
return FALSE;
43
return TRUE;
44
}
45
46
static BOOL create_tmp_ini_file(HMODULE hm, WCHAR *ini_file)
47
{
48
HRSRC hrsrc;
49
HGLOBAL hmem = NULL;
50
DWORD rsrc_size, bytes_written;
51
VOID *rsrc_data;
52
HANDLE hf = INVALID_HANDLE_VALUE;
53
54
if(!get_temp_ini_path(ini_file)) {
55
ERR("Can't get temp ini file path\n");
56
goto error;
57
}
58
59
if (!(hrsrc = FindResourceW(hm, L"REGINST", L"REGINST"))) {
60
ERR("Can't find REGINST resource\n");
61
goto error;
62
}
63
64
rsrc_size = SizeofResource(hm, hrsrc);
65
hmem = LoadResource(hm, hrsrc);
66
rsrc_data = LockResource(hmem);
67
68
if(!rsrc_data || !rsrc_size) {
69
ERR("Can't load REGINST resource\n");
70
goto error;
71
}
72
73
if((hf = CreateFileW(ini_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
74
FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) {
75
ERR("Unable to create temp ini file\n");
76
goto error;
77
}
78
if(!WriteFile(hf, rsrc_data, rsrc_size, &bytes_written, NULL) || rsrc_size != bytes_written) {
79
ERR("Write failed\n");
80
goto error;
81
}
82
FreeResource(hmem);
83
CloseHandle(hf);
84
return TRUE;
85
error:
86
if(hmem) FreeResource(hmem);
87
if(hf != INVALID_HANDLE_VALUE) CloseHandle(hf);
88
return FALSE;
89
}
90
91
static void strentry_atow(const STRENTRYA *aentry, STRENTRYW *wentry)
92
{
93
DWORD name_len, val_len;
94
95
name_len = MultiByteToWideChar(CP_ACP, 0, aentry->pszName, -1, NULL, 0);
96
val_len = MultiByteToWideChar(CP_ACP, 0, aentry->pszValue, -1, NULL, 0);
97
98
wentry->pszName = malloc(name_len * sizeof(WCHAR));
99
wentry->pszValue = malloc(val_len * sizeof(WCHAR));
100
101
MultiByteToWideChar(CP_ACP, 0, aentry->pszName, -1, wentry->pszName, name_len);
102
MultiByteToWideChar(CP_ACP, 0, aentry->pszValue, -1, wentry->pszValue, val_len);
103
}
104
105
static STRTABLEW *strtable_atow(const STRTABLEA *atable)
106
{
107
STRTABLEW *wtable;
108
DWORD j;
109
110
wtable = malloc(sizeof(STRTABLEW));
111
wtable->pse = malloc(atable->cEntries * sizeof(STRENTRYW));
112
wtable->cEntries = atable->cEntries;
113
114
for (j = 0; j < wtable->cEntries; j++)
115
strentry_atow(&atable->pse[j], &wtable->pse[j]);
116
117
return wtable;
118
}
119
120
static void free_strtable(STRTABLEW *wtable)
121
{
122
DWORD j;
123
124
for (j = 0; j < wtable->cEntries; j++)
125
{
126
free(wtable->pse[j].pszName);
127
free(wtable->pse[j].pszValue);
128
}
129
130
free(wtable->pse);
131
free(wtable);
132
}
133
134
/***********************************************************************
135
* RegInstallA (advpack.@)
136
*
137
* See RegInstallW.
138
*/
139
HRESULT WINAPI RegInstallA(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable)
140
{
141
UNICODE_STRING section;
142
STRTABLEW *wtable;
143
HRESULT hr;
144
145
TRACE("(%p, %s, %p)\n", hm, debugstr_a(pszSection), pstTable);
146
147
if (pstTable)
148
wtable = strtable_atow(pstTable);
149
else
150
wtable = NULL;
151
152
RtlCreateUnicodeStringFromAsciiz(&section, pszSection);
153
154
hr = RegInstallW(hm, section.Buffer, wtable);
155
156
if (pstTable)
157
free_strtable(wtable);
158
159
RtlFreeUnicodeString(&section);
160
161
return hr;
162
}
163
164
static HRESULT write_predefined_strings(HMODULE hm, LPCWSTR ini_path)
165
{
166
WCHAR mod_path[MAX_PATH + 2];
167
WCHAR sys_mod_path[MAX_PATH + 2];
168
WCHAR sys_root[MAX_PATH];
169
170
*mod_path = '\"';
171
if (!GetModuleFileNameW(hm, mod_path + 1, ARRAY_SIZE(mod_path) - 2))
172
return E_FAIL;
173
174
lstrcatW(mod_path, L"\"");
175
WritePrivateProfileStringW(L"Strings", L"_MOD_PATH", mod_path, ini_path);
176
177
*sys_root = '\0';
178
GetEnvironmentVariableW(L"SystemRoot", sys_root, ARRAY_SIZE(sys_root));
179
180
if(!wcsnicmp(sys_root, mod_path + 1, lstrlenW(sys_root)))
181
{
182
*sys_mod_path = '\"';
183
lstrcpyW(sys_mod_path + 1, L"%SystemRoot%");
184
lstrcatW(sys_mod_path, mod_path + 1 + lstrlenW(sys_root));
185
}
186
else
187
{
188
FIXME("SYS_MOD_PATH needs more work\n");
189
lstrcpyW(sys_mod_path, mod_path);
190
}
191
192
WritePrivateProfileStringW(L"Strings", L"_SYS_MOD_PATH", sys_mod_path, ini_path);
193
194
return S_OK;
195
}
196
197
/***********************************************************************
198
* RegInstallW (advpack.@)
199
*
200
* Loads an INF from a string resource, adds entries to the string
201
* substitution table, and executes the INF.
202
*
203
* PARAMS
204
* hm [I] Module that contains the REGINST resource.
205
* pszSection [I] The INF section to execute.
206
* pstTable [I] Table of string substitutions.
207
*
208
* RETURNS
209
* Success: S_OK.
210
* Failure: E_FAIL.
211
*/
212
HRESULT WINAPI RegInstallW(HMODULE hm, LPCWSTR pszSection, const STRTABLEW* pstTable)
213
{
214
unsigned int i;
215
CABINFOW cabinfo;
216
WCHAR tmp_ini_path[MAX_PATH];
217
HRESULT hr = E_FAIL;
218
219
TRACE("(%p, %s, %p)\n", hm, debugstr_w(pszSection), pstTable);
220
221
if(!create_tmp_ini_file(hm, tmp_ini_path))
222
return E_FAIL;
223
224
if (write_predefined_strings(hm, tmp_ini_path) != S_OK)
225
goto done;
226
227
/* Write the additional string table */
228
if (pstTable)
229
{
230
for(i = 0; i < pstTable->cEntries; i++)
231
{
232
WCHAR tmp_value[MAX_PATH + 2];
233
234
tmp_value[0] = '\"';
235
lstrcpyW(tmp_value + 1, pstTable->pse[i].pszValue);
236
lstrcatW(tmp_value, L"\"");
237
238
WritePrivateProfileStringW(L"Strings", pstTable->pse[i].pszName, tmp_value, tmp_ini_path);
239
}
240
}
241
242
/* flush cache */
243
WritePrivateProfileStringW(NULL, NULL, NULL, tmp_ini_path);
244
245
/* FIXME: read AdvOptions val for dwFlags */
246
ZeroMemory(&cabinfo, sizeof(CABINFOW));
247
cabinfo.pszInf = tmp_ini_path;
248
cabinfo.pszSection = (LPWSTR)pszSection;
249
cabinfo.dwFlags = 0;
250
251
hr = ExecuteCabW(NULL, &cabinfo, NULL);
252
253
done:
254
255
DeleteFileW(tmp_ini_path);
256
257
return hr;
258
}
259
260
/***********************************************************************
261
* RegRestoreAllA (advpack.@)
262
*
263
* See RegRestoreAllW.
264
*/
265
HRESULT WINAPI RegRestoreAllA(HWND hWnd, LPSTR pszTitleString, HKEY hkBackupKey)
266
{
267
UNICODE_STRING title;
268
HRESULT hr;
269
270
TRACE("(%p, %s, %p)\n", hWnd, debugstr_a(pszTitleString), hkBackupKey);
271
272
RtlCreateUnicodeStringFromAsciiz(&title, pszTitleString);
273
274
hr = RegRestoreAllW(hWnd, title.Buffer, hkBackupKey);
275
276
RtlFreeUnicodeString(&title);
277
278
return hr;
279
}
280
281
/***********************************************************************
282
* RegRestoreAllW (advpack.@)
283
*
284
* Restores all saved registry entries.
285
*
286
* PARAMS
287
* hWnd [I] Handle to the window used for the display.
288
* pszTitleString [I] Title of the window.
289
* hkBackupKey [I] Handle to the backup key.
290
*
291
* RETURNS
292
* Success: S_OK.
293
* Failure: E_FAIL.
294
*
295
* BUGS
296
* Unimplemented.
297
*/
298
HRESULT WINAPI RegRestoreAllW(HWND hWnd, LPWSTR pszTitleString, HKEY hkBackupKey)
299
{
300
FIXME("(%p, %s, %p) stub\n", hWnd, debugstr_w(pszTitleString), hkBackupKey);
301
302
return E_FAIL;
303
}
304
305
/***********************************************************************
306
* RegSaveRestoreA (advpack.@)
307
*
308
* See RegSaveRestoreW.
309
*/
310
HRESULT WINAPI RegSaveRestoreA(HWND hWnd, LPCSTR pszTitleString, HKEY hkBackupKey,
311
LPCSTR pcszRootKey, LPCSTR pcszSubKey,
312
LPCSTR pcszValueName, DWORD dwFlags)
313
{
314
UNICODE_STRING title, root, subkey, value;
315
HRESULT hr;
316
317
TRACE("(%p, %s, %p, %s, %s, %s, %ld)\n", hWnd, debugstr_a(pszTitleString),
318
hkBackupKey, debugstr_a(pcszRootKey), debugstr_a(pcszSubKey),
319
debugstr_a(pcszValueName), dwFlags);
320
321
RtlCreateUnicodeStringFromAsciiz(&title, pszTitleString);
322
RtlCreateUnicodeStringFromAsciiz(&root, pcszRootKey);
323
RtlCreateUnicodeStringFromAsciiz(&subkey, pcszSubKey);
324
RtlCreateUnicodeStringFromAsciiz(&value, pcszValueName);
325
326
hr = RegSaveRestoreW(hWnd, title.Buffer, hkBackupKey, root.Buffer,
327
subkey.Buffer, value.Buffer, dwFlags);
328
329
RtlFreeUnicodeString(&title);
330
RtlFreeUnicodeString(&root);
331
RtlFreeUnicodeString(&subkey);
332
RtlFreeUnicodeString(&value);
333
334
return hr;
335
}
336
337
/***********************************************************************
338
* RegSaveRestoreW (advpack.@)
339
*
340
* Saves or restores the specified registry value.
341
*
342
* PARAMS
343
* hWnd [I] Handle to the window used for the display.
344
* pszTitleString [I] Title of the window.
345
* hkBackupKey [I] Key used to store the backup data.
346
* pcszRootKey [I] Root key of the registry value
347
* pcszSubKey [I] Sub key of the registry value.
348
* pcszValueName [I] Value to save or restore.
349
* dwFlags [I] See advpub.h.
350
*
351
* RETURNS
352
* Success: S_OK.
353
* Failure: E_FAIL.
354
*
355
* BUGS
356
* Unimplemented.
357
*/
358
HRESULT WINAPI RegSaveRestoreW(HWND hWnd, LPCWSTR pszTitleString, HKEY hkBackupKey,
359
LPCWSTR pcszRootKey, LPCWSTR pcszSubKey,
360
LPCWSTR pcszValueName, DWORD dwFlags)
361
{
362
FIXME("(%p, %s, %p, %s, %s, %s, %ld): stub\n", hWnd, debugstr_w(pszTitleString),
363
hkBackupKey, debugstr_w(pcszRootKey), debugstr_w(pcszSubKey),
364
debugstr_w(pcszValueName), dwFlags);
365
366
return E_FAIL;
367
}
368
369
/***********************************************************************
370
* RegSaveRestoreOnINFA (advpack.@)
371
*
372
* See RegSaveRestoreOnINFW.
373
*/
374
HRESULT WINAPI RegSaveRestoreOnINFA(HWND hWnd, LPCSTR pszTitle, LPCSTR pszINF,
375
LPCSTR pszSection, HKEY hHKLMBackKey,
376
HKEY hHKCUBackKey, DWORD dwFlags)
377
{
378
UNICODE_STRING title, inf, section;
379
HRESULT hr;
380
381
TRACE("(%p, %s, %s, %s, %p, %p, %ld)\n", hWnd, debugstr_a(pszTitle),
382
debugstr_a(pszINF), debugstr_a(pszSection),
383
hHKLMBackKey, hHKCUBackKey, dwFlags);
384
385
RtlCreateUnicodeStringFromAsciiz(&title, pszTitle);
386
RtlCreateUnicodeStringFromAsciiz(&inf, pszINF);
387
RtlCreateUnicodeStringFromAsciiz(&section, pszSection);
388
389
hr = RegSaveRestoreOnINFW(hWnd, title.Buffer, inf.Buffer, section.Buffer,
390
hHKLMBackKey, hHKCUBackKey, dwFlags);
391
392
RtlFreeUnicodeString(&title);
393
RtlFreeUnicodeString(&inf);
394
RtlFreeUnicodeString(&section);
395
396
return hr;
397
}
398
399
/***********************************************************************
400
* RegSaveRestoreOnINFW (advpack.@)
401
*
402
* Saves or restores the specified INF Reg section.
403
*
404
* PARAMS
405
* hWnd [I] Handle to the window used for the display.
406
* pszTitle [I] Title of the window.
407
* pszINF [I] Filename of the INF.
408
* pszSection [I] Section to save or restore.
409
* hHKLMBackKey [I] Opened key in HKLM to store data.
410
* hHKCUBackKey [I] Opened key in HKCU to store data.
411
* dwFlags [I] See advpub.h
412
*
413
* RETURNS
414
* Success: S_OK.
415
* Failure: E_FAIL.
416
*
417
* BUGS
418
* Unimplemented.
419
*/
420
HRESULT WINAPI RegSaveRestoreOnINFW(HWND hWnd, LPCWSTR pszTitle, LPCWSTR pszINF,
421
LPCWSTR pszSection, HKEY hHKLMBackKey,
422
HKEY hHKCUBackKey, DWORD dwFlags)
423
{
424
FIXME("(%p, %s, %s, %s, %p, %p, %ld): stub\n", hWnd, debugstr_w(pszTitle),
425
debugstr_w(pszINF), debugstr_w(pszSection),
426
hHKLMBackKey, hHKCUBackKey, dwFlags);
427
428
return E_FAIL;
429
}
430
431