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 /***********************************************************************
101 * RegInstall (advpack.@)
104 HRESULT WINAPI
RegInstall(HMODULE hm
, LPCSTR pszSection
, LPCSTRTABLE pstTable
)
107 WCHAR tmp_ini_path
[MAX_PATH
];
108 WCHAR mod_path
[MAX_PATH
+ 2], sys_mod_path
[MAX_PATH
+ 2], sys_root
[MAX_PATH
];
110 WCHAR quote
[] = {'\"',0};
111 UNICODE_STRING section
;
113 TRACE("(%p %s %p)\n", hm
, pszSection
, pstTable
);
115 if (pstTable
) for(i
= 0; i
< pstTable
->cEntries
; i
++)
116 TRACE("%d: %s -> %s\n", i
, pstTable
->pse
[i
].pszName
,
117 pstTable
->pse
[i
].pszValue
);
119 if(!create_tmp_ini_file(hm
, tmp_ini_path
))
122 /* Write a couple of pre-defined strings */
124 GetModuleFileNameW(hm
, mod_path
+ 1, sizeof(mod_path
)/sizeof(WCHAR
) - 2);
125 strcatW(mod_path
, quote
);
126 WritePrivateProfileStringW(Strings
, MOD_PATH
, mod_path
, tmp_ini_path
);
129 GetEnvironmentVariableW(SystemRoot
, sys_root
, sizeof(sys_root
)/sizeof(WCHAR
));
130 if(!strncmpiW(sys_root
, mod_path
+ 1, strlenW(sys_root
))) {
131 sys_mod_path
[0] = '\"';
132 strcpyW(sys_mod_path
+ 1, escaped_SystemRoot
);
133 strcatW(sys_mod_path
, mod_path
+ 1 + strlenW(sys_root
));
135 FIXME("SYS_MOD_PATH needs more work\n");
136 strcpyW(sys_mod_path
, mod_path
);
138 WritePrivateProfileStringW(Strings
, SYS_MOD_PATH
, sys_mod_path
, tmp_ini_path
);
140 /* Write the additional string table */
141 if (pstTable
) for(i
= 0; i
< pstTable
->cEntries
; i
++) {
142 char tmp_value
[MAX_PATH
+ 2];
143 UNICODE_STRING name
, value
;
145 strcpy(tmp_value
+ 1, pstTable
->pse
[i
].pszValue
);
146 strcat(tmp_value
, "\"");
147 RtlCreateUnicodeStringFromAsciiz(&name
, pstTable
->pse
[i
].pszName
);
148 RtlCreateUnicodeStringFromAsciiz(&value
, tmp_value
);
149 WritePrivateProfileStringW(Strings
, name
.Buffer
, value
.Buffer
, tmp_ini_path
);
150 RtlFreeUnicodeString(&name
);
151 RtlFreeUnicodeString(&value
);
154 WritePrivateProfileStringW(NULL
, NULL
, NULL
, tmp_ini_path
);
157 if((hinf
= SetupOpenInfFileW(tmp_ini_path
, NULL
, INF_STYLE_WIN4
, NULL
)) ==
158 INVALID_HANDLE_VALUE
) {
159 ERR("Setupapi can't open inf\n");
163 /* append any layout files */
164 SetupOpenAppendInfFileW(NULL
, hinf
, NULL
);
166 /* Need to do a lot more here */
167 RtlCreateUnicodeStringFromAsciiz(§ion
, pszSection
);
168 SetupInstallFromInfSectionW(NULL
, hinf
, section
.Buffer
,
169 SPINST_INIFILES
| SPINST_REGISTRY
| SPINST_PROFILEITEMS
,
170 HKEY_LOCAL_MACHINE
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
171 RtlFreeUnicodeString(§ion
);
174 SetupCloseInfFile(hinf
);
175 DeleteFileW(tmp_ini_path
);