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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include "wine/unicode.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(advpack
);
35 static const WCHAR REGINST
[] = {'R','E','G','I','N','S','T',0};
36 static const WCHAR Strings
[] = {'S','t','r','i','n','g','s',0};
37 static const WCHAR MOD_PATH
[] = {'_','M','O','D','_','P','A','T','H',0};
38 static const WCHAR SYS_MOD_PATH
[] = {'_','S','Y','S','_','M','O','D','_','P','A','T','H',0};
39 static const WCHAR SystemRoot
[] = {'S','y','s','t','e','m','R','o','o','t',0};
40 static const WCHAR escaped_SystemRoot
[] = {'%','S','y','s','t','e','m','R','o','o','t','%',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(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 /***********************************************************************
174 * RegInstallW (advpack.@)
176 * Loads an INF from a string resource, adds entries to the string
177 * substitution table, and executes the INF.
180 * hm [I] Module that contains the REGINST resouce.
181 * pszSection [I] The INF section to execute.
182 * pstTable [I] Table of string substitutions.
188 HRESULT WINAPI
RegInstallW(HMODULE hm
, LPCWSTR pszSection
, const STRTABLEW
* pstTable
)
191 WCHAR tmp_ini_path
[MAX_PATH
];
192 WCHAR mod_path
[MAX_PATH
+ 2], sys_mod_path
[MAX_PATH
+ 2], sys_root
[MAX_PATH
];
194 static const WCHAR quote
[] = {'\"',0};
196 TRACE("(%p, %s, %p)\n", hm
, debugstr_w(pszSection
), pstTable
);
198 if(!create_tmp_ini_file(hm
, tmp_ini_path
))
201 /* Write a couple of pre-defined strings */
203 GetModuleFileNameW(hm
, mod_path
+ 1, sizeof(mod_path
)/sizeof(WCHAR
) - 2);
204 strcatW(mod_path
, quote
);
205 WritePrivateProfileStringW(Strings
, MOD_PATH
, mod_path
, tmp_ini_path
);
208 GetEnvironmentVariableW(SystemRoot
, sys_root
, sizeof(sys_root
)/sizeof(WCHAR
));
209 if(!strncmpiW(sys_root
, mod_path
+ 1, strlenW(sys_root
))) {
210 sys_mod_path
[0] = '\"';
211 strcpyW(sys_mod_path
+ 1, escaped_SystemRoot
);
212 strcatW(sys_mod_path
, mod_path
+ 1 + strlenW(sys_root
));
214 FIXME("SYS_MOD_PATH needs more work\n");
215 strcpyW(sys_mod_path
, mod_path
);
217 WritePrivateProfileStringW(Strings
, SYS_MOD_PATH
, sys_mod_path
, tmp_ini_path
);
219 /* Write the additional string table */
220 if (pstTable
) for(i
= 0; i
< pstTable
->cEntries
; i
++) {
221 WCHAR tmp_value
[MAX_PATH
+ 2];
224 lstrcpyW(tmp_value
+ 1, pstTable
->pse
[i
].pszValue
);
225 lstrcatW(tmp_value
, quote
);
227 WritePrivateProfileStringW(Strings
, pstTable
->pse
[i
].pszName
, tmp_value
, tmp_ini_path
);
230 WritePrivateProfileStringW(NULL
, NULL
, NULL
, tmp_ini_path
);
233 if((hinf
= SetupOpenInfFileW(tmp_ini_path
, NULL
, INF_STYLE_WIN4
, NULL
)) ==
234 INVALID_HANDLE_VALUE
) {
235 ERR("Setupapi can't open inf\n");
239 /* append any layout files */
240 SetupOpenAppendInfFileW(NULL
, hinf
, NULL
);
242 /* Need to do a lot more here */
243 SetupInstallFromInfSectionW(NULL
, hinf
, pszSection
,
244 SPINST_INIFILES
| SPINST_REGISTRY
| SPINST_PROFILEITEMS
,
245 HKEY_LOCAL_MACHINE
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
247 SetupCloseInfFile(hinf
);
248 DeleteFileW(tmp_ini_path
);
253 /***********************************************************************
254 * RegRestoreAllA (advpack.@)
256 * See RegRestoreAllW.
258 HRESULT WINAPI
RegRestoreAllA(HWND hWnd
, LPSTR pszTitleString
, HKEY hkBackupKey
)
260 UNICODE_STRING title
;
263 TRACE("(%p, %s, %p)\n", hWnd
, debugstr_a(pszTitleString
), hkBackupKey
);
265 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
267 hr
= RegRestoreAllW(hWnd
, title
.Buffer
, hkBackupKey
);
269 RtlFreeUnicodeString(&title
);
274 /***********************************************************************
275 * RegRestoreAllW (advpack.@)
277 * Restores all saved registry entries.
280 * hWnd [I] Handle to the window used for the display.
281 * pszTitleString [I] Title of the window.
282 * hkBackupKey [I] Handle to the backup key.
291 HRESULT WINAPI
RegRestoreAllW(HWND hWnd
, LPWSTR pszTitleString
, HKEY hkBackupKey
)
293 FIXME("(%p, %s, %p) stub\n", hWnd
, debugstr_w(pszTitleString
), hkBackupKey
);
298 /***********************************************************************
299 * RegSaveRestoreA (advpack.@)
301 * See RegSaveRestoreW.
303 HRESULT WINAPI
RegSaveRestoreA(HWND hWnd
, LPCSTR pszTitleString
, HKEY hkBackupKey
,
304 LPCSTR pcszRootKey
, LPCSTR pcszSubKey
,
305 LPCSTR pcszValueName
, DWORD dwFlags
)
307 UNICODE_STRING title
, root
, subkey
, value
;
310 TRACE("(%p, %s, %p, %s, %s, %s, %ld)\n", hWnd
, debugstr_a(pszTitleString
),
311 hkBackupKey
, debugstr_a(pcszRootKey
), debugstr_a(pcszSubKey
),
312 debugstr_a(pcszValueName
), dwFlags
);
314 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
315 RtlCreateUnicodeStringFromAsciiz(&root
, pcszRootKey
);
316 RtlCreateUnicodeStringFromAsciiz(&subkey
, pcszSubKey
);
317 RtlCreateUnicodeStringFromAsciiz(&value
, pcszValueName
);
319 hr
= RegSaveRestoreW(hWnd
, title
.Buffer
, hkBackupKey
, root
.Buffer
,
320 subkey
.Buffer
, value
.Buffer
, dwFlags
);
322 RtlFreeUnicodeString(&title
);
323 RtlFreeUnicodeString(&root
);
324 RtlFreeUnicodeString(&subkey
);
325 RtlFreeUnicodeString(&value
);
330 /***********************************************************************
331 * RegSaveRestoreW (advpack.@)
333 * Saves or restores the specified registry value.
336 * hWnd [I] Handle to the window used for the display.
337 * pszTitleString [I] Title of the window.
338 * hkBackupKey [I] Key used to store the backup data.
339 * pcszRootKey [I] Root key of the registry value
340 * pcszSubKey [I] Sub key of the registry value.
341 * pcszValueName [I] Value to save or restore.
342 * dwFlags [I] See advpub.h.
351 HRESULT WINAPI
RegSaveRestoreW(HWND hWnd
, LPCWSTR pszTitleString
, HKEY hkBackupKey
,
352 LPCWSTR pcszRootKey
, LPCWSTR pcszSubKey
,
353 LPCWSTR pcszValueName
, DWORD dwFlags
)
355 FIXME("(%p, %s, %p, %s, %s, %s, %ld): stub\n", hWnd
, debugstr_w(pszTitleString
),
356 hkBackupKey
, debugstr_w(pcszRootKey
), debugstr_w(pcszSubKey
),
357 debugstr_w(pcszValueName
), dwFlags
);
362 /***********************************************************************
363 * RegSaveRestoreOnINFA (advpack.@)
365 * See RegSaveRestoreOnINFW.
367 HRESULT WINAPI
RegSaveRestoreOnINFA(HWND hWnd
, LPCSTR pszTitle
, LPCSTR pszINF
,
368 LPCSTR pszSection
, HKEY hHKLMBackKey
,
369 HKEY hHKCUBackKey
, DWORD dwFlags
)
371 UNICODE_STRING title
, inf
, section
;
374 TRACE("(%p, %s, %s, %s, %p, %p, %ld)\n", hWnd
, debugstr_a(pszTitle
),
375 debugstr_a(pszINF
), debugstr_a(pszSection
),
376 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
378 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitle
);
379 RtlCreateUnicodeStringFromAsciiz(&inf
, pszINF
);
380 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
382 hr
= RegSaveRestoreOnINFW(hWnd
, title
.Buffer
, inf
.Buffer
, section
.Buffer
,
383 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
385 RtlFreeUnicodeString(&title
);
386 RtlFreeUnicodeString(&inf
);
387 RtlFreeUnicodeString(§ion
);
392 /***********************************************************************
393 * RegSaveRestoreOnINFW (advpack.@)
395 * Saves or restores the specified INF Reg section.
398 * hWnd [I] Handle to the window used for the display.
399 * pszTitle [I] Title of the window.
400 * pszINF [I] Filename of the INF.
401 * pszSection [I] Section to save or restore.
402 * hHKLMBackKey [I] Opened key in HKLM to store data.
403 * hHKCUBackKey [I] Opened key in HKCU to store data.
404 * dwFlags [I] See advpub.h
413 HRESULT WINAPI
RegSaveRestoreOnINFW(HWND hWnd
, LPCWSTR pszTitle
, LPCWSTR pszINF
,
414 LPCWSTR pszSection
, HKEY hHKLMBackKey
,
415 HKEY hHKCUBackKey
, DWORD dwFlags
)
417 FIXME("(%p, %s, %s, %s, %p, %p, %ld): stub\n", hWnd
, debugstr_w(pszTitle
),
418 debugstr_w(pszINF
), debugstr_w(pszSection
),
419 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);