New set of macros for server calls; makes requests without variable
[wine/multimedia.git] / dlls / ntdll / reg.c
blob3a67bd8b147c59db18dd4fe4512a84f637f7fdd8
1 /*
2 * Registry functions
4 * Copyright (C) 1999 Juergen Schmied
5 * Copyright (C) 2000 Alexandre Julliard
7 * NOTES:
8 * HKEY_LOCAL_MACHINE \\REGISTRY\\MACHINE
9 * HKEY_USERS \\REGISTRY\\USER
10 * HKEY_CURRENT_CONFIG \\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\HARDWARE PROFILES\\CURRENT
11 * HKEY_CLASSES \\REGISTRY\\MACHINE\\SOFTWARE\\CLASSES
14 #include <string.h>
15 #include "debugtools.h"
16 #include "winreg.h"
17 #include "winerror.h"
18 #include "wine/unicode.h"
19 #include "server.h"
20 #include "ntddk.h"
21 #include "ntdll_misc.h"
23 DEFAULT_DEBUG_CHANNEL(reg);
25 static const WCHAR root_name[] = { '\\','R','e','g','i','s','t','r','y','\\',0 };
26 static const UNICODE_STRING root_path =
28 sizeof(root_name)-sizeof(WCHAR), /* Length */
29 sizeof(root_name), /* MaximumLength */
30 (LPWSTR)root_name /* Buffer */
33 /* maximum length of a key/value name in bytes (without terminating null) */
34 #define MAX_NAME_LENGTH ((MAX_PATH-1) * sizeof(WCHAR))
37 /* copy a key name into the request buffer */
38 static inline NTSTATUS copy_nameU( LPWSTR Dest, const UNICODE_STRING *name, UINT max )
40 if (name->Length >= max) return STATUS_BUFFER_OVERFLOW;
41 if (name->Length) memcpy( Dest, name->Buffer, name->Length );
42 Dest[name->Length / sizeof(WCHAR)] = 0;
43 return STATUS_SUCCESS;
47 /******************************************************************************
48 * NtCreateKey [NTDLL]
49 * ZwCreateKey
51 NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
52 ULONG TitleIndex, const UNICODE_STRING *class, ULONG options,
53 PULONG dispos )
55 NTSTATUS ret;
56 DWORD len = attr->ObjectName->Length;
58 TRACE( "(0x%x,%s,%s,%lx,%lx,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
59 debugstr_us(class), options, access, retkey );
61 if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
62 len += sizeof(WCHAR); /* for storing name length */
63 if (class)
65 len += class->Length;
66 if (len > REQUEST_MAX_VAR_SIZE) return STATUS_BUFFER_OVERFLOW;
68 if (!retkey) return STATUS_INVALID_PARAMETER;
70 SERVER_START_VAR_REQ( create_key, len )
72 WCHAR *data = server_data_ptr(req);
74 req->parent = attr->RootDirectory;
75 req->access = access;
76 req->options = options;
77 req->modif = 0;
79 *data++ = attr->ObjectName->Length;
80 memcpy( data, attr->ObjectName->Buffer, attr->ObjectName->Length );
81 if (class) memcpy( (char *)data + attr->ObjectName->Length, class->Buffer, class->Length );
82 if (!(ret = SERVER_CALL()))
84 *retkey = req->hkey;
85 if (dispos) *dispos = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
88 SERVER_END_VAR_REQ;
89 TRACE("<- 0x%04x\n", *retkey);
90 return ret;
94 /******************************************************************************
95 * NtOpenKey [NTDLL.129]
96 * ZwOpenKey
97 * OUT PHANDLE retkey (returns 0 when failure)
98 * IN ACCESS_MASK access
99 * IN POBJECT_ATTRIBUTES attr
101 NTSTATUS WINAPI NtOpenKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
103 NTSTATUS ret;
104 DWORD len = attr->ObjectName->Length;
106 TRACE( "(0x%x,%s,%lx,%p)\n", attr->RootDirectory,
107 debugstr_us(attr->ObjectName), access, retkey );
109 if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
110 if (!retkey) return STATUS_INVALID_PARAMETER;
112 SERVER_START_VAR_REQ( open_key, len )
114 req->parent = attr->RootDirectory;
115 req->access = access;
116 memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len );
117 ret = SERVER_CALL();
118 *retkey = req->hkey;
120 SERVER_END_VAR_REQ;
121 TRACE("<- 0x%04x\n", *retkey);
122 return ret;
126 /******************************************************************************
127 * NtDeleteKey [NTDLL]
128 * ZwDeleteKey
130 NTSTATUS WINAPI NtDeleteKey( HANDLE hkey )
132 NTSTATUS ret;
134 TRACE( "(%x)\n", hkey );
136 SERVER_START_REQ( delete_key )
138 req->hkey = hkey;
139 ret = SERVER_CALL();
141 SERVER_END_REQ;
142 return ret;
146 /******************************************************************************
147 * NtDeleteValueKey [NTDLL]
148 * ZwDeleteValueKey
150 NTSTATUS WINAPI NtDeleteValueKey( HANDLE hkey, const UNICODE_STRING *name )
152 NTSTATUS ret;
154 TRACE( "(0x%x,%s)\n", hkey, debugstr_us(name) );
155 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
157 SERVER_START_VAR_REQ( delete_key_value, name->Length )
159 req->hkey = hkey;
160 memcpy( server_data_ptr(req), name->Buffer, name->Length );
161 ret = SERVER_CALL();
163 SERVER_END_VAR_REQ;
164 return ret;
168 /******************************************************************************
169 * fill_key_info
171 * Helper function for NtQueryKey and NtEnumerateKey
173 static NTSTATUS fill_key_info( KEY_INFORMATION_CLASS info_class, void *info, DWORD length,
174 DWORD *result_len, const struct enum_key_request *req )
176 WCHAR *name_ptr = server_data_ptr(req);
177 int name_size = *name_ptr++;
178 WCHAR *class_ptr = (WCHAR *)((char *)name_ptr + name_size);
179 int class_size = server_data_size(req) - sizeof(WCHAR) - name_size;
180 int fixed_size;
181 FILETIME modif;
183 RtlSecondsSince1970ToTime( req->modif, &modif );
185 switch(info_class)
187 case KeyBasicInformation:
189 KEY_BASIC_INFORMATION keyinfo;
190 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Name);
191 keyinfo.LastWriteTime = modif;
192 keyinfo.TitleIndex = 0;
193 keyinfo.NameLength = name_size;
194 memcpy( info, &keyinfo, min( length, fixed_size ) );
195 class_size = 0;
197 break;
198 case KeyFullInformation:
200 KEY_FULL_INFORMATION keyinfo;
201 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Class);
202 keyinfo.LastWriteTime = modif;
203 keyinfo.TitleIndex = 0;
204 keyinfo.ClassLength = class_size;
205 keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1;
206 keyinfo.SubKeys = req->subkeys;
207 keyinfo.MaxNameLen = req->max_subkey;
208 keyinfo.MaxClassLen = req->max_class;
209 keyinfo.Values = req->values;
210 keyinfo.MaxValueNameLen = req->max_value;
211 keyinfo.MaxValueDataLen = req->max_data;
212 memcpy( info, &keyinfo, min( length, fixed_size ) );
213 name_size = 0;
215 break;
216 case KeyNodeInformation:
218 KEY_NODE_INFORMATION keyinfo;
219 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Name);
220 keyinfo.LastWriteTime = modif;
221 keyinfo.TitleIndex = 0;
222 keyinfo.ClassLength = class_size;
223 keyinfo.ClassOffset = fixed_size + name_size;
224 if (!keyinfo.ClassLength || keyinfo.ClassOffset > length) keyinfo.ClassOffset = -1;
225 keyinfo.NameLength = name_size;
226 memcpy( info, &keyinfo, min( length, fixed_size ) );
228 break;
229 default:
230 FIXME("Information class not implemented\n");
231 return STATUS_INVALID_PARAMETER;
234 *result_len = fixed_size + name_size + class_size;
235 if (length <= fixed_size) return STATUS_BUFFER_OVERFLOW;
236 length -= fixed_size;
238 /* copy the name */
239 if (name_size)
241 memcpy( (char *)info + fixed_size, name_ptr, min(length,name_size) );
242 if (length < name_size) return STATUS_BUFFER_OVERFLOW;
243 length -= name_size;
246 /* copy the class */
247 if (class_size)
249 memcpy( (char *)info + fixed_size + name_size, class_ptr, min(length,class_size) );
250 if (length < class_size) return STATUS_BUFFER_OVERFLOW;
252 return STATUS_SUCCESS;
257 /******************************************************************************
258 * NtEnumerateKey [NTDLL]
259 * ZwEnumerateKey
261 * NOTES
262 * the name copied into the buffer is NOT 0-terminated
264 NTSTATUS WINAPI NtEnumerateKey( HANDLE handle, ULONG index, KEY_INFORMATION_CLASS info_class,
265 void *info, DWORD length, DWORD *result_len )
267 NTSTATUS ret;
269 /* -1 means query key, so avoid it here */
270 if (index == (ULONG)-1) return STATUS_NO_MORE_ENTRIES;
272 SERVER_START_VAR_REQ( enum_key, REQUEST_MAX_VAR_SIZE )
274 req->hkey = handle;
275 req->index = index;
276 req->full = (info_class == KeyFullInformation);
277 if (!(ret = SERVER_CALL()))
279 ret = fill_key_info( info_class, info, length, result_len, req );
282 SERVER_END_VAR_REQ;
283 return ret;
287 /******************************************************************************
288 * NtQueryKey [NTDLL]
289 * ZwQueryKey
291 NTSTATUS WINAPI NtQueryKey( HANDLE handle, KEY_INFORMATION_CLASS info_class,
292 void *info, DWORD length, DWORD *result_len )
294 NTSTATUS ret;
296 SERVER_START_VAR_REQ( enum_key, REQUEST_MAX_VAR_SIZE )
298 req->hkey = handle;
299 req->index = -1;
300 req->full = (info_class == KeyFullInformation);
301 if (!(ret = SERVER_CALL()))
303 ret = fill_key_info( info_class, info, length, result_len, req );
306 SERVER_END_VAR_REQ;
307 return ret;
311 /* fill the key value info structure for a specific info class */
312 static void copy_key_value_info( KEY_VALUE_INFORMATION_CLASS info_class, void *info,
313 DWORD length, int type, int name_len, int data_len )
315 switch(info_class)
317 case KeyValueBasicInformation:
319 KEY_VALUE_BASIC_INFORMATION keyinfo;
320 keyinfo.TitleIndex = 0;
321 keyinfo.Type = type;
322 keyinfo.NameLength = name_len;
323 length = min( length, sizeof(keyinfo) - sizeof(keyinfo.Name) );
324 memcpy( info, &keyinfo, length );
325 break;
327 case KeyValueFullInformation:
329 KEY_VALUE_FULL_INFORMATION keyinfo;
330 keyinfo.TitleIndex = 0;
331 keyinfo.Type = type;
332 keyinfo.DataOffset = sizeof(keyinfo) - sizeof(keyinfo.Name) + name_len;
333 keyinfo.DataLength = data_len;
334 keyinfo.NameLength = name_len;
335 length = min( length, sizeof(keyinfo) - sizeof(keyinfo.Name) );
336 memcpy( info, &keyinfo, length );
337 break;
339 case KeyValuePartialInformation:
341 KEY_VALUE_PARTIAL_INFORMATION keyinfo;
342 keyinfo.TitleIndex = 0;
343 keyinfo.Type = type;
344 keyinfo.DataLength = data_len;
345 length = min( length, sizeof(keyinfo) - sizeof(keyinfo.Data) );
346 memcpy( info, &keyinfo, length );
347 break;
349 default:
350 break;
355 /******************************************************************************
356 * NtEnumerateValueKey [NTDLL]
357 * ZwEnumerateValueKey
359 NTSTATUS WINAPI NtEnumerateValueKey( HANDLE handle, ULONG index,
360 KEY_VALUE_INFORMATION_CLASS info_class,
361 void *info, DWORD length, DWORD *result_len )
363 NTSTATUS ret;
364 char *data_ptr, *name_ptr;
365 int fixed_size = 0, name_len = 0, data_len = 0, offset = 0, type = 0, total_len = 0;
367 TRACE( "(0x%x,%lu,%d,%p,%ld)\n", handle, index, info_class, info, length );
369 /* compute the length we want to retrieve */
370 switch(info_class)
372 case KeyValueBasicInformation:
373 fixed_size = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR);
374 name_ptr = (char *)info + fixed_size;
375 data_ptr = NULL;
376 break;
377 case KeyValueFullInformation:
378 fixed_size = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR);
379 name_ptr = data_ptr = (char *)info + fixed_size;
380 break;
381 case KeyValuePartialInformation:
382 fixed_size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(UCHAR);
383 name_ptr = NULL;
384 data_ptr = (char *)info + fixed_size;
385 break;
386 default:
387 FIXME( "Information class %d not implemented\n", info_class );
388 return STATUS_INVALID_PARAMETER;
390 if (length > fixed_size) data_len = length - fixed_size;
394 size_t reqlen = data_len + sizeof(WCHAR);
395 if (name_ptr && !offset) reqlen += MAX_PATH*sizeof(WCHAR);
396 reqlen = min( reqlen, REQUEST_MAX_VAR_SIZE );
398 SERVER_START_VAR_REQ( enum_key_value, reqlen )
400 req->hkey = handle;
401 req->index = index;
402 req->offset = offset;
404 if (!(ret = SERVER_CALL()))
406 size_t size = server_data_size(req) - sizeof(WCHAR);
407 WCHAR *name = server_data_ptr(req);
408 if (!offset) /* name is only present on the first request */
410 name_len = *name++;
411 size -= name_len;
412 if (name_ptr)
414 if (name_len > data_len) /* overflow */
416 memcpy( name_ptr, name, data_len );
417 data_len = 0;
418 ret = STATUS_BUFFER_OVERFLOW;
420 else
422 memcpy( name_ptr, name, name_len );
423 data_len -= name_len;
424 if (data_ptr) data_ptr += name_len;
427 name += name_len / sizeof(WCHAR);
429 else name++; /* skip 0 length */
431 if (data_ptr)
433 size = min( size, data_len );
434 memcpy( data_ptr + offset, name, size );
435 offset += size;
436 data_len -= size;
438 type = req->type;
439 total_len = req->len;
442 SERVER_END_VAR_REQ;
443 if (ret) return ret;
444 } while (data_len && data_ptr && offset < total_len);
446 *result_len = total_len + fixed_size + (name_ptr ? name_len : 0);
448 if (data_ptr && offset < total_len) ret = STATUS_BUFFER_OVERFLOW;
449 if (length < fixed_size) ret = STATUS_BUFFER_OVERFLOW;
451 copy_key_value_info( info_class, info, length, type, name_len, total_len );
452 return ret;
457 /******************************************************************************
458 * NtQueryValueKey [NTDLL]
459 * ZwQueryValueKey
461 * NOTES
462 * the name in the KeyValueInformation is never set
464 NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name,
465 KEY_VALUE_INFORMATION_CLASS info_class,
466 void *info, DWORD length, DWORD *result_len )
468 NTSTATUS ret;
469 char *data_ptr;
470 int fixed_size = 0, data_len = 0, offset = 0, type = 0, total_len = 0;
472 TRACE( "(0x%x,%s,%d,%p,%ld)\n", handle, debugstr_us(name), info_class, info, length );
474 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
476 /* compute the length we want to retrieve */
477 switch(info_class)
479 case KeyValueBasicInformation:
480 fixed_size = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR);
481 data_ptr = NULL;
482 break;
483 case KeyValueFullInformation:
484 fixed_size = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR);
485 data_ptr = (char *)info + fixed_size;
486 break;
487 case KeyValuePartialInformation:
488 fixed_size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(UCHAR);
489 data_ptr = (char *)info + fixed_size;
490 break;
491 default:
492 FIXME( "Information class %d not implemented\n", info_class );
493 return STATUS_INVALID_PARAMETER;
495 if (data_ptr && length > fixed_size) data_len = length - fixed_size;
499 size_t reqlen = min( data_len, REQUEST_MAX_VAR_SIZE );
500 reqlen = max( reqlen, name->Length + sizeof(WCHAR) );
502 SERVER_START_VAR_REQ( get_key_value, reqlen )
504 WCHAR *nameptr = server_data_ptr(req);
506 req->hkey = handle;
507 req->offset = offset;
508 *nameptr++ = name->Length;
509 memcpy( nameptr, name->Buffer, name->Length );
511 if (!(ret = SERVER_CALL()))
513 size_t size = min( server_data_size(req), data_len );
514 type = req->type;
515 total_len = req->len;
516 if (size)
518 memcpy( data_ptr + offset, server_data_ptr(req), size );
519 offset += size;
520 data_len -= size;
524 SERVER_END_VAR_REQ;
525 if (ret) return ret;
526 } while (data_len && offset < total_len);
528 *result_len = total_len + fixed_size;
530 if (offset < total_len) ret = STATUS_BUFFER_OVERFLOW;
531 if (length < fixed_size) ret = STATUS_BUFFER_OVERFLOW;
533 copy_key_value_info( info_class, info, length, type, 0, total_len );
534 return ret;
538 /******************************************************************************
539 * NtFlushKey [NTDLL]
540 * ZwFlushKey
542 NTSTATUS WINAPI NtFlushKey(HANDLE KeyHandle)
544 FIXME("(0x%08x) stub!\n",
545 KeyHandle);
546 return 1;
549 /******************************************************************************
550 * NtLoadKey [NTDLL]
551 * ZwLoadKey
553 NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, const OBJECT_ATTRIBUTES *file )
555 FIXME("stub!\n");
556 dump_ObjectAttributes(attr);
557 dump_ObjectAttributes(file);
558 return STATUS_SUCCESS;
561 /******************************************************************************
562 * NtNotifyChangeKey [NTDLL]
563 * ZwNotifyChangeKey
565 NTSTATUS WINAPI NtNotifyChangeKey(
566 IN HANDLE KeyHandle,
567 IN HANDLE Event,
568 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
569 IN PVOID ApcContext OPTIONAL,
570 OUT PIO_STATUS_BLOCK IoStatusBlock,
571 IN ULONG CompletionFilter,
572 IN BOOLEAN Asynchroneous,
573 OUT PVOID ChangeBuffer,
574 IN ULONG Length,
575 IN BOOLEAN WatchSubtree)
577 FIXME("(0x%08x,0x%08x,%p,%p,%p,0x%08lx, 0x%08x,%p,0x%08lx,0x%08x) stub!\n",
578 KeyHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter,
579 Asynchroneous, ChangeBuffer, Length, WatchSubtree);
580 return STATUS_SUCCESS;
583 /******************************************************************************
584 * NtQueryMultipleValueKey [NTDLL]
585 * ZwQueryMultipleValueKey
588 NTSTATUS WINAPI NtQueryMultipleValueKey(
589 HANDLE KeyHandle,
590 PVALENTW ListOfValuesToQuery,
591 ULONG NumberOfItems,
592 PVOID MultipleValueInformation,
593 ULONG Length,
594 PULONG ReturnLength)
596 FIXME("(0x%08x,%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
597 KeyHandle, ListOfValuesToQuery, NumberOfItems, MultipleValueInformation,
598 Length,ReturnLength);
599 return STATUS_SUCCESS;
602 /******************************************************************************
603 * NtReplaceKey [NTDLL]
604 * ZwReplaceKey
606 NTSTATUS WINAPI NtReplaceKey(
607 IN POBJECT_ATTRIBUTES ObjectAttributes,
608 IN HANDLE Key,
609 IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
611 FIXME("(0x%08x),stub!\n", Key);
612 dump_ObjectAttributes(ObjectAttributes);
613 dump_ObjectAttributes(ReplacedObjectAttributes);
614 return STATUS_SUCCESS;
616 /******************************************************************************
617 * NtRestoreKey [NTDLL]
618 * ZwRestoreKey
620 NTSTATUS WINAPI NtRestoreKey(
621 HANDLE KeyHandle,
622 HANDLE FileHandle,
623 ULONG RestoreFlags)
625 FIXME("(0x%08x,0x%08x,0x%08lx) stub\n",
626 KeyHandle, FileHandle, RestoreFlags);
627 return STATUS_SUCCESS;
629 /******************************************************************************
630 * NtSaveKey [NTDLL]
631 * ZwSaveKey
633 NTSTATUS WINAPI NtSaveKey(
634 IN HANDLE KeyHandle,
635 IN HANDLE FileHandle)
637 FIXME("(0x%08x,0x%08x) stub\n",
638 KeyHandle, FileHandle);
639 return STATUS_SUCCESS;
641 /******************************************************************************
642 * NtSetInformationKey [NTDLL]
643 * ZwSetInformationKey
645 NTSTATUS WINAPI NtSetInformationKey(
646 IN HANDLE KeyHandle,
647 IN const int KeyInformationClass,
648 IN PVOID KeyInformation,
649 IN ULONG KeyInformationLength)
651 FIXME("(0x%08x,0x%08x,%p,0x%08lx) stub\n",
652 KeyHandle, KeyInformationClass, KeyInformation, KeyInformationLength);
653 return STATUS_SUCCESS;
657 /******************************************************************************
658 * NtSetValueKey [NTDLL]
659 * ZwSetValueKey
661 * NOTES
662 * win95 does not care about count for REG_SZ and finds out the len by itself (js)
663 * NT does definitely care (aj)
665 NTSTATUS WINAPI NtSetValueKey( HANDLE hkey, const UNICODE_STRING *name, ULONG TitleIndex,
666 ULONG type, const void *data, ULONG count )
668 NTSTATUS ret;
669 ULONG namelen, pos;
671 TRACE( "(0x%x,%s,%ld,%p,%ld)\n", hkey, debugstr_us(name), type, data, count );
673 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
675 namelen = name->Length + sizeof(WCHAR); /* for storing length */
676 pos = 0;
680 ULONG len = count - pos;
681 if (len > REQUEST_MAX_VAR_SIZE - namelen) len = REQUEST_MAX_VAR_SIZE - namelen;
683 SERVER_START_VAR_REQ( set_key_value, namelen + len )
685 WCHAR *name_ptr = server_data_ptr(req);
687 req->hkey = hkey;
688 req->type = type;
689 req->total = count;
690 req->offset = pos;
691 *name_ptr++ = name->Length;
692 memcpy( name_ptr, name->Buffer, name->Length );
693 memcpy( (char *)name_ptr + name->Length, (char *)data + pos, len );
694 pos += len;
695 ret = SERVER_CALL();
697 SERVER_END_VAR_REQ;
698 } while (!ret && pos < count);
699 return ret;
702 /******************************************************************************
703 * NtUnloadKey [NTDLL]
704 * ZwUnloadKey
706 NTSTATUS WINAPI NtUnloadKey(
707 IN HANDLE KeyHandle)
709 FIXME("(0x%08x) stub\n",
710 KeyHandle);
711 return STATUS_SUCCESS;
714 /******************************************************************************
715 * RtlFormatCurrentUserKeyPath [NTDLL.371]
717 NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(
718 IN OUT PUNICODE_STRING KeyPath)
720 /* LPSTR Path = "\\REGISTRY\\USER\\S-1-5-21-0000000000-000000000-0000000000-500";*/
721 LPSTR Path = "\\REGISTRY\\USER\\.DEFAULT";
722 ANSI_STRING AnsiPath;
724 FIXME("(%p) stub\n",KeyPath);
725 RtlInitAnsiString(&AnsiPath, Path);
726 return RtlAnsiStringToUnicodeString(KeyPath, &AnsiPath, TRUE);
729 /******************************************************************************
730 * RtlOpenCurrentUser [NTDLL]
732 * if we return just HKEY_CURRENT_USER the advapi try's to find a remote
733 * registry (odd handle) and fails
736 DWORD WINAPI RtlOpenCurrentUser(
737 IN ACCESS_MASK DesiredAccess, /* [in] */
738 OUT PHANDLE KeyHandle) /* [out] handle of HKEY_CURRENT_USER */
740 OBJECT_ATTRIBUTES ObjectAttributes;
741 UNICODE_STRING ObjectName;
742 NTSTATUS ret;
744 TRACE("(0x%08lx, %p) stub\n",DesiredAccess, KeyHandle);
746 RtlFormatCurrentUserKeyPath(&ObjectName);
747 InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
748 ret = NtOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
749 RtlFreeUnicodeString(&ObjectName);
750 return ret;