win32u: Respect per-monitor thread dpi awareness when getting window from point.
[wine.git] / dlls / advapi32 / registry.c
blob85e883bdcc99d03629b1f0af97129243ac7809d1
1 /*
2 * Registry management
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
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <stdio.h>
31 #include "ntstatus.h"
32 #define WIN32_NO_STATUS
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winreg.h"
36 #include "winerror.h"
37 #include "winternl.h"
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.
62 * PARAMS
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.
67 * RETURNS
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.@]
81 * See RegCreateKeyW.
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.@]
119 * See RegOpenKeyA.
121 LSTATUS WINAPI RegOpenKeyW( HKEY hkey, LPCWSTR name, PHKEY retkey )
123 if (!retkey)
124 return ERROR_INVALID_PARAMETER;
126 if (!name || !*name)
128 *retkey = hkey;
129 return ERROR_SUCCESS;
131 return RegOpenKeyExW( hkey, name, 0, MAXIMUM_ALLOWED, retkey );
135 /******************************************************************************
136 * RegOpenKeyA [ADVAPI32.@]
138 * Open a registry key.
140 * PARAMS
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
145 * RETURNS
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 )
151 if (!retkey)
152 return ERROR_INVALID_PARAMETER;
154 if (!name || !*name)
156 *retkey = hkey;
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.
168 * PARAMS
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.
174 * RETURNS
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.@]
188 * See RegEnumKeyW.
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.
201 * PARAMS
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.
208 * RETURNS
209 * Success: ERROR_SUCCESS. ldwTotsize contains num bytes copied.
210 * Failure: nonzero error code from Winerror.h ldwTotsize contains num needed
211 * bytes.
213 LSTATUS WINAPI RegQueryMultipleValuesA( HKEY hkey, PVALENTA val_list, DWORD num_vals,
214 LPSTR lpValueBuf, LPDWORD ldwTotsize )
216 unsigned int i;
217 DWORD maxBytes = *ldwTotsize;
218 LSTATUS status;
219 LPSTR bufptr = lpValueBuf;
220 *ldwTotsize = 0;
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)
231 return status;
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)
240 return status;
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 )
262 unsigned int i;
263 DWORD maxBytes = *ldwTotsize;
264 LSTATUS status;
265 LPSTR bufptr = (LPSTR)lpValueBuf;
266 *ldwTotsize = 0;
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)
276 return status;
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)
285 return status;
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.@]
313 * See RegDeleteKeyA.
315 LSTATUS WINAPI RegDeleteKeyW( HKEY hkey, LPCWSTR name )
317 return RegDeleteKeyExW( hkey, name, 0, 0 );
321 /******************************************************************************
322 * RegDeleteKeyA [ADVAPI32.@]
324 * Delete a registry key.
326 * PARAMS
327 * hkey [I] Handle to parent key containing the key to delete
328 * name [I] Name of the key user hkey to delete
330 * NOTES
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.
335 * RETURNS
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.
350 * PARAMS
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.
355 * count [I] Ignored.
357 * RETURNS
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.@]
373 * See RegSetValueW.
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.
390 * PARAMS
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
394 * of the key.
395 * count [I/O] Size of lpValue in bytes.
397 * RETURNS
398 * Success: ERROR_SUCCESS
399 * Failure: nonzero error code from Winerror.h
401 LSTATUS WINAPI RegQueryValueW( HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count )
403 DWORD ret;
404 HKEY subkey = hkey;
406 TRACE("(%p,%s,%p,%ld)\n", hkey, debugstr_w(name), data, count ? *count : 0 );
408 if (name && name[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 */
417 if (data) *data = 0;
418 if (count) *count = sizeof(WCHAR);
419 ret = ERROR_SUCCESS;
421 return ret;
425 /******************************************************************************
426 * RegQueryValueA [ADVAPI32.@]
428 * See RegQueryValueW.
430 LSTATUS WINAPI RegQueryValueA( HKEY hkey, LPCSTR name, LPSTR data, LPLONG count )
432 DWORD ret;
433 HKEY subkey = hkey;
435 TRACE("(%p,%s,%p,%ld)\n", hkey, debugstr_a(name), data, count ? *count : 0 );
437 if (name && name[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 */
446 if (data) *data = 0;
447 if (count) *count = 1;
448 ret = ERROR_SUCCESS;
450 return ret;
454 /******************************************************************************
455 * RegSaveKeyW [ADVAPI32.@]
457 * Save a key and all of its subkeys and values to a new file in the standard format.
459 * PARAMS
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
464 * RETURNS
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.@]
477 * See RegSaveKeyW.
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.
490 * PARAMS
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
496 * RETURNS
497 * Success: ERROR_SUCCESS
498 * Failure: nonzero error code from Winerror.h
500 LSTATUS WINAPI RegReplaceKeyW( HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpNewFile,
501 LPCWSTR lpOldFile )
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 )
515 UNICODE_STRING str;
516 LSTATUS ret;
517 HKEY subkey;
519 TRACE("%p, %s, %s.\n", hkey, debugstr_w(subkey_name), debugstr_w(new_name));
521 RtlInitUnicodeString(&str, new_name);
523 if (!subkey_name)
524 return RtlNtStatusToDosError( NtRenameKey( hkey, &str ));
526 if ((ret = RegOpenKeyExW( hkey, subkey_name, 0, KEY_WRITE, &subkey )))
527 return ret;
529 ret = RtlNtStatusToDosError( NtRenameKey( subkey, &str ));
530 RegCloseKey( subkey );
532 return ret;
536 /******************************************************************************
537 * RegReplaceKeyA [ADVAPI32.@]
539 * See RegReplaceKeyW.
541 LSTATUS WINAPI RegReplaceKeyA( HKEY hkey, LPCSTR lpSubKey, LPCSTR lpNewFile,
542 LPCSTR lpOldFile )
544 UNICODE_STRING lpSubKeyW;
545 UNICODE_STRING lpNewFileW;
546 UNICODE_STRING lpOldFileW;
547 LONG ret;
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 );
556 return ret;
560 /******************************************************************************
561 * RegConnectRegistryW [ADVAPI32.@]
563 * Establish a connection to a predefined registry key on another computer.
565 * PARAMS
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
570 * RETURNS
571 * Success: ERROR_SUCCESS
572 * Failure: nonzero error code from Winerror.h
574 LSTATUS WINAPI RegConnectRegistryW( LPCWSTR lpMachineName, HKEY hKey,
575 PHKEY phkResult )
577 LONG ret;
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 );
585 else {
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] == '\\')
591 lpMachineName += 2;
592 if (GetComputerNameW(compName, &len))
594 if (!wcsicmp(lpMachineName, compName))
595 ret = RegOpenKeyW(hKey, NULL, phkResult);
596 else
598 FIXME("Connect to %s is not supported.\n",debugstr_w(lpMachineName));
599 ret = ERROR_BAD_NETPATH;
602 else
603 ret = GetLastError();
605 return ret;
609 /******************************************************************************
610 * RegConnectRegistryA [ADVAPI32.@]
612 * See RegConnectRegistryW.
614 LSTATUS WINAPI RegConnectRegistryA( LPCSTR machine, HKEY hkey, PHKEY reskey )
616 UNICODE_STRING machineW;
617 LONG ret;
619 RtlCreateUnicodeStringFromAsciiz( &machineW, machine );
620 ret = RegConnectRegistryW( machineW.Buffer, hkey, reskey );
621 RtlFreeUnicodeString( &machineW );
622 return ret;
626 /******************************************************************************
627 * RegDisablePredefinedCache [ADVAPI32.@]
629 * Disables the caching of the HKEY_CURRENT_USER key for the process.
631 * PARAMS
632 * None.
634 * RETURNS
635 * Success: ERROR_SUCCESS
636 * Failure: nonzero error code from Winerror.h
638 * NOTES
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;
654 LONG ret;
656 if (subkey) RtlCreateUnicodeStringFromAsciiz( &subkeyW, subkey );
657 else subkeyW.Buffer = NULL;
658 ret = RegCopyTreeW( hsrc, subkeyW.Buffer, hdst );
659 RtlFreeUnicodeString( &subkeyW );
660 return ret;
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;