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/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(advpack
);
34 static BOOL
get_temp_ini_path(LPWSTR name
)
36 WCHAR tmp_dir
[MAX_PATH
];
38 if(!GetTempPathW(ARRAY_SIZE(tmp_dir
), tmp_dir
))
41 if (!GetTempFileNameW(tmp_dir
, L
"avp", 0, name
))
46 static BOOL
create_tmp_ini_file(HMODULE hm
, WCHAR
*ini_file
)
50 DWORD rsrc_size
, bytes_written
;
52 HANDLE hf
= INVALID_HANDLE_VALUE
;
54 if(!get_temp_ini_path(ini_file
)) {
55 ERR("Can't get temp ini file path\n");
59 if (!(hrsrc
= FindResourceW(hm
, L
"REGINST", L
"REGINST"))) {
60 ERR("Can't find REGINST resource\n");
64 rsrc_size
= SizeofResource(hm
, hrsrc
);
65 hmem
= LoadResource(hm
, hrsrc
);
66 rsrc_data
= LockResource(hmem
);
68 if(!rsrc_data
|| !rsrc_size
) {
69 ERR("Can't load REGINST resource\n");
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");
78 if(!WriteFile(hf
, rsrc_data
, rsrc_size
, &bytes_written
, NULL
) || rsrc_size
!= bytes_written
) {
79 ERR("Write failed\n");
86 if(hmem
) FreeResource(hmem
);
87 if(hf
!= INVALID_HANDLE_VALUE
) CloseHandle(hf
);
91 static void strentry_atow(const STRENTRYA
*aentry
, STRENTRYW
*wentry
)
93 DWORD name_len
, val_len
;
95 name_len
= MultiByteToWideChar(CP_ACP
, 0, aentry
->pszName
, -1, NULL
, 0);
96 val_len
= MultiByteToWideChar(CP_ACP
, 0, aentry
->pszValue
, -1, NULL
, 0);
98 wentry
->pszName
= HeapAlloc(GetProcessHeap(), 0, name_len
* sizeof(WCHAR
));
99 wentry
->pszValue
= HeapAlloc(GetProcessHeap(), 0, val_len
* sizeof(WCHAR
));
101 MultiByteToWideChar(CP_ACP
, 0, aentry
->pszName
, -1, wentry
->pszName
, name_len
);
102 MultiByteToWideChar(CP_ACP
, 0, aentry
->pszValue
, -1, wentry
->pszValue
, val_len
);
105 static STRTABLEW
*strtable_atow(const STRTABLEA
*atable
)
110 wtable
= HeapAlloc(GetProcessHeap(), 0, sizeof(STRTABLEW
));
111 wtable
->pse
= HeapAlloc(GetProcessHeap(), 0, atable
->cEntries
* sizeof(STRENTRYW
));
112 wtable
->cEntries
= atable
->cEntries
;
114 for (j
= 0; j
< wtable
->cEntries
; j
++)
115 strentry_atow(&atable
->pse
[j
], &wtable
->pse
[j
]);
120 static void free_strtable(STRTABLEW
*wtable
)
124 for (j
= 0; j
< wtable
->cEntries
; j
++)
126 HeapFree(GetProcessHeap(), 0, wtable
->pse
[j
].pszName
);
127 HeapFree(GetProcessHeap(), 0, wtable
->pse
[j
].pszValue
);
130 HeapFree(GetProcessHeap(), 0, wtable
->pse
);
131 HeapFree(GetProcessHeap(), 0, wtable
);
134 /***********************************************************************
135 * RegInstallA (advpack.@)
139 HRESULT WINAPI
RegInstallA(HMODULE hm
, LPCSTR pszSection
, const STRTABLEA
* pstTable
)
141 UNICODE_STRING section
;
145 TRACE("(%p, %s, %p)\n", hm
, debugstr_a(pszSection
), pstTable
);
148 wtable
= strtable_atow(pstTable
);
152 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
154 hr
= RegInstallW(hm
, section
.Buffer
, wtable
);
157 free_strtable(wtable
);
159 RtlFreeUnicodeString(§ion
);
164 static HRESULT
write_predefined_strings(HMODULE hm
, LPCWSTR ini_path
)
166 WCHAR mod_path
[MAX_PATH
+ 2];
167 WCHAR sys_mod_path
[MAX_PATH
+ 2];
168 WCHAR sys_root
[MAX_PATH
];
171 if (!GetModuleFileNameW(hm
, mod_path
+ 1, ARRAY_SIZE(mod_path
) - 2))
174 lstrcatW(mod_path
, L
"\"");
175 WritePrivateProfileStringW(L
"Strings", L
"_MOD_PATH", mod_path
, ini_path
);
178 GetEnvironmentVariableW(L
"SystemRoot", sys_root
, ARRAY_SIZE(sys_root
));
180 if(!wcsnicmp(sys_root
, mod_path
+ 1, lstrlenW(sys_root
)))
182 *sys_mod_path
= '\"';
183 lstrcpyW(sys_mod_path
+ 1, L
"%SystemRoot%");
184 lstrcatW(sys_mod_path
, mod_path
+ 1 + lstrlenW(sys_root
));
188 FIXME("SYS_MOD_PATH needs more work\n");
189 lstrcpyW(sys_mod_path
, mod_path
);
192 WritePrivateProfileStringW(L
"Strings", L
"_SYS_MOD_PATH", sys_mod_path
, ini_path
);
197 /***********************************************************************
198 * RegInstallW (advpack.@)
200 * Loads an INF from a string resource, adds entries to the string
201 * substitution table, and executes the INF.
204 * hm [I] Module that contains the REGINST resource.
205 * pszSection [I] The INF section to execute.
206 * pstTable [I] Table of string substitutions.
212 HRESULT WINAPI
RegInstallW(HMODULE hm
, LPCWSTR pszSection
, const STRTABLEW
* pstTable
)
216 WCHAR tmp_ini_path
[MAX_PATH
];
219 TRACE("(%p, %s, %p)\n", hm
, debugstr_w(pszSection
), pstTable
);
221 if(!create_tmp_ini_file(hm
, tmp_ini_path
))
224 if (write_predefined_strings(hm
, tmp_ini_path
) != S_OK
)
227 /* Write the additional string table */
230 for(i
= 0; i
< pstTable
->cEntries
; i
++)
232 WCHAR tmp_value
[MAX_PATH
+ 2];
235 lstrcpyW(tmp_value
+ 1, pstTable
->pse
[i
].pszValue
);
236 lstrcatW(tmp_value
, L
"\"");
238 WritePrivateProfileStringW(L
"Strings", pstTable
->pse
[i
].pszName
, tmp_value
, tmp_ini_path
);
243 WritePrivateProfileStringW(NULL
, NULL
, NULL
, tmp_ini_path
);
245 /* FIXME: read AdvOptions val for dwFlags */
246 ZeroMemory(&cabinfo
, sizeof(CABINFOW
));
247 cabinfo
.pszInf
= tmp_ini_path
;
248 cabinfo
.pszSection
= (LPWSTR
)pszSection
;
251 hr
= ExecuteCabW(NULL
, &cabinfo
, NULL
);
255 DeleteFileW(tmp_ini_path
);
260 /***********************************************************************
261 * RegRestoreAllA (advpack.@)
263 * See RegRestoreAllW.
265 HRESULT WINAPI
RegRestoreAllA(HWND hWnd
, LPSTR pszTitleString
, HKEY hkBackupKey
)
267 UNICODE_STRING title
;
270 TRACE("(%p, %s, %p)\n", hWnd
, debugstr_a(pszTitleString
), hkBackupKey
);
272 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
274 hr
= RegRestoreAllW(hWnd
, title
.Buffer
, hkBackupKey
);
276 RtlFreeUnicodeString(&title
);
281 /***********************************************************************
282 * RegRestoreAllW (advpack.@)
284 * Restores all saved registry entries.
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.
298 HRESULT WINAPI
RegRestoreAllW(HWND hWnd
, LPWSTR pszTitleString
, HKEY hkBackupKey
)
300 FIXME("(%p, %s, %p) stub\n", hWnd
, debugstr_w(pszTitleString
), hkBackupKey
);
305 /***********************************************************************
306 * RegSaveRestoreA (advpack.@)
308 * See RegSaveRestoreW.
310 HRESULT WINAPI
RegSaveRestoreA(HWND hWnd
, LPCSTR pszTitleString
, HKEY hkBackupKey
,
311 LPCSTR pcszRootKey
, LPCSTR pcszSubKey
,
312 LPCSTR pcszValueName
, DWORD dwFlags
)
314 UNICODE_STRING title
, root
, subkey
, value
;
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
);
321 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
322 RtlCreateUnicodeStringFromAsciiz(&root
, pcszRootKey
);
323 RtlCreateUnicodeStringFromAsciiz(&subkey
, pcszSubKey
);
324 RtlCreateUnicodeStringFromAsciiz(&value
, pcszValueName
);
326 hr
= RegSaveRestoreW(hWnd
, title
.Buffer
, hkBackupKey
, root
.Buffer
,
327 subkey
.Buffer
, value
.Buffer
, dwFlags
);
329 RtlFreeUnicodeString(&title
);
330 RtlFreeUnicodeString(&root
);
331 RtlFreeUnicodeString(&subkey
);
332 RtlFreeUnicodeString(&value
);
337 /***********************************************************************
338 * RegSaveRestoreW (advpack.@)
340 * Saves or restores the specified registry value.
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.
358 HRESULT WINAPI
RegSaveRestoreW(HWND hWnd
, LPCWSTR pszTitleString
, HKEY hkBackupKey
,
359 LPCWSTR pcszRootKey
, LPCWSTR pcszSubKey
,
360 LPCWSTR pcszValueName
, DWORD dwFlags
)
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
);
369 /***********************************************************************
370 * RegSaveRestoreOnINFA (advpack.@)
372 * See RegSaveRestoreOnINFW.
374 HRESULT WINAPI
RegSaveRestoreOnINFA(HWND hWnd
, LPCSTR pszTitle
, LPCSTR pszINF
,
375 LPCSTR pszSection
, HKEY hHKLMBackKey
,
376 HKEY hHKCUBackKey
, DWORD dwFlags
)
378 UNICODE_STRING title
, inf
, section
;
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
);
385 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitle
);
386 RtlCreateUnicodeStringFromAsciiz(&inf
, pszINF
);
387 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
389 hr
= RegSaveRestoreOnINFW(hWnd
, title
.Buffer
, inf
.Buffer
, section
.Buffer
,
390 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
392 RtlFreeUnicodeString(&title
);
393 RtlFreeUnicodeString(&inf
);
394 RtlFreeUnicodeString(§ion
);
399 /***********************************************************************
400 * RegSaveRestoreOnINFW (advpack.@)
402 * Saves or restores the specified INF Reg section.
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
420 HRESULT WINAPI
RegSaveRestoreOnINFW(HWND hWnd
, LPCWSTR pszTitle
, LPCWSTR pszINF
,
421 LPCWSTR pszSection
, HKEY hHKLMBackKey
,
422 HKEY hHKCUBackKey
, DWORD dwFlags
)
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
);