Fixed header dependencies to be fully compatible with the Windows
[wine/multimedia.git] / dlls / ntdll / reg.c
blob2e111ced3c4fb68d3a227bff84aaf7d85ed1e68b
1 /*
2 * Registry functions
4 * Copyright (C) 1999 Juergen Schmied
5 * Copyright (C) 2000 Alexandre Julliard
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * NOTES:
22 * HKEY_LOCAL_MACHINE \\REGISTRY\\MACHINE
23 * HKEY_USERS \\REGISTRY\\USER
24 * HKEY_CURRENT_CONFIG \\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\HARDWARE PROFILES\\CURRENT
25 * HKEY_CLASSES \\REGISTRY\\MACHINE\\SOFTWARE\\CLASSES
28 #include "config.h"
29 #include "wine/port.h"
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <string.h>
35 #include "winerror.h"
36 #include "wine/unicode.h"
37 #include "wine/library.h"
38 #include "wine/server.h"
39 #include "windef.h"
40 #include "winbase.h"
41 #include "winreg.h"
42 #include "winternl.h"
43 #include "ntdll_misc.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(reg);
48 /* maximum length of a key/value name in bytes (without terminating null) */
49 #define MAX_NAME_LENGTH ((MAX_PATH-1) * sizeof(WCHAR))
52 /******************************************************************************
53 * NtCreateKey [NTDLL.@]
54 * ZwCreateKey [NTDLL.@]
56 NTSTATUS WINAPI NtCreateKey( PHKEY retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
57 ULONG TitleIndex, const UNICODE_STRING *class, ULONG options,
58 PULONG dispos )
60 NTSTATUS ret;
62 TRACE( "(%p,%s,%s,%lx,%lx,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
63 debugstr_us(class), options, access, retkey );
65 if (attr->ObjectName->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
66 if (!retkey) return STATUS_INVALID_PARAMETER;
68 SERVER_START_REQ( create_key )
70 req->parent = attr->RootDirectory;
71 req->access = access;
72 req->options = options;
73 req->modif = 0;
74 req->namelen = attr->ObjectName->Length;
75 wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
76 if (class) wine_server_add_data( req, class->Buffer, class->Length );
77 if (!(ret = wine_server_call( req )))
79 *retkey = reply->hkey;
80 if (dispos) *dispos = reply->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
83 SERVER_END_REQ;
84 TRACE("<- %p\n", *retkey);
85 return ret;
89 /******************************************************************************
90 * NtOpenKey [NTDLL.@]
91 * ZwOpenKey [NTDLL.@]
93 * OUT PHKEY retkey (returns 0 when failure)
94 * IN ACCESS_MASK access
95 * IN POBJECT_ATTRIBUTES attr
97 NTSTATUS WINAPI NtOpenKey( PHKEY retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
99 NTSTATUS ret;
100 DWORD len = attr->ObjectName->Length;
102 TRACE( "(%p,%s,%lx,%p)\n", attr->RootDirectory,
103 debugstr_us(attr->ObjectName), access, retkey );
105 if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
106 if (!retkey) return STATUS_INVALID_PARAMETER;
108 SERVER_START_REQ( open_key )
110 req->parent = attr->RootDirectory;
111 req->access = access;
112 wine_server_add_data( req, attr->ObjectName->Buffer, len );
113 ret = wine_server_call( req );
114 *retkey = reply->hkey;
116 SERVER_END_REQ;
117 TRACE("<- %p\n", *retkey);
118 return ret;
122 /******************************************************************************
123 * NtDeleteKey [NTDLL.@]
124 * ZwDeleteKey [NTDLL.@]
126 NTSTATUS WINAPI NtDeleteKey( HKEY hkey )
128 NTSTATUS ret;
130 TRACE( "(%p)\n", hkey );
132 SERVER_START_REQ( delete_key )
134 req->hkey = hkey;
135 ret = wine_server_call( req );
137 SERVER_END_REQ;
138 return ret;
142 /******************************************************************************
143 * NtDeleteValueKey [NTDLL.@]
144 * ZwDeleteValueKey [NTDLL.@]
146 NTSTATUS WINAPI NtDeleteValueKey( HKEY hkey, const UNICODE_STRING *name )
148 NTSTATUS ret;
150 TRACE( "(%p,%s)\n", hkey, debugstr_us(name) );
151 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
153 SERVER_START_REQ( delete_key_value )
155 req->hkey = hkey;
156 wine_server_add_data( req, name->Buffer, name->Length );
157 ret = wine_server_call( req );
159 SERVER_END_REQ;
160 return ret;
164 /******************************************************************************
165 * enumerate_key
167 * Implementation of NtQueryKey and NtEnumerateKey
169 static NTSTATUS enumerate_key( HKEY handle, int index, KEY_INFORMATION_CLASS info_class,
170 void *info, DWORD length, DWORD *result_len )
173 NTSTATUS ret;
174 void *data_ptr;
175 size_t fixed_size;
177 switch(info_class)
179 case KeyBasicInformation: data_ptr = ((KEY_BASIC_INFORMATION *)info)->Name; break;
180 case KeyFullInformation: data_ptr = ((KEY_FULL_INFORMATION *)info)->Class; break;
181 case KeyNodeInformation: data_ptr = ((KEY_NODE_INFORMATION *)info)->Name; break;
182 default:
183 FIXME( "Information class %d not implemented\n", info_class );
184 return STATUS_INVALID_PARAMETER;
186 fixed_size = (char *)data_ptr - (char *)info;
188 SERVER_START_REQ( enum_key )
190 req->hkey = handle;
191 req->index = index;
192 req->info_class = info_class;
193 if (length > fixed_size) wine_server_set_reply( req, data_ptr, length - fixed_size );
194 if (!(ret = wine_server_call( req )))
196 LARGE_INTEGER modif;
198 RtlSecondsSince1970ToTime( reply->modif, &modif );
200 switch(info_class)
202 case KeyBasicInformation:
204 KEY_BASIC_INFORMATION keyinfo;
205 fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
206 keyinfo.LastWriteTime = modif;
207 keyinfo.TitleIndex = 0;
208 keyinfo.NameLength = reply->namelen;
209 memcpy( info, &keyinfo, min( length, fixed_size ) );
211 break;
212 case KeyFullInformation:
214 KEY_FULL_INFORMATION keyinfo;
215 fixed_size = (char *)keyinfo.Class - (char *)&keyinfo;
216 keyinfo.LastWriteTime = modif;
217 keyinfo.TitleIndex = 0;
218 keyinfo.ClassLength = wine_server_reply_size(reply);
219 keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1;
220 keyinfo.SubKeys = reply->subkeys;
221 keyinfo.MaxNameLen = reply->max_subkey;
222 keyinfo.MaxClassLen = reply->max_class;
223 keyinfo.Values = reply->values;
224 keyinfo.MaxValueNameLen = reply->max_value;
225 keyinfo.MaxValueDataLen = reply->max_data;
226 memcpy( info, &keyinfo, min( length, fixed_size ) );
228 break;
229 case KeyNodeInformation:
231 KEY_NODE_INFORMATION keyinfo;
232 fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
233 keyinfo.LastWriteTime = modif;
234 keyinfo.TitleIndex = 0;
235 keyinfo.ClassLength = max( 0, wine_server_reply_size(reply) - reply->namelen );
236 keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size + reply->namelen : -1;
237 keyinfo.NameLength = reply->namelen;
238 memcpy( info, &keyinfo, min( length, fixed_size ) );
240 break;
242 *result_len = fixed_size + reply->total;
243 if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
246 SERVER_END_REQ;
247 return ret;
252 /******************************************************************************
253 * NtEnumerateKey [NTDLL.@]
254 * ZwEnumerateKey [NTDLL.@]
256 * NOTES
257 * the name copied into the buffer is NOT 0-terminated
259 NTSTATUS WINAPI NtEnumerateKey( HKEY handle, ULONG index, KEY_INFORMATION_CLASS info_class,
260 void *info, DWORD length, DWORD *result_len )
262 /* -1 means query key, so avoid it here */
263 if (index == (ULONG)-1) return STATUS_NO_MORE_ENTRIES;
264 return enumerate_key( handle, index, info_class, info, length, result_len );
268 /******************************************************************************
269 * NtQueryKey [NTDLL.@]
270 * ZwQueryKey [NTDLL.@]
272 NTSTATUS WINAPI NtQueryKey( HKEY handle, KEY_INFORMATION_CLASS info_class,
273 void *info, DWORD length, DWORD *result_len )
275 return enumerate_key( handle, -1, info_class, info, length, result_len );
279 /* fill the key value info structure for a specific info class */
280 static void copy_key_value_info( KEY_VALUE_INFORMATION_CLASS info_class, void *info,
281 DWORD length, int type, int name_len, int data_len )
283 switch(info_class)
285 case KeyValueBasicInformation:
287 KEY_VALUE_BASIC_INFORMATION keyinfo;
288 keyinfo.TitleIndex = 0;
289 keyinfo.Type = type;
290 keyinfo.NameLength = name_len;
291 length = min( length, (char *)keyinfo.Name - (char *)&keyinfo );
292 memcpy( info, &keyinfo, length );
293 break;
295 case KeyValueFullInformation:
297 KEY_VALUE_FULL_INFORMATION keyinfo;
298 keyinfo.TitleIndex = 0;
299 keyinfo.Type = type;
300 keyinfo.DataOffset = (char *)keyinfo.Name - (char *)&keyinfo + name_len;
301 keyinfo.DataLength = data_len;
302 keyinfo.NameLength = name_len;
303 length = min( length, (char *)keyinfo.Name - (char *)&keyinfo );
304 memcpy( info, &keyinfo, length );
305 break;
307 case KeyValuePartialInformation:
309 KEY_VALUE_PARTIAL_INFORMATION keyinfo;
310 keyinfo.TitleIndex = 0;
311 keyinfo.Type = type;
312 keyinfo.DataLength = data_len;
313 length = min( length, (char *)keyinfo.Data - (char *)&keyinfo );
314 memcpy( info, &keyinfo, length );
315 break;
317 default:
318 break;
323 /******************************************************************************
324 * NtEnumerateValueKey [NTDLL.@]
325 * ZwEnumerateValueKey [NTDLL.@]
327 NTSTATUS WINAPI NtEnumerateValueKey( HKEY handle, ULONG index,
328 KEY_VALUE_INFORMATION_CLASS info_class,
329 void *info, DWORD length, DWORD *result_len )
331 NTSTATUS ret;
332 void *ptr;
333 size_t fixed_size;
335 TRACE( "(%p,%lu,%d,%p,%ld)\n", handle, index, info_class, info, length );
337 /* compute the length we want to retrieve */
338 switch(info_class)
340 case KeyValueBasicInformation: ptr = ((KEY_VALUE_BASIC_INFORMATION *)info)->Name; break;
341 case KeyValueFullInformation: ptr = ((KEY_VALUE_FULL_INFORMATION *)info)->Name; break;
342 case KeyValuePartialInformation: ptr = ((KEY_VALUE_PARTIAL_INFORMATION *)info)->Data; break;
343 default:
344 FIXME( "Information class %d not implemented\n", info_class );
345 return STATUS_INVALID_PARAMETER;
347 fixed_size = (char *)ptr - (char *)info;
349 SERVER_START_REQ( enum_key_value )
351 req->hkey = handle;
352 req->index = index;
353 req->info_class = info_class;
354 if (length > fixed_size) wine_server_set_reply( req, ptr, length - fixed_size );
355 if (!(ret = wine_server_call( req )))
357 copy_key_value_info( info_class, info, length, reply->type, reply->namelen,
358 wine_server_reply_size(reply) - reply->namelen );
359 *result_len = fixed_size + reply->total;
360 if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
363 SERVER_END_REQ;
364 return ret;
368 /******************************************************************************
369 * NtQueryValueKey [NTDLL.@]
370 * ZwQueryValueKey [NTDLL.@]
372 * NOTES
373 * the name in the KeyValueInformation is never set
375 NTSTATUS WINAPI NtQueryValueKey( HKEY handle, const UNICODE_STRING *name,
376 KEY_VALUE_INFORMATION_CLASS info_class,
377 void *info, DWORD length, DWORD *result_len )
379 NTSTATUS ret;
380 UCHAR *data_ptr;
381 int fixed_size = 0;
383 TRACE( "(%p,%s,%d,%p,%ld)\n", handle, debugstr_us(name), info_class, info, length );
385 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
387 /* compute the length we want to retrieve */
388 switch(info_class)
390 case KeyValueBasicInformation:
391 fixed_size = (char *)((KEY_VALUE_BASIC_INFORMATION *)info)->Name - (char *)info;
392 data_ptr = NULL;
393 break;
394 case KeyValueFullInformation:
395 data_ptr = (UCHAR *)((KEY_VALUE_FULL_INFORMATION *)info)->Name;
396 fixed_size = (char *)data_ptr - (char *)info;
397 break;
398 case KeyValuePartialInformation:
399 data_ptr = ((KEY_VALUE_PARTIAL_INFORMATION *)info)->Data;
400 fixed_size = (char *)data_ptr - (char *)info;
401 break;
402 default:
403 FIXME( "Information class %d not implemented\n", info_class );
404 return STATUS_INVALID_PARAMETER;
407 SERVER_START_REQ( get_key_value )
409 req->hkey = handle;
410 wine_server_add_data( req, name->Buffer, name->Length );
411 if (length > fixed_size) wine_server_set_reply( req, data_ptr, length - fixed_size );
412 if (!(ret = wine_server_call( req )))
414 copy_key_value_info( info_class, info, length, reply->type,
415 0, wine_server_reply_size(reply) );
416 *result_len = fixed_size + reply->total;
417 if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
420 SERVER_END_REQ;
421 return ret;
425 /******************************************************************************
426 * NtFlushKey [NTDLL.@]
427 * ZwFlushKey [NTDLL.@]
429 NTSTATUS WINAPI NtFlushKey(HKEY KeyHandle)
431 FIXME("(%p) stub!\n",
432 KeyHandle);
433 return 1;
436 /******************************************************************************
437 * NtLoadKey [NTDLL.@]
438 * ZwLoadKey [NTDLL.@]
440 NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, const OBJECT_ATTRIBUTES *file )
442 FIXME("stub!\n");
443 dump_ObjectAttributes(attr);
444 dump_ObjectAttributes(file);
445 return STATUS_SUCCESS;
448 /******************************************************************************
449 * NtNotifyChangeKey [NTDLL.@]
450 * ZwNotifyChangeKey [NTDLL.@]
452 NTSTATUS WINAPI NtNotifyChangeKey(
453 IN HKEY KeyHandle,
454 IN HANDLE Event,
455 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
456 IN PVOID ApcContext OPTIONAL,
457 OUT PIO_STATUS_BLOCK IoStatusBlock,
458 IN ULONG CompletionFilter,
459 IN BOOLEAN Asynchroneous,
460 OUT PVOID ChangeBuffer,
461 IN ULONG Length,
462 IN BOOLEAN WatchSubtree)
464 FIXME("(%p,%p,%p,%p,%p,0x%08lx, 0x%08x,%p,0x%08lx,0x%08x) stub!\n",
465 KeyHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter,
466 Asynchroneous, ChangeBuffer, Length, WatchSubtree);
467 return STATUS_SUCCESS;
470 /******************************************************************************
471 * NtQueryMultipleValueKey [NTDLL]
472 * ZwQueryMultipleValueKey
475 NTSTATUS WINAPI NtQueryMultipleValueKey(
476 HKEY KeyHandle,
477 PVALENTW ListOfValuesToQuery,
478 ULONG NumberOfItems,
479 PVOID MultipleValueInformation,
480 ULONG Length,
481 PULONG ReturnLength)
483 FIXME("(%p,%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
484 KeyHandle, ListOfValuesToQuery, NumberOfItems, MultipleValueInformation,
485 Length,ReturnLength);
486 return STATUS_SUCCESS;
489 /******************************************************************************
490 * NtReplaceKey [NTDLL.@]
491 * ZwReplaceKey [NTDLL.@]
493 NTSTATUS WINAPI NtReplaceKey(
494 IN POBJECT_ATTRIBUTES ObjectAttributes,
495 IN HKEY Key,
496 IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
498 FIXME("(%p),stub!\n", Key);
499 dump_ObjectAttributes(ObjectAttributes);
500 dump_ObjectAttributes(ReplacedObjectAttributes);
501 return STATUS_SUCCESS;
503 /******************************************************************************
504 * NtRestoreKey [NTDLL.@]
505 * ZwRestoreKey [NTDLL.@]
507 NTSTATUS WINAPI NtRestoreKey(
508 HKEY KeyHandle,
509 HANDLE FileHandle,
510 ULONG RestoreFlags)
512 FIXME("(%p,%p,0x%08lx) stub\n",
513 KeyHandle, FileHandle, RestoreFlags);
514 return STATUS_SUCCESS;
516 /******************************************************************************
517 * NtSaveKey [NTDLL.@]
518 * ZwSaveKey [NTDLL.@]
520 NTSTATUS WINAPI NtSaveKey(
521 IN HKEY KeyHandle,
522 IN HANDLE FileHandle)
524 FIXME("(%p,%p) stub\n",
525 KeyHandle, FileHandle);
526 return STATUS_SUCCESS;
528 /******************************************************************************
529 * NtSetInformationKey [NTDLL.@]
530 * ZwSetInformationKey [NTDLL.@]
532 NTSTATUS WINAPI NtSetInformationKey(
533 IN HKEY KeyHandle,
534 IN const int KeyInformationClass,
535 IN PVOID KeyInformation,
536 IN ULONG KeyInformationLength)
538 FIXME("(%p,0x%08x,%p,0x%08lx) stub\n",
539 KeyHandle, KeyInformationClass, KeyInformation, KeyInformationLength);
540 return STATUS_SUCCESS;
544 /******************************************************************************
545 * NtSetValueKey [NTDLL.@]
546 * ZwSetValueKey [NTDLL.@]
548 * NOTES
549 * win95 does not care about count for REG_SZ and finds out the len by itself (js)
550 * NT does definitely care (aj)
552 NTSTATUS WINAPI NtSetValueKey( HKEY hkey, const UNICODE_STRING *name, ULONG TitleIndex,
553 ULONG type, const void *data, ULONG count )
555 NTSTATUS ret;
557 TRACE( "(%p,%s,%ld,%p,%ld)\n", hkey, debugstr_us(name), type, data, count );
559 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
561 SERVER_START_REQ( set_key_value )
563 req->hkey = hkey;
564 req->type = type;
565 req->namelen = name->Length;
566 wine_server_add_data( req, name->Buffer, name->Length );
567 wine_server_add_data( req, data, count );
568 ret = wine_server_call( req );
570 SERVER_END_REQ;
571 return ret;
574 /******************************************************************************
575 * NtUnloadKey [NTDLL.@]
576 * ZwUnloadKey [NTDLL.@]
578 NTSTATUS WINAPI NtUnloadKey(
579 IN HKEY KeyHandle)
581 FIXME("(%p) stub\n",
582 KeyHandle);
583 return STATUS_SUCCESS;
586 /******************************************************************************
587 * RtlFormatCurrentUserKeyPath [NTDLL.@]
589 * NOTE: under NT the user name part of the path is an SID.
591 NTSTATUS WINAPI RtlFormatCurrentUserKeyPath( IN OUT PUNICODE_STRING KeyPath)
593 const char *user = wine_get_user_name();
594 char *buffer;
595 ANSI_STRING AnsiPath;
596 NTSTATUS ret;
598 if (!(buffer = RtlAllocateHeap( ntdll_get_process_heap(), 0, strlen(user)+16 )))
599 return STATUS_NO_MEMORY;
601 strcpy( buffer, "\\Registry\\User\\" );
602 strcat( buffer, user );
603 RtlInitAnsiString( &AnsiPath, buffer );
604 ret = RtlAnsiStringToUnicodeString(KeyPath, &AnsiPath, TRUE);
605 RtlFreeAnsiString( &AnsiPath );
606 return ret;
609 /******************************************************************************
610 * RtlOpenCurrentUser [NTDLL.@]
612 * if we return just HKEY_CURRENT_USER the advapi tries to find a remote
613 * registry (odd handle) and fails
616 DWORD WINAPI RtlOpenCurrentUser(
617 IN ACCESS_MASK DesiredAccess, /* [in] */
618 OUT PHKEY KeyHandle) /* [out] handle of HKEY_CURRENT_USER */
620 OBJECT_ATTRIBUTES ObjectAttributes;
621 UNICODE_STRING ObjectName;
622 NTSTATUS ret;
624 TRACE("(0x%08lx, %p) stub\n",DesiredAccess, KeyHandle);
626 RtlFormatCurrentUserKeyPath(&ObjectName);
627 InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
628 ret = NtCreateKey(KeyHandle, DesiredAccess, &ObjectAttributes, 0, NULL, 0, NULL);
629 RtlFreeUnicodeString(&ObjectName);
630 return ret;