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
];
229 TRACE("(%p, %s, %p)\n", hm
, debugstr_w(pszSection
), pstTable
);
231 if(!create_tmp_ini_file(hm
, tmp_ini_path
))
234 if (write_predefined_strings(hm
, tmp_ini_path
))
237 /* Write the additional string table */
240 for(i
= 0; i
< pstTable
->cEntries
; i
++)
242 WCHAR tmp_value
[MAX_PATH
+ 2];
245 lstrcpyW(tmp_value
+ 1, pstTable
->pse
[i
].pszValue
);
246 lstrcatW(tmp_value
, quote
);
248 WritePrivateProfileStringW(Strings
, pstTable
->pse
[i
].pszName
, tmp_value
, tmp_ini_path
);
253 WritePrivateProfileStringW(NULL
, NULL
, NULL
, tmp_ini_path
);
255 /* FIXME: read AdvOptions val for dwFlags */
256 ZeroMemory(&cabinfo
, sizeof(CABINFOW
));
257 cabinfo
.pszInf
= tmp_ini_path
;
258 cabinfo
.pszSection
= (LPWSTR
)pszSection
;
261 hr
= ExecuteCabW(NULL
, &cabinfo
, NULL
);
265 DeleteFileW(tmp_ini_path
);
270 /***********************************************************************
271 * RegRestoreAllA (advpack.@)
273 * See RegRestoreAllW.
275 HRESULT WINAPI
RegRestoreAllA(HWND hWnd
, LPSTR pszTitleString
, HKEY hkBackupKey
)
277 UNICODE_STRING title
;
280 TRACE("(%p, %s, %p)\n", hWnd
, debugstr_a(pszTitleString
), hkBackupKey
);
282 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
284 hr
= RegRestoreAllW(hWnd
, title
.Buffer
, hkBackupKey
);
286 RtlFreeUnicodeString(&title
);
291 /***********************************************************************
292 * RegRestoreAllW (advpack.@)
294 * Restores all saved registry entries.
297 * hWnd [I] Handle to the window used for the display.
298 * pszTitleString [I] Title of the window.
299 * hkBackupKey [I] Handle to the backup key.
308 HRESULT WINAPI
RegRestoreAllW(HWND hWnd
, LPWSTR pszTitleString
, HKEY hkBackupKey
)
310 FIXME("(%p, %s, %p) stub\n", hWnd
, debugstr_w(pszTitleString
), hkBackupKey
);
315 /***********************************************************************
316 * RegSaveRestoreA (advpack.@)
318 * See RegSaveRestoreW.
320 HRESULT WINAPI
RegSaveRestoreA(HWND hWnd
, LPCSTR pszTitleString
, HKEY hkBackupKey
,
321 LPCSTR pcszRootKey
, LPCSTR pcszSubKey
,
322 LPCSTR pcszValueName
, DWORD dwFlags
)
324 UNICODE_STRING title
, root
, subkey
, value
;
327 TRACE("(%p, %s, %p, %s, %s, %s, %d)\n", hWnd
, debugstr_a(pszTitleString
),
328 hkBackupKey
, debugstr_a(pcszRootKey
), debugstr_a(pcszSubKey
),
329 debugstr_a(pcszValueName
), dwFlags
);
331 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitleString
);
332 RtlCreateUnicodeStringFromAsciiz(&root
, pcszRootKey
);
333 RtlCreateUnicodeStringFromAsciiz(&subkey
, pcszSubKey
);
334 RtlCreateUnicodeStringFromAsciiz(&value
, pcszValueName
);
336 hr
= RegSaveRestoreW(hWnd
, title
.Buffer
, hkBackupKey
, root
.Buffer
,
337 subkey
.Buffer
, value
.Buffer
, dwFlags
);
339 RtlFreeUnicodeString(&title
);
340 RtlFreeUnicodeString(&root
);
341 RtlFreeUnicodeString(&subkey
);
342 RtlFreeUnicodeString(&value
);
347 /***********************************************************************
348 * RegSaveRestoreW (advpack.@)
350 * Saves or restores the specified registry value.
353 * hWnd [I] Handle to the window used for the display.
354 * pszTitleString [I] Title of the window.
355 * hkBackupKey [I] Key used to store the backup data.
356 * pcszRootKey [I] Root key of the registry value
357 * pcszSubKey [I] Sub key of the registry value.
358 * pcszValueName [I] Value to save or restore.
359 * dwFlags [I] See advpub.h.
368 HRESULT WINAPI
RegSaveRestoreW(HWND hWnd
, LPCWSTR pszTitleString
, HKEY hkBackupKey
,
369 LPCWSTR pcszRootKey
, LPCWSTR pcszSubKey
,
370 LPCWSTR pcszValueName
, DWORD dwFlags
)
372 FIXME("(%p, %s, %p, %s, %s, %s, %d): stub\n", hWnd
, debugstr_w(pszTitleString
),
373 hkBackupKey
, debugstr_w(pcszRootKey
), debugstr_w(pcszSubKey
),
374 debugstr_w(pcszValueName
), dwFlags
);
379 /***********************************************************************
380 * RegSaveRestoreOnINFA (advpack.@)
382 * See RegSaveRestoreOnINFW.
384 HRESULT WINAPI
RegSaveRestoreOnINFA(HWND hWnd
, LPCSTR pszTitle
, LPCSTR pszINF
,
385 LPCSTR pszSection
, HKEY hHKLMBackKey
,
386 HKEY hHKCUBackKey
, DWORD dwFlags
)
388 UNICODE_STRING title
, inf
, section
;
391 TRACE("(%p, %s, %s, %s, %p, %p, %d)\n", hWnd
, debugstr_a(pszTitle
),
392 debugstr_a(pszINF
), debugstr_a(pszSection
),
393 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
395 RtlCreateUnicodeStringFromAsciiz(&title
, pszTitle
);
396 RtlCreateUnicodeStringFromAsciiz(&inf
, pszINF
);
397 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
399 hr
= RegSaveRestoreOnINFW(hWnd
, title
.Buffer
, inf
.Buffer
, section
.Buffer
,
400 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);
402 RtlFreeUnicodeString(&title
);
403 RtlFreeUnicodeString(&inf
);
404 RtlFreeUnicodeString(§ion
);
409 /***********************************************************************
410 * RegSaveRestoreOnINFW (advpack.@)
412 * Saves or restores the specified INF Reg section.
415 * hWnd [I] Handle to the window used for the display.
416 * pszTitle [I] Title of the window.
417 * pszINF [I] Filename of the INF.
418 * pszSection [I] Section to save or restore.
419 * hHKLMBackKey [I] Opened key in HKLM to store data.
420 * hHKCUBackKey [I] Opened key in HKCU to store data.
421 * dwFlags [I] See advpub.h
430 HRESULT WINAPI
RegSaveRestoreOnINFW(HWND hWnd
, LPCWSTR pszTitle
, LPCWSTR pszINF
,
431 LPCWSTR pszSection
, HKEY hHKLMBackKey
,
432 HKEY hHKCUBackKey
, DWORD dwFlags
)
434 FIXME("(%p, %s, %s, %s, %p, %p, %d): stub\n", hWnd
, debugstr_w(pszTitle
),
435 debugstr_w(pszINF
), debugstr_w(pszSection
),
436 hHKLMBackKey
, hHKCUBackKey
, dwFlags
);