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
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};
41 static const WCHAR quote
[] = {'\"',0};
43 static BOOL
get_temp_ini_path(LPWSTR name
)
45 WCHAR tmp_dir
[MAX_PATH
];
46 WCHAR prefix
[] = {'a','v','p',0};
48 if(!GetTempPathW(sizeof(tmp_dir
)/sizeof(WCHAR
), tmp_dir
))
51 if(!GetTempFileNameW(tmp_dir
, prefix
, 0, name
))
56 static BOOL
create_tmp_ini_file(HMODULE hm
, WCHAR
*ini_file
)
60 DWORD rsrc_size
, bytes_written
;
62 HANDLE hf
= INVALID_HANDLE_VALUE
;
64 if(!get_temp_ini_path(ini_file
)) {
65 ERR("Can't get temp ini file path\n");
69 if(!(hrsrc
= FindResourceW(hm
, REGINST
, REGINST
))) {
70 ERR("Can't find REGINST resource\n");
74 rsrc_size
= SizeofResource(hm
, hrsrc
);
75 hmem
= LoadResource(hm
, hrsrc
);
76 rsrc_data
= LockResource(hmem
);
78 if(!rsrc_data
|| !rsrc_size
) {
79 ERR("Can't load REGINST resource\n");
83 if((hf
= CreateFileW(ini_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
84 FILE_ATTRIBUTE_NORMAL
, NULL
)) == INVALID_HANDLE_VALUE
) {
85 ERR("Unable to create temp ini file\n");
88 if(!WriteFile(hf
, rsrc_data
, rsrc_size
, &bytes_written
, NULL
) || rsrc_size
!= bytes_written
) {
89 ERR("Write failed\n");
96 if(hmem
) FreeResource(hmem
);
97 if(hf
!= INVALID_HANDLE_VALUE
) CloseHandle(hf
);
101 static void strentry_atow(STRENTRYA
*aentry
, STRENTRYW
*wentry
)
103 DWORD name_len
, val_len
;
105 name_len
= MultiByteToWideChar(CP_ACP
, 0, aentry
->pszName
, -1, NULL
, 0);
106 val_len
= MultiByteToWideChar(CP_ACP
, 0, aentry
->pszValue
, -1, NULL
, 0);
108 wentry
->pszName
= HeapAlloc(GetProcessHeap(), 0, name_len
* sizeof(WCHAR
));
109 wentry
->pszValue
= HeapAlloc(GetProcessHeap(), 0, val_len
* sizeof(WCHAR
));
111 MultiByteToWideChar(CP_ACP
, 0, aentry
->pszName
, -1, wentry
->pszName
, name_len
);
112 MultiByteToWideChar(CP_ACP
, 0, aentry
->pszValue
, -1, wentry
->pszValue
, val_len
);
115 static STRTABLEW
*strtable_atow(const STRTABLEA
*atable
)
120 wtable
= HeapAlloc(GetProcessHeap(), 0, sizeof(STRTABLEW
));
121 wtable
->pse
= HeapAlloc(GetProcessHeap(), 0, atable
->cEntries
* sizeof(STRENTRYW
));
122 wtable
->cEntries
= atable
->cEntries
;
124 for (j
= 0; j
< wtable
->cEntries
; j
++)
125 strentry_atow(&atable
->pse
[j
], &wtable
->pse
[j
]);
130 static void free_strtable(STRTABLEW
*wtable
)
134 for (j
= 0; j
< wtable
->cEntries
; j
++)
136 HeapFree(GetProcessHeap(), 0, wtable
->pse
[j
].pszName
);
137 HeapFree(GetProcessHeap(), 0, wtable
->pse
[j
].pszValue
);
140 HeapFree(GetProcessHeap(), 0, wtable
->pse
);
141 HeapFree(GetProcessHeap(), 0, wtable
);
144 /***********************************************************************
145 * RegInstallA (advpack.@)
149 HRESULT WINAPI
RegInstallA(HMODULE hm
, LPCSTR pszSection
, const STRTABLEA
* pstTable
)
151 UNICODE_STRING section
;
155 TRACE("(%p, %s, %p)\n", hm
, debugstr_a(pszSection
), pstTable
);
158 wtable
= strtable_atow(pstTable
);
162 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
164 hr
= RegInstallW(hm
, section
.Buffer
, wtable
);
167 free_strtable(wtable
);
169 RtlFreeUnicodeString(§ion
);
174 static HRESULT
write_predefined_strings(HMODULE hm
, LPWSTR ini_path
)
176 WCHAR mod_path
[MAX_PATH
+ 2];
177 WCHAR sys_mod_path
[MAX_PATH
+ 2];
178 WCHAR sys_root
[MAX_PATH
];
181 if (!GetModuleFileNameW(hm
, mod_path
+ 1, sizeof(mod_path
) / sizeof(WCHAR
) - 2))
184 lstrcatW(mod_path
, quote
);
185 WritePrivateProfileStringW(Strings
, MOD_PATH
, mod_path
, ini_path
);
188 GetEnvironmentVariableW(SystemRoot
, sys_root
, sizeof(sys_root
) / sizeof(WCHAR
));
190 if(!strncmpiW(sys_root
, mod_path
+ 1, strlenW(sys_root
)))
192 *sys_mod_path
= '\"';
193 strcpyW(sys_mod_path
+ 1, escaped_SystemRoot
);
194 strcatW(sys_mod_path
, mod_path
+ 1 + strlenW(sys_root
));
198 FIXME("SYS_MOD_PATH needs more work\n");
199 strcpyW(sys_mod_path
, mod_path
);
202 WritePrivateProfileStringW(Strings
, SYS_MOD_PATH
, sys_mod_path
, ini_path
);
207 /***********************************************************************
208 * RegInstallW (advpack.@)
210 * Loads an INF from a string resource, adds entries to the string
211 * substitution table, and executes the INF.
214 * hm [I] Module that contains the REGINST resouce.
215 * pszSection [I] The INF section to execute.
216 * pstTable [I] Table of string substitutions.
222 HRESULT WINAPI
RegInstallW(HMODULE hm
, LPCWSTR pszSection
, const STRTABLEW
* pstTable
)
226 WCHAR tmp_ini_path
[MAX_PATH
];
227 HINF hinf
= INVALID_HANDLE_VALUE
;
230 TRACE("(%p, %s, %p)\n", hm
, debugstr_w(pszSection
), pstTable
);
232 if(!create_tmp_ini_file(hm
, tmp_ini_path
))
235 if (write_predefined_strings(hm
, tmp_ini_path
))
238 /* Write the additional string table */
241 for(i
= 0; i
< pstTable
->cEntries
; i
++)
243 WCHAR tmp_value
[MAX_PATH
+ 2];
246 lstrcpyW(tmp_value
+ 1, pstTable
->pse
[i
].pszValue
);
247 lstrcatW(tmp_value
, quote
);
249 WritePrivateProfileStringW(Strings
, pstTable
->pse
[i
].pszName
, tmp_value
, tmp_ini_path
);
254 WritePrivateProfileStringW(NULL
, NULL
, NULL
, tmp_ini_path
);
256 /* FIXME: read AdvOptions val for dwFlags */
257 ZeroMemory(&cabinfo
, sizeof(CABINFOW
));
258 cabinfo
.pszInf
= tmp_ini_path
;
259 cabinfo
.pszSection
= (LPWSTR
)pszSection
;
262 hr
= ExecuteCabW(NULL
, &cabinfo
, NULL
);
265 if (hinf
!= INVALID_HANDLE_VALUE
)
266 SetupCloseInfFile(hinf
);
268 DeleteFileW(tmp_ini_path
);
273 /***********************************************************************
274 * RegRestoreAllA (advpack.@)
276 * See RegRestoreAllW.
278 HRESULT WINAPI
RegRestoreAllA(HWND hWnd
, LPSTR pszTitleString
, HKEY hkBackupKey
)
280 UNICODE_STRING title
;
283 TRACE("(%p, %s, %p)\n", hWnd
, debugstr_a(pszTitleString
), hkBackupKey
);
285 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
287 hr
= RegRestoreAllW(hWnd
, title
.Buffer
, hkBackupKey
);
289 RtlFreeUnicodeString(&title
);
294 /***********************************************************************
295 * RegRestoreAllW (advpack.@)
297 * Restores all saved registry entries.
300 * hWnd [I] Handle to the window used for the display.
301 * pszTitleString [I] Title of the window.
302 * hkBackupKey [I] Handle to the backup key.
311 HRESULT WINAPI
RegRestoreAllW(HWND hWnd
, LPWSTR pszTitleString
, HKEY hkBackupKey
)
313 FIXME("(%p, %s, %p) stub\n", hWnd
, debugstr_w(pszTitleString
), hkBackupKey
);
318 /***********************************************************************
319 * RegSaveRestoreA (advpack.@)
321 * See RegSaveRestoreW.
323 HRESULT WINAPI
RegSaveRestoreA(HWND hWnd
, LPCSTR pszTitleString
, HKEY hkBackupKey
,
324 LPCSTR pcszRootKey
, LPCSTR pcszSubKey
,
325 LPCSTR pcszValueName
, DWORD dwFlags
)
327 UNICODE_STRING title
, root
, subkey
, value
;
330 TRACE("(%p, %s, %p, %s, %s, %s, %ld)\n", hWnd
, debugstr_a(pszTitleString
),
331 hkBackupKey
, debugstr_a(pcszRootKey
), debugstr_a(pcszSubKey
),
332 debugstr_a(pcszValueName
), dwFlags
);
334 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
335 RtlCreateUnicodeStringFromAsciiz(&root
, pcszRootKey
);
336 RtlCreateUnicodeStringFromAsciiz(&subkey
, pcszSubKey
);
337 RtlCreateUnicodeStringFromAsciiz(&value
, pcszValueName
);
339 hr
= RegSaveRestoreW(hWnd
, title
.Buffer
, hkBackupKey
, root
.Buffer
,
340 subkey
.Buffer
, value
.Buffer
, dwFlags
);
342 RtlFreeUnicodeString(&title
);
343 RtlFreeUnicodeString(&root
);
344 RtlFreeUnicodeString(&subkey
);
345 RtlFreeUnicodeString(&value
);
350 /***********************************************************************
351 * RegSaveRestoreW (advpack.@)
353 * Saves or restores the specified registry value.
356 * hWnd [I] Handle to the window used for the display.
357 * pszTitleString [I] Title of the window.
358 * hkBackupKey [I] Key used to store the backup data.
359 * pcszRootKey [I] Root key of the registry value
360 * pcszSubKey [I] Sub key of the registry value.
361 * pcszValueName [I] Value to save or restore.
362 * dwFlags [I] See advpub.h.
371 HRESULT WINAPI
RegSaveRestoreW(HWND hWnd
, LPCWSTR pszTitleString
, HKEY hkBackupKey
,
372 LPCWSTR pcszRootKey
, LPCWSTR pcszSubKey
,
373 LPCWSTR pcszValueName
, DWORD dwFlags
)
375 FIXME("(%p, %s, %p, %s, %s, %s, %ld): stub\n", hWnd
, debugstr_w(pszTitleString
),
376 hkBackupKey
, debugstr_w(pcszRootKey
), debugstr_w(pcszSubKey
),
377 debugstr_w(pcszValueName
), dwFlags
);
382 /***********************************************************************
383 * RegSaveRestoreOnINFA (advpack.@)
385 * See RegSaveRestoreOnINFW.
387 HRESULT WINAPI
RegSaveRestoreOnINFA(HWND hWnd
, LPCSTR pszTitle
, LPCSTR pszINF
,
388 LPCSTR pszSection
, HKEY hHKLMBackKey
,
389 HKEY hHKCUBackKey
, DWORD dwFlags
)
391 UNICODE_STRING title
, inf
, section
;
394 TRACE("(%p, %s, %s, %s, %p, %p, %ld)\n", hWnd
, debugstr_a(pszTitle
),
395 debugstr_a(pszINF
), debugstr_a(pszSection
),
396 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
398 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitle
);
399 RtlCreateUnicodeStringFromAsciiz(&inf
, pszINF
);
400 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
402 hr
= RegSaveRestoreOnINFW(hWnd
, title
.Buffer
, inf
.Buffer
, section
.Buffer
,
403 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
405 RtlFreeUnicodeString(&title
);
406 RtlFreeUnicodeString(&inf
);
407 RtlFreeUnicodeString(§ion
);
412 /***********************************************************************
413 * RegSaveRestoreOnINFW (advpack.@)
415 * Saves or restores the specified INF Reg section.
418 * hWnd [I] Handle to the window used for the display.
419 * pszTitle [I] Title of the window.
420 * pszINF [I] Filename of the INF.
421 * pszSection [I] Section to save or restore.
422 * hHKLMBackKey [I] Opened key in HKLM to store data.
423 * hHKCUBackKey [I] Opened key in HKCU to store data.
424 * dwFlags [I] See advpub.h
433 HRESULT WINAPI
RegSaveRestoreOnINFW(HWND hWnd
, LPCWSTR pszTitle
, LPCWSTR pszINF
,
434 LPCWSTR pszSection
, HKEY hHKLMBackKey
,
435 HKEY hHKCUBackKey
, DWORD dwFlags
)
437 FIXME("(%p, %s, %s, %s, %p, %p, %ld): stub\n", hWnd
, debugstr_w(pszTitle
),
438 debugstr_w(pszINF
), debugstr_w(pszSection
),
439 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);