ReactOS  0.4.13-dev-259-g5ca9c9c
reg.c
Go to the documentation of this file.
1 /*
2  * SHLWAPI registry functions
3  *
4  * Copyright 1998 Juergen Schmied
5  * Copyright 2001 Guy Albertelli
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include <stdarg.h>
23 #include <string.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "winreg.h"
28 #include "wine/debug.h"
29 #define NO_SHLWAPI_STREAM
30 #include "shlwapi.h"
31 #include "wine/unicode.h"
32 
34 
35 /* Key/Value names for MIME content types */
36 static const char lpszContentTypeA[] = "Content Type";
37 static const WCHAR lpszContentTypeW[] = { 'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
38 
39 static const char szMimeDbContentA[] = "MIME\\Database\\Content Type\\";
40 static const WCHAR szMimeDbContentW[] = { 'M', 'I', 'M','E','\\',
41  'D','a','t','a','b','a','s','e','\\','C','o','n','t','e','n','t',
42  ' ','T','y','p','e','\\', 0 };
43 static const DWORD dwLenMimeDbContent = 27; /* strlen of szMimeDbContentA/W */
44 
45 static const char szExtensionA[] = "Extension";
46 static const WCHAR szExtensionW[] = { 'E', 'x', 't','e','n','s','i','o','n','\0' };
47 
48 /* internal structure of what the HUSKEY points to */
49 typedef struct {
50  HKEY HKCUstart; /* Start key in CU hive */
51  HKEY HKCUkey; /* Opened key in CU hive */
52  HKEY HKLMstart; /* Start key in LM hive */
53  HKEY HKLMkey; /* Opened key in LM hive */
54  WCHAR lpszPath[MAX_PATH];
55 } SHUSKEY, *LPSHUSKEY;
56 
59 
60 
61 #define REG_HKCU TRUE
62 #define REG_HKLM FALSE
63 /*************************************************************************
64  * REG_GetHKEYFromHUSKEY
65  *
66  * Function: Return the proper registry key from the HUSKEY structure
67  * also allow special predefined values.
68  */
70 {
71  HKEY test = hUSKey;
72  LPSHUSKEY mihk = hUSKey;
73 
74  if ((test == HKEY_CLASSES_ROOT) ||
76  (test == HKEY_CURRENT_USER) ||
77  (test == HKEY_DYN_DATA) ||
78  (test == HKEY_LOCAL_MACHINE) ||
80 /* FIXME: need to define for Win2k, ME, XP
81  * (test == HKEY_PERFORMANCE_TEXT) ||
82  * (test == HKEY_PERFORMANCE_NLSTEXT) ||
83  */
84  (test == HKEY_USERS)) return test;
85  if (which == REG_HKCU) return mihk->HKCUkey;
86  return mihk->HKLMkey;
87 }
88 
89 
90 /*************************************************************************
91  * SHRegOpenUSKeyA [SHLWAPI.@]
92  *
93  * Open a user-specific registry key.
94  *
95  * PARAMS
96  * Path [I] Key name to open
97  * AccessType [I] Access type
98  * hRelativeUSKey [I] Relative user key
99  * phNewUSKey [O] Destination for created key
100  * fIgnoreHKCU [I] TRUE=Don't check HKEY_CURRENT_USER
101  *
102  * RETURNS
103  * Success: ERROR_SUCCESS
104  * Failure: An error code from RegOpenKeyExA().
105  */
106 LONG WINAPI SHRegOpenUSKeyA(LPCSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey,
107  PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
108 {
110 
111  if (Path)
113 
114  return SHRegOpenUSKeyW(Path ? szPath : NULL, AccessType, hRelativeUSKey,
115  phNewUSKey, fIgnoreHKCU);
116 }
117 
118 /*************************************************************************
119  * SHRegOpenUSKeyW [SHLWAPI.@]
120  *
121  * See SHRegOpenUSKeyA.
122  */
123 LONG WINAPI SHRegOpenUSKeyW(LPCWSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey,
124  PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
125 {
126  LONG ret2, ret1 = ~ERROR_SUCCESS;
127  LPSHUSKEY hKey;
128 
129  TRACE("(%s,0x%x,%p,%p,%d)\n", debugstr_w(Path),(LONG)AccessType,
130  hRelativeUSKey, phNewUSKey, fIgnoreHKCU);
131 
132  if (phNewUSKey)
133  *phNewUSKey = NULL;
134 
135  /* Create internal HUSKEY */
136  hKey = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*hKey));
137  lstrcpynW(hKey->lpszPath, Path, sizeof(hKey->lpszPath)/sizeof(WCHAR));
138 
139  if (hRelativeUSKey)
140  {
143 
144  /* FIXME: if either of these keys is NULL, create the start key from
145  * the relative keys start+path
146  */
147  }
148  else
149  {
152  }
153 
154  if (!fIgnoreHKCU)
155  {
156  ret1 = RegOpenKeyExW(hKey->HKCUstart, hKey->lpszPath, 0, AccessType, &hKey->HKCUkey);
157  if (ret1)
158  hKey->HKCUkey = 0;
159  }
160 
161  ret2 = RegOpenKeyExW(hKey->HKLMstart, hKey->lpszPath, 0, AccessType, &hKey->HKLMkey);
162  if (ret2)
163  hKey->HKLMkey = 0;
164 
165  if (ret1 || ret2)
166  TRACE("one or more opens failed: HKCU=%d HKLM=%d\n", ret1, ret2);
167 
168  if (ret1 && ret2)
169  {
170  /* Neither open succeeded: fail */
171  SHRegCloseUSKey(hKey);
172  return ret2;
173  }
174 
175  TRACE("HUSKEY=%p\n", hKey);
176  if (phNewUSKey)
177  *phNewUSKey = hKey;
178  return ERROR_SUCCESS;
179 }
180 
181 /*************************************************************************
182  * SHRegCloseUSKey [SHLWAPI.@]
183  *
184  * Close a user-specific registry key
185  *
186  * RETURNS
187  * Success: ERROR_SUCCESS
188  * Failure: An error code from RegCloseKey().
189  */
191  HUSKEY hUSKey) /* [I] Key to close */
192 {
193  LPSHUSKEY hKey = hUSKey;
195 
196  if (!hKey)
198 
199  if (hKey->HKCUkey)
200  ret = RegCloseKey(hKey->HKCUkey);
201  if (hKey->HKCUstart && hKey->HKCUstart != HKEY_CURRENT_USER)
202  ret = RegCloseKey(hKey->HKCUstart);
203  if (hKey->HKLMkey)
204  ret = RegCloseKey(hKey->HKLMkey);
205  if (hKey->HKLMstart && hKey->HKLMstart != HKEY_LOCAL_MACHINE)
206  ret = RegCloseKey(hKey->HKLMstart);
207 
208  HeapFree(GetProcessHeap(), 0, hKey);
209  return ret;
210 }
211 
212 /*************************************************************************
213  * SHRegCreateUSKeyA [SHLWAPI.@]
214  *
215  * See SHRegCreateUSKeyW.
216  */
218  PHUSKEY new_uskey, DWORD flags)
219 {
220  WCHAR *pathW;
221  LONG ret;
222 
223  TRACE("(%s, 0x%08x, %p, %p, 0x%08x)\n", debugstr_a(path), samDesired, relative_key,
224  new_uskey, flags);
225 
226  if (path)
227  {
228  INT len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
229  pathW = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
230  if (!pathW)
232  MultiByteToWideChar(CP_ACP, 0, path, -1, pathW, len);
233  }
234  else
235  pathW = NULL;
236 
237  ret = SHRegCreateUSKeyW(pathW, samDesired, relative_key, new_uskey, flags);
238  HeapFree(GetProcessHeap(), 0, pathW);
239  return ret;
240 }
241 
242 /*************************************************************************
243  * SHRegCreateUSKeyW [SHLWAPI.@]
244  *
245  * Create or open a user-specific registry key.
246  *
247  * PARAMS
248  * path [I] Key name to create or open.
249  * samDesired [I] Wanted security access.
250  * relative_key [I] Base path if 'path' is relative. NULL otherwise.
251  * new_uskey [O] Receives a handle to the new or opened key.
252  * flags [I] Base key under which the key should be opened.
253  *
254  * RETURNS
255  * Success: ERROR_SUCCESS
256  * Failure: Nonzero error code from winerror.h
257  */
259  PHUSKEY new_uskey, DWORD flags)
260 {
262  SHUSKEY *ret_key;
263 
264  TRACE("(%s, 0x%08x, %p, %p, 0x%08x)\n", debugstr_w(path), samDesired,
265  relative_key, new_uskey, flags);
266 
267  if (!new_uskey) return ERROR_INVALID_PARAMETER;
268 
269  *new_uskey = NULL;
270 
271  if (flags & ~SHREGSET_FORCE_HKCU)
272  {
273  FIXME("unsupported flags 0x%08x\n", flags);
274  return ERROR_SUCCESS;
275  }
276 
277  ret_key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret_key));
278  lstrcpynW(ret_key->lpszPath, path, sizeof(ret_key->lpszPath)/sizeof(WCHAR));
279 
280  if (relative_key)
281  {
282  ret_key->HKCUstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(relative_key, REG_HKCU));
283  ret_key->HKLMstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(relative_key, REG_HKLM));
284  }
285  else
286  {
287  ret_key->HKCUstart = HKEY_CURRENT_USER;
288  ret_key->HKLMstart = HKEY_LOCAL_MACHINE;
289  }
290 
292  {
293  ret = RegCreateKeyExW(ret_key->HKCUstart, path, 0, NULL, 0, samDesired, NULL, &ret_key->HKCUkey, NULL);
294  if (ret == ERROR_SUCCESS)
295  *new_uskey = ret_key;
296  else
297  HeapFree(GetProcessHeap(), 0, ret_key);
298  }
299 
300  return ret;
301 }
302 
303 /*************************************************************************
304  * SHRegDeleteEmptyUSKeyA [SHLWAPI.@]
305  *
306  * Delete an empty user-specific registry key.
307  *
308  * PARAMS
309  * hUSKey [I] Handle to an open registry key.
310  * pszValue [I] Empty key name.
311  * delRegFlags [I] Flag that specifies the base from which to delete
312  * the key.
313  *
314  * RETURNS
315  * Success: ERROR_SUCCESS
316  * Failure: Nonzero error code from winerror.h
317  */
319 {
320  FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags);
321  return ERROR_SUCCESS;
322 }
323 
324 /*************************************************************************
325  * SHRegDeleteEmptyUSKeyW [SHLWAPI.@]
326  *
327  * See SHRegDeleteEmptyUSKeyA.
328  */
330 {
331  FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags);
332  return ERROR_SUCCESS;
333 }
334 
335 /*************************************************************************
336  * SHRegDeleteUSValueA [SHLWAPI.@]
337  *
338  * Delete a user-specific registry value.
339  *
340  * PARAMS
341  * hUSKey [I] Handle to an open registry key.
342  * pszValue [I] Specifies the value to delete.
343  * delRegFlags [I] Flag that specifies the base of the key from which to
344  * delete the value.
345  *
346  * RETURNS
347  * Success: ERROR_SUCCESS
348  * Failure: Nonzero error code from winerror.h
349  */
351 {
352  FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags);
353  return ERROR_SUCCESS;
354 }
355 
356 /*************************************************************************
357  * SHRegDeleteUSValueW [SHLWAPI.@]
358  *
359  * See SHRegDeleteUSValueA.
360  */
362 {
363  FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags);
364  return ERROR_SUCCESS;
365 }
366 
367 /*************************************************************************
368  * SHRegEnumUSValueA [SHLWAPI.@]
369  *
370  * Enumerate values of a specified registry key.
371  *
372  * PARAMS
373  * hUSKey [I] Handle to an open registry key.
374  * dwIndex [I] Index of the value to be retrieved.
375  * pszValueName [O] Buffer to receive the value name.
376  * pcchValueNameLen [I] Size of pszValueName in characters.
377  * pdwType [O] Receives data type of the value.
378  * pvData [O] Receives value data. May be NULL.
379  * pcbData [I/O] Size of pvData in bytes.
380  * enumRegFlags [I] Flag that specifies the base key under which to
381  * enumerate values.
382  *
383  * RETURNS
384  * Success: ERROR_SUCCESS
385  * Failure: Nonzero error code from winerror.h
386  */
387 LONG WINAPI SHRegEnumUSValueA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszValueName,
388  LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData,
389  LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
390 {
391  HKEY dokey;
392 
393  TRACE("(%p, 0x%08x, %p, %p, %p, %p, %p, 0x%08x)\n", hUSKey, dwIndex,
394  pszValueName, pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags);
395 
396  if (((enumRegFlags == SHREGENUM_HKCU) ||
397  (enumRegFlags == SHREGENUM_DEFAULT)) &&
398  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
399  return RegEnumValueA(dokey, dwIndex, pszValueName, pcchValueNameLen,
400  NULL, pdwType, pvData, pcbData);
401  }
402 
403  if (((enumRegFlags == SHREGENUM_HKLM) ||
404  (enumRegFlags == SHREGENUM_DEFAULT)) &&
405  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
406  return RegEnumValueA(dokey, dwIndex, pszValueName, pcchValueNameLen,
407  NULL, pdwType, pvData, pcbData);
408  }
409  FIXME("no support for SHREGENUM_BOTH\n");
410  return ERROR_INVALID_FUNCTION;
411 }
412 
413 /*************************************************************************
414  * SHRegEnumUSValueW [SHLWAPI.@]
415  *
416  * See SHRegEnumUSValueA.
417  */
418 LONG WINAPI SHRegEnumUSValueW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszValueName,
419  LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData,
420  LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
421 {
422  HKEY dokey;
423 
424  TRACE("(%p, 0x%08x, %p, %p, %p, %p, %p, 0x%08x)\n", hUSKey, dwIndex,
425  pszValueName, pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags);
426 
427  if (((enumRegFlags == SHREGENUM_HKCU) ||
428  (enumRegFlags == SHREGENUM_DEFAULT)) &&
429  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
430  return RegEnumValueW(dokey, dwIndex, pszValueName, pcchValueNameLen,
431  NULL, pdwType, pvData, pcbData);
432  }
433 
434  if (((enumRegFlags == SHREGENUM_HKLM) ||
435  (enumRegFlags == SHREGENUM_DEFAULT)) &&
436  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
437  return RegEnumValueW(dokey, dwIndex, pszValueName, pcchValueNameLen,
438  NULL, pdwType, pvData, pcbData);
439  }
440  FIXME("no support for SHREGENUM_BOTH\n");
441  return ERROR_INVALID_FUNCTION;
442 }
443 
444 /*************************************************************************
445  * SHRegQueryUSValueA [SHLWAPI.@]
446  *
447  * Query a user-specific registry value.
448  *
449  * RETURNS
450  * Success: ERROR_SUCCESS
451  * Failure: An error code from RegQueryValueExA().
452  */
454  HUSKEY hUSKey, /* [I] Key to query */
455  LPCSTR pszValue, /* [I] Value name under hUSKey */
456  LPDWORD pdwType, /* [O] Destination for value type */
457  LPVOID pvData, /* [O] Destination for value data */
458  LPDWORD pcbData, /* [O] Destination for value length */
459  BOOL fIgnoreHKCU, /* [I] TRUE=Don't check HKEY_CURRENT_USER */
460  LPVOID pvDefaultData, /* [I] Default data if pszValue does not exist */
461  DWORD dwDefaultDataSize) /* [I] Length of pvDefaultData */
462 {
464  LONG i, maxmove;
465  HKEY dokey;
466  CHAR *src, *dst;
467 
468  /* if user wants HKCU, and it exists, then try it */
469  if (!fIgnoreHKCU && (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
470  ret = RegQueryValueExA(dokey,
471  pszValue, 0, pdwType, pvData, pcbData);
472  TRACE("HKCU RegQueryValue returned %08x\n", ret);
473  }
474 
475  /* if HKCU did not work and HKLM exists, then try it */
476  if ((ret != ERROR_SUCCESS) &&
477  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
478  ret = RegQueryValueExA(dokey,
479  pszValue, 0, pdwType, pvData, pcbData);
480  TRACE("HKLM RegQueryValue returned %08x\n", ret);
481  }
482 
483  /* if neither worked, and default data exists, then use it */
484  if (ret != ERROR_SUCCESS) {
485  if (pvDefaultData && (dwDefaultDataSize != 0)) {
486  maxmove = (dwDefaultDataSize >= *pcbData) ? *pcbData : dwDefaultDataSize;
487  src = pvDefaultData;
488  dst = pvData;
489  for(i=0; i<maxmove; i++) *dst++ = *src++;
490  *pcbData = maxmove;
491  TRACE("setting default data\n");
492  ret = ERROR_SUCCESS;
493  }
494  }
495  return ret;
496 }
497 
498 
499 /*************************************************************************
500  * SHRegQueryUSValueW [SHLWAPI.@]
501  *
502  * See SHRegQueryUSValueA.
503  */
505  HUSKEY hUSKey,
506  LPCWSTR pszValue,
507  LPDWORD pdwType,
508  LPVOID pvData,
510  BOOL fIgnoreHKCU,
511  LPVOID pvDefaultData,
512  DWORD dwDefaultDataSize)
513 {
515  LONG i, maxmove;
516  HKEY dokey;
517  CHAR *src, *dst;
518 
519  /* if user wants HKCU, and it exists, then try it */
520  if (!fIgnoreHKCU && (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
521  ret = RegQueryValueExW(dokey,
522  pszValue, 0, pdwType, pvData, pcbData);
523  TRACE("HKCU RegQueryValue returned %08x\n", ret);
524  }
525 
526  /* if HKCU did not work and HKLM exists, then try it */
527  if ((ret != ERROR_SUCCESS) &&
528  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
529  ret = RegQueryValueExW(dokey,
530  pszValue, 0, pdwType, pvData, pcbData);
531  TRACE("HKLM RegQueryValue returned %08x\n", ret);
532  }
533 
534  /* if neither worked, and default data exists, then use it */
535  if (ret != ERROR_SUCCESS) {
536  if (pvDefaultData && (dwDefaultDataSize != 0)) {
537  maxmove = (dwDefaultDataSize >= *pcbData) ? *pcbData : dwDefaultDataSize;
538  src = pvDefaultData;
539  dst = pvData;
540  for(i=0; i<maxmove; i++) *dst++ = *src++;
541  *pcbData = maxmove;
542  TRACE("setting default data\n");
543  ret = ERROR_SUCCESS;
544  }
545  }
546  return ret;
547 }
548 
549 /*************************************************************************
550  * SHRegGetUSValueA [SHLWAPI.@]
551  *
552  * Get a user-specific registry value.
553  *
554  * RETURNS
555  * Success: ERROR_SUCCESS
556  * Failure: An error code from SHRegOpenUSKeyA() or SHRegQueryUSValueA().
557  *
558  * NOTES
559  * This function opens pSubKey, queries the value, and then closes the key.
560  */
562  LPCSTR pSubKey, /* [I] Key name to open */
563  LPCSTR pValue, /* [I] Value name to open */
564  LPDWORD pwType, /* [O] Destination for the type of the value */
565  LPVOID pvData, /* [O] Destination for the value */
566  LPDWORD pcbData, /* [I] Destination for the length of the value **/
567  BOOL flagIgnoreHKCU, /* [I] TRUE=Don't check HKEY_CURRENT_USER */
568  LPVOID pDefaultData, /* [I] Default value if it doesn't exist */
569  DWORD wDefaultDataSize) /* [I] Length of pDefaultData */
570 {
571  HUSKEY myhuskey;
572  LONG ret;
573 
574  if (!pvData || !pcbData) return ERROR_INVALID_FUNCTION; /* FIXME:wrong*/
575  TRACE("key '%s', value '%s', datalen %d, %s\n",
576  debugstr_a(pSubKey), debugstr_a(pValue), *pcbData,
577  (flagIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM");
578 
579  ret = SHRegOpenUSKeyA(pSubKey, 0x1, 0, &myhuskey, flagIgnoreHKCU);
580  if (ret == ERROR_SUCCESS) {
581  ret = SHRegQueryUSValueA(myhuskey, pValue, pwType, pvData,
582  pcbData, flagIgnoreHKCU, pDefaultData,
583  wDefaultDataSize);
584  SHRegCloseUSKey(myhuskey);
585  }
586  return ret;
587 }
588 
589 /*************************************************************************
590  * SHRegGetUSValueW [SHLWAPI.@]
591  *
592  * See SHRegGetUSValueA.
593  */
595  LPCWSTR pSubKey,
596  LPCWSTR pValue,
597  LPDWORD pwType,
598  LPVOID pvData,
600  BOOL flagIgnoreHKCU,
601  LPVOID pDefaultData,
602  DWORD wDefaultDataSize)
603 {
604  HUSKEY myhuskey;
605  LONG ret;
606 
607  if (!pvData || !pcbData) return ERROR_INVALID_FUNCTION; /* FIXME:wrong*/
608  TRACE("key '%s', value '%s', datalen %d, %s\n",
609  debugstr_w(pSubKey), debugstr_w(pValue), *pcbData,
610  (flagIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM");
611 
612  ret = SHRegOpenUSKeyW(pSubKey, 0x1, 0, &myhuskey, flagIgnoreHKCU);
613  if (ret == ERROR_SUCCESS) {
614  ret = SHRegQueryUSValueW(myhuskey, pValue, pwType, pvData,
615  pcbData, flagIgnoreHKCU, pDefaultData,
616  wDefaultDataSize);
617  SHRegCloseUSKey(myhuskey);
618  }
619  return ret;
620 }
621 
622 /*************************************************************************
623  * SHRegSetUSValueA [SHLWAPI.@]
624  *
625  * Set a user-specific registry value.
626  *
627  * PARAMS
628  * pszSubKey [I] Name of key to set the value in
629  * pszValue [I] Name of value under pszSubKey to set the value in
630  * dwType [I] Type of the value
631  * pvData [I] Data to set as the value
632  * cbData [I] length of pvData
633  * dwFlags [I] SHREGSET_ flags from "shlwapi.h"
634  *
635  * RETURNS
636  * Success: ERROR_SUCCESS
637  * Failure: An error code from SHRegOpenUSKeyA() or SHRegWriteUSValueA(), or
638  * ERROR_INVALID_FUNCTION if pvData is NULL.
639  *
640  * NOTES
641  * This function opens pszSubKey, sets the value, and then closes the key.
642  */
643 LONG WINAPI SHRegSetUSValueA(LPCSTR pszSubKey, LPCSTR pszValue, DWORD dwType,
644  LPVOID pvData, DWORD cbData, DWORD dwFlags)
645 {
646  BOOL ignoreHKCU = TRUE;
647  HUSKEY hkey;
648  LONG ret;
649 
650  TRACE("(%s,%s,%d,%p,%d,0x%08x\n", debugstr_a(pszSubKey), debugstr_a(pszValue),
651  dwType, pvData, cbData, dwFlags);
652 
653  if (!pvData)
654  return ERROR_INVALID_FUNCTION;
655 
657  ignoreHKCU = FALSE;
658 
659  ret = SHRegOpenUSKeyA(pszSubKey, KEY_ALL_ACCESS, 0, &hkey, ignoreHKCU);
660  if (ret == ERROR_SUCCESS)
661  {
662  ret = SHRegWriteUSValueA(hkey, pszValue, dwType, pvData, cbData, dwFlags);
663  SHRegCloseUSKey(hkey);
664  }
665  return ret;
666 }
667 
668 /*************************************************************************
669  * SHRegSetUSValueW [SHLWAPI.@]
670  *
671  * See SHRegSetUSValueA.
672  */
673 LONG WINAPI SHRegSetUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwType,
674  LPVOID pvData, DWORD cbData, DWORD dwFlags)
675 {
676  BOOL ignoreHKCU = TRUE;
677  HUSKEY hkey;
678  LONG ret;
679 
680  TRACE("(%s,%s,%d,%p,%d,0x%08x\n", debugstr_w(pszSubKey), debugstr_w(pszValue),
681  dwType, pvData, cbData, dwFlags);
682 
683  if (!pvData)
684  return ERROR_INVALID_FUNCTION;
685 
687  ignoreHKCU = FALSE;
688 
689  ret = SHRegOpenUSKeyW(pszSubKey, KEY_ALL_ACCESS, 0, &hkey, ignoreHKCU);
690  if (ret == ERROR_SUCCESS)
691  {
692  ret = SHRegWriteUSValueW(hkey, pszValue, dwType, pvData, cbData, dwFlags);
693  SHRegCloseUSKey(hkey);
694  }
695  return ret;
696 }
697 
698 /*************************************************************************
699  * SHRegGetBoolUSValueA [SHLWAPI.@]
700  *
701  * Get a user-specific registry boolean value.
702  *
703  * RETURNS
704  * Success: ERROR_SUCCESS
705  * Failure: An error code from SHRegOpenUSKeyA() or SHRegQueryUSValueA().
706  *
707  * NOTES
708  * This function opens pszSubKey, queries the value, and then closes the key.
709  *
710  * Boolean values are one of the following:
711  * True: YES,TRUE,non-zero
712  * False: NO,FALSE,0
713  */
715  LPCSTR pszSubKey, /* [I] Key name to open */
716  LPCSTR pszValue, /* [I] Value name to open */
717  BOOL fIgnoreHKCU, /* [I] TRUE=Don't check HKEY_CURRENT_USER */
718  BOOL fDefault) /* [I] Default value to use if pszValue is not present */
719 {
720  DWORD type, datalen, work;
721  BOOL ret = fDefault;
722  CHAR data[10];
723 
724  TRACE("key '%s', value '%s', %s\n",
725  debugstr_a(pszSubKey), debugstr_a(pszValue),
726  (fIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM");
727 
728  datalen = sizeof(data)-1;
729  if (!SHRegGetUSValueA( pszSubKey, pszValue, &type,
730  data, &datalen,
731  fIgnoreHKCU, 0, 0)) {
732  /* process returned data via type into bool */
733  switch (type) {
734  case REG_SZ:
735  data[9] = '\0'; /* set end of string */
736  if (lstrcmpiA(data, "YES") == 0) ret = TRUE;
737  if (lstrcmpiA(data, "TRUE") == 0) ret = TRUE;
738  if (lstrcmpiA(data, "NO") == 0) ret = FALSE;
739  if (lstrcmpiA(data, "FALSE") == 0) ret = FALSE;
740  break;
741  case REG_DWORD:
742  work = *(LPDWORD)data;
743  ret = (work != 0);
744  break;
745  case REG_BINARY:
746  if (datalen == 1) {
747  ret = (data[0] != '\0');
748  break;
749  }
750  default:
751  FIXME("Unsupported registry data type %d\n", type);
752  ret = FALSE;
753  }
754  TRACE("got value (type=%d), returning <%s>\n", type,
755  (ret) ? "TRUE" : "FALSE");
756  }
757  else {
758  ret = fDefault;
759  TRACE("returning default data <%s>\n",
760  (ret) ? "TRUE" : "FALSE");
761  }
762  return ret;
763 }
764 
765 /*************************************************************************
766  * SHRegGetBoolUSValueW [SHLWAPI.@]
767  *
768  * See SHRegGetBoolUSValueA.
769  */
771  LPCWSTR pszSubKey,
772  LPCWSTR pszValue,
773  BOOL fIgnoreHKCU,
774  BOOL fDefault)
775 {
776  static const WCHAR wYES[]= {'Y','E','S','\0'};
777  static const WCHAR wTRUE[]= {'T','R','U','E','\0'};
778  static const WCHAR wNO[]= {'N','O','\0'};
779  static const WCHAR wFALSE[]={'F','A','L','S','E','\0'};
780  DWORD type, datalen, work;
781  BOOL ret = fDefault;
782  WCHAR data[10];
783 
784  TRACE("key '%s', value '%s', %s\n",
785  debugstr_w(pszSubKey), debugstr_w(pszValue),
786  (fIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM");
787 
788  datalen = (sizeof(data)-1) * sizeof(WCHAR);
789  if (!SHRegGetUSValueW( pszSubKey, pszValue, &type,
790  data, &datalen,
791  fIgnoreHKCU, 0, 0)) {
792  /* process returned data via type into bool */
793  switch (type) {
794  case REG_SZ:
795  data[9] = '\0'; /* set end of string */
796  if (lstrcmpiW(data, wYES)==0 || lstrcmpiW(data, wTRUE)==0)
797  ret = TRUE;
798  else if (lstrcmpiW(data, wNO)==0 || lstrcmpiW(data, wFALSE)==0)
799  ret = FALSE;
800  break;
801  case REG_DWORD:
802  work = *(LPDWORD)data;
803  ret = (work != 0);
804  break;
805  case REG_BINARY:
806  if (datalen == 1) {
807  ret = (data[0] != '\0');
808  break;
809  }
810  default:
811  FIXME("Unsupported registry data type %d\n", type);
812  ret = FALSE;
813  }
814  TRACE("got value (type=%d), returning <%s>\n", type,
815  (ret) ? "TRUE" : "FALSE");
816  }
817  else {
818  ret = fDefault;
819  TRACE("returning default data <%s>\n",
820  (ret) ? "TRUE" : "FALSE");
821  }
822  return ret;
823 }
824 
825 /*************************************************************************
826  * SHRegQueryInfoUSKeyA [SHLWAPI.@]
827  *
828  * Get information about a user-specific registry key.
829  *
830  * RETURNS
831  * Success: ERROR_SUCCESS
832  * Failure: An error code from RegQueryInfoKeyA().
833  */
835  HUSKEY hUSKey, /* [I] Key to query */
836  LPDWORD pcSubKeys, /* [O] Destination for number of sub keys */
837  LPDWORD pcchMaxSubKeyLen, /* [O] Destination for the length of the biggest sub key name */
838  LPDWORD pcValues, /* [O] Destination for number of values */
839  LPDWORD pcchMaxValueNameLen,/* [O] Destination for the length of the biggest value */
840  SHREGENUM_FLAGS enumRegFlags) /* [in] SHREGENUM_ flags from "shlwapi.h" */
841 {
842  HKEY dokey;
843  LONG ret;
844 
845  TRACE("(%p,%p,%p,%p,%p,%d)\n",
846  hUSKey,pcSubKeys,pcchMaxSubKeyLen,pcValues,
847  pcchMaxValueNameLen,enumRegFlags);
848 
849  /* if user wants HKCU, and it exists, then try it */
850  if (((enumRegFlags == SHREGENUM_HKCU) ||
851  (enumRegFlags == SHREGENUM_DEFAULT)) &&
852  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
853  ret = RegQueryInfoKeyA(dokey, 0, 0, 0,
854  pcSubKeys, pcchMaxSubKeyLen, 0,
855  pcValues, pcchMaxValueNameLen, 0, 0, 0);
856  if ((ret == ERROR_SUCCESS) ||
857  (enumRegFlags == SHREGENUM_HKCU))
858  return ret;
859  }
860  if (((enumRegFlags == SHREGENUM_HKLM) ||
861  (enumRegFlags == SHREGENUM_DEFAULT)) &&
862  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
863  return RegQueryInfoKeyA(dokey, 0, 0, 0,
864  pcSubKeys, pcchMaxSubKeyLen, 0,
865  pcValues, pcchMaxValueNameLen, 0, 0, 0);
866  }
867  return ERROR_INVALID_FUNCTION;
868 }
869 
870 /*************************************************************************
871  * SHRegQueryInfoUSKeyW [SHLWAPI.@]
872  *
873  * See SHRegQueryInfoUSKeyA.
874  */
876  HUSKEY hUSKey,
877  LPDWORD pcSubKeys,
878  LPDWORD pcchMaxSubKeyLen,
879  LPDWORD pcValues,
880  LPDWORD pcchMaxValueNameLen,
881  SHREGENUM_FLAGS enumRegFlags)
882 {
883  HKEY dokey;
884  LONG ret;
885 
886  TRACE("(%p,%p,%p,%p,%p,%d)\n",
887  hUSKey,pcSubKeys,pcchMaxSubKeyLen,pcValues,
888  pcchMaxValueNameLen,enumRegFlags);
889 
890  /* if user wants HKCU, and it exists, then try it */
891  if (((enumRegFlags == SHREGENUM_HKCU) ||
892  (enumRegFlags == SHREGENUM_DEFAULT)) &&
893  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
894  ret = RegQueryInfoKeyW(dokey, 0, 0, 0,
895  pcSubKeys, pcchMaxSubKeyLen, 0,
896  pcValues, pcchMaxValueNameLen, 0, 0, 0);
897  if ((ret == ERROR_SUCCESS) ||
898  (enumRegFlags == SHREGENUM_HKCU))
899  return ret;
900  }
901  if (((enumRegFlags == SHREGENUM_HKLM) ||
902  (enumRegFlags == SHREGENUM_DEFAULT)) &&
903  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
904  return RegQueryInfoKeyW(dokey, 0, 0, 0,
905  pcSubKeys, pcchMaxSubKeyLen, 0,
906  pcValues, pcchMaxValueNameLen, 0, 0, 0);
907  }
908  return ERROR_INVALID_FUNCTION;
909 }
910 
911 /*************************************************************************
912  * SHRegEnumUSKeyA [SHLWAPI.@]
913  *
914  * Enumerate a user-specific registry key.
915  *
916  * RETURNS
917  * Success: ERROR_SUCCESS
918  * Failure: An error code from RegEnumKeyExA().
919  */
921  HUSKEY hUSKey, /* [in] Key to enumerate */
922  DWORD dwIndex, /* [in] Index within hUSKey */
923  LPSTR pszName, /* [out] Name of the enumerated value */
924  LPDWORD pcchValueNameLen, /* [in/out] Length of pszName */
925  SHREGENUM_FLAGS enumRegFlags) /* [in] SHREGENUM_ flags from "shlwapi.h" */
926 {
927  HKEY dokey;
928 
929  TRACE("(%p,%d,%p,%p(%d),%d)\n",
930  hUSKey, dwIndex, pszName, pcchValueNameLen,
931  *pcchValueNameLen, enumRegFlags);
932 
933  if (((enumRegFlags == SHREGENUM_HKCU) ||
934  (enumRegFlags == SHREGENUM_DEFAULT)) &&
935  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
936  return RegEnumKeyExA(dokey, dwIndex, pszName, pcchValueNameLen,
937  0, 0, 0, 0);
938  }
939 
940  if (((enumRegFlags == SHREGENUM_HKLM) ||
941  (enumRegFlags == SHREGENUM_DEFAULT)) &&
942  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
943  return RegEnumKeyExA(dokey, dwIndex, pszName, pcchValueNameLen,
944  0, 0, 0, 0);
945  }
946  FIXME("no support for SHREGENUM_BOTH\n");
947  return ERROR_INVALID_FUNCTION;
948 }
949 
950 /*************************************************************************
951  * SHRegEnumUSKeyW [SHLWAPI.@]
952  *
953  * See SHRegEnumUSKeyA.
954  */
956  HUSKEY hUSKey,
957  DWORD dwIndex,
958  LPWSTR pszName,
959  LPDWORD pcchValueNameLen,
960  SHREGENUM_FLAGS enumRegFlags)
961 {
962  HKEY dokey;
963 
964  TRACE("(%p,%d,%p,%p(%d),%d)\n",
965  hUSKey, dwIndex, pszName, pcchValueNameLen,
966  *pcchValueNameLen, enumRegFlags);
967 
968  if (((enumRegFlags == SHREGENUM_HKCU) ||
969  (enumRegFlags == SHREGENUM_DEFAULT)) &&
970  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
971  return RegEnumKeyExW(dokey, dwIndex, pszName, pcchValueNameLen,
972  0, 0, 0, 0);
973  }
974 
975  if (((enumRegFlags == SHREGENUM_HKLM) ||
976  (enumRegFlags == SHREGENUM_DEFAULT)) &&
977  (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
978  return RegEnumKeyExW(dokey, dwIndex, pszName, pcchValueNameLen,
979  0, 0, 0, 0);
980  }
981  FIXME("no support for SHREGENUM_BOTH\n");
982  return ERROR_INVALID_FUNCTION;
983 }
984 
985 
986 /*************************************************************************
987  * SHRegWriteUSValueA [SHLWAPI.@]
988  *
989  * Write a user-specific registry value.
990  *
991  * PARAMS
992  * hUSKey [I] Key to write the value to
993  * pszValue [I] Name of value under hUSKey to write the value as
994  * dwType [I] Type of the value
995  * pvData [I] Data to set as the value
996  * cbData [I] length of pvData
997  * dwFlags [I] SHREGSET_ flags from "shlwapi.h"
998  *
999  * RETURNS
1000  * Success: ERROR_SUCCESS.
1001  * Failure: ERROR_INVALID_PARAMETER, if any parameter is invalid, otherwise
1002  * an error code from RegSetValueExA().
1003  *
1004  * NOTES
1005  * dwFlags must have at least SHREGSET_FORCE_HKCU or SHREGSET_FORCE_HKLM set.
1006  */
1008  LPVOID pvData, DWORD cbData, DWORD dwFlags)
1009 {
1010  WCHAR szValue[MAX_PATH];
1011 
1012  if (pszValue)
1013  MultiByteToWideChar(CP_ACP, 0, pszValue, -1, szValue, MAX_PATH);
1014 
1015  return SHRegWriteUSValueW(hUSKey, pszValue ? szValue : NULL, dwType,
1016  pvData, cbData, dwFlags);
1017 }
1018 
1019 /*************************************************************************
1020  * SHRegWriteUSValueW [SHLWAPI.@]
1021  *
1022  * See SHRegWriteUSValueA.
1023  */
1025  LPVOID pvData, DWORD cbData, DWORD dwFlags)
1026 {
1027  DWORD dummy;
1028  LPSHUSKEY hKey = hUSKey;
1030 
1031  TRACE("(%p,%s,%d,%p,%d,%d)\n", hUSKey, debugstr_w(pszValue),
1032  dwType, pvData, cbData, dwFlags);
1033 
1034  if (!hUSKey || IsBadWritePtr(hUSKey, sizeof(SHUSKEY)) ||
1036  return ERROR_INVALID_PARAMETER;
1037 
1039  {
1040  if (!hKey->HKCUkey)
1041  {
1042  /* Create the key */
1043  ret = RegCreateKeyW(hKey->HKCUstart, hKey->lpszPath, &hKey->HKCUkey);
1044  TRACE("Creating HKCU key, ret = %d\n", ret);
1045  if (ret && (dwFlags & (SHREGSET_FORCE_HKCU)))
1046  {
1047  hKey->HKCUkey = 0;
1048  return ret;
1049  }
1050  }
1051 
1052  if (!ret)
1053  {
1054  if ((dwFlags & SHREGSET_FORCE_HKCU) ||
1055  RegQueryValueExW(hKey->HKCUkey, pszValue, NULL, NULL, NULL, &dummy))
1056  {
1057  /* Doesn't exist or we are forcing: Write value */
1058  ret = RegSetValueExW(hKey->HKCUkey, pszValue, 0, dwType, pvData, cbData);
1059  TRACE("Writing HKCU value, ret = %d\n", ret);
1060  }
1061  }
1062  }
1063 
1065  {
1066  if (!hKey->HKLMkey)
1067  {
1068  /* Create the key */
1069  ret = RegCreateKeyW(hKey->HKLMstart, hKey->lpszPath, &hKey->HKLMkey);
1070  TRACE("Creating HKLM key, ret = %d\n", ret);
1071  if (ret && (dwFlags & (SHREGSET_FORCE_HKLM)))
1072  {
1073  hKey->HKLMkey = 0;
1074  return ret;
1075  }
1076  }
1077 
1078  if (!ret)
1079  {
1080  if ((dwFlags & SHREGSET_FORCE_HKLM) ||
1081  RegQueryValueExW(hKey->HKLMkey, pszValue, NULL, NULL, NULL, &dummy))
1082  {
1083  /* Doesn't exist or we are forcing: Write value */
1084  ret = RegSetValueExW(hKey->HKLMkey, pszValue, 0, dwType, pvData, cbData);
1085  TRACE("Writing HKLM value, ret = %d\n", ret);
1086  }
1087  }
1088  }
1089 
1090  return ret;
1091 }
1092 
1093 /*************************************************************************
1094  * SHRegGetPathA [SHLWAPI.@]
1095  *
1096  * Get a path from the registry.
1097  *
1098  * PARAMS
1099  * hKey [I] Handle to registry key
1100  * lpszSubKey [I] Name of sub key containing path to get
1101  * lpszValue [I] Name of value containing path to get
1102  * lpszPath [O] Buffer for returned path
1103  * dwFlags [I] Reserved
1104  *
1105  * RETURNS
1106  * Success: ERROR_SUCCESS. lpszPath contains the path.
1107  * Failure: An error code from RegOpenKeyExA() or SHQueryValueExA().
1108  */
1109 DWORD WINAPI SHRegGetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
1110  LPSTR lpszPath, DWORD dwFlags)
1111 {
1112  DWORD dwSize = MAX_PATH;
1113 
1114  TRACE("(hkey=%p,%s,%s,%p,%d)\n", hKey, debugstr_a(lpszSubKey),
1115  debugstr_a(lpszValue), lpszPath, dwFlags);
1116 
1117  return SHGetValueA(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize);
1118 }
1119 
1120 /*************************************************************************
1121  * SHRegGetPathW [SHLWAPI.@]
1122  *
1123  * See SHRegGetPathA.
1124  */
1125 DWORD WINAPI SHRegGetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
1126  LPWSTR lpszPath, DWORD dwFlags)
1127 {
1128  DWORD dwSize = MAX_PATH;
1129 
1130  TRACE("(hkey=%p,%s,%s,%p,%d)\n", hKey, debugstr_w(lpszSubKey),
1131  debugstr_w(lpszValue), lpszPath, dwFlags);
1132 
1133  return SHGetValueW(hKey, lpszSubKey, lpszValue, 0, lpszPath, &dwSize);
1134 }
1135 
1136 
1137 /*************************************************************************
1138  * SHRegSetPathA [SHLWAPI.@]
1139  *
1140  * Write a path to the registry.
1141  *
1142  * PARAMS
1143  * hKey [I] Handle to registry key
1144  * lpszSubKey [I] Name of sub key containing path to set
1145  * lpszValue [I] Name of value containing path to set
1146  * lpszPath [O] Path to write
1147  * dwFlags [I] Reserved, must be 0.
1148  *
1149  * RETURNS
1150  * Success: ERROR_SUCCESS.
1151  * Failure: An error code from SHSetValueA().
1152  */
1153 DWORD WINAPI SHRegSetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
1154  LPCSTR lpszPath, DWORD dwFlags)
1155 {
1156  char szBuff[MAX_PATH];
1157 
1158  FIXME("(hkey=%p,%s,%s,%p,%d) - semi-stub\n",hKey, debugstr_a(lpszSubKey),
1159  debugstr_a(lpszValue), lpszPath, dwFlags);
1160 
1161  lstrcpyA(szBuff, lpszPath);
1162 
1163  /* FIXME: PathUnExpandEnvStringsA(szBuff); */
1164 
1165  return SHSetValueA(hKey,lpszSubKey, lpszValue, REG_SZ, szBuff,
1166  lstrlenA(szBuff));
1167 }
1168 
1169 /*************************************************************************
1170  * SHRegSetPathW [SHLWAPI.@]
1171  *
1172  * See SHRegSetPathA.
1173  */
1174 DWORD WINAPI SHRegSetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
1175  LPCWSTR lpszPath, DWORD dwFlags)
1176 {
1177  WCHAR szBuff[MAX_PATH];
1178 
1179  FIXME("(hkey=%p,%s,%s,%p,%d) - semi-stub\n",hKey, debugstr_w(lpszSubKey),
1180  debugstr_w(lpszValue), lpszPath, dwFlags);
1181 
1182  lstrcpyW(szBuff, lpszPath);
1183 
1184  /* FIXME: PathUnExpandEnvStringsW(szBuff); */
1185 
1186  return SHSetValueW(hKey,lpszSubKey, lpszValue, REG_SZ, szBuff,
1187  lstrlenW(szBuff));
1188 }
1189 
1190 /*************************************************************************
1191  * SHGetValueA [SHLWAPI.@]
1192  *
1193  * Get a value from the registry.
1194  *
1195  * PARAMS
1196  * hKey [I] Handle to registry key
1197  * lpszSubKey [I] Name of sub key containing value to get
1198  * lpszValue [I] Name of value to get
1199  * pwType [O] Pointer to the values type
1200  * pvData [O] Pointer to the values data
1201  * pcbData [O] Pointer to the values size
1202  *
1203  * RETURNS
1204  * Success: ERROR_SUCCESS. Output parameters contain the details read.
1205  * Failure: An error code from RegOpenKeyExA() or SHQueryValueExA().
1206  */
1207 DWORD WINAPI SHGetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
1208  LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
1209 {
1210  DWORD dwRet = 0;
1211  HKEY hSubKey = 0;
1212 
1213  TRACE("(hkey=%p,%s,%s,%p,%p,%p)\n", hKey, debugstr_a(lpszSubKey),
1214  debugstr_a(lpszValue), pwType, pvData, pcbData);
1215 
1216  /* lpszSubKey can be 0. In this case the value is taken from the
1217  * current key.
1218  */
1219  if(lpszSubKey)
1220  dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey);
1221 
1222  if (! dwRet)
1223  {
1224  /* SHQueryValueEx expands Environment strings */
1225  dwRet = SHQueryValueExA(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData);
1226  if (hSubKey) RegCloseKey(hSubKey);
1227  }
1228  return dwRet;
1229 }
1230 
1231 /*************************************************************************
1232  * SHGetValueW [SHLWAPI.@]
1233  *
1234  * See SHGetValueA.
1235  */
1236 DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
1237  LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
1238 {
1239  DWORD dwRet = 0;
1240  HKEY hSubKey = 0;
1241 
1242  TRACE("(hkey=%p,%s,%s,%p,%p,%p)\n", hKey, debugstr_w(lpszSubKey),
1243  debugstr_w(lpszValue), pwType, pvData, pcbData);
1244 
1245  if(lpszSubKey)
1246  dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey);
1247 
1248  if (! dwRet)
1249  {
1250  dwRet = SHQueryValueExW(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData);
1251  if (hSubKey) RegCloseKey(hSubKey);
1252  }
1253  return dwRet;
1254 }
1255 
1256 /*************************************************************************
1257  * SHSetValueA [SHLWAPI.@]
1258  *
1259  * Set a value in the registry.
1260  *
1261  * PARAMS
1262  * hKey [I] Handle to registry key
1263  * lpszSubKey [I] Name of sub key under hKey
1264  * lpszValue [I] Name of value to set
1265  * dwType [I] Type of the value
1266  * pvData [I] Data of the value
1267  * cbData [I] Size of the value
1268  *
1269  * RETURNS
1270  * Success: ERROR_SUCCESS. The value is set with the data given.
1271  * Failure: An error code from RegCreateKeyExA() or RegSetValueExA()
1272  *
1273  * NOTES
1274  * If lpszSubKey does not exist, it is created before the value is set. If
1275  * lpszSubKey is NULL or an empty string, then the value is added directly
1276  * to hKey instead.
1277  */
1278 DWORD WINAPI SHSetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
1279  DWORD dwType, LPCVOID pvData, DWORD cbData)
1280 {
1281  DWORD dwRet = ERROR_SUCCESS, dwDummy;
1282  HKEY hSubKey;
1283 
1284  TRACE("(hkey=%p,%s,%s,%d,%p,%d)\n", hKey, debugstr_a(lpszSubKey),
1285  debugstr_a(lpszValue), dwType, pvData, cbData);
1286 
1287  if (lpszSubKey && *lpszSubKey)
1288  dwRet = RegCreateKeyExA(hKey, lpszSubKey, 0, NULL,
1289  0, KEY_SET_VALUE, NULL, &hSubKey, &dwDummy);
1290  else
1291  hSubKey = hKey;
1292  if (!dwRet)
1293  {
1294  dwRet = RegSetValueExA(hSubKey, lpszValue, 0, dwType, pvData, cbData);
1295  if (hSubKey != hKey)
1296  RegCloseKey(hSubKey);
1297  }
1298  return dwRet;
1299 }
1300 
1301 /*************************************************************************
1302  * SHSetValueW [SHLWAPI.@]
1303  *
1304  * See SHSetValueA.
1305  */
1306 DWORD WINAPI SHSetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
1307  DWORD dwType, LPCVOID pvData, DWORD cbData)
1308 {
1309  DWORD dwRet = ERROR_SUCCESS, dwDummy;
1310  HKEY hSubKey;
1311 
1312  TRACE("(hkey=%p,%s,%s,%d,%p,%d)\n", hKey, debugstr_w(lpszSubKey),
1313  debugstr_w(lpszValue), dwType, pvData, cbData);
1314 
1315  if (lpszSubKey && *lpszSubKey)
1316  dwRet = RegCreateKeyExW(hKey, lpszSubKey, 0, NULL,
1317  0, KEY_SET_VALUE, NULL, &hSubKey, &dwDummy);
1318  else
1319  hSubKey = hKey;
1320  if (!dwRet)
1321  {
1322  dwRet = RegSetValueExW(hSubKey, lpszValue, 0, dwType, pvData, cbData);
1323  if (hSubKey != hKey)
1324  RegCloseKey(hSubKey);
1325  }
1326  return dwRet;
1327 }
1328 
1329 /*************************************************************************
1330  * SHQueryInfoKeyA [SHLWAPI.@]
1331  *
1332  * Get information about a registry key. See RegQueryInfoKeyA().
1333  *
1334  * RETURNS
1335  * The result of calling RegQueryInfoKeyA().
1336  */
1337 LONG WINAPI SHQueryInfoKeyA(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax,
1338  LPDWORD pwValues, LPDWORD pwValueMax)
1339 {
1340  TRACE("(hkey=%p,%p,%p,%p,%p)\n", hKey, pwSubKeys, pwSubKeyMax,
1341  pwValues, pwValueMax);
1342  return RegQueryInfoKeyA(hKey, NULL, NULL, NULL, pwSubKeys, pwSubKeyMax,
1343  NULL, pwValues, pwValueMax, NULL, NULL, NULL);
1344 }
1345 
1346 /*************************************************************************
1347  * SHQueryInfoKeyW [SHLWAPI.@]
1348  *
1349  * See SHQueryInfoKeyA.
1350  */
1351 LONG WINAPI SHQueryInfoKeyW(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax,
1352  LPDWORD pwValues, LPDWORD pwValueMax)
1353 {
1354  TRACE("(hkey=%p,%p,%p,%p,%p)\n", hKey, pwSubKeys, pwSubKeyMax,
1355  pwValues, pwValueMax);
1356  return RegQueryInfoKeyW(hKey, NULL, NULL, NULL, pwSubKeys, pwSubKeyMax,
1357  NULL, pwValues, pwValueMax, NULL, NULL, NULL);
1358 }
1359 
1360 /*************************************************************************
1361  * SHQueryValueExA [SHLWAPI.@]
1362  *
1363  * Get a value from the registry, expanding environment variable strings.
1364  *
1365  * PARAMS
1366  * hKey [I] Handle to registry key
1367  * lpszValue [I] Name of value to query
1368  * lpReserved [O] Reserved for future use; must be NULL
1369  * pwType [O] Optional pointer updated with the values type
1370  * pvData [O] Optional pointer updated with the values data
1371  * pcbData [O] Optional pointer updated with the values size
1372  *
1373  * RETURNS
1374  * Success: ERROR_SUCCESS. Any non NULL output parameters are updated with
1375  * information about the value.
1376  * Failure: ERROR_OUTOFMEMORY if memory allocation fails, or the type of the
1377  * data is REG_EXPAND_SZ and pcbData is NULL. Otherwise an error
1378  * code from RegQueryValueExA() or ExpandEnvironmentStringsA().
1379  *
1380  * NOTES
1381  * Either pwType, pvData or pcbData may be NULL if the caller doesn't want
1382  * the type, data or size information for the value.
1383  *
1384  * If the type of the data is REG_EXPAND_SZ, it is expanded to REG_SZ. The
1385  * value returned will be truncated if it is of type REG_SZ and bigger than
1386  * the buffer given to store it.
1387  *
1388  * REG_EXPAND_SZ:
1389  * case-1: the unexpanded string is smaller than the expanded one
1390  * subcase-1: the buffer is too small to hold the unexpanded string:
1391  * function fails and returns the size of the unexpanded string.
1392  *
1393  * subcase-2: buffer is too small to hold the expanded string:
1394  * the function return success (!!) and the result is truncated
1395  * *** This is clearly an error in the native implementation. ***
1396  *
1397  * case-2: the unexpanded string is bigger than the expanded one
1398  * The buffer must have enough space to hold the unexpanded
1399  * string even if the result is smaller.
1400  *
1401  */
1403  LPDWORD lpReserved, LPDWORD pwType,
1405 {
1406  DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen;
1407 
1408  TRACE("(hkey=%p,%s,%p,%p,%p,%p=%d)\n", hKey, debugstr_a(lpszValue),
1409  lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
1410 
1411  if (pcbData) dwUnExpDataLen = *pcbData;
1412 
1413  dwRet = RegQueryValueExA(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen);
1414 
1415  if (pcbData && (dwType == REG_EXPAND_SZ))
1416  {
1417  DWORD nBytesToAlloc;
1418 
1419  /* Expand type REG_EXPAND_SZ into REG_SZ */
1420  LPSTR szData;
1421 
1422  /* If the caller didn't supply a buffer or the buffer is too small we have
1423  * to allocate our own
1424  */
1425  if ((!pvData) || (dwRet == ERROR_MORE_DATA) )
1426  {
1427  char cNull = '\0';
1428  nBytesToAlloc = dwUnExpDataLen;
1429 
1430  szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
1431  RegQueryValueExA (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc);
1432  dwExpDataLen = ExpandEnvironmentStringsA(szData, &cNull, 1);
1433  dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
1434  LocalFree(szData);
1435  }
1436  else
1437  {
1438  nBytesToAlloc = (lstrlenA(pvData)+1) * sizeof (CHAR);
1439  szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
1441  dwExpDataLen = ExpandEnvironmentStringsA(szData, pvData, *pcbData / sizeof(CHAR));
1442  if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA;
1443  dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
1444  LocalFree(szData);
1445  }
1446  }
1447 
1448  /* Update the type and data size if the caller wanted them */
1449  if ( dwType == REG_EXPAND_SZ ) dwType = REG_SZ;
1450  if ( pwType ) *pwType = dwType;
1451  if ( pcbData ) *pcbData = dwUnExpDataLen;
1452  return dwRet;
1453 }
1454 
1455 
1456 /*************************************************************************
1457  * SHQueryValueExW [SHLWAPI.@]
1458  *
1459  * See SHQueryValueExA.
1460  */
1462  LPDWORD lpReserved, LPDWORD pwType,
1464 {
1465  DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen;
1466 
1467  TRACE("(hkey=%p,%s,%p,%p,%p,%p=%d)\n", hKey, debugstr_w(lpszValue),
1468  lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
1469 
1470  if (pcbData) dwUnExpDataLen = *pcbData;
1471 
1472  dwRet = RegQueryValueExW(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen);
1473  if (dwRet!=ERROR_SUCCESS && dwRet!=ERROR_MORE_DATA)
1474  return dwRet;
1475 
1476  if (pcbData && (dwType == REG_EXPAND_SZ))
1477  {
1478  DWORD nBytesToAlloc;
1479 
1480  /* Expand type REG_EXPAND_SZ into REG_SZ */
1481  LPWSTR szData;
1482 
1483  /* If the caller didn't supply a buffer or the buffer is too small we have
1484  * to allocate our own
1485  */
1486  if ((!pvData) || (dwRet == ERROR_MORE_DATA) )
1487  {
1488  WCHAR cNull = '\0';
1489  nBytesToAlloc = dwUnExpDataLen;
1490 
1491  szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
1492  RegQueryValueExW (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc);
1493  dwExpDataLen = ExpandEnvironmentStringsW(szData, &cNull, 1);
1494  dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
1495  LocalFree(szData);
1496  }
1497  else
1498  {
1499  nBytesToAlloc = (lstrlenW(pvData) + 1) * sizeof(WCHAR);
1500  szData = LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
1502  dwExpDataLen = ExpandEnvironmentStringsW(szData, pvData, *pcbData/sizeof(WCHAR) );
1503  if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA;
1504  dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
1505  LocalFree(szData);
1506  }
1507  }
1508 
1509  /* Update the type and data size if the caller wanted them */
1510  if ( dwType == REG_EXPAND_SZ ) dwType = REG_SZ;
1511  if ( pwType ) *pwType = dwType;
1512  if ( pcbData ) *pcbData = dwUnExpDataLen;
1513  return dwRet;
1514 }
1515 
1516 /*************************************************************************
1517  * SHDeleteKeyA [SHLWAPI.@]
1518  *
1519  * Delete a registry key and any sub keys/values present
1520  *
1521  * This function forwards to the unicode version directly, to avoid
1522  * handling subkeys that are not representable in ASCII.
1523  *
1524  * PARAMS
1525  * hKey [I] Handle to registry key
1526  * lpszSubKey [I] Name of sub key to delete
1527  *
1528  * RETURNS
1529  * Success: ERROR_SUCCESS. The key is deleted.
1530  * Failure: An error code from RegOpenKeyExA(), RegQueryInfoKeyA(),
1531  * RegEnumKeyExA() or RegDeleteKeyA().
1532  */
1534 {
1535  WCHAR subkeyW[MAX_PATH];
1536 
1537  MultiByteToWideChar (CP_ACP, 0, lpszSubKey, -1, subkeyW, sizeof(subkeyW)/sizeof(WCHAR));
1538  return SHDeleteKeyW(hKey, subkeyW);
1539 }
1540 
1541 /*************************************************************************
1542  * SHDeleteKeyW [SHLWAPI.@]
1543  *
1544  * See SHDeleteKeyA.
1545  */
1547 {
1548  DWORD dwRet, dwMaxSubkeyLen = 0, dwSize;
1549  WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
1550  HKEY hSubKey = 0;
1551 
1552  TRACE("(hkey=%p,%s)\n", hKey, debugstr_w(lpszSubKey));
1553 
1554  dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
1555  if(!dwRet)
1556  {
1557  /* Find the maximum subkey length so that we can allocate a buffer */
1558  dwRet = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
1559  &dwMaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
1560  if(!dwRet)
1561  {
1562  dwMaxSubkeyLen++;
1563  if (dwMaxSubkeyLen > sizeof(szNameBuf)/sizeof(WCHAR))
1564  /* Name too big: alloc a buffer for it */
1565  lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxSubkeyLen*sizeof(WCHAR));
1566 
1567  if(!lpszName)
1568  dwRet = ERROR_NOT_ENOUGH_MEMORY;
1569  else
1570  {
1571  while (dwRet == ERROR_SUCCESS)
1572  {
1573  dwSize = dwMaxSubkeyLen;
1574  dwRet = RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL, NULL, NULL, NULL);
1575  if (dwRet == ERROR_SUCCESS || dwRet == ERROR_MORE_DATA)
1576  dwRet = SHDeleteKeyW(hSubKey, lpszName);
1577  }
1578  if (dwRet == ERROR_NO_MORE_ITEMS)
1579  dwRet = ERROR_SUCCESS;
1580 
1581  if (lpszName != szNameBuf)
1582  HeapFree(GetProcessHeap(), 0, lpszName); /* Free buffer if allocated */
1583  }
1584  }
1585 
1586  RegCloseKey(hSubKey);
1587  if(!dwRet)
1588  dwRet = RegDeleteKeyW(hKey, lpszSubKey);
1589  }
1590  return dwRet;
1591 }
1592 
1593 /*************************************************************************
1594  * SHDeleteEmptyKeyA [SHLWAPI.@]
1595  *
1596  * Delete a registry key with no sub keys.
1597  *
1598  * PARAMS
1599  * hKey [I] Handle to registry key
1600  * lpszSubKey [I] Name of sub key to delete
1601  *
1602  * RETURNS
1603  * Success: ERROR_SUCCESS. The key is deleted.
1604  * Failure: If the key is not empty, returns ERROR_KEY_HAS_CHILDREN. Otherwise
1605  * returns an error code from RegOpenKeyExA(), RegQueryInfoKeyA() or
1606  * RegDeleteKeyA().
1607  */
1609 {
1610  DWORD dwRet, dwKeyCount = 0;
1611  HKEY hSubKey = 0;
1612 
1613  TRACE("(hkey=%p,%s)\n", hKey, debugstr_a(lpszSubKey));
1614 
1615  dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
1616  if(!dwRet)
1617  {
1618  dwRet = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount,
1619  NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1620  RegCloseKey(hSubKey);
1621  if(!dwRet)
1622  {
1623  if (!dwKeyCount)
1624  dwRet = RegDeleteKeyA(hKey, lpszSubKey);
1625  else
1626  dwRet = ERROR_KEY_HAS_CHILDREN;
1627  }
1628  }
1629  return dwRet;
1630 }
1631 
1632 /*************************************************************************
1633  * SHDeleteEmptyKeyW [SHLWAPI.@]
1634  *
1635  * See SHDeleteEmptyKeyA.
1636  */
1638 {
1639  DWORD dwRet, dwKeyCount = 0;
1640  HKEY hSubKey = 0;
1641 
1642  TRACE("(hkey=%p, %s)\n", hKey, debugstr_w(lpszSubKey));
1643 
1644  dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
1645  if(!dwRet)
1646  {
1647  dwRet = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwKeyCount,
1648  NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1649  RegCloseKey(hSubKey);
1650  if(!dwRet)
1651  {
1652  if (!dwKeyCount)
1653  dwRet = RegDeleteKeyW(hKey, lpszSubKey);
1654  else
1655  dwRet = ERROR_KEY_HAS_CHILDREN;
1656  }
1657  }
1658  return dwRet;
1659 }
1660 
1661 /*************************************************************************
1662  * SHDeleteOrphanKeyA [SHLWAPI.@]
1663  *
1664  * Delete a registry key with no sub keys or values.
1665  *
1666  * PARAMS
1667  * hKey [I] Handle to registry key
1668  * lpszSubKey [I] Name of sub key to possibly delete
1669  *
1670  * RETURNS
1671  * Success: ERROR_SUCCESS. The key has been deleted if it was an orphan.
1672  * Failure: An error from RegOpenKeyExA(), RegQueryValueExA(), or RegDeleteKeyA().
1673  */
1675 {
1676  HKEY hSubKey;
1677  DWORD dwKeyCount = 0, dwValueCount = 0, dwRet;
1678 
1679  TRACE("(hkey=%p,%s)\n", hKey, debugstr_a(lpszSubKey));
1680 
1681  dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
1682 
1683  if(!dwRet)
1684  {
1685  /* Get subkey and value count */
1686  dwRet = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount,
1687  NULL, NULL, &dwValueCount, NULL, NULL, NULL, NULL);
1688 
1689  if(!dwRet && !dwKeyCount && !dwValueCount)
1690  {
1691  dwRet = RegDeleteKeyA(hKey, lpszSubKey);
1692  }
1693  RegCloseKey(hSubKey);
1694  }
1695  return dwRet;
1696 }
1697 
1698 /*************************************************************************
1699  * SHDeleteOrphanKeyW [SHLWAPI.@]
1700  *
1701  * See SHDeleteOrphanKeyA.
1702  */
1704 {
1705  HKEY hSubKey;
1706  DWORD dwKeyCount = 0, dwValueCount = 0, dwRet;
1707 
1708  TRACE("(hkey=%p,%s)\n", hKey, debugstr_w(lpszSubKey));
1709 
1710  dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
1711 
1712  if(!dwRet)
1713  {
1714  /* Get subkey and value count */
1715  dwRet = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwKeyCount,
1716  NULL, NULL, &dwValueCount, NULL, NULL, NULL, NULL);
1717 
1718  if(!dwRet && !dwKeyCount && !dwValueCount)
1719  {
1720  dwRet = RegDeleteKeyW(hKey, lpszSubKey);
1721  }
1722  RegCloseKey(hSubKey);
1723  }
1724  return dwRet;
1725 }
1726 
1727 /*************************************************************************
1728  * SHDeleteValueA [SHLWAPI.@]
1729  *
1730  * Delete a value from the registry.
1731  *
1732  * PARAMS
1733  * hKey [I] Handle to registry key
1734  * lpszSubKey [I] Name of sub key containing value to delete
1735  * lpszValue [I] Name of value to delete
1736  *
1737  * RETURNS
1738  * Success: ERROR_SUCCESS. The value is deleted.
1739  * Failure: An error code from RegOpenKeyExA() or RegDeleteValueA().
1740  */
1741 DWORD WINAPI SHDeleteValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue)
1742 {
1743  DWORD dwRet;
1744  HKEY hSubKey;
1745 
1746  TRACE("(hkey=%p,%s,%s)\n", hKey, debugstr_a(lpszSubKey), debugstr_a(lpszValue));
1747 
1748  dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_SET_VALUE, &hSubKey);
1749  if (!dwRet)
1750  {
1751  dwRet = RegDeleteValueA(hSubKey, lpszValue);
1752  RegCloseKey(hSubKey);
1753  }
1754  return dwRet;
1755 }
1756 
1757 /*************************************************************************
1758  * SHDeleteValueW [SHLWAPI.@]
1759  *
1760  * See SHDeleteValueA.
1761  */
1762 DWORD WINAPI SHDeleteValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue)
1763 {
1764  DWORD dwRet;
1765  HKEY hSubKey;
1766 
1767  TRACE("(hkey=%p,%s,%s)\n", hKey, debugstr_w(lpszSubKey), debugstr_w(lpszValue));
1768 
1769  dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_SET_VALUE, &hSubKey);
1770  if (!dwRet)
1771  {
1772  dwRet = RegDeleteValueW(hSubKey, lpszValue);
1773  RegCloseKey(hSubKey);
1774  }
1775  return dwRet;
1776 }
1777 
1778 /*************************************************************************
1779  * SHEnumKeyExA [SHLWAPI.@]
1780  *
1781  * Enumerate sub keys in a registry key.
1782  *
1783  * PARAMS
1784  * hKey [I] Handle to registry key
1785  * dwIndex [I] Index of key to enumerate
1786  * lpszSubKey [O] Pointer updated with the subkey name
1787  * pwLen [O] Pointer updated with the subkey length
1788  *
1789  * RETURNS
1790  * Success: ERROR_SUCCESS. lpszSubKey and pwLen are updated.
1791  * Failure: An error code from RegEnumKeyExA().
1792  */
1793 LONG WINAPI SHEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpszSubKey,
1794  LPDWORD pwLen)
1795 {
1796  TRACE("(hkey=%p,%d,%s,%p)\n", hKey, dwIndex, debugstr_a(lpszSubKey), pwLen);
1797 
1798  return RegEnumKeyExA(hKey, dwIndex, lpszSubKey, pwLen, NULL, NULL, NULL, NULL);
1799 }
1800 
1801 /*************************************************************************
1802  * SHEnumKeyExW [SHLWAPI.@]
1803  *
1804  * See SHEnumKeyExA.
1805  */
1806 LONG WINAPI SHEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpszSubKey,
1807  LPDWORD pwLen)
1808 {
1809  TRACE("(hkey=%p,%d,%s,%p)\n", hKey, dwIndex, debugstr_w(lpszSubKey), pwLen);
1810 
1811  return RegEnumKeyExW(hKey, dwIndex, lpszSubKey, pwLen, NULL, NULL, NULL, NULL);
1812 }
1813 
1814 /*************************************************************************
1815  * SHEnumValueA [SHLWAPI.@]
1816  *
1817  * Enumerate values in a registry key.
1818  *
1819  * PARAMS
1820  * hKey [I] Handle to registry key
1821  * dwIndex [I] Index of key to enumerate
1822  * lpszValue [O] Pointer updated with the values name
1823  * pwLen [O] Pointer updated with the values length
1824  * pwType [O] Pointer updated with the values type
1825  * pvData [O] Pointer updated with the values data
1826  * pcbData [O] Pointer updated with the values size
1827  *
1828  * RETURNS
1829  * Success: ERROR_SUCCESS. Output parameters are updated.
1830  * Failure: An error code from RegEnumValueA().
1831  */
1832 LONG WINAPI SHEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpszValue,
1833  LPDWORD pwLen, LPDWORD pwType,
1835 {
1836  TRACE("(hkey=%p,%d,%s,%p,%p,%p,%p)\n", hKey, dwIndex,
1837  debugstr_a(lpszValue), pwLen, pwType, pvData, pcbData);
1838 
1839  return RegEnumValueA(hKey, dwIndex, lpszValue, pwLen, NULL,
1840  pwType, pvData, pcbData);
1841 }
1842 
1843 /*************************************************************************
1844  * SHEnumValueW [SHLWAPI.@]
1845  *
1846  * See SHEnumValueA.
1847  */
1848 LONG WINAPI SHEnumValueW(HKEY hKey, DWORD dwIndex, LPWSTR lpszValue,
1849  LPDWORD pwLen, LPDWORD pwType,
1851 {
1852  TRACE("(hkey=%p,%d,%s,%p,%p,%p,%p)\n", hKey, dwIndex,
1853  debugstr_w(lpszValue), pwLen, pwType, pvData, pcbData);
1854 
1855  return RegEnumValueW(hKey, dwIndex, lpszValue, pwLen, NULL,
1856  pwType, pvData, pcbData);
1857 }
1858 
1859 /*************************************************************************
1860  * @ [SHLWAPI.205]
1861  *
1862  * Get a value from the registry.
1863  *
1864  * PARAMS
1865  * hKey [I] Handle to registry key
1866  * pSubKey [I] Name of sub key containing value to get
1867  * pValue [I] Name of value to get
1868  * pwType [O] Destination for the values type
1869  * pvData [O] Destination for the values data
1870  * pbData [O] Destination for the values size
1871  *
1872  * RETURNS
1873  * Success: ERROR_SUCCESS. Output parameters contain the details read.
1874  * Failure: An error code from RegOpenKeyExA() or SHQueryValueExA(),
1875  * or ERROR_INVALID_FUNCTION in the machine is in safe mode.
1876  */
1878  LPDWORD pwType, LPVOID pvData, LPDWORD pbData)
1879 {
1881  return ERROR_INVALID_FUNCTION;
1882  return SHGetValueA(hkey, pSubKey, pValue, pwType, pvData, pbData);
1883 }
1884 
1885 /*************************************************************************
1886  * @ [SHLWAPI.206]
1887  *
1888  * Unicode version of SHGetValueGoodBootW.
1889  */
1891  LPDWORD pwType, LPVOID pvData, LPDWORD pbData)
1892 {
1894  return ERROR_INVALID_FUNCTION;
1895  return SHGetValueW(hkey, pSubKey, pValue, pwType, pvData, pbData);
1896 }
1897 
1898 /*************************************************************************
1899  * @ [SHLWAPI.320]
1900  *
1901  * Set a MIME content type in the registry.
1902  *
1903  * PARAMS
1904  * lpszSubKey [I] Name of key under HKEY_CLASSES_ROOT.
1905  * lpszValue [I] Value to set
1906  *
1907  * RETURNS
1908  * Success: TRUE
1909  * Failure: FALSE
1910  */
1912 {
1913  if (!lpszValue)
1914  {
1915  WARN("Invalid lpszValue would crash under Win32!\n");
1916  return FALSE;
1917  }
1918 
1919  return !SHSetValueA(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeA,
1920  REG_SZ, lpszValue, strlen(lpszValue));
1921 }
1922 
1923 /*************************************************************************
1924  * @ [SHLWAPI.321]
1925  *
1926  * Unicode version of RegisterMIMETypeForExtensionA.
1927  */
1929 {
1930  if (!lpszValue)
1931  {
1932  WARN("Invalid lpszValue would crash under Win32!\n");
1933  return FALSE;
1934  }
1935 
1936  return !SHSetValueW(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeW,
1937  REG_SZ, lpszValue, strlenW(lpszValue));
1938 }
1939 
1940 /*************************************************************************
1941  * @ [SHLWAPI.322]
1942  *
1943  * Delete a MIME content type from the registry.
1944  *
1945  * PARAMS
1946  * lpszSubKey [I] Name of sub key
1947  *
1948  * RETURNS
1949  * Success: TRUE
1950  * Failure: FALSE
1951  */
1953 {
1954  return !SHDeleteValueA(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeA);
1955 }
1956 
1957 /*************************************************************************
1958  * @ [SHLWAPI.323]
1959  *
1960  * Unicode version of UnregisterMIMETypeForExtensionA.
1961  */
1963 {
1964  return !SHDeleteValueW(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeW);
1965 }
1966 
1967 /*************************************************************************
1968  * @ [SHLWAPI.328]
1969  *
1970  * Get the registry path to a MIME content key.
1971  *
1972  * PARAMS
1973  * lpszType [I] Content type to get the path for
1974  * lpszBuffer [O] Destination for path
1975  * dwLen [I] Length of lpszBuffer
1976  *
1977  * RETURNS
1978  * Success: TRUE. lpszBuffer contains the full path.
1979  * Failure: FALSE.
1980  *
1981  * NOTES
1982  * The base path for the key is "MIME\Database\Content Type\"
1983  */
1984 BOOL WINAPI GetMIMETypeSubKeyA(LPCSTR lpszType, LPSTR lpszBuffer, DWORD dwLen)
1985 {
1986  TRACE("(%s,%p,%d)\n", debugstr_a(lpszType), lpszBuffer, dwLen);
1987 
1988  if (dwLen > dwLenMimeDbContent && lpszType && lpszBuffer)
1989  {
1990  size_t dwStrLen = strlen(lpszType);
1991 
1992  if (dwStrLen < dwLen - dwLenMimeDbContent)
1993  {
1995  memcpy(lpszBuffer + dwLenMimeDbContent, lpszType, dwStrLen + 1);
1996  return TRUE;
1997  }
1998  }
1999  return FALSE;
2000 }
2001 
2002 /*************************************************************************
2003  * @ [SHLWAPI.329]
2004  *
2005  * Unicode version of GetMIMETypeSubKeyA.
2006  */
2007 BOOL WINAPI GetMIMETypeSubKeyW(LPCWSTR lpszType, LPWSTR lpszBuffer, DWORD dwLen)
2008 {
2009  TRACE("(%s,%p,%d)\n", debugstr_w(lpszType), lpszBuffer, dwLen);
2010 
2011  if (dwLen > dwLenMimeDbContent && lpszType && lpszBuffer)
2012  {
2013  DWORD dwStrLen = strlenW(lpszType);
2014 
2015  if (dwStrLen < dwLen - dwLenMimeDbContent)
2016  {
2017  memcpy(lpszBuffer, szMimeDbContentW, dwLenMimeDbContent * sizeof(WCHAR));
2018  memcpy(lpszBuffer + dwLenMimeDbContent, lpszType, (dwStrLen + 1) * sizeof(WCHAR));
2019  return TRUE;
2020  }
2021  }
2022  return FALSE;
2023 }
2024 
2025 /*************************************************************************
2026  * @ [SHLWAPI.330]
2027  *
2028  * Get the file extension for a given Mime type.
2029  *
2030  * PARAMS
2031  * lpszType [I] Mime type to get the file extension for
2032  * lpExt [O] Destination for the resulting extension
2033  * iLen [I] Length of lpExt in characters
2034  *
2035  * RETURNS
2036  * Success: TRUE. lpExt contains the file extension.
2037  * Failure: FALSE, if any parameter is invalid or the extension cannot be
2038  * retrieved. If iLen > 0, lpExt is set to an empty string.
2039  *
2040  * NOTES
2041  * - The extension returned in lpExt always has a leading '.' character, even
2042  * if the registry Mime database entry does not.
2043  * - iLen must be long enough for the file extension for this function to succeed.
2044  */
2046 {
2047  char szSubKey[MAX_PATH];
2048  DWORD dwlen = iLen - 1, dwType;
2049  BOOL bRet = FALSE;
2050 
2051  if (iLen > 0 && lpExt)
2052  *lpExt = '\0';
2053 
2054  if (lpszType && lpExt && iLen > 2 &&
2055  GetMIMETypeSubKeyA(lpszType, szSubKey, MAX_PATH) &&
2056  !SHGetValueA(HKEY_CLASSES_ROOT, szSubKey, szExtensionA, &dwType, lpExt + 1, &dwlen) &&
2057  lpExt[1])
2058  {
2059  if (lpExt[1] == '.')
2060  memmove(lpExt, lpExt + 1, strlen(lpExt + 1) + 1);
2061  else
2062  *lpExt = '.'; /* Supply a '.' */
2063  bRet = TRUE;
2064  }
2065  return bRet;
2066 }
2067 
2068 /*************************************************************************
2069  * @ [SHLWAPI.331]
2070  *
2071  * Unicode version of MIME_GetExtensionA.
2072  */
2074 {
2075  WCHAR szSubKey[MAX_PATH];
2076  DWORD dwlen = iLen - 1, dwType;
2077  BOOL bRet = FALSE;
2078 
2079  if (iLen > 0 && lpExt)
2080  *lpExt = '\0';
2081 
2082  if (lpszType && lpExt && iLen > 2 &&
2083  GetMIMETypeSubKeyW(lpszType, szSubKey, MAX_PATH) &&
2084  !SHGetValueW(HKEY_CLASSES_ROOT, szSubKey, szExtensionW, &dwType, lpExt + 1, &dwlen) &&
2085  lpExt[1])
2086  {
2087  if (lpExt[1] == '.')
2088  memmove(lpExt, lpExt + 1, (strlenW(lpExt + 1) + 1) * sizeof(WCHAR));
2089  else
2090  *lpExt = '.'; /* Supply a '.' */
2091  bRet = TRUE;
2092  }
2093  return bRet;
2094 }
2095 
2096 /*************************************************************************
2097  * @ [SHLWAPI.324]
2098  *
2099  * Set the file extension for a MIME content key.
2100  *
2101  * PARAMS
2102  * lpszExt [I] File extension to set
2103  * lpszType [I] Content type to set the extension for
2104  *
2105  * RETURNS
2106  * Success: TRUE. The file extension is set in the registry.
2107  * Failure: FALSE.
2108  */
2110 {
2111  DWORD dwLen;
2112  char szKey[MAX_PATH];
2113 
2114  TRACE("(%s,%s)\n", debugstr_a(lpszExt), debugstr_a(lpszType));
2115 
2116  if (!GetMIMETypeSubKeyA(lpszType, szKey, MAX_PATH)) /* Get full path to the key */
2117  return FALSE;
2118 
2119  dwLen = strlen(lpszExt) + 1;
2120 
2121  if (SHSetValueA(HKEY_CLASSES_ROOT, szKey, szExtensionA, REG_SZ, lpszExt, dwLen))
2122  return FALSE;
2123  return TRUE;
2124 }
2125 
2126 /*************************************************************************
2127  * @ [SHLWAPI.325]
2128  *
2129  * Unicode version of RegisterExtensionForMIMETypeA.
2130  */
2132 {
2133  DWORD dwLen;
2134  WCHAR szKey[MAX_PATH];
2135 
2136  TRACE("(%s,%s)\n", debugstr_w(lpszExt), debugstr_w(lpszType));
2137 
2138  /* Get the full path to the key */
2139  if (!GetMIMETypeSubKeyW(lpszType, szKey, MAX_PATH)) /* Get full path to the key */
2140  return FALSE;
2141 
2142  dwLen = (lstrlenW(lpszExt) + 1) * sizeof(WCHAR);
2143 
2144  if (SHSetValueW(HKEY_CLASSES_ROOT, szKey, szExtensionW, REG_SZ, lpszExt, dwLen))
2145  return FALSE;
2146  return TRUE;
2147 }
2148 
2149 /*************************************************************************
2150  * @ [SHLWAPI.326]
2151  *
2152  * Delete a file extension from a MIME content type.
2153  *
2154  * PARAMS
2155  * lpszType [I] Content type to delete the extension for
2156  *
2157  * RETURNS
2158  * Success: TRUE. The file extension is deleted from the registry.
2159  * Failure: FALSE. The extension may have been removed but the key remains.
2160  *
2161  * NOTES
2162  * If deleting the extension leaves an orphan key, the key is removed also.
2163  */
2165 {
2166  char szKey[MAX_PATH];
2167 
2168  TRACE("(%s)\n", debugstr_a(lpszType));
2169 
2170  if (!GetMIMETypeSubKeyA(lpszType, szKey, MAX_PATH)) /* Get full path to the key */
2171  return FALSE;
2172 
2174  return FALSE;
2175 
2177  return FALSE;
2178  return TRUE;
2179 }
2180 
2181 /*************************************************************************
2182  * @ [SHLWAPI.327]
2183  *
2184  * Unicode version of UnregisterExtensionForMIMETypeA.
2185  */
2187 {
2188  WCHAR szKey[MAX_PATH];
2189 
2190  TRACE("(%s)\n", debugstr_w(lpszType));
2191 
2192  if (!GetMIMETypeSubKeyW(lpszType, szKey, MAX_PATH)) /* Get full path to the key */
2193  return FALSE;
2194 
2196  return FALSE;
2197 
2199  return FALSE;
2200  return TRUE;
2201 }
2202 
2203 /*************************************************************************
2204  * SHRegDuplicateHKey [SHLWAPI.@]
2205  *
2206  * Create a duplicate of a registry handle.
2207  *
2208  * PARAMS
2209  * hKey [I] key to duplicate.
2210  *
2211  * RETURNS
2212  * A new handle pointing to the same key as hKey.
2213  */
2215 {
2216  HKEY newKey = 0;
2217 
2218  RegOpenKeyExA(hKey, 0, 0, MAXIMUM_ALLOWED, &newKey);
2219  TRACE("new key is %p\n", newKey);
2220  return newKey;
2221 }
2222 
2223 
2224 /*************************************************************************
2225  * SHCopyKeyA [SHLWAPI.@]
2226  *
2227  * Copy a key and its values/sub keys to another location.
2228  *
2229  * PARAMS
2230  * hKeySrc [I] Source key to copy from
2231  * lpszSrcSubKey [I] Sub key under hKeySrc, or NULL to use hKeySrc directly
2232  * hKeyDst [I] Destination key
2233  * dwReserved [I] Reserved, must be 0
2234  *
2235  * RETURNS
2236  * Success: ERROR_SUCCESS. The key is copied to the destination key.
2237  * Failure: A standard windows error code.
2238  *
2239  * NOTES
2240  * If hKeyDst is a key under hKeySrc, this function will misbehave
2241  * (It will loop until out of stack, or the registry is full). This
2242  * bug is present in Win32 also.
2243  */
2244 DWORD WINAPI SHCopyKeyA(HKEY hKeySrc, LPCSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved)
2245 {
2246  WCHAR szSubKeyW[MAX_PATH];
2247 
2248  TRACE("(hkey=%p,%s,%p08x,%d)\n", hKeySrc, debugstr_a(lpszSrcSubKey), hKeyDst, dwReserved);
2249 
2250  if (lpszSrcSubKey)
2251  MultiByteToWideChar(CP_ACP, 0, lpszSrcSubKey, -1, szSubKeyW, MAX_PATH);
2252 
2253  return SHCopyKeyW(hKeySrc, lpszSrcSubKey ? szSubKeyW : NULL, hKeyDst, dwReserved);
2254 }
2255 
2256 /*************************************************************************
2257  * SHCopyKeyW [SHLWAPI.@]
2258  *
2259  * See SHCopyKeyA.
2260  */
2261 DWORD WINAPI SHCopyKeyW(HKEY hKeySrc, LPCWSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved)
2262 {
2263  DWORD dwKeyCount = 0, dwValueCount = 0, dwMaxKeyLen = 0;
2264  DWORD dwMaxValueLen = 0, dwMaxDataLen = 0, i;
2265  BYTE buff[1024];
2266  LPVOID lpBuff = buff;
2267  WCHAR szName[MAX_PATH], *lpszName = szName;
2268  DWORD dwRet = S_OK;
2269 
2270  TRACE("hkey=%p,%s,%p08x,%d)\n", hKeySrc, debugstr_w(lpszSrcSubKey), hKeyDst, dwReserved);
2271 
2272  if(!hKeyDst || !hKeySrc)
2273  dwRet = ERROR_INVALID_PARAMETER;
2274  else
2275  {
2276  /* Open source key */
2277  if(lpszSrcSubKey)
2278  dwRet = RegOpenKeyExW(hKeySrc, lpszSrcSubKey, 0, KEY_ALL_ACCESS, &hKeySrc);
2279 
2280  if(dwRet)
2281  hKeyDst = NULL; /* Don't close this key since we didn't open it */
2282  else
2283  {
2284  /* Get details about sub keys and values */
2285  dwRet = RegQueryInfoKeyW(hKeySrc, NULL, NULL, NULL, &dwKeyCount, &dwMaxKeyLen,
2286  NULL, &dwValueCount, &dwMaxValueLen, &dwMaxDataLen,
2287  NULL, NULL);
2288  if(!dwRet)
2289  {
2290  if (dwMaxValueLen > dwMaxKeyLen)
2291  dwMaxKeyLen = dwMaxValueLen; /* Get max size for key/value names */
2292 
2293  if (dwMaxKeyLen++ > MAX_PATH - 1)
2294  lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxKeyLen * sizeof(WCHAR));
2295 
2296  if (dwMaxDataLen > sizeof(buff))
2297  lpBuff = HeapAlloc(GetProcessHeap(), 0, dwMaxDataLen);
2298 
2299  if (!lpszName || !lpBuff)
2300  dwRet = ERROR_NOT_ENOUGH_MEMORY;
2301  }
2302  }
2303  }
2304 
2305  /* Copy all the sub keys */
2306  for(i = 0; i < dwKeyCount && !dwRet; i++)
2307  {
2308  HKEY hSubKeySrc, hSubKeyDst;
2309  DWORD dwSize = dwMaxKeyLen;
2310 
2311  dwRet = RegEnumKeyExW(hKeySrc, i, lpszName, &dwSize, NULL, NULL, NULL, NULL);
2312 
2313  if(!dwRet)
2314  {
2315  /* Open source sub key */
2316  dwRet = RegOpenKeyExW(hKeySrc, lpszName, 0, KEY_READ, &hSubKeySrc);
2317 
2318  if(!dwRet)
2319  {
2320  /* Create destination sub key */
2321  dwRet = RegCreateKeyW(hKeyDst, lpszName, &hSubKeyDst);
2322 
2323  if(!dwRet)
2324  {
2325  /* Recursively copy keys and values from the sub key */
2326  dwRet = SHCopyKeyW(hSubKeySrc, NULL, hSubKeyDst, 0);
2327  RegCloseKey(hSubKeyDst);
2328  }
2329  }
2330  RegCloseKey(hSubKeySrc);
2331  }
2332  }
2333 
2334  /* Copy all the values in this key */
2335  for (i = 0; i < dwValueCount && !dwRet; i++)
2336  {
2337  DWORD dwNameSize = dwMaxKeyLen, dwType, dwLen = dwMaxDataLen;
2338 
2339  dwRet = RegEnumValueW(hKeySrc, i, lpszName, &dwNameSize, NULL, &dwType, lpBuff, &dwLen);
2340 
2341  if (!dwRet)
2342  dwRet = SHSetValueW(hKeyDst, NULL, lpszName, dwType, lpBuff, dwLen);
2343  }
2344 
2345  /* Free buffers if allocated */
2346  if (lpszName != szName)
2347  HeapFree(GetProcessHeap(), 0, lpszName);
2348  if (lpBuff != buff)
2349  HeapFree(GetProcessHeap(), 0, lpBuff);
2350 
2351  if (lpszSrcSubKey && hKeyDst)
2352  RegCloseKey(hKeyDst);
2353  return dwRet;
2354 }
2355 
2356 /*
2357  * The following functions are ORDINAL ONLY:
2358  */
2359 
2360 /*************************************************************************
2361  * @ [SHLWAPI.280]
2362  *
2363  * Read an integer value from the registry, falling back to a default.
2364  *
2365  * PARAMS
2366  * hKey [I] Registry key to read from
2367  * lpszValue [I] Value name to read
2368  * iDefault [I] Default value to return
2369  *
2370  * RETURNS
2371  * The value contained in the given registry value if present, otherwise
2372  * iDefault.
2373  */
2374 int WINAPI SHRegGetIntW(HKEY hKey, LPCWSTR lpszValue, int iDefault)
2375 {
2376  TRACE("(%p,%s,%d)\n", hKey, debugstr_w(lpszValue), iDefault);
2377 
2378  if (hKey)
2379  {
2380  WCHAR szBuff[32];
2381  DWORD dwSize = sizeof(szBuff);
2382  szBuff[0] = '\0';
2383  SHQueryValueExW(hKey, lpszValue, 0, 0, szBuff, &dwSize);
2384 
2385  if(*szBuff >= '0' && *szBuff <= '9')
2386  return StrToIntW(szBuff);
2387  }
2388  return iDefault;
2389 }
2390 
2391 /*************************************************************************
2392  * @ [SHLWAPI.343]
2393  *
2394  * Create or open an explorer ClassId Key.
2395  *
2396  * PARAMS
2397  * guid [I] Explorer ClassId key to open
2398  * lpszValue [I] Value name under the ClassId Key
2399  * bUseHKCU [I] TRUE=Use HKEY_CURRENT_USER, FALSE=Use HKEY_CLASSES_ROOT
2400  * bCreate [I] TRUE=Create the key if it doesn't exist, FALSE=Don't
2401  * phKey [O] Destination for the resulting key handle
2402  *
2403  * RETURNS
2404  * Success: S_OK. phKey contains the resulting registry handle.
2405  * Failure: An HRESULT error code indicating the problem.
2406  */
2408 {
2409  WCHAR szValue[MAX_PATH];
2410 
2411  if (lpszValue)
2412  MultiByteToWideChar(CP_ACP, 0, lpszValue, -1, szValue, sizeof(szValue)/sizeof(WCHAR));
2413 
2414  return SHRegGetCLSIDKeyW(guid, lpszValue ? szValue : NULL, bUseHKCU, bCreate, phKey);
2415 }
2416 
2417 /*************************************************************************
2418  * @ [SHLWAPI.344]
2419  *
2420  * Unicode version of SHRegGetCLSIDKeyA.
2421  */
2423  BOOL bCreate, PHKEY phKey)
2424 {
2425  static const WCHAR szClassIdKey[] = { 'S','o','f','t','w','a','r','e','\\',
2426  'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
2427  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
2428  'E','x','p','l','o','r','e','r','\\','C','L','S','I','D','\\' };
2429 #define szClassIdKeyLen (sizeof(szClassIdKey)/sizeof(WCHAR))
2430  WCHAR szKey[MAX_PATH];
2431  DWORD dwRet;
2432  HKEY hkey;
2433 
2434  /* Create the key string */
2435  memcpy(szKey, szClassIdKey, sizeof(szClassIdKey));
2436  SHStringFromGUIDW(guid, szKey + szClassIdKeyLen, 39); /* Append guid */
2437 
2438  if(lpszValue)
2439  {
2440  szKey[szClassIdKeyLen + 39] = '\\';
2441  strcpyW(szKey + szClassIdKeyLen + 40, lpszValue); /* Append value name */
2442  }
2443 
2444  hkey = bUseHKCU ? HKEY_CURRENT_USER : HKEY_CLASSES_ROOT;
2445 
2446  if(bCreate)
2447  dwRet = RegCreateKeyW(hkey, szKey, phKey);
2448  else
2449  dwRet = RegOpenKeyExW(hkey, szKey, 0, KEY_READ, phKey);
2450 
2451  return dwRet ? HRESULT_FROM_WIN32(dwRet) : S_OK;
2452 }
2453 
2454 /*************************************************************************
2455  * SHRegisterValidateTemplate [SHLWAPI.@]
2456  *
2457  * observed from the ie 5.5 installer:
2458  * - allocates a buffer with the size of the given file
2459  * - read the file content into the buffer
2460  * - creates the key szTemplateKey
2461  * - sets "205523652929647911071668590831910975402"=dword:00002e37 at
2462  * the key
2463  *
2464  * PARAMS
2465  * filename [I] An existing file its content is read into an allocated
2466  * buffer
2467  * unknown [I]
2468  *
2469  * RETURNS
2470  * Success: ERROR_SUCCESS.
2471  */
2473 {
2474 /* static const WCHAR szTemplateKey[] = { 'S','o','f','t','w','a','r','e','\\',
2475  * 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
2476  * 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
2477  * 'E','x','p','l','o','r','e','r','\\',
2478  * 'T','e','m','p','l','a','t','e','R','e','g','i','s','t','r','y',0 };
2479  */
2480  FIXME("stub: %s, %08x\n", debugstr_w(filename), unknown);
2481 
2482  return S_OK;
2483 }
#define HKEY_USERS
Definition: winreg.h:13
LONG WINAPI SHRegEnumUSValueW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszValueName, LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
Definition: reg.c:418
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
LONG WINAPI SHRegEnumUSKeyA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszName, LPDWORD pcchValueNameLen, SHREGENUM_FLAGS enumRegFlags)
Definition: reg.c:920
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
DWORD WINAPI SHCopyKeyW(HKEY hKeySrc, LPCWSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved)
Definition: reg.c:2261
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4041
BOOL WINAPI RegisterExtensionForMIMETypeW(LPCWSTR lpszExt, LPCWSTR lpszType)
Definition: reg.c:2131
SHREGENUM_FLAGS
Definition: shlwapi.h:303
static const WCHAR szMimeDbContentW[]
Definition: reg.c:40
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI SHSetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, DWORD dwType, LPCVOID pvData, DWORD cbData)
Definition: reg.c:1306
#define TRUE
Definition: types.h:120
BOOL WINAPI RegisterMIMETypeForExtensionA(LPCSTR lpszSubKey, LPCSTR lpszValue)
Definition: reg.c:1911
WCHAR lpszPath[MAX_PATH]
Definition: reg.c:54
LONG WINAPI SHRegSetUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwType, LPVOID pvData, DWORD cbData, DWORD dwFlags)
Definition: reg.c:673
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
BOOL WINAPI UnregisterExtensionForMIMETypeA(LPCSTR lpszType)
Definition: reg.c:2164
BOOL NTAPI IsBadWritePtr(IN LPVOID lp, IN UINT_PTR ucb)
Definition: except.c:885
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define REG_HKLM
Definition: reg.c:62
Definition: reg.c:49
#define ERROR_SUCCESS
Definition: deptool.c:10
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
static const DWORD dwLenMimeDbContent
Definition: reg.c:43
DWORD WINAPI SHGetValueGoodBootW(HKEY hkey, LPCWSTR pSubKey, LPCWSTR pValue, LPDWORD pwType, LPVOID pvData, LPDWORD pbData)
Definition: reg.c:1890
#define KEY_SET_VALUE
Definition: nt_native.h:1017
Definition: scsiwmi.h:51
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
LONG WINAPI SHRegGetUSValueA(LPCSTR pSubKey, LPCSTR pValue, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData, BOOL flagIgnoreHKCU, LPVOID pDefaultData, DWORD wDefaultDataSize)
Definition: reg.c:561
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define REG_BINARY
Definition: nt_native.h:1496
#define SHREGSET_HKCU
Definition: shlwapi.h:311
#define KEY_READ
Definition: nt_native.h:1023
HKEY HKLMstart
Definition: reg.c:52
DWORD WINAPI SHRegGetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, LPSTR lpszPath, DWORD dwFlags)
Definition: reg.c:1109
LONG WINAPI RegQueryInfoKeyA(HKEY hKey, LPSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3625
#define CP_ACP
Definition: compat.h:99
static GLenum which
Definition: wgl_font.c:159
static const WCHAR szExtensionW[]
Definition: reg.c:46
#define HKEY_CURRENT_USER
Definition: winreg.h:11
LONG WINAPI SHRegOpenUSKeyA(LPCSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey, PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
Definition: reg.c:106
char CHAR
Definition: xmlstorage.h:175
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
LONG WINAPI SHRegDeleteEmptyUSKeyW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags)
Definition: reg.c:329
#define WARN(fmt,...)
Definition: debug.h:111
static const WCHAR szData[]
Definition: msipriv.h:1195
LONG WINAPI SHEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpszSubKey, LPDWORD pwLen)
Definition: reg.c:1806
BOOL WINAPI SHRegGetBoolUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, BOOL fIgnoreHKCU, BOOL fDefault)
Definition: reg.c:770
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1240
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3346
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
BOOL WINAPI SHRegGetBoolUSValueA(LPCSTR pszSubKey, LPCSTR pszValue, BOOL fIgnoreHKCU, BOOL fDefault)
Definition: reg.c:714
HRESULT WINAPI SHRegisterValidateTemplate(LPCWSTR filename, BOOL unknown)
Definition: reg.c:2472
struct SHUSKEY * LPSHUSKEY
LONG WINAPI SHRegCreateUSKeyA(LPCSTR path, REGSAM samDesired, HUSKEY relative_key, PHUSKEY new_uskey, DWORD flags)
Definition: reg.c:217
#define test
Definition: rosglue.h:37
#define HKEY_DYN_DATA
Definition: winreg.h:16
LONG WINAPI SHRegOpenUSKeyW(LPCWSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey, PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
Definition: reg.c:123
DWORD WINAPI SHDeleteValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue)
Definition: reg.c:1762
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1027
char * LPSTR
Definition: xmlstorage.h:182
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
const char * filename
Definition: ioapi.h:135
#define lstrlenW
Definition: compat.h:407
#define SHREGSET_HKLM
Definition: shlwapi.h:313
BOOL WINAPI RegisterExtensionForMIMETypeA(LPCSTR lpszExt, LPCSTR lpszType)
Definition: reg.c:2109
int32_t INT
Definition: typedefs.h:56
DWORD WINAPI SHSetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, DWORD dwType, LPCVOID pvData, DWORD cbData)
Definition: reg.c:1278
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1094
#define lstrcpynW
Definition: compat.h:397
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define szClassIdKeyLen
#define SHREGSET_FORCE_HKLM
Definition: shlwapi.h:314
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const GUID * guid
LONG WINAPI SHRegEnumUSKeyW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszName, LPDWORD pcchValueNameLen, SHREGENUM_FLAGS enumRegFlags)
Definition: reg.c:955
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
BOOL WINAPI MIME_GetExtensionA(LPCSTR lpszType, LPSTR lpExt, INT iLen)
Definition: reg.c:2045
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
DWORD WINAPI SHGetValueGoodBootA(HKEY hkey, LPCSTR pSubKey, LPCSTR pValue, LPDWORD pwType, LPVOID pvData, LPDWORD pbData)
Definition: reg.c:1877
#define debugstr_w
Definition: kernel32.h:32
LONG WINAPI SHQueryInfoKeyA(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax, LPDWORD pwValues, LPDWORD pwValueMax)
Definition: reg.c:1337
#define FIXME(fmt,...)
Definition: debug.h:110
static const WCHAR lpszContentTypeW[]
Definition: reg.c:37
LONG WINAPI SHRegWriteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, DWORD dwType, LPVOID pvData, DWORD cbData, DWORD dwFlags)
Definition: reg.c:1024
static const char lpszContentTypeA[]
Definition: reg.c:36
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2867
_In_ ULONG _In_opt_ PVOID pvData
Definition: winddi.h:3748
smooth NULL
Definition: ftsmooth.c:416
LONG WINAPI SHRegQueryUSValueA(HUSKEY hUSKey, LPCSTR pszValue, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, BOOL fIgnoreHKCU, LPVOID pvDefaultData, DWORD dwDefaultDataSize)
Definition: reg.c:453
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:399
LONG WINAPI SHRegDeleteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags)
Definition: reg.c:361
DWORD WINAPI SHRegSetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, LPCWSTR lpszPath, DWORD dwFlags)
Definition: reg.c:1174
const char * LPCSTR
Definition: xmlstorage.h:183
BOOL WINAPI UnregisterMIMETypeForExtensionW(LPCWSTR lpszSubKey)
Definition: reg.c:1962
#define SM_CLEANBOOT
Definition: winuser.h:1017
LONG WINAPI SHRegDeleteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags)
Definition: reg.c:350
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4917
LONG WINAPI SHEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpszSubKey, LPDWORD pwLen)
Definition: reg.c:1793
DWORD WINAPI SHDeleteOrphanKeyA(HKEY hKey, LPCSTR lpszSubKey)
Definition: reg.c:1674
HKEY HKCUstart
Definition: reg.c:50
#define TRACE(s)
Definition: solgame.cpp:4
#define SHREGSET_FORCE_HKCU
Definition: shlwapi.h:312
LONG WINAPI RegEnumValueA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpdwReserved, _Out_opt_ LPDWORD lpdwType, _Out_opt_ LPBYTE lpData, _Inout_opt_ LPDWORD lpcbData)
Definition: reg.c:2705
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD WINAPI SHDeleteEmptyKeyW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1637
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
#define LMEM_ZEROINIT
Definition: winbase.h:356
HRESULT WINAPI SHRegGetCLSIDKeyW(REFGUID, LPCWSTR, BOOL, BOOL, PHKEY)
Definition: reg.c:2422
DWORD WINAPI SHCopyKeyA(HKEY hKeySrc, LPCSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved)
Definition: reg.c:2244
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG WINAPI SHEnumValueW(HKEY hKey, DWORD dwIndex, LPWSTR lpszValue, LPDWORD pwLen, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
Definition: reg.c:1848
BOOL WINAPI UnregisterMIMETypeForExtensionA(LPCSTR lpszSubKey)
Definition: reg.c:1952
#define debugstr_a
Definition: kernel32.h:31
LONG HRESULT
Definition: typedefs.h:77
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
DWORD WINAPI SHQueryValueExA(HKEY hKey, LPCSTR lpszValue, LPDWORD lpReserved, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
Definition: reg.c:1402
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI SHDeleteEmptyKeyA(HKEY hKey, LPCSTR lpszSubKey)
Definition: reg.c:1608
LONG WINAPI SHRegWriteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, DWORD dwType, LPVOID pvData, DWORD cbData, DWORD dwFlags)
Definition: reg.c:1007
Definition: id3.c:18
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3704
GLbitfield flags
Definition: glext.h:7161
BOOL WINAPI RegisterMIMETypeForExtensionW(LPCWSTR lpszSubKey, LPCWSTR lpszValue)
Definition: reg.c:1928
int ret
WINE_DEFAULT_DEBUG_CHANNEL(reg)
DWORD WINAPI SHQueryValueExW(HKEY hKey, LPCWSTR lpszValue, LPDWORD lpReserved, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
Definition: reg.c:1461
#define LPDWORD
Definition: nt_native.h:46
LONG WINAPI SHRegQueryUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, BOOL fIgnoreHKCU, LPVOID pvDefaultData, DWORD dwDefaultDataSize)
Definition: reg.c:504
LONG WINAPI SHQueryInfoKeyW(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax, LPDWORD pwValues, LPDWORD pwValueMax)
Definition: reg.c:1351
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
Definition: reg.c:1236
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1202
LONG WINAPI SHRegEnumUSValueA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszValueName, LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
Definition: reg.c:387
GLenum src
Definition: glext.h:6340
#define ERROR_KEY_HAS_CHILDREN
Definition: winerror.h:599
LONG WINAPI SHRegQueryInfoUSKeyW(HUSKEY hUSKey, LPDWORD pcSubKeys, LPDWORD pcchMaxSubKeyLen, LPDWORD pcValues, LPDWORD pcchMaxValueNameLen, SHREGENUM_FLAGS enumRegFlags)
Definition: reg.c:875
LONG WINAPI SHEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpszValue, LPDWORD pwLen, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
Definition: reg.c:1832
#define ERROR_MORE_DATA
Definition: dderror.h:13
int WINAPI SHRegGetIntW(HKEY hKey, LPCWSTR lpszValue, int iDefault)
Definition: reg.c:2374
INT WINAPI SHStringFromGUIDW(REFGUID, LPWSTR, INT)
Definition: ordinal.c:608
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1225
#define S_OK
Definition: intsafe.h:59
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
DWORD WINAPI SHDeleteKeyA(HKEY hKey, LPCSTR lpszSubKey)
Definition: reg.c:1533
PRTL_UNICODE_STRING_BUFFER Path
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
_In_ int _In_ BOOL bCreate
Definition: shlobj.h:1435
#define lstrcpyW
Definition: compat.h:406
DWORD WINAPI SHDeleteValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue)
Definition: reg.c:1741
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2368
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
LPCWSTR szPath
Definition: env.c:35
unsigned char dummy
Definition: maze.c:118
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
LONG WINAPI SHRegCloseUSKey(HUSKEY hUSKey)
Definition: reg.c:190
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
BOOL WINAPI GetMIMETypeSubKeyA(LPCSTR lpszType, LPSTR lpszBuffer, DWORD dwLen)
Definition: reg.c:1984
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2331
Definition: services.c:325
GLenum GLenum dst
Definition: glext.h:6340
LONG WINAPI SHRegDeleteEmptyUSKeyA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags)
Definition: reg.c:318
ACCESS_MASK REGSAM
Definition: winreg.h:69
LONG WINAPI SHRegCreateUSKeyW(LPCWSTR path, REGSAM samDesired, HUSKEY relative_key, PHUSKEY new_uskey, DWORD flags)
Definition: reg.c:258
DWORD WINAPI SHRegSetPathA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, LPCSTR lpszPath, DWORD dwFlags)
Definition: reg.c:1153
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
DWORD WINAPI SHGetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
Definition: reg.c:1207
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
INT WINAPI StrToIntW(LPCWSTR lpString)
Definition: string.c:411
#define MultiByteToWideChar
Definition: compat.h:100
HKEY HKLMkey
Definition: reg.c:53
BOOL WINAPI GetMIMETypeSubKeyW(LPCWSTR lpszType, LPWSTR lpszBuffer, DWORD dwLen)
Definition: reg.c:2007
CONST void * LPCVOID
Definition: windef.h:191
static const WCHAR szName[]
Definition: msipriv.h:1194
BOOL WINAPI UnregisterExtensionForMIMETypeW(LPCWSTR lpszType)
Definition: reg.c:2186
HRESULT WINAPI SHRegGetCLSIDKeyA(REFGUID guid, LPCSTR lpszValue, BOOL bUseHKCU, BOOL bCreate, PHKEY phKey)
Definition: reg.c:2407
uint32_t * LPDWORD
Definition: typedefs.h:57
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
DWORD WINAPI SHRegGetPathW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue, LPWSTR lpszPath, DWORD dwFlags)
Definition: reg.c:1125
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2541
#define HKEY_PERFORMANCE_DATA
Definition: winreg.h:14
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4831
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1032
DWORD WINAPI SHDeleteOrphanKeyW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1703
WCHAR * LPWSTR
Definition: xmlstorage.h:184
SHREGDEL_FLAGS
Definition: shlwapi.h:295
static HKEY REG_GetHKEYFromHUSKEY(HUSKEY hUSKey, BOOL which)
Definition: reg.c:69
LONG WINAPI SHRegGetUSValueW(LPCWSTR pSubKey, LPCWSTR pValue, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData, BOOL flagIgnoreHKCU, LPVOID pDefaultData, DWORD wDefaultDataSize)
Definition: reg.c:594
#define REG_DWORD
Definition: sdbapi.c:596
static const char szExtensionA[]
Definition: reg.c:45
HKEY HKCUkey
Definition: reg.c:51
LONG WINAPI SHRegQueryInfoUSKeyA(HUSKEY hUSKey, LPDWORD pcSubKeys, LPDWORD pcchMaxSubKeyLen, LPDWORD pcValues, LPDWORD pcchMaxValueNameLen, SHREGENUM_FLAGS enumRegFlags)
Definition: reg.c:834
static unsigned char buff[32768]
Definition: fatten.c:17
DWORD WINAPI SHDeleteKeyW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1546
#define HeapFree(x, y, z)
Definition: compat.h:394
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
LONG WINAPI RegEnumKeyExA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2456
BOOL WINAPI MIME_GetExtensionW(LPCWSTR lpszType, LPWSTR lpExt, INT iLen)
Definition: reg.c:2073
static const char szMimeDbContentA[]
Definition: reg.c:39
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4953
#define REG_HKCU
Definition: reg.c:61
DWORD type
Definition: reg.c:66
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
LONG WINAPI SHRegSetUSValueA(LPCSTR pszSubKey, LPCSTR pszValue, DWORD dwType, LPVOID pvData, DWORD cbData, DWORD dwFlags)
Definition: reg.c:643
HKEY WINAPI SHRegDuplicateHKey(HKEY hKey)
Definition: reg.c:2214
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_updates_bytes_to_ pdwDataLen BYTE * pbData
Definition: wincrypt.h:4201
#define REG_SZ
Definition: layer.c:22