2 * Advpack registry functions
4 * Copyright 2004 Huw D M Davies
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.
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.
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
29 #include "wine/unicode.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(advpack
);
34 static const WCHAR REGINST
[] = {'R','E','G','I','N','S','T',0};
35 static const WCHAR Strings
[] = {'S','t','r','i','n','g','s',0};
36 static const WCHAR MOD_PATH
[] = {'_','M','O','D','_','P','A','T','H',0};
37 static const WCHAR SYS_MOD_PATH
[] = {'_','S','Y','S','_','M','O','D','_','P','A','T','H',0};
38 static const WCHAR SystemRoot
[] = {'S','y','s','t','e','m','R','o','o','t',0};
39 static const WCHAR escaped_SystemRoot
[] = {'%','S','y','s','t','e','m','R','o','o','t','%',0};
40 static const WCHAR quote
[] = {'\"',0};
42 static BOOL
get_temp_ini_path(LPWSTR name
)
44 WCHAR tmp_dir
[MAX_PATH
];
45 WCHAR prefix
[] = {'a','v','p',0};
47 if(!GetTempPathW(sizeof(tmp_dir
)/sizeof(WCHAR
), tmp_dir
))
50 if(!GetTempFileNameW(tmp_dir
, prefix
, 0, name
))
55 static BOOL
create_tmp_ini_file(HMODULE hm
, WCHAR
*ini_file
)
59 DWORD rsrc_size
, bytes_written
;
61 HANDLE hf
= INVALID_HANDLE_VALUE
;
63 if(!get_temp_ini_path(ini_file
)) {
64 ERR("Can't get temp ini file path\n");
68 if(!(hrsrc
= FindResourceW(hm
, REGINST
, REGINST
))) {
69 ERR("Can't find REGINST resource\n");
73 rsrc_size
= SizeofResource(hm
, hrsrc
);
74 hmem
= LoadResource(hm
, hrsrc
);
75 rsrc_data
= LockResource(hmem
);
77 if(!rsrc_data
|| !rsrc_size
) {
78 ERR("Can't load REGINST resource\n");
82 if((hf
= CreateFileW(ini_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
83 FILE_ATTRIBUTE_NORMAL
, NULL
)) == INVALID_HANDLE_VALUE
) {
84 ERR("Unable to create temp ini file\n");
87 if(!WriteFile(hf
, rsrc_data
, rsrc_size
, &bytes_written
, NULL
) || rsrc_size
!= bytes_written
) {
88 ERR("Write failed\n");
95 if(hmem
) FreeResource(hmem
);
96 if(hf
!= INVALID_HANDLE_VALUE
) CloseHandle(hf
);
100 static void strentry_atow(const STRENTRYA
*aentry
, STRENTRYW
*wentry
)
102 DWORD name_len
, val_len
;
104 name_len
= MultiByteToWideChar(CP_ACP
, 0, aentry
->pszName
, -1, NULL
, 0);
105 val_len
= MultiByteToWideChar(CP_ACP
, 0, aentry
->pszValue
, -1, NULL
, 0);
107 wentry
->pszName
= HeapAlloc(GetProcessHeap(), 0, name_len
* sizeof(WCHAR
));
108 wentry
->pszValue
= HeapAlloc(GetProcessHeap(), 0, val_len
* sizeof(WCHAR
));
110 MultiByteToWideChar(CP_ACP
, 0, aentry
->pszName
, -1, wentry
->pszName
, name_len
);
111 MultiByteToWideChar(CP_ACP
, 0, aentry
->pszValue
, -1, wentry
->pszValue
, val_len
);
114 static STRTABLEW
*strtable_atow(const STRTABLEA
*atable
)
119 wtable
= HeapAlloc(GetProcessHeap(), 0, sizeof(STRTABLEW
));
120 wtable
->pse
= HeapAlloc(GetProcessHeap(), 0, atable
->cEntries
* sizeof(STRENTRYW
));
121 wtable
->cEntries
= atable
->cEntries
;
123 for (j
= 0; j
< wtable
->cEntries
; j
++)
124 strentry_atow(&atable
->pse
[j
], &wtable
->pse
[j
]);
129 static void free_strtable(STRTABLEW
*wtable
)
133 for (j
= 0; j
< wtable
->cEntries
; j
++)
135 HeapFree(GetProcessHeap(), 0, wtable
->pse
[j
].pszName
);
136 HeapFree(GetProcessHeap(), 0, wtable
->pse
[j
].pszValue
);
139 HeapFree(GetProcessHeap(), 0, wtable
->pse
);
140 HeapFree(GetProcessHeap(), 0, wtable
);
143 /***********************************************************************
144 * RegInstallA (advpack.@)
148 HRESULT WINAPI
RegInstallA(HMODULE hm
, LPCSTR pszSection
, const STRTABLEA
* pstTable
)
150 UNICODE_STRING section
;
154 TRACE("(%p, %s, %p)\n", hm
, debugstr_a(pszSection
), pstTable
);
157 wtable
= strtable_atow(pstTable
);
161 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
163 hr
= RegInstallW(hm
, section
.Buffer
, wtable
);
166 free_strtable(wtable
);
168 RtlFreeUnicodeString(§ion
);
173 static HRESULT
write_predefined_strings(HMODULE hm
, LPCWSTR ini_path
)
175 WCHAR mod_path
[MAX_PATH
+ 2];
176 WCHAR sys_mod_path
[MAX_PATH
+ 2];
177 WCHAR sys_root
[MAX_PATH
];
180 if (!GetModuleFileNameW(hm
, mod_path
+ 1, sizeof(mod_path
) / sizeof(WCHAR
) - 2))
183 lstrcatW(mod_path
, quote
);
184 WritePrivateProfileStringW(Strings
, MOD_PATH
, mod_path
, ini_path
);
187 GetEnvironmentVariableW(SystemRoot
, sys_root
, sizeof(sys_root
) / sizeof(WCHAR
));
189 if(!strncmpiW(sys_root
, mod_path
+ 1, strlenW(sys_root
)))
191 *sys_mod_path
= '\"';
192 strcpyW(sys_mod_path
+ 1, escaped_SystemRoot
);
193 strcatW(sys_mod_path
, mod_path
+ 1 + strlenW(sys_root
));
197 FIXME("SYS_MOD_PATH needs more work\n");
198 strcpyW(sys_mod_path
, mod_path
);
201 WritePrivateProfileStringW(Strings
, SYS_MOD_PATH
, sys_mod_path
, ini_path
);
206 /***********************************************************************
207 * RegInstallW (advpack.@)
209 * Loads an INF from a string resource, adds entries to the string
210 * substitution table, and executes the INF.
213 * hm [I] Module that contains the REGINST resource.
214 * pszSection [I] The INF section to execute.
215 * pstTable [I] Table of string substitutions.
221 HRESULT WINAPI
RegInstallW(HMODULE hm
, LPCWSTR pszSection
, const STRTABLEW
* pstTable
)
225 WCHAR tmp_ini_path
[MAX_PATH
];
228 TRACE("(%p, %s, %p)\n", hm
, debugstr_w(pszSection
), pstTable
);
230 if(!create_tmp_ini_file(hm
, tmp_ini_path
))
233 if (write_predefined_strings(hm
, tmp_ini_path
))
236 /* Write the additional string table */
239 for(i
= 0; i
< pstTable
->cEntries
; i
++)
241 WCHAR tmp_value
[MAX_PATH
+ 2];
244 lstrcpyW(tmp_value
+ 1, pstTable
->pse
[i
].pszValue
);
245 lstrcatW(tmp_value
, quote
);
247 WritePrivateProfileStringW(Strings
, pstTable
->pse
[i
].pszName
, tmp_value
, tmp_ini_path
);
252 WritePrivateProfileStringW(NULL
, NULL
, NULL
, tmp_ini_path
);
254 /* FIXME: read AdvOptions val for dwFlags */
255 ZeroMemory(&cabinfo
, sizeof(CABINFOW
));
256 cabinfo
.pszInf
= tmp_ini_path
;
257 cabinfo
.pszSection
= (LPWSTR
)pszSection
;
260 hr
= ExecuteCabW(NULL
, &cabinfo
, NULL
);
264 DeleteFileW(tmp_ini_path
);
269 /***********************************************************************
270 * RegRestoreAllA (advpack.@)
272 * See RegRestoreAllW.
274 HRESULT WINAPI
RegRestoreAllA(HWND hWnd
, LPSTR pszTitleString
, HKEY hkBackupKey
)
276 UNICODE_STRING title
;
279 TRACE("(%p, %s, %p)\n", hWnd
, debugstr_a(pszTitleString
), hkBackupKey
);
281 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
283 hr
= RegRestoreAllW(hWnd
, title
.Buffer
, hkBackupKey
);
285 RtlFreeUnicodeString(&title
);
290 /***********************************************************************
291 * RegRestoreAllW (advpack.@)
293 * Restores all saved registry entries.
296 * hWnd [I] Handle to the window used for the display.
297 * pszTitleString [I] Title of the window.
298 * hkBackupKey [I] Handle to the backup key.
307 HRESULT WINAPI
RegRestoreAllW(HWND hWnd
, LPWSTR pszTitleString
, HKEY hkBackupKey
)
309 FIXME("(%p, %s, %p) stub\n", hWnd
, debugstr_w(pszTitleString
), hkBackupKey
);
314 /***********************************************************************
315 * RegSaveRestoreA (advpack.@)
317 * See RegSaveRestoreW.
319 HRESULT WINAPI
RegSaveRestoreA(HWND hWnd
, LPCSTR pszTitleString
, HKEY hkBackupKey
,
320 LPCSTR pcszRootKey
, LPCSTR pcszSubKey
,
321 LPCSTR pcszValueName
, DWORD dwFlags
)
323 UNICODE_STRING title
, root
, subkey
, value
;
326 TRACE("(%p, %s, %p, %s, %s, %s, %d)\n", hWnd
, debugstr_a(pszTitleString
),
327 hkBackupKey
, debugstr_a(pcszRootKey
), debugstr_a(pcszSubKey
),
328 debugstr_a(pcszValueName
), dwFlags
);
330 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
331 RtlCreateUnicodeStringFromAsciiz(&root
, pcszRootKey
);
332 RtlCreateUnicodeStringFromAsciiz(&subkey
, pcszSubKey
);
333 RtlCreateUnicodeStringFromAsciiz(&value
, pcszValueName
);
335 hr
= RegSaveRestoreW(hWnd
, title
.Buffer
, hkBackupKey
, root
.Buffer
,
336 subkey
.Buffer
, value
.Buffer
, dwFlags
);
338 RtlFreeUnicodeString(&title
);
339 RtlFreeUnicodeString(&root
);
340 RtlFreeUnicodeString(&subkey
);
341 RtlFreeUnicodeString(&value
);
346 /***********************************************************************
347 * RegSaveRestoreW (advpack.@)
349 * Saves or restores the specified registry value.
352 * hWnd [I] Handle to the window used for the display.
353 * pszTitleString [I] Title of the window.
354 * hkBackupKey [I] Key used to store the backup data.
355 * pcszRootKey [I] Root key of the registry value
356 * pcszSubKey [I] Sub key of the registry value.
357 * pcszValueName [I] Value to save or restore.
358 * dwFlags [I] See advpub.h.
367 HRESULT WINAPI
RegSaveRestoreW(HWND hWnd
, LPCWSTR pszTitleString
, HKEY hkBackupKey
,
368 LPCWSTR pcszRootKey
, LPCWSTR pcszSubKey
,
369 LPCWSTR pcszValueName
, DWORD dwFlags
)
371 FIXME("(%p, %s, %p, %s, %s, %s, %d): stub\n", hWnd
, debugstr_w(pszTitleString
),
372 hkBackupKey
, debugstr_w(pcszRootKey
), debugstr_w(pcszSubKey
),
373 debugstr_w(pcszValueName
), dwFlags
);
378 /***********************************************************************
379 * RegSaveRestoreOnINFA (advpack.@)
381 * See RegSaveRestoreOnINFW.
383 HRESULT WINAPI
RegSaveRestoreOnINFA(HWND hWnd
, LPCSTR pszTitle
, LPCSTR pszINF
,
384 LPCSTR pszSection
, HKEY hHKLMBackKey
,
385 HKEY hHKCUBackKey
, DWORD dwFlags
)
387 UNICODE_STRING title
, inf
, section
;
390 TRACE("(%p, %s, %s, %s, %p, %p, %d)\n", hWnd
, debugstr_a(pszTitle
),
391 debugstr_a(pszINF
), debugstr_a(pszSection
),
392 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
394 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitle
);
395 RtlCreateUnicodeStringFromAsciiz(&inf
, pszINF
);
396 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
398 hr
= RegSaveRestoreOnINFW(hWnd
, title
.Buffer
, inf
.Buffer
, section
.Buffer
,
399 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
401 RtlFreeUnicodeString(&title
);
402 RtlFreeUnicodeString(&inf
);
403 RtlFreeUnicodeString(§ion
);
408 /***********************************************************************
409 * RegSaveRestoreOnINFW (advpack.@)
411 * Saves or restores the specified INF Reg section.
414 * hWnd [I] Handle to the window used for the display.
415 * pszTitle [I] Title of the window.
416 * pszINF [I] Filename of the INF.
417 * pszSection [I] Section to save or restore.
418 * hHKLMBackKey [I] Opened key in HKLM to store data.
419 * hHKCUBackKey [I] Opened key in HKCU to store data.
420 * dwFlags [I] See advpub.h
429 HRESULT WINAPI
RegSaveRestoreOnINFW(HWND hWnd
, LPCWSTR pszTitle
, LPCWSTR pszINF
,
430 LPCWSTR pszSection
, HKEY hHKLMBackKey
,
431 HKEY hHKCUBackKey
, DWORD dwFlags
)
433 FIXME("(%p, %s, %s, %s, %p, %p, %d): stub\n", hWnd
, debugstr_w(pszTitle
),
434 debugstr_w(pszINF
), debugstr_w(pszSection
),
435 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);