Mercurial > trustbridge
comparison cinst/nssstore_win.c @ 674:f1795a232418
Implement reading registry entries for other users.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Fri, 27 Jun 2014 16:18:10 +0200 |
parents | d4766b4922c9 |
children | 4ad764bfb39c |
comparison
equal
deleted
inserted
replaced
673:e8bc1215904e | 674:f1795a232418 |
---|---|
137 } | 137 } |
138 } | 138 } |
139 return true; | 139 return true; |
140 } | 140 } |
141 | 141 |
142 /**@brief Read (and expand if necessary) a registry string. | |
143 * | |
144 * Reads a registry string and calls ExpandEnvironmentString | |
145 * if necessary on it. Returns a newly allocated string array | |
146 * with the expanded registry value converted to UTF-8 | |
147 * | |
148 * Caller has to free return value with free. | |
149 * | |
150 * @param [in] root the root key (e.g. HKEY_LOCAL_MACHINE) | |
151 * @param [in] key the key | |
152 * @param [in] name the name of the value to read. | |
153 * | |
154 * @returns the expanded, null terminated utf-8 string of the value. | |
155 * or NULL on error. | |
156 */ | |
157 static char* | |
158 read_registry_string (const HKEY root, const wchar_t *key, | |
159 const wchar_t *name) | |
160 { | |
161 HKEY key_handle = NULL; | |
162 DWORD size = 0, | |
163 type = 0, | |
164 ex_size = 0, | |
165 dwRet = 0; | |
166 LONG ret = 0; | |
167 char *retval = NULL; | |
168 wchar_t *buf = NULL, | |
169 *ex_buf = NULL; | |
170 if (root == NULL || key == NULL || name == NULL) | |
171 { | |
172 ERRORPRINTF ("Invalid call to read_registry_string"); | |
173 return NULL; | |
174 } | |
175 | |
176 ret = RegOpenKeyExW (root, key, 0, KEY_READ, &key_handle); | |
177 if (ret != ERROR_SUCCESS) | |
178 { | |
179 ERRORPRINTF ("Failed to open key."); | |
180 return NULL; | |
181 } | |
182 | |
183 /* Get the size */ | |
184 ret = RegQueryValueExW (key_handle, name, 0, NULL, NULL, &size); | |
185 if (ret != ERROR_MORE_DATA && !(ret == ERROR_SUCCESS && size != 0)) | |
186 { | |
187 ERRORPRINTF ("Failed to get required registry size."); | |
188 return retval; | |
189 } | |
190 | |
191 /* Size is size in bytes not in characters */ | |
192 buf = xmalloc (size + sizeof(wchar_t)); | |
193 | |
194 /* If the stored value is not zero terminated the returned value also | |
195 is not zero terminated. That's why we reserve more and ensure it's | |
196 initialized. */ | |
197 memset (buf, 0, size + sizeof(wchar_t)); | |
198 | |
199 ret = RegQueryValueExW (key_handle, name, 0, &type, (LPBYTE) buf, &size); | |
200 if (ret != ERROR_SUCCESS) | |
201 { | |
202 ERRORPRINTF ("Failed get registry value."); | |
203 return retval; | |
204 } | |
205 | |
206 if (type == REG_SZ || (type == REG_EXPAND_SZ && wcschr (buf, '%') == NULL)) | |
207 { | |
208 /* Nothing to expand, we are done */ | |
209 retval = wchar_to_utf8 (buf, wcslen (buf)); | |
210 goto done; | |
211 } | |
212 | |
213 if (type != REG_EXPAND_SZ) | |
214 { | |
215 ERRORPRINTF ("Unhandled registry type %i", type); | |
216 goto done; | |
217 } | |
218 | |
219 /* Expand the registry string */ | |
220 ex_size = ExpandEnvironmentStringsW (buf, NULL, 0); | |
221 | |
222 if (ex_size == 0) | |
223 { | |
224 PRINTLASTERROR ("Failed to determine expanded environment size."); | |
225 goto done; | |
226 } | |
227 | |
228 ex_buf = xmalloc ((ex_size + 1) * sizeof(wchar_t)); | |
229 | |
230 dwRet = ExpandEnvironmentStringsW (buf, ex_buf, ex_size); | |
231 | |
232 ex_buf[ex_size] = '\0'; /* Make sure it's a string */ | |
233 | |
234 if (dwRet == 0 || dwRet != ex_size) | |
235 { | |
236 PRINTLASTERROR ("Failed to expand environment variables."); | |
237 goto done; | |
238 } | |
239 | |
240 retval = wchar_to_utf8 (ex_buf, ex_size); | |
241 | |
242 done: | |
243 xfree (ex_buf); | |
244 xfree (buf); | |
245 | |
246 RegCloseKey (key_handle); | |
247 return retval; | |
248 } | |
142 /**@brief Get the path to all users default registry hive | 249 /**@brief Get the path to all users default registry hive |
143 * | 250 * |
144 * Enumerates the keys in #PROFILE_LIST and retuns a | 251 * Enumerates the keys in #PROFILE_LIST and retuns a |
145 * strv array with the utf-8 encoded paths to their suggested | 252 * strv array with the utf-8 encoded paths to their suggested |
146 * registry hive location. | 253 * registry hive location. |
150 * | 257 * |
151 * Use strv_free to free that array. | 258 * Use strv_free to free that array. |
152 * | 259 * |
153 * @returns a newly allocated strv of the paths to the registry hives or NULL | 260 * @returns a newly allocated strv of the paths to the registry hives or NULL |
154 */ | 261 */ |
155 | |
156 static char** | 262 static char** |
157 locate_other_hives() | 263 locate_other_hives() |
158 { | 264 { |
159 HKEY profile_list = NULL; | 265 HKEY profile_list = NULL; |
160 int ret = 0; | 266 int ret = 0; |
196 | 302 |
197 while ((ret = RegEnumKeyExW (profile_list, index++, | 303 while ((ret = RegEnumKeyExW (profile_list, index++, |
198 key_name, &key_len, | 304 key_name, &key_len, |
199 NULL, NULL, NULL, NULL)) == ERROR_SUCCESS) | 305 NULL, NULL, NULL, NULL)) == ERROR_SUCCESS) |
200 { | 306 { |
307 char *profile_path = NULL; | |
308 wchar_t *key_path = NULL; | |
309 size_t key_path_len = 0, | |
310 profile_path_len = 0; | |
311 | |
201 if (key_len == 257) | 312 if (key_len == 257) |
202 { | 313 { |
203 ERRORPRINTF ("Registry key too long."); | 314 ERRORPRINTF ("Registry key too long."); |
204 goto done; | 315 goto done; |
205 } | 316 } |
213 /* S-1-5-21 is the well known prefix for local users. Skip all | 324 /* S-1-5-21 is the well known prefix for local users. Skip all |
214 others and the current user*/ | 325 others and the current user*/ |
215 continue; | 326 continue; |
216 } | 327 } |
217 | 328 |
329 key_path_len = key_len + wcslen(PROFILE_LIST L"\\") + 1; | |
330 key_path = xmalloc (key_path_len * sizeof (wchar_t)); | |
331 | |
332 wcscpy_s (key_path, key_path_len, PROFILE_LIST L"\\"); | |
333 wcscat_s (key_path, key_path_len, key_name); | |
334 key_path[key_len - 1] = '\0'; | |
335 | |
218 DEBUGPRINTF ("Key : %S", key_name); | 336 DEBUGPRINTF ("Key : %S", key_name); |
337 profile_path = read_registry_string (HKEY_LOCAL_MACHINE, | |
338 key_path, L"ProfileImagePath"); | |
339 xfree (key_path); | |
340 | |
341 if (profile_path == NULL) | |
342 { | |
343 ERRORPRINTF ("Failed to get profile path."); | |
344 continue; | |
345 } | |
346 profile_path_len = strlen (profile_path); | |
347 str_append_str (&profile_path, &profile_path_len, "\\ntuser.dat", 11); | |
348 | |
349 strv_append (&retval, profile_path, profile_path_len); | |
350 DEBUGPRINTF ("Trying to access registry hive: %s", profile_path); | |
351 | |
352 xfree (profile_path); | |
219 } | 353 } |
220 | 354 |
221 if (ret != ERROR_NO_MORE_ITEMS) | 355 if (ret != ERROR_NO_MORE_ITEMS) |
222 { | 356 { |
223 ERRORPRINTF ("Failed to enumeratre profile list. Error: %i", ret); | 357 ERRORPRINTF ("Failed to enumeratre profile list. Error: %i", ret); |