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
21 #include "advpack_private.h"
23 static const WCHAR REGINST
[] = {'R','E','G','I','N','S','T',0};
24 static const WCHAR Strings
[] = {'S','t','r','i','n','g','s',0};
25 static const WCHAR MOD_PATH
[] = {'_','M','O','D','_','P','A','T','H',0};
26 static const WCHAR SYS_MOD_PATH
[] = {'_','S','Y','S','_','M','O','D','_','P','A','T','H',0};
27 static const WCHAR SystemRoot
[] = {'S','y','s','t','e','m','R','o','o','t',0};
28 static const WCHAR escaped_SystemRoot
[] = {'%','S','y','s','t','e','m','R','o','o','t','%',0};
29 static const WCHAR quote
[] = {'\"',0};
31 static BOOL
get_temp_ini_path(LPWSTR name
)
33 WCHAR tmp_dir
[MAX_PATH
];
34 WCHAR prefix
[] = {'a','v','p',0};
36 if(!GetTempPathW(sizeof(tmp_dir
)/sizeof(WCHAR
), tmp_dir
))
39 if(!GetTempFileNameW(tmp_dir
, prefix
, 0, name
))
44 static BOOL
create_tmp_ini_file(HMODULE hm
, WCHAR
*ini_file
)
48 DWORD rsrc_size
, bytes_written
;
50 HANDLE hf
= INVALID_HANDLE_VALUE
;
52 if(!get_temp_ini_path(ini_file
)) {
53 ERR("Can't get temp ini file path\n");
57 if(!(hrsrc
= FindResourceW(hm
, REGINST
, REGINST
))) {
58 ERR("Can't find REGINST resource\n");
62 rsrc_size
= SizeofResource(hm
, hrsrc
);
63 hmem
= LoadResource(hm
, hrsrc
);
64 rsrc_data
= LockResource(hmem
);
66 if(!rsrc_data
|| !rsrc_size
) {
67 ERR("Can't load REGINST resource\n");
71 if((hf
= CreateFileW(ini_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
72 FILE_ATTRIBUTE_NORMAL
, NULL
)) == INVALID_HANDLE_VALUE
) {
73 ERR("Unable to create temp ini file\n");
76 if(!WriteFile(hf
, rsrc_data
, rsrc_size
, &bytes_written
, NULL
) || rsrc_size
!= bytes_written
) {
77 ERR("Write failed\n");
84 if(hmem
) FreeResource(hmem
);
85 if(hf
!= INVALID_HANDLE_VALUE
) CloseHandle(hf
);
89 static void strentry_atow(const STRENTRYA
*aentry
, STRENTRYW
*wentry
)
91 DWORD name_len
, val_len
;
93 name_len
= MultiByteToWideChar(CP_ACP
, 0, aentry
->pszName
, -1, NULL
, 0);
94 val_len
= MultiByteToWideChar(CP_ACP
, 0, aentry
->pszValue
, -1, NULL
, 0);
96 wentry
->pszName
= HeapAlloc(GetProcessHeap(), 0, name_len
* sizeof(WCHAR
));
97 wentry
->pszValue
= HeapAlloc(GetProcessHeap(), 0, val_len
* sizeof(WCHAR
));
99 MultiByteToWideChar(CP_ACP
, 0, aentry
->pszName
, -1, wentry
->pszName
, name_len
);
100 MultiByteToWideChar(CP_ACP
, 0, aentry
->pszValue
, -1, wentry
->pszValue
, val_len
);
103 static STRTABLEW
*strtable_atow(const STRTABLEA
*atable
)
108 wtable
= HeapAlloc(GetProcessHeap(), 0, sizeof(STRTABLEW
));
109 wtable
->pse
= HeapAlloc(GetProcessHeap(), 0, atable
->cEntries
* sizeof(STRENTRYW
));
110 wtable
->cEntries
= atable
->cEntries
;
112 for (j
= 0; j
< wtable
->cEntries
; j
++)
113 strentry_atow(&atable
->pse
[j
], &wtable
->pse
[j
]);
118 static void free_strtable(STRTABLEW
*wtable
)
122 for (j
= 0; j
< wtable
->cEntries
; j
++)
124 HeapFree(GetProcessHeap(), 0, wtable
->pse
[j
].pszName
);
125 HeapFree(GetProcessHeap(), 0, wtable
->pse
[j
].pszValue
);
128 HeapFree(GetProcessHeap(), 0, wtable
->pse
);
129 HeapFree(GetProcessHeap(), 0, wtable
);
132 /***********************************************************************
133 * RegInstallA (advpack.@)
137 HRESULT WINAPI
RegInstallA(HMODULE hm
, LPCSTR pszSection
, const STRTABLEA
* pstTable
)
139 UNICODE_STRING section
;
143 TRACE("(%p, %s, %p)\n", hm
, debugstr_a(pszSection
), pstTable
);
146 wtable
= strtable_atow(pstTable
);
150 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
152 hr
= RegInstallW(hm
, section
.Buffer
, wtable
);
155 free_strtable(wtable
);
157 RtlFreeUnicodeString(§ion
);
162 static HRESULT
write_predefined_strings(HMODULE hm
, LPCWSTR ini_path
)
164 WCHAR mod_path
[MAX_PATH
+ 2];
165 WCHAR sys_mod_path
[MAX_PATH
+ 2];
166 WCHAR sys_root
[MAX_PATH
];
169 if (!GetModuleFileNameW(hm
, mod_path
+ 1, sizeof(mod_path
) / sizeof(WCHAR
) - 2))
172 lstrcatW(mod_path
, quote
);
173 WritePrivateProfileStringW(Strings
, MOD_PATH
, mod_path
, ini_path
);
176 GetEnvironmentVariableW(SystemRoot
, sys_root
, sizeof(sys_root
) / sizeof(WCHAR
));
178 if(!strncmpiW(sys_root
, mod_path
+ 1, strlenW(sys_root
)))
180 *sys_mod_path
= '\"';
181 strcpyW(sys_mod_path
+ 1, escaped_SystemRoot
);
182 strcatW(sys_mod_path
, mod_path
+ 1 + strlenW(sys_root
));
186 FIXME("SYS_MOD_PATH needs more work\n");
187 strcpyW(sys_mod_path
, mod_path
);
190 WritePrivateProfileStringW(Strings
, SYS_MOD_PATH
, sys_mod_path
, ini_path
);
195 /***********************************************************************
196 * RegInstallW (advpack.@)
198 * Loads an INF from a string resource, adds entries to the string
199 * substitution table, and executes the INF.
202 * hm [I] Module that contains the REGINST resource.
203 * pszSection [I] The INF section to execute.
204 * pstTable [I] Table of string substitutions.
210 HRESULT WINAPI
RegInstallW(HMODULE hm
, LPCWSTR pszSection
, const STRTABLEW
* pstTable
)
214 WCHAR tmp_ini_path
[MAX_PATH
];
217 TRACE("(%p, %s, %p)\n", hm
, debugstr_w(pszSection
), pstTable
);
219 if(!create_tmp_ini_file(hm
, tmp_ini_path
))
222 if (write_predefined_strings(hm
, tmp_ini_path
) != S_OK
)
225 /* Write the additional string table */
228 for(i
= 0; i
< pstTable
->cEntries
; i
++)
230 WCHAR tmp_value
[MAX_PATH
+ 2];
233 lstrcpyW(tmp_value
+ 1, pstTable
->pse
[i
].pszValue
);
234 lstrcatW(tmp_value
, quote
);
236 WritePrivateProfileStringW(Strings
, pstTable
->pse
[i
].pszName
, tmp_value
, tmp_ini_path
);
241 WritePrivateProfileStringW(NULL
, NULL
, NULL
, tmp_ini_path
);
243 /* FIXME: read AdvOptions val for dwFlags */
244 ZeroMemory(&cabinfo
, sizeof(CABINFOW
));
245 cabinfo
.pszInf
= tmp_ini_path
;
246 cabinfo
.pszSection
= (LPWSTR
)pszSection
;
249 hr
= ExecuteCabW(NULL
, &cabinfo
, NULL
);
253 DeleteFileW(tmp_ini_path
);
258 /***********************************************************************
259 * RegRestoreAllA (advpack.@)
261 * See RegRestoreAllW.
263 HRESULT WINAPI
RegRestoreAllA(HWND hWnd
, LPSTR pszTitleString
, HKEY hkBackupKey
)
265 UNICODE_STRING title
;
268 TRACE("(%p, %s, %p)\n", hWnd
, debugstr_a(pszTitleString
), hkBackupKey
);
270 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
272 hr
= RegRestoreAllW(hWnd
, title
.Buffer
, hkBackupKey
);
274 RtlFreeUnicodeString(&title
);
279 /***********************************************************************
280 * RegRestoreAllW (advpack.@)
282 * Restores all saved registry entries.
285 * hWnd [I] Handle to the window used for the display.
286 * pszTitleString [I] Title of the window.
287 * hkBackupKey [I] Handle to the backup key.
296 HRESULT WINAPI
RegRestoreAllW(HWND hWnd
, LPWSTR pszTitleString
, HKEY hkBackupKey
)
298 FIXME("(%p, %s, %p) stub\n", hWnd
, debugstr_w(pszTitleString
), hkBackupKey
);
303 /***********************************************************************
304 * RegSaveRestoreA (advpack.@)
306 * See RegSaveRestoreW.
308 HRESULT WINAPI
RegSaveRestoreA(HWND hWnd
, LPCSTR pszTitleString
, HKEY hkBackupKey
,
309 LPCSTR pcszRootKey
, LPCSTR pcszSubKey
,
310 LPCSTR pcszValueName
, DWORD dwFlags
)
312 UNICODE_STRING title
, root
, subkey
, value
;
315 TRACE("(%p, %s, %p, %s, %s, %s, %d)\n", hWnd
, debugstr_a(pszTitleString
),
316 hkBackupKey
, debugstr_a(pcszRootKey
), debugstr_a(pcszSubKey
),
317 debugstr_a(pcszValueName
), dwFlags
);
319 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
320 RtlCreateUnicodeStringFromAsciiz(&root
, pcszRootKey
);
321 RtlCreateUnicodeStringFromAsciiz(&subkey
, pcszSubKey
);
322 RtlCreateUnicodeStringFromAsciiz(&value
, pcszValueName
);
324 hr
= RegSaveRestoreW(hWnd
, title
.Buffer
, hkBackupKey
, root
.Buffer
,
325 subkey
.Buffer
, value
.Buffer
, dwFlags
);
327 RtlFreeUnicodeString(&title
);
328 RtlFreeUnicodeString(&root
);
329 RtlFreeUnicodeString(&subkey
);
330 RtlFreeUnicodeString(&value
);
335 /***********************************************************************
336 * RegSaveRestoreW (advpack.@)
338 * Saves or restores the specified registry value.
341 * hWnd [I] Handle to the window used for the display.
342 * pszTitleString [I] Title of the window.
343 * hkBackupKey [I] Key used to store the backup data.
344 * pcszRootKey [I] Root key of the registry value
345 * pcszSubKey [I] Sub key of the registry value.
346 * pcszValueName [I] Value to save or restore.
347 * dwFlags [I] See advpub.h.
356 HRESULT WINAPI
RegSaveRestoreW(HWND hWnd
, LPCWSTR pszTitleString
, HKEY hkBackupKey
,
357 LPCWSTR pcszRootKey
, LPCWSTR pcszSubKey
,
358 LPCWSTR pcszValueName
, DWORD dwFlags
)
360 FIXME("(%p, %s, %p, %s, %s, %s, %d): stub\n", hWnd
, debugstr_w(pszTitleString
),
361 hkBackupKey
, debugstr_w(pcszRootKey
), debugstr_w(pcszSubKey
),
362 debugstr_w(pcszValueName
), dwFlags
);
367 /***********************************************************************
368 * RegSaveRestoreOnINFA (advpack.@)
370 * See RegSaveRestoreOnINFW.
372 HRESULT WINAPI
RegSaveRestoreOnINFA(HWND hWnd
, LPCSTR pszTitle
, LPCSTR pszINF
,
373 LPCSTR pszSection
, HKEY hHKLMBackKey
,
374 HKEY hHKCUBackKey
, DWORD dwFlags
)
376 UNICODE_STRING title
, inf
, section
;
379 TRACE("(%p, %s, %s, %s, %p, %p, %d)\n", hWnd
, debugstr_a(pszTitle
),
380 debugstr_a(pszINF
), debugstr_a(pszSection
),
381 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
383 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitle
);
384 RtlCreateUnicodeStringFromAsciiz(&inf
, pszINF
);
385 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
387 hr
= RegSaveRestoreOnINFW(hWnd
, title
.Buffer
, inf
.Buffer
, section
.Buffer
,
388 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
390 RtlFreeUnicodeString(&title
);
391 RtlFreeUnicodeString(&inf
);
392 RtlFreeUnicodeString(§ion
);
397 /***********************************************************************
398 * RegSaveRestoreOnINFW (advpack.@)
400 * Saves or restores the specified INF Reg section.
403 * hWnd [I] Handle to the window used for the display.
404 * pszTitle [I] Title of the window.
405 * pszINF [I] Filename of the INF.
406 * pszSection [I] Section to save or restore.
407 * hHKLMBackKey [I] Opened key in HKLM to store data.
408 * hHKCUBackKey [I] Opened key in HKCU to store data.
409 * dwFlags [I] See advpub.h
418 HRESULT WINAPI
RegSaveRestoreOnINFW(HWND hWnd
, LPCWSTR pszTitle
, LPCWSTR pszINF
,
419 LPCWSTR pszSection
, HKEY hHKLMBackKey
,
420 HKEY hHKCUBackKey
, DWORD dwFlags
)
422 FIXME("(%p, %s, %s, %s, %p, %p, %d): stub\n", hWnd
, debugstr_w(pszTitle
),
423 debugstr_w(pszINF
), debugstr_w(pszSection
),
424 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);