4 * Copyright (C) 1999 Alexandre Julliard
5 * Copyright (C) 2017 Dmitry Timoshkov
7 * Based on misc/registry.c code
8 * Copyright (C) 1996 Marcus Meissner
9 * Copyright (C) 1998 Matthew Becker
10 * Copyright (C) 1999 Sylvain St-Germain
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #define WIN32_NO_STATUS
39 #include "wine/debug.h"
40 #include "wine/list.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(reg
);
44 NTSTATUS WINAPI
RemapPredefinedHandleInternal( HKEY hkey
, HKEY override
);
45 NTSTATUS WINAPI
DisablePredefinedHandleTableInternal( HKEY hkey
);
48 /******************************************************************************
49 * RegOverridePredefKey [ADVAPI32.@]
51 LSTATUS WINAPI
RegOverridePredefKey( HKEY hkey
, HKEY override
)
53 return RtlNtStatusToDosError( RemapPredefinedHandleInternal( hkey
, override
));
57 /******************************************************************************
58 * RegCreateKeyW [ADVAPI32.@]
60 * Creates the specified reg key.
63 * hKey [I] Handle to an open key.
64 * lpSubKey [I] Name of a key that will be opened or created.
65 * phkResult [O] Receives a handle to the opened or created key.
68 * Success: ERROR_SUCCESS
69 * Failure: nonzero error code defined in Winerror.h
71 LSTATUS WINAPI
RegCreateKeyW( HKEY hkey
, LPCWSTR lpSubKey
, PHKEY phkResult
)
73 return RegCreateKeyExW( hkey
, lpSubKey
, 0, NULL
, REG_OPTION_NON_VOLATILE
,
74 MAXIMUM_ALLOWED
, NULL
, phkResult
, NULL
);
78 /******************************************************************************
79 * RegCreateKeyA [ADVAPI32.@]
83 LSTATUS WINAPI
RegCreateKeyA( HKEY hkey
, LPCSTR lpSubKey
, PHKEY phkResult
)
85 return RegCreateKeyExA( hkey
, lpSubKey
, 0, NULL
, REG_OPTION_NON_VOLATILE
,
86 MAXIMUM_ALLOWED
, NULL
, phkResult
, NULL
);
90 /******************************************************************************
91 * RegCreateKeyTransactedW [ADVAPI32.@]
93 LSTATUS WINAPI
RegCreateKeyTransactedW( HKEY hkey
, LPCWSTR name
, DWORD reserved
, LPWSTR
class,
94 DWORD options
, REGSAM access
, SECURITY_ATTRIBUTES
*sa
,
95 PHKEY retkey
, LPDWORD dispos
, HANDLE transaction
, PVOID reserved2
)
97 FIXME( "(%p,%s,%lu,%s,%lu,%lu,%p,%p,%p,%p,%p): stub\n", hkey
, debugstr_w(name
), reserved
,
98 debugstr_w(class), options
, access
, sa
, retkey
, dispos
, transaction
, reserved2
);
99 return ERROR_CALL_NOT_IMPLEMENTED
;
103 /******************************************************************************
104 * RegCreateKeyTransactedA [ADVAPI32.@]
106 LSTATUS WINAPI
RegCreateKeyTransactedA( HKEY hkey
, LPCSTR name
, DWORD reserved
, LPSTR
class,
107 DWORD options
, REGSAM access
, SECURITY_ATTRIBUTES
*sa
,
108 PHKEY retkey
, LPDWORD dispos
, HANDLE transaction
, PVOID reserved2
)
110 FIXME( "(%p,%s,%lu,%s,%lu,%lu,%p,%p,%p,%p,%p): stub\n", hkey
, debugstr_a(name
), reserved
,
111 debugstr_a(class), options
, access
, sa
, retkey
, dispos
, transaction
, reserved2
);
112 return ERROR_CALL_NOT_IMPLEMENTED
;
116 /******************************************************************************
117 * RegOpenKeyW [ADVAPI32.@]
121 LSTATUS WINAPI
RegOpenKeyW( HKEY hkey
, LPCWSTR name
, PHKEY retkey
)
124 return ERROR_INVALID_PARAMETER
;
129 return ERROR_SUCCESS
;
131 return RegOpenKeyExW( hkey
, name
, 0, MAXIMUM_ALLOWED
, retkey
);
135 /******************************************************************************
136 * RegOpenKeyA [ADVAPI32.@]
138 * Open a registry key.
141 * hkey [I] Handle of parent key to open the new key under
142 * name [I] Name of the key under hkey to open
143 * retkey [O] Destination for the resulting Handle
146 * Success: ERROR_SUCCESS
147 * Failure: A standard Win32 error code. When retkey is valid, *retkey is set to 0.
149 LSTATUS WINAPI
RegOpenKeyA( HKEY hkey
, LPCSTR name
, PHKEY retkey
)
152 return ERROR_INVALID_PARAMETER
;
157 return ERROR_SUCCESS
;
159 return RegOpenKeyExA( hkey
, name
, 0, MAXIMUM_ALLOWED
, retkey
);
163 /******************************************************************************
164 * RegEnumKeyW [ADVAPI32.@]
166 * Enumerates subkeys of the specified open reg key.
169 * hKey [I] Handle to an open key.
170 * dwIndex [I] Index of the subkey of hKey to retrieve.
171 * lpName [O] Name of the subkey.
172 * cchName [I] Size of lpName in TCHARS.
175 * Success: ERROR_SUCCESS
176 * Failure: system error code. If there are no more subkeys available, the
177 * function returns ERROR_NO_MORE_ITEMS.
179 LSTATUS WINAPI
RegEnumKeyW( HKEY hkey
, DWORD index
, LPWSTR name
, DWORD name_len
)
181 return RegEnumKeyExW( hkey
, index
, name
, &name_len
, NULL
, NULL
, NULL
, NULL
);
185 /******************************************************************************
186 * RegEnumKeyA [ADVAPI32.@]
190 LSTATUS WINAPI
RegEnumKeyA( HKEY hkey
, DWORD index
, LPSTR name
, DWORD name_len
)
192 return RegEnumKeyExA( hkey
, index
, name
, &name_len
, NULL
, NULL
, NULL
, NULL
);
196 /******************************************************************************
197 * RegQueryMultipleValuesA [ADVAPI32.@]
199 * Retrieves the type and data for a list of value names associated with a key.
202 * hKey [I] Handle to an open key.
203 * val_list [O] Array of VALENT structures that describes the entries.
204 * num_vals [I] Number of elements in val_list.
205 * lpValueBuf [O] Pointer to a buffer that receives the data for each value.
206 * ldwTotsize [I/O] Size of lpValueBuf.
209 * Success: ERROR_SUCCESS. ldwTotsize contains num bytes copied.
210 * Failure: nonzero error code from Winerror.h ldwTotsize contains num needed
213 LSTATUS WINAPI
RegQueryMultipleValuesA( HKEY hkey
, PVALENTA val_list
, DWORD num_vals
,
214 LPSTR lpValueBuf
, LPDWORD ldwTotsize
)
217 DWORD maxBytes
= *ldwTotsize
;
219 LPSTR bufptr
= lpValueBuf
;
222 TRACE("(%p,%p,%ld,%p,%p=%ld)\n", hkey
, val_list
, num_vals
, lpValueBuf
, ldwTotsize
, *ldwTotsize
);
224 for(i
=0; i
< num_vals
; ++i
)
227 val_list
[i
].ve_valuelen
=0;
228 status
= RegQueryValueExA(hkey
, val_list
[i
].ve_valuename
, NULL
, NULL
, NULL
, &val_list
[i
].ve_valuelen
);
229 if(status
!= ERROR_SUCCESS
)
234 if(lpValueBuf
!= NULL
&& *ldwTotsize
+ val_list
[i
].ve_valuelen
<= maxBytes
)
236 status
= RegQueryValueExA(hkey
, val_list
[i
].ve_valuename
, NULL
, &val_list
[i
].ve_type
,
237 (LPBYTE
)bufptr
, &val_list
[i
].ve_valuelen
);
238 if(status
!= ERROR_SUCCESS
)
243 val_list
[i
].ve_valueptr
= (DWORD_PTR
)bufptr
;
245 bufptr
+= val_list
[i
].ve_valuelen
;
248 *ldwTotsize
+= val_list
[i
].ve_valuelen
;
250 return lpValueBuf
!= NULL
&& *ldwTotsize
<= maxBytes
? ERROR_SUCCESS
: ERROR_MORE_DATA
;
254 /******************************************************************************
255 * RegQueryMultipleValuesW [ADVAPI32.@]
257 * See RegQueryMultipleValuesA.
259 LSTATUS WINAPI
RegQueryMultipleValuesW( HKEY hkey
, PVALENTW val_list
, DWORD num_vals
,
260 LPWSTR lpValueBuf
, LPDWORD ldwTotsize
)
263 DWORD maxBytes
= *ldwTotsize
;
265 LPSTR bufptr
= (LPSTR
)lpValueBuf
;
268 TRACE("(%p,%p,%ld,%p,%p=%ld)\n", hkey
, val_list
, num_vals
, lpValueBuf
, ldwTotsize
, *ldwTotsize
);
270 for(i
=0; i
< num_vals
; ++i
)
272 val_list
[i
].ve_valuelen
=0;
273 status
= RegQueryValueExW(hkey
, val_list
[i
].ve_valuename
, NULL
, NULL
, NULL
, &val_list
[i
].ve_valuelen
);
274 if(status
!= ERROR_SUCCESS
)
279 if(lpValueBuf
!= NULL
&& *ldwTotsize
+ val_list
[i
].ve_valuelen
<= maxBytes
)
281 status
= RegQueryValueExW(hkey
, val_list
[i
].ve_valuename
, NULL
, &val_list
[i
].ve_type
,
282 (LPBYTE
)bufptr
, &val_list
[i
].ve_valuelen
);
283 if(status
!= ERROR_SUCCESS
)
288 val_list
[i
].ve_valueptr
= (DWORD_PTR
)bufptr
;
290 bufptr
+= val_list
[i
].ve_valuelen
;
293 *ldwTotsize
+= val_list
[i
].ve_valuelen
;
295 return lpValueBuf
!= NULL
&& *ldwTotsize
<= maxBytes
? ERROR_SUCCESS
: ERROR_MORE_DATA
;
299 /******************************************************************************
300 * RegQueryReflectionKey [ADVAPI32.@]
302 LONG WINAPI
RegQueryReflectionKey( HKEY hkey
, BOOL
*is_reflection_disabled
)
304 FIXME( "%p, %p stub\n", hkey
, is_reflection_disabled
);
305 *is_reflection_disabled
= TRUE
;
306 return ERROR_CALL_NOT_IMPLEMENTED
;
310 /******************************************************************************
311 * RegDeleteKeyW [ADVAPI32.@]
315 LSTATUS WINAPI
RegDeleteKeyW( HKEY hkey
, LPCWSTR name
)
317 return RegDeleteKeyExW( hkey
, name
, 0, 0 );
321 /******************************************************************************
322 * RegDeleteKeyA [ADVAPI32.@]
324 * Delete a registry key.
327 * hkey [I] Handle to parent key containing the key to delete
328 * name [I] Name of the key user hkey to delete
332 * MSDN is wrong when it says that hkey must be opened with the DELETE access
333 * right. In reality, it opens a new handle with DELETE access.
336 * Success: ERROR_SUCCESS
337 * Failure: Error code
339 LSTATUS WINAPI
RegDeleteKeyA( HKEY hkey
, LPCSTR name
)
341 return RegDeleteKeyExA( hkey
, name
, 0, 0 );
345 /******************************************************************************
346 * RegSetValueW [ADVAPI32.@]
348 * Sets the data for the default or unnamed value of a reg key.
351 * hkey [I] Handle to an open key.
352 * subkey [I] Name of a subkey of hKey.
353 * type [I] Type of information to store.
354 * data [I] String that contains the data to set for the default value.
358 * Success: ERROR_SUCCESS
359 * Failure: nonzero error code from Winerror.h
361 LSTATUS WINAPI
RegSetValueW( HKEY hkey
, LPCWSTR subkey
, DWORD type
, LPCWSTR data
, DWORD count
)
363 TRACE("(%p,%s,%ld,%s,%ld)\n", hkey
, debugstr_w(subkey
), type
, debugstr_w(data
), count
);
365 if (type
!= REG_SZ
|| !data
) return ERROR_INVALID_PARAMETER
;
367 return RegSetKeyValueW( hkey
, subkey
, NULL
, type
, data
, (lstrlenW(data
) + 1)*sizeof(WCHAR
) );
370 /******************************************************************************
371 * RegSetValueA [ADVAPI32.@]
375 LSTATUS WINAPI
RegSetValueA( HKEY hkey
, LPCSTR subkey
, DWORD type
, LPCSTR data
, DWORD count
)
377 TRACE("(%p,%s,%ld,%s,%ld)\n", hkey
, debugstr_a(subkey
), type
, debugstr_a(data
), count
);
379 if (type
!= REG_SZ
|| !data
) return ERROR_INVALID_PARAMETER
;
381 return RegSetKeyValueA( hkey
, subkey
, NULL
, type
, data
, strlen(data
) + 1 );
385 /******************************************************************************
386 * RegQueryValueW [ADVAPI32.@]
388 * Retrieves the data associated with the default or unnamed value of a key.
391 * hkey [I] Handle to an open key.
392 * name [I] Name of the subkey of hKey.
393 * data [O] Receives the string associated with the default value
395 * count [I/O] Size of lpValue in bytes.
398 * Success: ERROR_SUCCESS
399 * Failure: nonzero error code from Winerror.h
401 LSTATUS WINAPI
RegQueryValueW( HKEY hkey
, LPCWSTR name
, LPWSTR data
, LPLONG count
)
406 TRACE("(%p,%s,%p,%ld)\n", hkey
, debugstr_w(name
), data
, count
? *count
: 0 );
410 if ((ret
= RegOpenKeyW( hkey
, name
, &subkey
)) != ERROR_SUCCESS
) return ret
;
412 ret
= RegQueryValueExW( subkey
, NULL
, NULL
, NULL
, (LPBYTE
)data
, (LPDWORD
)count
);
413 if (subkey
!= hkey
) RegCloseKey( subkey
);
414 if (ret
== ERROR_FILE_NOT_FOUND
)
416 /* return empty string if default value not found */
418 if (count
) *count
= sizeof(WCHAR
);
425 /******************************************************************************
426 * RegQueryValueA [ADVAPI32.@]
428 * See RegQueryValueW.
430 LSTATUS WINAPI
RegQueryValueA( HKEY hkey
, LPCSTR name
, LPSTR data
, LPLONG count
)
435 TRACE("(%p,%s,%p,%ld)\n", hkey
, debugstr_a(name
), data
, count
? *count
: 0 );
439 if ((ret
= RegOpenKeyA( hkey
, name
, &subkey
)) != ERROR_SUCCESS
) return ret
;
441 ret
= RegQueryValueExA( subkey
, NULL
, NULL
, NULL
, (LPBYTE
)data
, (LPDWORD
)count
);
442 if (subkey
!= hkey
) RegCloseKey( subkey
);
443 if (ret
== ERROR_FILE_NOT_FOUND
)
445 /* return empty string if default value not found */
447 if (count
) *count
= 1;
454 /******************************************************************************
455 * RegSaveKeyW [ADVAPI32.@]
457 * Save a key and all of its subkeys and values to a new file in the standard format.
460 * hkey [I] Handle of key where save begins
461 * lpFile [I] Address of filename to save to
462 * sa [I] Address of security structure
465 * Success: ERROR_SUCCESS
466 * Failure: nonzero error code from Winerror.h
468 LSTATUS WINAPI
RegSaveKeyW( HKEY hkey
, LPCWSTR file
, LPSECURITY_ATTRIBUTES sa
)
470 return RegSaveKeyExW(hkey
, file
, sa
, 0);
474 /******************************************************************************
475 * RegSaveKeyA [ADVAPI32.@]
479 LSTATUS WINAPI
RegSaveKeyA( HKEY hkey
, LPCSTR file
, LPSECURITY_ATTRIBUTES sa
)
481 return RegSaveKeyExA(hkey
, file
, sa
, 0);
485 /******************************************************************************
486 * RegReplaceKeyW [ADVAPI32.@]
488 * Replace the file backing a registry key and all its subkeys with another file.
491 * hkey [I] Handle of open key
492 * lpSubKey [I] Address of name of subkey
493 * lpNewFile [I] Address of filename for file with new data
494 * lpOldFile [I] Address of filename for backup file
497 * Success: ERROR_SUCCESS
498 * Failure: nonzero error code from Winerror.h
500 LSTATUS WINAPI
RegReplaceKeyW( HKEY hkey
, LPCWSTR lpSubKey
, LPCWSTR lpNewFile
,
503 FIXME("(%p,%s,%s,%s): stub\n", hkey
, debugstr_w(lpSubKey
),
504 debugstr_w(lpNewFile
),debugstr_w(lpOldFile
));
505 return ERROR_SUCCESS
;
509 /******************************************************************************
510 * RegRenameKey [ADVAPI32.@]
513 LSTATUS WINAPI
RegRenameKey( HKEY hkey
, LPCWSTR subkey_name
, LPCWSTR new_name
)
519 TRACE("%p, %s, %s.\n", hkey
, debugstr_w(subkey_name
), debugstr_w(new_name
));
521 RtlInitUnicodeString(&str
, new_name
);
524 return RtlNtStatusToDosError( NtRenameKey( hkey
, &str
));
526 if ((ret
= RegOpenKeyExW( hkey
, subkey_name
, 0, KEY_WRITE
, &subkey
)))
529 ret
= RtlNtStatusToDosError( NtRenameKey( subkey
, &str
));
530 RegCloseKey( subkey
);
536 /******************************************************************************
537 * RegReplaceKeyA [ADVAPI32.@]
539 * See RegReplaceKeyW.
541 LSTATUS WINAPI
RegReplaceKeyA( HKEY hkey
, LPCSTR lpSubKey
, LPCSTR lpNewFile
,
544 UNICODE_STRING lpSubKeyW
;
545 UNICODE_STRING lpNewFileW
;
546 UNICODE_STRING lpOldFileW
;
549 RtlCreateUnicodeStringFromAsciiz( &lpSubKeyW
, lpSubKey
);
550 RtlCreateUnicodeStringFromAsciiz( &lpOldFileW
, lpOldFile
);
551 RtlCreateUnicodeStringFromAsciiz( &lpNewFileW
, lpNewFile
);
552 ret
= RegReplaceKeyW( hkey
, lpSubKeyW
.Buffer
, lpNewFileW
.Buffer
, lpOldFileW
.Buffer
);
553 RtlFreeUnicodeString( &lpOldFileW
);
554 RtlFreeUnicodeString( &lpNewFileW
);
555 RtlFreeUnicodeString( &lpSubKeyW
);
560 /******************************************************************************
561 * RegConnectRegistryW [ADVAPI32.@]
563 * Establish a connection to a predefined registry key on another computer.
566 * lpMachineName [I] Address of name of remote computer
567 * hHey [I] Predefined registry handle
568 * phkResult [I] Address of buffer for remote registry handle
571 * Success: ERROR_SUCCESS
572 * Failure: nonzero error code from Winerror.h
574 LSTATUS WINAPI
RegConnectRegistryW( LPCWSTR lpMachineName
, HKEY hKey
,
579 TRACE("(%s,%p,%p)\n",debugstr_w(lpMachineName
), hKey
, phkResult
);
581 if (!lpMachineName
|| !*lpMachineName
) {
582 /* Use the local machine name */
583 ret
= RegOpenKeyW( hKey
, NULL
, phkResult
);
586 WCHAR compName
[MAX_COMPUTERNAME_LENGTH
+ 1];
587 DWORD len
= ARRAY_SIZE( compName
);
589 /* MSDN says lpMachineName must start with \\ : not so */
590 if( lpMachineName
[0] == '\\' && lpMachineName
[1] == '\\')
592 if (GetComputerNameW(compName
, &len
))
594 if (!wcsicmp(lpMachineName
, compName
))
595 ret
= RegOpenKeyW(hKey
, NULL
, phkResult
);
598 FIXME("Connect to %s is not supported.\n",debugstr_w(lpMachineName
));
599 ret
= ERROR_BAD_NETPATH
;
603 ret
= GetLastError();
609 /******************************************************************************
610 * RegConnectRegistryA [ADVAPI32.@]
612 * See RegConnectRegistryW.
614 LSTATUS WINAPI
RegConnectRegistryA( LPCSTR machine
, HKEY hkey
, PHKEY reskey
)
616 UNICODE_STRING machineW
;
619 RtlCreateUnicodeStringFromAsciiz( &machineW
, machine
);
620 ret
= RegConnectRegistryW( machineW
.Buffer
, hkey
, reskey
);
621 RtlFreeUnicodeString( &machineW
);
626 /******************************************************************************
627 * RegDisablePredefinedCache [ADVAPI32.@]
629 * Disables the caching of the HKEY_CURRENT_USER key for the process.
635 * Success: ERROR_SUCCESS
636 * Failure: nonzero error code from Winerror.h
639 * This is useful for services that use impersonation.
641 LSTATUS WINAPI
RegDisablePredefinedCache(void)
643 return RtlNtStatusToDosError( DisablePredefinedHandleTableInternal( HKEY_CURRENT_USER
));
647 /******************************************************************************
648 * RegCopyTreeA [ADVAPI32.@]
651 LONG WINAPI
RegCopyTreeA( HKEY hsrc
, const char *subkey
, HKEY hdst
)
653 UNICODE_STRING subkeyW
;
656 if (subkey
) RtlCreateUnicodeStringFromAsciiz( &subkeyW
, subkey
);
657 else subkeyW
.Buffer
= NULL
;
658 ret
= RegCopyTreeW( hsrc
, subkeyW
.Buffer
, hdst
);
659 RtlFreeUnicodeString( &subkeyW
);
664 /******************************************************************************
665 * RegEnableReflectionKey [ADVAPI32.@]
668 LONG WINAPI
RegEnableReflectionKey(HKEY base
)
670 FIXME("%p: stub\n", base
);
671 return ERROR_CALL_NOT_IMPLEMENTED
;
675 /******************************************************************************
676 * RegDisableReflectionKey [ADVAPI32.@]
679 LONG WINAPI
RegDisableReflectionKey(HKEY base
)
681 FIXME("%p: stub\n", base
);
682 return ERROR_SUCCESS
;