ReactOS 0.4.17-dev-343-gb35a9be
kernelbase.c
Go to the documentation of this file.
1/*
2 * SHLWAPI kernelbase functions
3 *
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998-2000 Juergen Schmied
6 * Copyright 2000 Huw D M Davies for CodeWeavers.
7 * Copyright 2001-2003 Jon Griffiths
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#define COBJMACROS
25#include "windef.h"
26#include "winbase.h"
27#include "wininet.h"
28#include "shlobj.h"
29#include "winternl.h"
30#define NO_SHLWAPI_STREAM
31#include "shlwapi.h"
32#include "intshcut.h"
33#include "mlang.h"
34#include <shlwapi_undoc.h>
35#include "wine/unicode.h"
36#include "wine/debug.h"
37
39
41{
42 WCHAR *ret = NULL;
43
44 if (str)
45 {
47 ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
48 if (ret)
50 }
51
52 return ret;
53}
54
55/*************************************************************************
56 * @ [SHLWAPI.15]
57 *
58 * Get Explorers "AcceptLanguage" setting.
59 *
60 * PARAMS
61 * langbuf [O] Destination for language string
62 * buflen [I] Length of langbuf in characters
63 * [0] Success: used length of langbuf
64 *
65 * RETURNS
66 * Success: S_OK. langbuf is set to the language string found.
67 * Failure: E_FAIL, If any arguments are invalid, error occurred, or Explorer
68 * does not contain the setting.
69 * E_NOT_SUFFICIENT_BUFFER, If the buffer is not big enough
70 */
72{
73 static const WCHAR szkeyW[] = {
74 'S','o','f','t','w','a','r','e','\\',
75 'M','i','c','r','o','s','o','f','t','\\',
76 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
77 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
78 static const WCHAR valueW[] = {
79 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
80 DWORD mystrlen, mytype;
81 DWORD len;
82 HKEY mykey;
83 LCID mylcid;
84 WCHAR *mystr;
85 LONG lres;
86
87 TRACE("(%p, %p) *%p: %d\n", langbuf, buflen, buflen, buflen ? *buflen : -1);
88
89 if(!langbuf || !buflen || !*buflen)
90 return E_FAIL;
91
92 mystrlen = (*buflen > 20) ? *buflen : 20 ;
93 len = mystrlen * sizeof(WCHAR);
94 mystr = HeapAlloc(GetProcessHeap(), 0, len);
95 mystr[0] = 0;
96 RegOpenKeyW(HKEY_CURRENT_USER, szkeyW, &mykey);
97 lres = RegQueryValueExW(mykey, valueW, 0, &mytype, (PBYTE)mystr, &len);
98 RegCloseKey(mykey);
99 len = lstrlenW(mystr);
100
101 if (!lres && (*buflen > len)) {
102 lstrcpyW(langbuf, mystr);
103 *buflen = len;
104 HeapFree(GetProcessHeap(), 0, mystr);
105 return S_OK;
106 }
107
108 /* Did not find a value in the registry or the user buffer is too small */
109 mylcid = GetUserDefaultLCID();
110 LcidToRfc1766W(mylcid, mystr, mystrlen);
111 len = lstrlenW(mystr);
112
113 memcpy( langbuf, mystr, min(*buflen, len+1)*sizeof(WCHAR) );
114 HeapFree(GetProcessHeap(), 0, mystr);
115
116 if (*buflen > len) {
117 *buflen = len;
118 return S_OK;
119 }
120
121 *buflen = 0;
123}
124
125/*************************************************************************
126 * @ [SHLWAPI.14]
127 *
128 * Ascii version of GetAcceptLanguagesW.
129 */
131{
132 WCHAR *langbufW;
133 DWORD buflenW, convlen;
135
136 TRACE("(%p, %p) *%p: %d\n", langbuf, buflen, buflen, buflen ? *buflen : -1);
137
138 if(!langbuf || !buflen || !*buflen) return E_FAIL;
139
140 buflenW = *buflen;
141 langbufW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * buflenW);
142 retval = GetAcceptLanguagesW(langbufW, &buflenW);
143
144 if (retval == S_OK)
145 {
146 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, -1, langbuf, *buflen, NULL, NULL);
147 convlen--; /* do not count the terminating 0 */
148 }
149 else /* copy partial string anyway */
150 {
151 convlen = WideCharToMultiByte(CP_ACP, 0, langbufW, *buflen, langbuf, *buflen, NULL, NULL);
152 if (convlen < *buflen)
153 {
154 langbuf[convlen] = 0;
155 convlen--; /* do not count the terminating 0 */
156 }
157 else
158 {
159 convlen = *buflen;
160 }
161 }
162 *buflen = buflenW ? convlen : 0;
163
164 HeapFree(GetProcessHeap(), 0, langbufW);
165 return retval;
166}
167
168/*************************************************************************
169 * @ [SHLWAPI.30]
170 *
171 * Determine if a Unicode character is a blank.
172 *
173 * PARAMS
174 * wc [I] Character to check.
175 *
176 * RETURNS
177 * TRUE, if wc is a blank,
178 * FALSE otherwise.
179 *
180 */
182{
183 WORD CharType;
184
185 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_BLANK);
186}
187
188/*************************************************************************
189 * @ [SHLWAPI.31]
190 *
191 * Determine if a Unicode character is punctuation.
192 *
193 * PARAMS
194 * wc [I] Character to check.
195 *
196 * RETURNS
197 * TRUE, if wc is punctuation,
198 * FALSE otherwise.
199 */
201{
202 WORD CharType;
203
204 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_PUNCT);
205}
206
207/*************************************************************************
208 * @ [SHLWAPI.32]
209 *
210 * Determine if a Unicode character is a control character.
211 *
212 * PARAMS
213 * wc [I] Character to check.
214 *
215 * RETURNS
216 * TRUE, if wc is a control character,
217 * FALSE otherwise.
218 */
220{
221 WORD CharType;
222
223 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_CNTRL);
224}
225
226/*************************************************************************
227 * @ [SHLWAPI.33]
228 *
229 * Determine if a Unicode character is a digit.
230 *
231 * PARAMS
232 * wc [I] Character to check.
233 *
234 * RETURNS
235 * TRUE, if wc is a digit,
236 * FALSE otherwise.
237 */
239{
240 WORD CharType;
241
242 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_DIGIT);
243}
244
245/*************************************************************************
246 * @ [SHLWAPI.34]
247 *
248 * Determine if a Unicode character is a hex digit.
249 *
250 * PARAMS
251 * wc [I] Character to check.
252 *
253 * RETURNS
254 * TRUE, if wc is a hex digit,
255 * FALSE otherwise.
256 */
258{
259 WORD CharType;
260
261 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_XDIGIT);
262}
263
265{
266 WORD CharType;
267 return GetStringTypeA(GetSystemDefaultLCID(), CT_CTYPE1, &c, 1, &CharType) && (CharType & C1_SPACE);
268}
269
270/*************************************************************************
271 * @ [SHLWAPI.29]
272 *
273 * Determine if a Unicode character is a space.
274 *
275 * PARAMS
276 * wc [I] Character to check.
277 *
278 * RETURNS
279 * TRUE, if wc is a space,
280 * FALSE otherwise.
281 */
283{
284 WORD CharType;
285
286 return GetStringTypeW(CT_CTYPE1, &wc, 1, &CharType) && (CharType & C1_SPACE);
287}
288
289/*************************************************************************
290 * @ [SHLWAPI.219]
291 *
292 * Call IUnknown_QueryInterface() on a table of objects.
293 *
294 * RETURNS
295 * Success: S_OK.
296 * Failure: E_POINTER or E_NOINTERFACE.
297 */
299 void *base, /* [in] Table of interfaces */
300 const QITAB *table, /* [in] Array of REFIIDs and indexes into the table */
301 REFIID riid, /* [in] REFIID to get interface for */
302 void **ppv) /* [out] Destination for interface pointer */
303{
304 HRESULT ret;
305 IUnknown *a_vtbl;
306 const QITAB *xmove;
307
308 TRACE("(%p %p %s %p)\n", base, table, debugstr_guid(riid), ppv);
309 if (ppv) {
310 xmove = table;
311 while (xmove->piid) {
312 TRACE("trying (offset %d) %s\n", xmove->dwOffset, debugstr_guid(xmove->piid));
313 if (IsEqualIID(riid, xmove->piid)) {
314 a_vtbl = (IUnknown*)(xmove->dwOffset + (LPBYTE)base);
315 TRACE("matched, returning (%p)\n", a_vtbl);
316 *ppv = a_vtbl;
317 IUnknown_AddRef(a_vtbl);
318 return S_OK;
319 }
320 xmove++;
321 }
322
324 a_vtbl = (IUnknown*)(table->dwOffset + (LPBYTE)base);
325 TRACE("returning first for IUnknown (%p)\n", a_vtbl);
326 *ppv = a_vtbl;
327 IUnknown_AddRef(a_vtbl);
328 return S_OK;
329 }
330 *ppv = 0;
332 } else
333 ret = E_POINTER;
334
335 TRACE("-- 0x%08x\n", ret);
336 return ret;
337}
338
339/* internal structure of what the HUSKEY points to */
340typedef struct {
341 HKEY HKCUstart; /* Start key in CU hive */
342 HKEY HKCUkey; /* Opened key in CU hive */
343 HKEY HKLMstart; /* Start key in LM hive */
344 HKEY HKLMkey; /* Opened key in LM hive */
345 WCHAR lpszPath[MAX_PATH];
347
348
349#define REG_HKCU TRUE
350#define REG_HKLM FALSE
351/*************************************************************************
352 * REG_GetHKEYFromHUSKEY
353 *
354 * Function: Return the proper registry key from the HUSKEY structure
355 * also allow special predefined values.
356 */
358{
359 HKEY test = hUSKey;
360 LPSHUSKEY mihk = hUSKey;
361
362 if ((test == HKEY_CLASSES_ROOT) ||
364 (test == HKEY_CURRENT_USER) ||
365 (test == HKEY_DYN_DATA) ||
368/* FIXME: need to define for Win2k, ME, XP
369 * (test == HKEY_PERFORMANCE_TEXT) ||
370 * (test == HKEY_PERFORMANCE_NLSTEXT) ||
371 */
372 (test == HKEY_USERS)) return test;
373 if (which == REG_HKCU) return mihk->HKCUkey;
374 return mihk->HKLMkey;
375}
376
377
378/*************************************************************************
379 * SHRegOpenUSKeyA [SHLWAPI.@]
380 *
381 * Open a user-specific registry key.
382 *
383 * PARAMS
384 * Path [I] Key name to open
385 * AccessType [I] Access type
386 * hRelativeUSKey [I] Relative user key
387 * phNewUSKey [O] Destination for created key
388 * fIgnoreHKCU [I] TRUE=Don't check HKEY_CURRENT_USER
389 *
390 * RETURNS
391 * Success: ERROR_SUCCESS
392 * Failure: An error code from RegOpenKeyExA().
393 */
394LONG WINAPI SHRegOpenUSKeyA(LPCSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey,
395 PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
396{
398
399 if (Path)
401
402 return SHRegOpenUSKeyW(Path ? szPath : NULL, AccessType, hRelativeUSKey,
403 phNewUSKey, fIgnoreHKCU);
404}
405
406/*************************************************************************
407 * SHRegOpenUSKeyW [SHLWAPI.@]
408 *
409 * See SHRegOpenUSKeyA.
410 */
411LONG WINAPI SHRegOpenUSKeyW(LPCWSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey,
412 PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
413{
414 LONG ret2, ret1 = ~ERROR_SUCCESS;
416
417 TRACE("(%s,0x%x,%p,%p,%d)\n", debugstr_w(Path),(LONG)AccessType,
418 hRelativeUSKey, phNewUSKey, fIgnoreHKCU);
419
420 if (phNewUSKey)
421 *phNewUSKey = NULL;
422
423 /* Create internal HUSKEY */
425 lstrcpynW(hKey->lpszPath, Path, sizeof(hKey->lpszPath)/sizeof(WCHAR));
426
427 if (hRelativeUSKey)
428 {
429 hKey->HKCUstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(hRelativeUSKey, REG_HKCU));
430 hKey->HKLMstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(hRelativeUSKey, REG_HKLM));
431
432 /* FIXME: if either of these keys is NULL, create the start key from
433 * the relative keys start+path
434 */
435 }
436 else
437 {
438 hKey->HKCUstart = HKEY_CURRENT_USER;
439 hKey->HKLMstart = HKEY_LOCAL_MACHINE;
440 }
441
442 if (!fIgnoreHKCU)
443 {
444 ret1 = RegOpenKeyExW(hKey->HKCUstart, hKey->lpszPath, 0, AccessType, &hKey->HKCUkey);
445 if (ret1)
446 hKey->HKCUkey = 0;
447 }
448
449 ret2 = RegOpenKeyExW(hKey->HKLMstart, hKey->lpszPath, 0, AccessType, &hKey->HKLMkey);
450 if (ret2)
451 hKey->HKLMkey = 0;
452
453 if (ret1 || ret2)
454 TRACE("one or more opens failed: HKCU=%d HKLM=%d\n", ret1, ret2);
455
456 if (ret1 && ret2)
457 {
458 /* Neither open succeeded: fail */
460 return ret2;
461 }
462
463 TRACE("HUSKEY=%p\n", hKey);
464 if (phNewUSKey)
465 *phNewUSKey = hKey;
466 return ERROR_SUCCESS;
467}
468
469/*************************************************************************
470 * SHRegCloseUSKey [SHLWAPI.@]
471 *
472 * Close a user-specific registry key
473 *
474 * RETURNS
475 * Success: ERROR_SUCCESS
476 * Failure: An error code from RegCloseKey().
477 */
479 HUSKEY hUSKey) /* [I] Key to close */
480{
481 LPSHUSKEY hKey = hUSKey;
483
484 if (!hKey)
486
487 if (hKey->HKCUkey)
488 ret = RegCloseKey(hKey->HKCUkey);
489 if (hKey->HKCUstart && hKey->HKCUstart != HKEY_CURRENT_USER)
490 ret = RegCloseKey(hKey->HKCUstart);
491 if (hKey->HKLMkey)
492 ret = RegCloseKey(hKey->HKLMkey);
493 if (hKey->HKLMstart && hKey->HKLMstart != HKEY_LOCAL_MACHINE)
494 ret = RegCloseKey(hKey->HKLMstart);
495
497 return ret;
498}
499
500/*************************************************************************
501 * SHRegCreateUSKeyA [SHLWAPI.@]
502 *
503 * See SHRegCreateUSKeyW.
504 */
506 PHUSKEY new_uskey, DWORD flags)
507{
508 WCHAR *pathW;
509 LONG ret;
510
511 TRACE("(%s, 0x%08x, %p, %p, 0x%08x)\n", debugstr_a(path), samDesired, relative_key,
512 new_uskey, flags);
513
514 if (path)
515 {
516 INT len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
517 pathW = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
518 if (!pathW)
521 }
522 else
523 pathW = NULL;
524
525 ret = SHRegCreateUSKeyW(pathW, samDesired, relative_key, new_uskey, flags);
527 return ret;
528}
529
530/*************************************************************************
531 * SHRegCreateUSKeyW [SHLWAPI.@]
532 *
533 * Create or open a user-specific registry key.
534 *
535 * PARAMS
536 * path [I] Key name to create or open.
537 * samDesired [I] Wanted security access.
538 * relative_key [I] Base path if 'path' is relative. NULL otherwise.
539 * new_uskey [O] Receives a handle to the new or opened key.
540 * flags [I] Base key under which the key should be opened.
541 *
542 * RETURNS
543 * Success: ERROR_SUCCESS
544 * Failure: Nonzero error code from winerror.h
545 */
547 PHUSKEY new_uskey, DWORD flags)
548{
550 SHUSKEY *ret_key;
551
552 TRACE("(%s, 0x%08x, %p, %p, 0x%08x)\n", debugstr_w(path), samDesired,
553 relative_key, new_uskey, flags);
554
555 if (!new_uskey) return ERROR_INVALID_PARAMETER;
556
557 *new_uskey = NULL;
558
560 {
561 FIXME("unsupported flags 0x%08x\n", flags);
562 return ERROR_SUCCESS;
563 }
564
565 ret_key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret_key));
566 lstrcpynW(ret_key->lpszPath, path, sizeof(ret_key->lpszPath)/sizeof(WCHAR));
567
568 if (relative_key)
569 {
572 }
573 else
574 {
575 ret_key->HKCUstart = HKEY_CURRENT_USER;
576 ret_key->HKLMstart = HKEY_LOCAL_MACHINE;
577 }
578
580 {
581 ret = RegCreateKeyExW(ret_key->HKCUstart, path, 0, NULL, 0, samDesired, NULL, &ret_key->HKCUkey, NULL);
582 if (ret == ERROR_SUCCESS)
583 *new_uskey = ret_key;
584 else
585 HeapFree(GetProcessHeap(), 0, ret_key);
586 }
587
588 return ret;
589}
590
591/*************************************************************************
592 * SHRegDeleteEmptyUSKeyA [SHLWAPI.@]
593 *
594 * Delete an empty user-specific registry key.
595 *
596 * PARAMS
597 * hUSKey [I] Handle to an open registry key.
598 * pszValue [I] Empty key name.
599 * delRegFlags [I] Flag that specifies the base from which to delete
600 * the key.
601 *
602 * RETURNS
603 * Success: ERROR_SUCCESS
604 * Failure: Nonzero error code from winerror.h
605 */
607{
608 FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags);
609 return ERROR_SUCCESS;
610}
611
612/*************************************************************************
613 * SHRegDeleteEmptyUSKeyW [SHLWAPI.@]
614 *
615 * See SHRegDeleteEmptyUSKeyA.
616 */
618{
619 FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags);
620 return ERROR_SUCCESS;
621}
622
623/*************************************************************************
624 * SHRegDeleteUSValueA [SHLWAPI.@]
625 *
626 * Delete a user-specific registry value.
627 *
628 * PARAMS
629 * hUSKey [I] Handle to an open registry key.
630 * pszValue [I] Specifies the value to delete.
631 * delRegFlags [I] Flag that specifies the base of the key from which to
632 * delete the value.
633 *
634 * RETURNS
635 * Success: ERROR_SUCCESS
636 * Failure: Nonzero error code from winerror.h
637 */
639{
640 FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags);
641 return ERROR_SUCCESS;
642}
643
644/*************************************************************************
645 * SHRegDeleteUSValueW [SHLWAPI.@]
646 *
647 * See SHRegDeleteUSValueA.
648 */
650{
651 FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags);
652 return ERROR_SUCCESS;
653}
654
655/*************************************************************************
656 * SHRegEnumUSValueA [SHLWAPI.@]
657 *
658 * Enumerate values of a specified registry key.
659 *
660 * PARAMS
661 * hUSKey [I] Handle to an open registry key.
662 * dwIndex [I] Index of the value to be retrieved.
663 * pszValueName [O] Buffer to receive the value name.
664 * pcchValueNameLen [I] Size of pszValueName in characters.
665 * pdwType [O] Receives data type of the value.
666 * pvData [O] Receives value data. May be NULL.
667 * pcbData [I/O] Size of pvData in bytes.
668 * enumRegFlags [I] Flag that specifies the base key under which to
669 * enumerate values.
670 *
671 * RETURNS
672 * Success: ERROR_SUCCESS
673 * Failure: Nonzero error code from winerror.h
674 */
675LONG WINAPI SHRegEnumUSValueA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszValueName,
676 LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData,
677 LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
678{
679 HKEY dokey;
680
681 TRACE("(%p, 0x%08x, %p, %p, %p, %p, %p, 0x%08x)\n", hUSKey, dwIndex,
682 pszValueName, pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags);
683
684 if (((enumRegFlags == SHREGENUM_HKCU) ||
685 (enumRegFlags == SHREGENUM_DEFAULT)) &&
686 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
687 return RegEnumValueA(dokey, dwIndex, pszValueName, pcchValueNameLen,
689 }
690
691 if (((enumRegFlags == SHREGENUM_HKLM) ||
692 (enumRegFlags == SHREGENUM_DEFAULT)) &&
693 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
694 return RegEnumValueA(dokey, dwIndex, pszValueName, pcchValueNameLen,
696 }
697 FIXME("no support for SHREGENUM_BOTH\n");
699}
700
701/*************************************************************************
702 * SHRegEnumUSValueW [SHLWAPI.@]
703 *
704 * See SHRegEnumUSValueA.
705 */
706LONG WINAPI SHRegEnumUSValueW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszValueName,
707 LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData,
708 LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
709{
710 HKEY dokey;
711
712 TRACE("(%p, 0x%08x, %p, %p, %p, %p, %p, 0x%08x)\n", hUSKey, dwIndex,
713 pszValueName, pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags);
714
715 if (((enumRegFlags == SHREGENUM_HKCU) ||
716 (enumRegFlags == SHREGENUM_DEFAULT)) &&
717 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
718 return RegEnumValueW(dokey, dwIndex, pszValueName, pcchValueNameLen,
720 }
721
722 if (((enumRegFlags == SHREGENUM_HKLM) ||
723 (enumRegFlags == SHREGENUM_DEFAULT)) &&
724 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
725 return RegEnumValueW(dokey, dwIndex, pszValueName, pcchValueNameLen,
727 }
728 FIXME("no support for SHREGENUM_BOTH\n");
730}
731
732/*************************************************************************
733 * SHRegQueryUSValueA [SHLWAPI.@]
734 *
735 * Query a user-specific registry value.
736 *
737 * RETURNS
738 * Success: ERROR_SUCCESS
739 * Failure: An error code from RegQueryValueExA().
740 */
742 HUSKEY hUSKey, /* [I] Key to query */
743 LPCSTR pszValue, /* [I] Value name under hUSKey */
744 LPDWORD pdwType, /* [O] Destination for value type */
745 LPVOID pvData, /* [O] Destination for value data */
746 LPDWORD pcbData, /* [O] Destination for value length */
747 BOOL fIgnoreHKCU, /* [I] TRUE=Don't check HKEY_CURRENT_USER */
748 LPVOID pvDefaultData, /* [I] Default data if pszValue does not exist */
749 DWORD dwDefaultDataSize) /* [I] Length of pvDefaultData */
750{
751 LONG ret = ~ERROR_SUCCESS;
752 LONG i, maxmove;
753 HKEY dokey;
754 CHAR *src, *dst;
755
756 /* if user wants HKCU, and it exists, then try it */
757 if (!fIgnoreHKCU && (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
758 ret = RegQueryValueExA(dokey,
760 TRACE("HKCU RegQueryValue returned %08x\n", ret);
761 }
762
763 /* if HKCU did not work and HKLM exists, then try it */
764 if ((ret != ERROR_SUCCESS) &&
765 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
766 ret = RegQueryValueExA(dokey,
768 TRACE("HKLM RegQueryValue returned %08x\n", ret);
769 }
770
771 /* if neither worked, and default data exists, then use it */
772 if (ret != ERROR_SUCCESS) {
773 if (pvDefaultData && (dwDefaultDataSize != 0)) {
775 src = pvDefaultData;
776 dst = pvData;
777 for(i=0; i<maxmove; i++) *dst++ = *src++;
778 *pcbData = maxmove;
779 TRACE("setting default data\n");
781 }
782 }
783 return ret;
784}
785
786
787/*************************************************************************
788 * SHRegQueryUSValueW [SHLWAPI.@]
789 *
790 * See SHRegQueryUSValueA.
791 */
793 HUSKEY hUSKey,
798 BOOL fIgnoreHKCU,
799 LPVOID pvDefaultData,
801{
802 LONG ret = ~ERROR_SUCCESS;
803 LONG i, maxmove;
804 HKEY dokey;
805 CHAR *src, *dst;
806
807 /* if user wants HKCU, and it exists, then try it */
808 if (!fIgnoreHKCU && (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
809 ret = RegQueryValueExW(dokey,
811 TRACE("HKCU RegQueryValue returned %08x\n", ret);
812 }
813
814 /* if HKCU did not work and HKLM exists, then try it */
815 if ((ret != ERROR_SUCCESS) &&
816 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
817 ret = RegQueryValueExW(dokey,
819 TRACE("HKLM RegQueryValue returned %08x\n", ret);
820 }
821
822 /* if neither worked, and default data exists, then use it */
823 if (ret != ERROR_SUCCESS) {
824 if (pvDefaultData && (dwDefaultDataSize != 0)) {
826 src = pvDefaultData;
827 dst = pvData;
828 for(i=0; i<maxmove; i++) *dst++ = *src++;
829 *pcbData = maxmove;
830 TRACE("setting default data\n");
832 }
833 }
834 return ret;
835}
836
837/*************************************************************************
838 * SHRegGetUSValueA [SHLWAPI.@]
839 *
840 * Get a user-specific registry value.
841 *
842 * RETURNS
843 * Success: ERROR_SUCCESS
844 * Failure: An error code from SHRegOpenUSKeyA() or SHRegQueryUSValueA().
845 *
846 * NOTES
847 * This function opens pSubKey, queries the value, and then closes the key.
848 */
850 LPCSTR pSubKey, /* [I] Key name to open */
851 LPCSTR pValue, /* [I] Value name to open */
852 LPDWORD pwType, /* [O] Destination for the type of the value */
853 LPVOID pvData, /* [O] Destination for the value */
854 LPDWORD pcbData, /* [I] Destination for the length of the value **/
855 BOOL flagIgnoreHKCU, /* [I] TRUE=Don't check HKEY_CURRENT_USER */
856 LPVOID pDefaultData, /* [I] Default value if it doesn't exist */
857 DWORD wDefaultDataSize) /* [I] Length of pDefaultData */
858{
859 HUSKEY myhuskey;
860 LONG ret;
861
862 if (!pvData || !pcbData) return ERROR_INVALID_FUNCTION; /* FIXME:wrong*/
863 TRACE("key '%s', value '%s', datalen %d, %s\n",
864 debugstr_a(pSubKey), debugstr_a(pValue), *pcbData,
865 (flagIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM");
866
867 ret = SHRegOpenUSKeyA(pSubKey, 0x1, 0, &myhuskey, flagIgnoreHKCU);
868 if (ret == ERROR_SUCCESS) {
869 ret = SHRegQueryUSValueA(myhuskey, pValue, pwType, pvData,
870 pcbData, flagIgnoreHKCU, pDefaultData,
871 wDefaultDataSize);
872 SHRegCloseUSKey(myhuskey);
873 }
874 return ret;
875}
876
877/*************************************************************************
878 * SHRegGetUSValueW [SHLWAPI.@]
879 *
880 * See SHRegGetUSValueA.
881 */
883 LPCWSTR pSubKey,
885 LPDWORD pwType,
888 BOOL flagIgnoreHKCU,
889 LPVOID pDefaultData,
890 DWORD wDefaultDataSize)
891{
892 HUSKEY myhuskey;
893 LONG ret;
894
895 if (!pvData || !pcbData) return ERROR_INVALID_FUNCTION; /* FIXME:wrong*/
896 TRACE("key '%s', value '%s', datalen %d, %s\n",
897 debugstr_w(pSubKey), debugstr_w(pValue), *pcbData,
898 (flagIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM");
899
900 ret = SHRegOpenUSKeyW(pSubKey, 0x1, 0, &myhuskey, flagIgnoreHKCU);
901 if (ret == ERROR_SUCCESS) {
902 ret = SHRegQueryUSValueW(myhuskey, pValue, pwType, pvData,
903 pcbData, flagIgnoreHKCU, pDefaultData,
904 wDefaultDataSize);
905 SHRegCloseUSKey(myhuskey);
906 }
907 return ret;
908}
909
910/*************************************************************************
911 * SHRegSetUSValueA [SHLWAPI.@]
912 *
913 * Set a user-specific registry value.
914 *
915 * PARAMS
916 * pszSubKey [I] Name of key to set the value in
917 * pszValue [I] Name of value under pszSubKey to set the value in
918 * dwType [I] Type of the value
919 * pvData [I] Data to set as the value
920 * cbData [I] length of pvData
921 * dwFlags [I] SHREGSET_ flags from "shlwapi.h"
922 *
923 * RETURNS
924 * Success: ERROR_SUCCESS
925 * Failure: An error code from SHRegOpenUSKeyA() or SHRegWriteUSValueA(), or
926 * ERROR_INVALID_FUNCTION if pvData is NULL.
927 *
928 * NOTES
929 * This function opens pszSubKey, sets the value, and then closes the key.
930 */
933{
934 BOOL ignoreHKCU = TRUE;
935 HUSKEY hkey;
936 LONG ret;
937
938 TRACE("(%s,%s,%d,%p,%d,0x%08x\n", debugstr_a(pszSubKey), debugstr_a(pszValue),
939 dwType, pvData, cbData, dwFlags);
940
941 if (!pvData)
943
945 ignoreHKCU = FALSE;
946
947 ret = SHRegOpenUSKeyA(pszSubKey, KEY_ALL_ACCESS, 0, &hkey, ignoreHKCU);
948 if (ret == ERROR_SUCCESS)
949 {
951 SHRegCloseUSKey(hkey);
952 }
953 return ret;
954}
955
956/*************************************************************************
957 * SHRegSetUSValueW [SHLWAPI.@]
958 *
959 * See SHRegSetUSValueA.
960 */
963{
964 BOOL ignoreHKCU = TRUE;
965 HUSKEY hkey;
966 LONG ret;
967
968 TRACE("(%s,%s,%d,%p,%d,0x%08x\n", debugstr_w(pszSubKey), debugstr_w(pszValue),
969 dwType, pvData, cbData, dwFlags);
970
971 if (!pvData)
973
975 ignoreHKCU = FALSE;
976
977 ret = SHRegOpenUSKeyW(pszSubKey, KEY_ALL_ACCESS, 0, &hkey, ignoreHKCU);
978 if (ret == ERROR_SUCCESS)
979 {
981 SHRegCloseUSKey(hkey);
982 }
983 return ret;
984}
985
986/*************************************************************************
987 * SHRegGetBoolUSValueA [SHLWAPI.@]
988 *
989 * Get a user-specific registry boolean value.
990 *
991 * RETURNS
992 * Success: ERROR_SUCCESS
993 * Failure: An error code from SHRegOpenUSKeyA() or SHRegQueryUSValueA().
994 *
995 * NOTES
996 * This function opens pszSubKey, queries the value, and then closes the key.
997 *
998 * Boolean values are one of the following:
999 * True: YES,TRUE,non-zero
1000 * False: NO,FALSE,0
1001 */
1003 LPCSTR pszSubKey, /* [I] Key name to open */
1004 LPCSTR pszValue, /* [I] Value name to open */
1005 BOOL fIgnoreHKCU, /* [I] TRUE=Don't check HKEY_CURRENT_USER */
1006 BOOL fDefault) /* [I] Default value to use if pszValue is not present */
1007{
1008 DWORD type, datalen, work;
1009 BOOL ret = fDefault;
1010 CHAR data[10];
1011
1012 TRACE("key '%s', value '%s', %s\n",
1014 (fIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM");
1015
1016 datalen = sizeof(data)-1;
1018 data, &datalen,
1019 fIgnoreHKCU, 0, 0)) {
1020 /* process returned data via type into bool */
1021 switch (type) {
1022 case REG_SZ:
1023 data[9] = '\0'; /* set end of string */
1024 if (lstrcmpiA(data, "YES") == 0) ret = TRUE;
1025 if (lstrcmpiA(data, "TRUE") == 0) ret = TRUE;
1026 if (lstrcmpiA(data, "NO") == 0) ret = FALSE;
1027 if (lstrcmpiA(data, "FALSE") == 0) ret = FALSE;
1028 break;
1029 case REG_DWORD:
1030 work = *(LPDWORD)data;
1031 ret = (work != 0);
1032 break;
1033 case REG_BINARY:
1034 if (datalen == 1) {
1035 ret = (data[0] != '\0');
1036 break;
1037 }
1038 default:
1039 FIXME("Unsupported registry data type %d\n", type);
1040 ret = FALSE;
1041 }
1042 TRACE("got value (type=%d), returning <%s>\n", type,
1043 (ret) ? "TRUE" : "FALSE");
1044 }
1045 else {
1046 ret = fDefault;
1047 TRACE("returning default data <%s>\n",
1048 (ret) ? "TRUE" : "FALSE");
1049 }
1050 return ret;
1051}
1052
1053/*************************************************************************
1054 * SHRegGetBoolUSValueW [SHLWAPI.@]
1055 *
1056 * See SHRegGetBoolUSValueA.
1057 */
1061 BOOL fIgnoreHKCU,
1062 BOOL fDefault)
1063{
1064 static const WCHAR wYES[]= {'Y','E','S','\0'};
1065 static const WCHAR wTRUE[]= {'T','R','U','E','\0'};
1066 static const WCHAR wNO[]= {'N','O','\0'};
1067 static const WCHAR wFALSE[]={'F','A','L','S','E','\0'};
1068 DWORD type, datalen, work;
1069 BOOL ret = fDefault;
1070 WCHAR data[10];
1071
1072 TRACE("key '%s', value '%s', %s\n",
1074 (fIgnoreHKCU) ? "Ignoring HKCU" : "Tries HKCU then HKLM");
1075
1076 datalen = (sizeof(data)-1) * sizeof(WCHAR);
1078 data, &datalen,
1079 fIgnoreHKCU, 0, 0)) {
1080 /* process returned data via type into bool */
1081 switch (type) {
1082 case REG_SZ:
1083 data[9] = '\0'; /* set end of string */
1084 if (lstrcmpiW(data, wYES)==0 || lstrcmpiW(data, wTRUE)==0)
1085 ret = TRUE;
1086 else if (lstrcmpiW(data, wNO)==0 || lstrcmpiW(data, wFALSE)==0)
1087 ret = FALSE;
1088 break;
1089 case REG_DWORD:
1090 work = *(LPDWORD)data;
1091 ret = (work != 0);
1092 break;
1093 case REG_BINARY:
1094 if (datalen == 1) {
1095 ret = (data[0] != '\0');
1096 break;
1097 }
1098 default:
1099 FIXME("Unsupported registry data type %d\n", type);
1100 ret = FALSE;
1101 }
1102 TRACE("got value (type=%d), returning <%s>\n", type,
1103 (ret) ? "TRUE" : "FALSE");
1104 }
1105 else {
1106 ret = fDefault;
1107 TRACE("returning default data <%s>\n",
1108 (ret) ? "TRUE" : "FALSE");
1109 }
1110 return ret;
1111}
1112
1113/*************************************************************************
1114 * SHRegQueryInfoUSKeyA [SHLWAPI.@]
1115 *
1116 * Get information about a user-specific registry key.
1117 *
1118 * RETURNS
1119 * Success: ERROR_SUCCESS
1120 * Failure: An error code from RegQueryInfoKeyA().
1121 */
1123 HUSKEY hUSKey, /* [I] Key to query */
1124 LPDWORD pcSubKeys, /* [O] Destination for number of sub keys */
1125 LPDWORD pcchMaxSubKeyLen, /* [O] Destination for the length of the biggest sub key name */
1126 LPDWORD pcValues, /* [O] Destination for number of values */
1127 LPDWORD pcchMaxValueNameLen,/* [O] Destination for the length of the biggest value */
1128 SHREGENUM_FLAGS enumRegFlags) /* [in] SHREGENUM_ flags from "shlwapi.h" */
1129{
1130 HKEY dokey;
1131 LONG ret;
1132
1133 TRACE("(%p,%p,%p,%p,%p,%d)\n",
1134 hUSKey,pcSubKeys,pcchMaxSubKeyLen,pcValues,
1135 pcchMaxValueNameLen,enumRegFlags);
1136
1137 /* if user wants HKCU, and it exists, then try it */
1138 if (((enumRegFlags == SHREGENUM_HKCU) ||
1139 (enumRegFlags == SHREGENUM_DEFAULT)) &&
1140 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
1141 ret = RegQueryInfoKeyA(dokey, 0, 0, 0,
1142 pcSubKeys, pcchMaxSubKeyLen, 0,
1143 pcValues, pcchMaxValueNameLen, 0, 0, 0);
1144 if ((ret == ERROR_SUCCESS) ||
1145 (enumRegFlags == SHREGENUM_HKCU))
1146 return ret;
1147 }
1148 if (((enumRegFlags == SHREGENUM_HKLM) ||
1149 (enumRegFlags == SHREGENUM_DEFAULT)) &&
1150 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
1151 return RegQueryInfoKeyA(dokey, 0, 0, 0,
1152 pcSubKeys, pcchMaxSubKeyLen, 0,
1153 pcValues, pcchMaxValueNameLen, 0, 0, 0);
1154 }
1156}
1157
1158/*************************************************************************
1159 * SHRegQueryInfoUSKeyW [SHLWAPI.@]
1160 *
1161 * See SHRegQueryInfoUSKeyA.
1162 */
1164 HUSKEY hUSKey,
1165 LPDWORD pcSubKeys,
1166 LPDWORD pcchMaxSubKeyLen,
1167 LPDWORD pcValues,
1168 LPDWORD pcchMaxValueNameLen,
1169 SHREGENUM_FLAGS enumRegFlags)
1170{
1171 HKEY dokey;
1172 LONG ret;
1173
1174 TRACE("(%p,%p,%p,%p,%p,%d)\n",
1175 hUSKey,pcSubKeys,pcchMaxSubKeyLen,pcValues,
1176 pcchMaxValueNameLen,enumRegFlags);
1177
1178 /* if user wants HKCU, and it exists, then try it */
1179 if (((enumRegFlags == SHREGENUM_HKCU) ||
1180 (enumRegFlags == SHREGENUM_DEFAULT)) &&
1181 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
1182 ret = RegQueryInfoKeyW(dokey, 0, 0, 0,
1183 pcSubKeys, pcchMaxSubKeyLen, 0,
1184 pcValues, pcchMaxValueNameLen, 0, 0, 0);
1185 if ((ret == ERROR_SUCCESS) ||
1186 (enumRegFlags == SHREGENUM_HKCU))
1187 return ret;
1188 }
1189 if (((enumRegFlags == SHREGENUM_HKLM) ||
1190 (enumRegFlags == SHREGENUM_DEFAULT)) &&
1191 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
1192 return RegQueryInfoKeyW(dokey, 0, 0, 0,
1193 pcSubKeys, pcchMaxSubKeyLen, 0,
1194 pcValues, pcchMaxValueNameLen, 0, 0, 0);
1195 }
1197}
1198
1199/*************************************************************************
1200 * SHRegEnumUSKeyA [SHLWAPI.@]
1201 *
1202 * Enumerate a user-specific registry key.
1203 *
1204 * RETURNS
1205 * Success: ERROR_SUCCESS
1206 * Failure: An error code from RegEnumKeyExA().
1207 */
1209 HUSKEY hUSKey, /* [in] Key to enumerate */
1210 DWORD dwIndex, /* [in] Index within hUSKey */
1211 LPSTR pszName, /* [out] Name of the enumerated value */
1212 LPDWORD pcchValueNameLen, /* [in/out] Length of pszName */
1213 SHREGENUM_FLAGS enumRegFlags) /* [in] SHREGENUM_ flags from "shlwapi.h" */
1214{
1215 HKEY dokey;
1216
1217 TRACE("(%p,%d,%p,%p(%d),%d)\n",
1218 hUSKey, dwIndex, pszName, pcchValueNameLen,
1219 *pcchValueNameLen, enumRegFlags);
1220
1221 if (((enumRegFlags == SHREGENUM_HKCU) ||
1222 (enumRegFlags == SHREGENUM_DEFAULT)) &&
1223 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
1224 return RegEnumKeyExA(dokey, dwIndex, pszName, pcchValueNameLen,
1225 0, 0, 0, 0);
1226 }
1227
1228 if (((enumRegFlags == SHREGENUM_HKLM) ||
1229 (enumRegFlags == SHREGENUM_DEFAULT)) &&
1230 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
1231 return RegEnumKeyExA(dokey, dwIndex, pszName, pcchValueNameLen,
1232 0, 0, 0, 0);
1233 }
1234 FIXME("no support for SHREGENUM_BOTH\n");
1236}
1237
1238/*************************************************************************
1239 * SHRegEnumUSKeyW [SHLWAPI.@]
1240 *
1241 * See SHRegEnumUSKeyA.
1242 */
1244 HUSKEY hUSKey,
1245 DWORD dwIndex,
1246 LPWSTR pszName,
1247 LPDWORD pcchValueNameLen,
1248 SHREGENUM_FLAGS enumRegFlags)
1249{
1250 HKEY dokey;
1251
1252 TRACE("(%p,%d,%p,%p(%d),%d)\n",
1253 hUSKey, dwIndex, pszName, pcchValueNameLen,
1254 *pcchValueNameLen, enumRegFlags);
1255
1256 if (((enumRegFlags == SHREGENUM_HKCU) ||
1257 (enumRegFlags == SHREGENUM_DEFAULT)) &&
1258 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
1259 return RegEnumKeyExW(dokey, dwIndex, pszName, pcchValueNameLen,
1260 0, 0, 0, 0);
1261 }
1262
1263 if (((enumRegFlags == SHREGENUM_HKLM) ||
1264 (enumRegFlags == SHREGENUM_DEFAULT)) &&
1265 (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
1266 return RegEnumKeyExW(dokey, dwIndex, pszName, pcchValueNameLen,
1267 0, 0, 0, 0);
1268 }
1269 FIXME("no support for SHREGENUM_BOTH\n");
1271}
1272
1273
1274/*************************************************************************
1275 * SHRegWriteUSValueA [SHLWAPI.@]
1276 *
1277 * Write a user-specific registry value.
1278 *
1279 * PARAMS
1280 * hUSKey [I] Key to write the value to
1281 * pszValue [I] Name of value under hUSKey to write the value as
1282 * dwType [I] Type of the value
1283 * pvData [I] Data to set as the value
1284 * cbData [I] length of pvData
1285 * dwFlags [I] SHREGSET_ flags from "shlwapi.h"
1286 *
1287 * RETURNS
1288 * Success: ERROR_SUCCESS.
1289 * Failure: ERROR_INVALID_PARAMETER, if any parameter is invalid, otherwise
1290 * an error code from RegSetValueExA().
1291 *
1292 * NOTES
1293 * dwFlags must have at least SHREGSET_FORCE_HKCU or SHREGSET_FORCE_HKLM set.
1294 */
1297{
1298 WCHAR szValue[MAX_PATH];
1299
1300 if (pszValue)
1301 MultiByteToWideChar(CP_ACP, 0, pszValue, -1, szValue, MAX_PATH);
1302
1303 return SHRegWriteUSValueW(hUSKey, pszValue ? szValue : NULL, dwType,
1305}
1306
1307/*************************************************************************
1308 * SHRegWriteUSValueW [SHLWAPI.@]
1309 *
1310 * See SHRegWriteUSValueA.
1311 */
1314{
1315 DWORD dummy;
1316 LPSHUSKEY hKey = hUSKey;
1318
1319 TRACE("(%p,%s,%d,%p,%d,%d)\n", hUSKey, debugstr_w(pszValue),
1320 dwType, pvData, cbData, dwFlags);
1321
1322 if (!hUSKey || IsBadWritePtr(hUSKey, sizeof(SHUSKEY)) ||
1325
1327 {
1328 if (!hKey->HKCUkey)
1329 {
1330 /* Create the key */
1331 ret = RegCreateKeyW(hKey->HKCUstart, hKey->lpszPath, &hKey->HKCUkey);
1332 TRACE("Creating HKCU key, ret = %d\n", ret);
1333 if (ret && (dwFlags & (SHREGSET_FORCE_HKCU)))
1334 {
1335 hKey->HKCUkey = 0;
1336 return ret;
1337 }
1338 }
1339
1340 if (!ret)
1341 {
1342 if ((dwFlags & SHREGSET_FORCE_HKCU) ||
1344 {
1345 /* Doesn't exist or we are forcing: Write value */
1346 ret = RegSetValueExW(hKey->HKCUkey, pszValue, 0, dwType, pvData, cbData);
1347 TRACE("Writing HKCU value, ret = %d\n", ret);
1348 }
1349 }
1350 }
1351
1353 {
1354 if (!hKey->HKLMkey)
1355 {
1356 /* Create the key */
1357 ret = RegCreateKeyW(hKey->HKLMstart, hKey->lpszPath, &hKey->HKLMkey);
1358 TRACE("Creating HKLM key, ret = %d\n", ret);
1359 if (ret && (dwFlags & (SHREGSET_FORCE_HKLM)))
1360 {
1361 hKey->HKLMkey = 0;
1362 return ret;
1363 }
1364 }
1365
1366 if (!ret)
1367 {
1368 if ((dwFlags & SHREGSET_FORCE_HKLM) ||
1370 {
1371 /* Doesn't exist or we are forcing: Write value */
1372 ret = RegSetValueExW(hKey->HKLMkey, pszValue, 0, dwType, pvData, cbData);
1373 TRACE("Writing HKLM value, ret = %d\n", ret);
1374 }
1375 }
1376 }
1377
1378 return ret;
1379}
PRTL_UNICODE_STRING_BUFFER Path
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
const GUID IID_IUnknown
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
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:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
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:2504
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:3583
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:2668
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
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:4882
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:2830
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:3662
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:4009
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:2419
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
BOOL NTAPI IsBadWritePtr(IN LPVOID lp, IN UINT_PTR ucb)
Definition: except.c:883
BOOL WINAPI GetStringTypeA(LCID locale, DWORD type, LPCSTR src, INT count, LPWORD chartype)
Definition: locale.c:3212
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4133
BOOL WINAPI GetStringTypeW(DWORD type, LPCWSTR src, INT count, LPWORD chartype)
Definition: locale.c:3098
LCID WINAPI GetUserDefaultLCID(void)
Definition: locale.c:1216
LCID WINAPI GetSystemDefaultLCID(void)
Definition: locale.c:1235
HRESULT WINAPI LcidToRfc1766W(LCID lcid, LPWSTR pszRfc1766, INT nChar)
Definition: mlang.c:1247
HKEY WINAPI SHRegDuplicateHKey(HKEY hKey)
Definition: main.c:1828
return ret
Definition: mutex.c:146
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
PWCHAR pValue
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
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
#define C1_CNTRL
Definition: unicode.h:36
#define C1_DIGIT
Definition: unicode.h:33
#define C1_PUNCT
Definition: unicode.h:35
#define C1_SPACE
Definition: unicode.h:34
#define C1_BLANK
Definition: unicode.h:37
#define C1_XDIGIT
Definition: unicode.h:38
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1033
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
BOOL WINAPI IsCharXDigitW(WCHAR wc)
Definition: kernelbase.c:257
LONG WINAPI SHRegOpenUSKeyW(LPCWSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey, PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
Definition: kernelbase.c:411
LONG WINAPI SHRegQueryInfoUSKeyW(HUSKEY hUSKey, LPDWORD pcSubKeys, LPDWORD pcchMaxSubKeyLen, LPDWORD pcValues, LPDWORD pcchMaxValueNameLen, SHREGENUM_FLAGS enumRegFlags)
Definition: kernelbase.c:1163
struct SHUSKEY * LPSHUSKEY
HRESULT WINAPI GetAcceptLanguagesA(LPSTR langbuf, LPDWORD buflen)
Definition: kernelbase.c:130
LONG WINAPI SHRegQueryUSValueA(HUSKEY hUSKey, LPCSTR pszValue, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, BOOL fIgnoreHKCU, LPVOID pvDefaultData, DWORD dwDefaultDataSize)
Definition: kernelbase.c:741
static HKEY REG_GetHKEYFromHUSKEY(HUSKEY hUSKey, BOOL which)
Definition: kernelbase.c:357
LONG WINAPI SHRegEnumUSKeyA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszName, LPDWORD pcchValueNameLen, SHREGENUM_FLAGS enumRegFlags)
Definition: kernelbase.c:1208
LONG WINAPI SHRegGetUSValueA(LPCSTR pSubKey, LPCSTR pValue, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData, BOOL flagIgnoreHKCU, LPVOID pDefaultData, DWORD wDefaultDataSize)
Definition: kernelbase.c:849
BOOL WINAPI IsCharSpaceA(CHAR c)
Definition: kernelbase.c:264
LONG WINAPI SHRegDeleteEmptyUSKeyA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags)
Definition: kernelbase.c:606
#define REG_HKCU
Definition: kernelbase.c:349
#define REG_HKLM
Definition: kernelbase.c:350
LONG WINAPI SHRegWriteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, DWORD dwType, LPVOID pvData, DWORD cbData, DWORD dwFlags)
Definition: kernelbase.c:1295
LONG WINAPI SHRegEnumUSKeyW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszName, LPDWORD pcchValueNameLen, SHREGENUM_FLAGS enumRegFlags)
Definition: kernelbase.c:1243
LONG WINAPI SHRegSetUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwType, LPVOID pvData, DWORD cbData, DWORD dwFlags)
Definition: kernelbase.c:961
LONG WINAPI SHRegOpenUSKeyA(LPCSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey, PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
Definition: kernelbase.c:394
LONG WINAPI SHRegCreateUSKeyA(LPCSTR path, REGSAM samDesired, HUSKEY relative_key, PHUSKEY new_uskey, DWORD flags)
Definition: kernelbase.c:505
LONG WINAPI SHRegDeleteEmptyUSKeyW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags)
Definition: kernelbase.c:617
BOOL WINAPI IsCharCntrlW(WCHAR wc)
Definition: kernelbase.c:219
LONG WINAPI SHRegQueryInfoUSKeyA(HUSKEY hUSKey, LPDWORD pcSubKeys, LPDWORD pcchMaxSubKeyLen, LPDWORD pcValues, LPDWORD pcchMaxValueNameLen, SHREGENUM_FLAGS enumRegFlags)
Definition: kernelbase.c:1122
LONG WINAPI SHRegWriteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, DWORD dwType, LPVOID pvData, DWORD cbData, DWORD dwFlags)
Definition: kernelbase.c:1312
LONG WINAPI SHRegSetUSValueA(LPCSTR pszSubKey, LPCSTR pszValue, DWORD dwType, LPVOID pvData, DWORD cbData, DWORD dwFlags)
Definition: kernelbase.c:931
LONG WINAPI SHRegCloseUSKey(HUSKEY hUSKey)
Definition: kernelbase.c:478
LONG WINAPI SHRegCreateUSKeyW(LPCWSTR path, REGSAM samDesired, HUSKEY relative_key, PHUSKEY new_uskey, DWORD flags)
Definition: kernelbase.c:546
BOOL WINAPI SHRegGetBoolUSValueA(LPCSTR pszSubKey, LPCSTR pszValue, BOOL fIgnoreHKCU, BOOL fDefault)
Definition: kernelbase.c:1002
static WCHAR * heap_strdupAtoW(LPCSTR str)
Definition: kernelbase.c:40
HRESULT WINAPI QISearch(void *base, const QITAB *table, REFIID riid, void **ppv)
Definition: kernelbase.c:298
BOOL WINAPI IsCharDigitW(WCHAR wc)
Definition: kernelbase.c:238
BOOL WINAPI IsCharBlankW(WCHAR wc)
Definition: kernelbase.c:181
LONG WINAPI SHRegGetUSValueW(LPCWSTR pSubKey, LPCWSTR pValue, LPDWORD pwType, LPVOID pvData, LPDWORD pcbData, BOOL flagIgnoreHKCU, LPVOID pDefaultData, DWORD wDefaultDataSize)
Definition: kernelbase.c:882
LONG WINAPI SHRegEnumUSValueW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszValueName, LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
Definition: kernelbase.c:706
BOOL WINAPI SHRegGetBoolUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, BOOL fIgnoreHKCU, BOOL fDefault)
Definition: kernelbase.c:1058
LONG WINAPI SHRegEnumUSValueA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszValueName, LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
Definition: kernelbase.c:675
BOOL WINAPI IsCharPunctW(WCHAR wc)
Definition: kernelbase.c:200
LONG WINAPI SHRegDeleteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags)
Definition: kernelbase.c:638
HRESULT WINAPI GetAcceptLanguagesW(LPWSTR langbuf, LPDWORD buflen)
Definition: kernelbase.c:71
LONG WINAPI SHRegQueryUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, LPDWORD pdwType, LPVOID pvData, LPDWORD pcbData, BOOL fIgnoreHKCU, LPVOID pvDefaultData, DWORD dwDefaultDataSize)
Definition: kernelbase.c:792
LONG WINAPI SHRegDeleteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags)
Definition: kernelbase.c:649
BOOL WINAPI IsCharSpaceW(WCHAR wc)
Definition: kernelbase.c:282
#define REG_SZ
Definition: layer.c:22
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
LPCWSTR szPath
Definition: env.c:37
static const WCHAR pathW[]
Definition: path.c:2368
static WCHAR valueW[]
Definition: reg.c:1394
#define min(a, b)
Definition: monoChain.cc:55
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
_In_ LPWSTR _In_ DWORD _In_ LPCVOID pvData
Definition: netsh.h:116
#define REG_BINARY
Definition: nt_native.h:1499
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define LPDWORD
Definition: nt_native.h:46
BYTE * PBYTE
Definition: pedump.c:66
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
char CHAR
Definition: pedump.c:57
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define SHREGSET_HKCU
Definition: shlwapi.h:719
SHREGENUM_FLAGS
Definition: shlwapi.h:732
@ SHREGENUM_HKCU
Definition: shlwapi.h:734
@ SHREGENUM_DEFAULT
Definition: shlwapi.h:733
@ SHREGENUM_HKLM
Definition: shlwapi.h:735
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
#define SHREGSET_HKLM
Definition: shlwapi.h:721
#define SHREGSET_FORCE_HKLM
Definition: shlwapi.h:722
_In_opt_ LPCSTR _In_opt_ LPCSTR _In_ SRRF _Out_opt_ LPDWORD pdwType
Definition: shlwapi.h:783
_In_opt_ _Inout_opt_ _Out_writes_bytes_to_opt_ pcbData _Inout_opt_ LPDWORD _In_ _In_ DWORD dwDefaultDataSize
Definition: shlwapi.h:781
SHREGDEL_FLAGS
Definition: shlwapi.h:725
_In_ _Out_writes_opt_ pcchValueName _Inout_opt_ LPDWORD _Out_opt_ _Out_writes_bytes_to_opt_ pcbData _Inout_opt_ LPDWORD pcbData
Definition: shlwapi.h:757
_In_opt_ LPCSTR pszSubKey
Definition: shlwapi.h:783
#define SHREGSET_FORCE_HKCU
Definition: shlwapi.h:720
_In_opt_ LPCSTR _In_opt_ LPCSTR pszValue
Definition: shlwapi.h:783
#define test
Definition: rosglue.h:37
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:615
DWORD LCID
Definition: nls.h:13
#define TRACE(s)
Definition: solgame.cpp:4
Definition: shlwapi.h:139
const IID * piid
Definition: shlwapi.h:140
DWORD dwOffset
Definition: shlwapi.h:142
HKEY HKCUkey
Definition: kernelbase.c:342
WCHAR lpszPath[MAX_PATH]
Definition: kernelbase.c:345
HKEY HKLMstart
Definition: kernelbase.c:343
HKEY HKLMkey
Definition: kernelbase.c:344
HKEY HKCUstart
Definition: kernelbase.c:341
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
uint32_t * LPDWORD
Definition: typedefs.h:59
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
int retval
Definition: wcstombs.cpp:91
static GLenum which
Definition: wgl_font.c:159
#define WINAPI
Definition: msvc.h:6
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:3437
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480
#define CT_CTYPE1
Definition: winnls.h:265
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
#define HKEY_DYN_DATA
Definition: winreg.h:16
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:76
#define HKEY_PERFORMANCE_DATA
Definition: winreg.h:14
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13