Fixed packing and layout of many system structures.
[wine/wine64.git] / dlls / ntdll / reg.c
blobf0b934e73ec6b662dbec7f2757080ba827d830ba
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 "wine/server.h"
20 #include "ntddk.h"
21 #include "ntdll_misc.h"
23 DEFAULT_DEBUG_CHANNEL(reg);
25 /* maximum length of a key/value name in bytes (without terminating null) */
26 #define MAX_NAME_LENGTH ((MAX_PATH-1) * sizeof(WCHAR))
29 /******************************************************************************
30 * NtCreateKey [NTDLL.@]
31 * ZwCreateKey [NTDLL.@]
33 NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
34 ULONG TitleIndex, const UNICODE_STRING *class, ULONG options,
35 PULONG dispos )
37 NTSTATUS ret;
38 DWORD len = attr->ObjectName->Length;
40 TRACE( "(0x%x,%s,%s,%lx,%lx,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
41 debugstr_us(class), options, access, retkey );
43 if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
44 len += sizeof(WCHAR); /* for storing name length */
45 if (class)
47 len += class->Length;
48 if (len > REQUEST_MAX_VAR_SIZE) return STATUS_BUFFER_OVERFLOW;
50 if (!retkey) return STATUS_INVALID_PARAMETER;
52 SERVER_START_VAR_REQ( create_key, len )
54 WCHAR *data = server_data_ptr(req);
56 req->parent = attr->RootDirectory;
57 req->access = access;
58 req->options = options;
59 req->modif = 0;
61 *data++ = attr->ObjectName->Length;
62 memcpy( data, attr->ObjectName->Buffer, attr->ObjectName->Length );
63 if (class) memcpy( (char *)data + attr->ObjectName->Length, class->Buffer, class->Length );
64 if (!(ret = SERVER_CALL()))
66 *retkey = req->hkey;
67 if (dispos) *dispos = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
70 SERVER_END_VAR_REQ;
71 TRACE("<- 0x%04x\n", *retkey);
72 return ret;
76 /******************************************************************************
77 * NtOpenKey [NTDLL.@]
78 * ZwOpenKey [NTDLL.@]
80 * OUT PHANDLE retkey (returns 0 when failure)
81 * IN ACCESS_MASK access
82 * IN POBJECT_ATTRIBUTES attr
84 NTSTATUS WINAPI NtOpenKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
86 NTSTATUS ret;
87 DWORD len = attr->ObjectName->Length;
89 TRACE( "(0x%x,%s,%lx,%p)\n", attr->RootDirectory,
90 debugstr_us(attr->ObjectName), access, retkey );
92 if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
93 if (!retkey) return STATUS_INVALID_PARAMETER;
95 SERVER_START_VAR_REQ( open_key, len )
97 req->parent = attr->RootDirectory;
98 req->access = access;
99 memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len );
100 ret = SERVER_CALL();
101 *retkey = req->hkey;
103 SERVER_END_VAR_REQ;
104 TRACE("<- 0x%04x\n", *retkey);
105 return ret;
109 /******************************************************************************
110 * NtDeleteKey [NTDLL.@]
111 * ZwDeleteKey [NTDLL.@]
113 NTSTATUS WINAPI NtDeleteKey( HANDLE hkey )
115 NTSTATUS ret;
117 TRACE( "(%x)\n", hkey );
119 SERVER_START_REQ( delete_key )
121 req->hkey = hkey;
122 ret = SERVER_CALL();
124 SERVER_END_REQ;
125 return ret;
129 /******************************************************************************
130 * NtDeleteValueKey [NTDLL.@]
131 * ZwDeleteValueKey [NTDLL.@]
133 NTSTATUS WINAPI NtDeleteValueKey( HANDLE hkey, const UNICODE_STRING *name )
135 NTSTATUS ret;
137 TRACE( "(0x%x,%s)\n", hkey, debugstr_us(name) );
138 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
140 SERVER_START_VAR_REQ( delete_key_value, name->Length )
142 req->hkey = hkey;
143 memcpy( server_data_ptr(req), name->Buffer, name->Length );
144 ret = SERVER_CALL();
146 SERVER_END_VAR_REQ;
147 return ret;
151 /******************************************************************************
152 * fill_key_info
154 * Helper function for NtQueryKey and NtEnumerateKey
156 static NTSTATUS fill_key_info( KEY_INFORMATION_CLASS info_class, void *info, DWORD length,
157 DWORD *result_len, const struct enum_key_request *req )
159 WCHAR *name_ptr = server_data_ptr(req);
160 int name_size = *name_ptr++;
161 WCHAR *class_ptr = (WCHAR *)((char *)name_ptr + name_size);
162 int class_size = server_data_size(req) - sizeof(WCHAR) - name_size;
163 int fixed_size;
164 LARGE_INTEGER modif;
166 RtlSecondsSince1970ToTime( req->modif, (FILETIME *)&modif );
168 switch(info_class)
170 case KeyBasicInformation:
172 KEY_BASIC_INFORMATION keyinfo;
173 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Name);
174 keyinfo.LastWriteTime = modif;
175 keyinfo.TitleIndex = 0;
176 keyinfo.NameLength = name_size;
177 memcpy( info, &keyinfo, min( length, fixed_size ) );
178 class_size = 0;
180 break;
181 case KeyFullInformation:
183 KEY_FULL_INFORMATION keyinfo;
184 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Class);
185 keyinfo.LastWriteTime = modif;
186 keyinfo.TitleIndex = 0;
187 keyinfo.ClassLength = class_size;
188 keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1;
189 keyinfo.SubKeys = req->subkeys;
190 keyinfo.MaxNameLen = req->max_subkey;
191 keyinfo.MaxClassLen = req->max_class;
192 keyinfo.Values = req->values;
193 keyinfo.MaxValueNameLen = req->max_value;
194 keyinfo.MaxValueDataLen = req->max_data;
195 memcpy( info, &keyinfo, min( length, fixed_size ) );
196 name_size = 0;
198 break;
199 case KeyNodeInformation:
201 KEY_NODE_INFORMATION keyinfo;
202 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Name);
203 keyinfo.LastWriteTime = modif;
204 keyinfo.TitleIndex = 0;
205 keyinfo.ClassLength = class_size;
206 keyinfo.ClassOffset = fixed_size + name_size;
207 if (!keyinfo.ClassLength || keyinfo.ClassOffset > length) keyinfo.ClassOffset = -1;
208 keyinfo.NameLength = name_size;
209 memcpy( info, &keyinfo, min( length, fixed_size ) );
211 break;
212 default:
213 FIXME("Information class not implemented\n");
214 return STATUS_INVALID_PARAMETER;
217 *result_len = fixed_size + name_size + class_size;
218 if (length <= fixed_size) return STATUS_BUFFER_OVERFLOW;
219 length -= fixed_size;
221 /* copy the name */
222 if (name_size)
224 memcpy( (char *)info + fixed_size, name_ptr, min(length,name_size) );
225 if (length < name_size) return STATUS_BUFFER_OVERFLOW;
226 length -= name_size;
229 /* copy the class */
230 if (class_size)
232 memcpy( (char *)info + fixed_size + name_size, class_ptr, min(length,class_size) );
233 if (length < class_size) return STATUS_BUFFER_OVERFLOW;
235 return STATUS_SUCCESS;
240 /******************************************************************************
241 * NtEnumerateKey [NTDLL.@]
242 * ZwEnumerateKey [NTDLL.@]
244 * NOTES
245 * the name copied into the buffer is NOT 0-terminated
247 NTSTATUS WINAPI NtEnumerateKey( HANDLE handle, ULONG index, KEY_INFORMATION_CLASS info_class,
248 void *info, DWORD length, DWORD *result_len )
250 NTSTATUS ret;
252 /* -1 means query key, so avoid it here */
253 if (index == (ULONG)-1) return STATUS_NO_MORE_ENTRIES;
255 SERVER_START_VAR_REQ( enum_key, REQUEST_MAX_VAR_SIZE )
257 req->hkey = handle;
258 req->index = index;
259 req->full = (info_class == KeyFullInformation);
260 if (!(ret = SERVER_CALL()))
262 ret = fill_key_info( info_class, info, length, result_len, req );
265 SERVER_END_VAR_REQ;
266 return ret;
270 /******************************************************************************
271 * NtQueryKey [NTDLL.@]
272 * ZwQueryKey [NTDLL.@]
274 NTSTATUS WINAPI NtQueryKey( HANDLE handle, KEY_INFORMATION_CLASS info_class,
275 void *info, DWORD length, DWORD *result_len )
277 NTSTATUS ret;
279 SERVER_START_VAR_REQ( enum_key, REQUEST_MAX_VAR_SIZE )
281 req->hkey = handle;
282 req->index = -1;
283 req->full = (info_class == KeyFullInformation);
284 if (!(ret = SERVER_CALL()))
286 ret = fill_key_info( info_class, info, length, result_len, req );
289 SERVER_END_VAR_REQ;
290 return ret;
294 /* fill the key value info structure for a specific info class */
295 static void copy_key_value_info( KEY_VALUE_INFORMATION_CLASS info_class, void *info,
296 DWORD length, int type, int name_len, int data_len )
298 switch(info_class)
300 case KeyValueBasicInformation:
302 KEY_VALUE_BASIC_INFORMATION keyinfo;
303 keyinfo.TitleIndex = 0;
304 keyinfo.Type = type;
305 keyinfo.NameLength = name_len;
306 length = min( length, sizeof(keyinfo) - sizeof(keyinfo.Name) );
307 memcpy( info, &keyinfo, length );
308 break;
310 case KeyValueFullInformation:
312 KEY_VALUE_FULL_INFORMATION keyinfo;
313 keyinfo.TitleIndex = 0;
314 keyinfo.Type = type;
315 keyinfo.DataOffset = sizeof(keyinfo) - sizeof(keyinfo.Name) + name_len;
316 keyinfo.DataLength = data_len;
317 keyinfo.NameLength = name_len;
318 length = min( length, sizeof(keyinfo) - sizeof(keyinfo.Name) );
319 memcpy( info, &keyinfo, length );
320 break;
322 case KeyValuePartialInformation:
324 KEY_VALUE_PARTIAL_INFORMATION keyinfo;
325 keyinfo.TitleIndex = 0;
326 keyinfo.Type = type;
327 keyinfo.DataLength = data_len;
328 length = min( length, sizeof(keyinfo) - sizeof(keyinfo.Data) );
329 memcpy( info, &keyinfo, length );
330 break;
332 default:
333 break;
338 /******************************************************************************
339 * NtEnumerateValueKey [NTDLL.@]
340 * ZwEnumerateValueKey [NTDLL.@]
342 NTSTATUS WINAPI NtEnumerateValueKey( HANDLE handle, ULONG index,
343 KEY_VALUE_INFORMATION_CLASS info_class,
344 void *info, DWORD length, DWORD *result_len )
346 NTSTATUS ret;
347 char *data_ptr, *name_ptr;
348 int fixed_size = 0, name_len = 0, data_len = 0, offset = 0, type = 0, total_len = 0;
350 TRACE( "(0x%x,%lu,%d,%p,%ld)\n", handle, index, info_class, info, length );
352 /* compute the length we want to retrieve */
353 switch(info_class)
355 case KeyValueBasicInformation:
356 fixed_size = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR);
357 name_ptr = (char *)info + fixed_size;
358 data_ptr = NULL;
359 break;
360 case KeyValueFullInformation:
361 fixed_size = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR);
362 name_ptr = data_ptr = (char *)info + fixed_size;
363 break;
364 case KeyValuePartialInformation:
365 fixed_size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(UCHAR);
366 name_ptr = NULL;
367 data_ptr = (char *)info + fixed_size;
368 break;
369 default:
370 FIXME( "Information class %d not implemented\n", info_class );
371 return STATUS_INVALID_PARAMETER;
373 if (length > fixed_size) data_len = length - fixed_size;
377 size_t reqlen = data_len + sizeof(WCHAR);
378 if (name_ptr && !offset) reqlen += MAX_PATH*sizeof(WCHAR);
379 reqlen = min( reqlen, REQUEST_MAX_VAR_SIZE );
381 SERVER_START_VAR_REQ( enum_key_value, reqlen )
383 req->hkey = handle;
384 req->index = index;
385 req->offset = offset;
387 if (!(ret = SERVER_CALL()))
389 size_t size = server_data_size(req) - sizeof(WCHAR);
390 WCHAR *name = server_data_ptr(req);
391 if (!offset) /* name is only present on the first request */
393 name_len = *name++;
394 size -= name_len;
395 if (name_ptr)
397 if (name_len > data_len) /* overflow */
399 memcpy( name_ptr, name, data_len );
400 data_len = 0;
401 ret = STATUS_BUFFER_OVERFLOW;
403 else
405 memcpy( name_ptr, name, name_len );
406 data_len -= name_len;
407 if (data_ptr) data_ptr += name_len;
410 name += name_len / sizeof(WCHAR);
412 else name++; /* skip 0 length */
414 if (data_ptr)
416 size = min( size, data_len );
417 memcpy( data_ptr + offset, name, size );
418 offset += size;
419 data_len -= size;
421 type = req->type;
422 total_len = req->len;
425 SERVER_END_VAR_REQ;
426 if (ret) return ret;
427 } while (data_len && data_ptr && offset < total_len);
429 *result_len = total_len + fixed_size + (name_ptr ? name_len : 0);
431 if (data_ptr && offset < total_len) ret = STATUS_BUFFER_OVERFLOW;
432 if (length < fixed_size) ret = STATUS_BUFFER_OVERFLOW;
434 copy_key_value_info( info_class, info, length, type, name_len, total_len );
435 return ret;
440 /******************************************************************************
441 * NtQueryValueKey [NTDLL.@]
442 * ZwQueryValueKey [NTDLL.@]
444 * NOTES
445 * the name in the KeyValueInformation is never set
447 NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name,
448 KEY_VALUE_INFORMATION_CLASS info_class,
449 void *info, DWORD length, DWORD *result_len )
451 NTSTATUS ret;
452 char *data_ptr;
453 int fixed_size = 0, data_len = 0, offset = 0, type = 0, total_len = 0;
455 TRACE( "(0x%x,%s,%d,%p,%ld)\n", handle, debugstr_us(name), info_class, info, length );
457 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
459 /* compute the length we want to retrieve */
460 switch(info_class)
462 case KeyValueBasicInformation:
463 fixed_size = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR);
464 data_ptr = NULL;
465 break;
466 case KeyValueFullInformation:
467 fixed_size = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR);
468 data_ptr = (char *)info + fixed_size;
469 break;
470 case KeyValuePartialInformation:
471 fixed_size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(UCHAR);
472 data_ptr = (char *)info + fixed_size;
473 break;
474 default:
475 FIXME( "Information class %d not implemented\n", info_class );
476 return STATUS_INVALID_PARAMETER;
478 if (data_ptr && length > fixed_size) data_len = length - fixed_size;
482 size_t reqlen = min( data_len, REQUEST_MAX_VAR_SIZE );
483 reqlen = max( reqlen, name->Length + sizeof(WCHAR) );
485 SERVER_START_VAR_REQ( get_key_value, reqlen )
487 WCHAR *nameptr = server_data_ptr(req);
489 req->hkey = handle;
490 req->offset = offset;
491 *nameptr++ = name->Length;
492 memcpy( nameptr, name->Buffer, name->Length );
494 if (!(ret = SERVER_CALL()))
496 size_t size = min( server_data_size(req), data_len );
497 type = req->type;
498 total_len = req->len;
499 if (size)
501 memcpy( data_ptr + offset, server_data_ptr(req), size );
502 offset += size;
503 data_len -= size;
507 SERVER_END_VAR_REQ;
508 if (ret) return ret;
509 } while (data_len && offset < total_len);
511 *result_len = total_len + fixed_size;
513 if (offset < total_len) ret = STATUS_BUFFER_OVERFLOW;
514 if (length < fixed_size) ret = STATUS_BUFFER_OVERFLOW;
516 copy_key_value_info( info_class, info, length, type, 0, total_len );
517 return ret;
521 /******************************************************************************
522 * NtFlushKey [NTDLL.@]
523 * ZwFlushKey [NTDLL.@]
525 NTSTATUS WINAPI NtFlushKey(HANDLE KeyHandle)
527 FIXME("(0x%08x) stub!\n",
528 KeyHandle);
529 return 1;
532 /******************************************************************************
533 * NtLoadKey [NTDLL.@]
534 * ZwLoadKey [NTDLL.@]
536 NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, const OBJECT_ATTRIBUTES *file )
538 FIXME("stub!\n");
539 dump_ObjectAttributes(attr);
540 dump_ObjectAttributes(file);
541 return STATUS_SUCCESS;
544 /******************************************************************************
545 * NtNotifyChangeKey [NTDLL.@]
546 * ZwNotifyChangeKey [NTDLL.@]
548 NTSTATUS WINAPI NtNotifyChangeKey(
549 IN HANDLE KeyHandle,
550 IN HANDLE Event,
551 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
552 IN PVOID ApcContext OPTIONAL,
553 OUT PIO_STATUS_BLOCK IoStatusBlock,
554 IN ULONG CompletionFilter,
555 IN BOOLEAN Asynchroneous,
556 OUT PVOID ChangeBuffer,
557 IN ULONG Length,
558 IN BOOLEAN WatchSubtree)
560 FIXME("(0x%08x,0x%08x,%p,%p,%p,0x%08lx, 0x%08x,%p,0x%08lx,0x%08x) stub!\n",
561 KeyHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter,
562 Asynchroneous, ChangeBuffer, Length, WatchSubtree);
563 return STATUS_SUCCESS;
566 /******************************************************************************
567 * NtQueryMultipleValueKey [NTDLL]
568 * ZwQueryMultipleValueKey
571 NTSTATUS WINAPI NtQueryMultipleValueKey(
572 HANDLE KeyHandle,
573 PVALENTW ListOfValuesToQuery,
574 ULONG NumberOfItems,
575 PVOID MultipleValueInformation,
576 ULONG Length,
577 PULONG ReturnLength)
579 FIXME("(0x%08x,%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
580 KeyHandle, ListOfValuesToQuery, NumberOfItems, MultipleValueInformation,
581 Length,ReturnLength);
582 return STATUS_SUCCESS;
585 /******************************************************************************
586 * NtReplaceKey [NTDLL.@]
587 * ZwReplaceKey [NTDLL.@]
589 NTSTATUS WINAPI NtReplaceKey(
590 IN POBJECT_ATTRIBUTES ObjectAttributes,
591 IN HANDLE Key,
592 IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
594 FIXME("(0x%08x),stub!\n", Key);
595 dump_ObjectAttributes(ObjectAttributes);
596 dump_ObjectAttributes(ReplacedObjectAttributes);
597 return STATUS_SUCCESS;
599 /******************************************************************************
600 * NtRestoreKey [NTDLL.@]
601 * ZwRestoreKey [NTDLL.@]
603 NTSTATUS WINAPI NtRestoreKey(
604 HANDLE KeyHandle,
605 HANDLE FileHandle,
606 ULONG RestoreFlags)
608 FIXME("(0x%08x,0x%08x,0x%08lx) stub\n",
609 KeyHandle, FileHandle, RestoreFlags);
610 return STATUS_SUCCESS;
612 /******************************************************************************
613 * NtSaveKey [NTDLL.@]
614 * ZwSaveKey [NTDLL.@]
616 NTSTATUS WINAPI NtSaveKey(
617 IN HANDLE KeyHandle,
618 IN HANDLE FileHandle)
620 FIXME("(0x%08x,0x%08x) stub\n",
621 KeyHandle, FileHandle);
622 return STATUS_SUCCESS;
624 /******************************************************************************
625 * NtSetInformationKey [NTDLL.@]
626 * ZwSetInformationKey [NTDLL.@]
628 NTSTATUS WINAPI NtSetInformationKey(
629 IN HANDLE KeyHandle,
630 IN const int KeyInformationClass,
631 IN PVOID KeyInformation,
632 IN ULONG KeyInformationLength)
634 FIXME("(0x%08x,0x%08x,%p,0x%08lx) stub\n",
635 KeyHandle, KeyInformationClass, KeyInformation, KeyInformationLength);
636 return STATUS_SUCCESS;
640 /******************************************************************************
641 * NtSetValueKey [NTDLL.@]
642 * ZwSetValueKey [NTDLL.@]
644 * NOTES
645 * win95 does not care about count for REG_SZ and finds out the len by itself (js)
646 * NT does definitely care (aj)
648 NTSTATUS WINAPI NtSetValueKey( HANDLE hkey, const UNICODE_STRING *name, ULONG TitleIndex,
649 ULONG type, const void *data, ULONG count )
651 NTSTATUS ret;
652 ULONG namelen, pos;
654 TRACE( "(0x%x,%s,%ld,%p,%ld)\n", hkey, debugstr_us(name), type, data, count );
656 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
658 namelen = name->Length + sizeof(WCHAR); /* for storing length */
659 pos = 0;
663 ULONG len = count - pos;
664 if (len > REQUEST_MAX_VAR_SIZE - namelen) len = REQUEST_MAX_VAR_SIZE - namelen;
666 SERVER_START_VAR_REQ( set_key_value, namelen + len )
668 WCHAR *name_ptr = server_data_ptr(req);
670 req->hkey = hkey;
671 req->type = type;
672 req->total = count;
673 req->offset = pos;
674 *name_ptr++ = name->Length;
675 memcpy( name_ptr, name->Buffer, name->Length );
676 memcpy( (char *)name_ptr + name->Length, (char *)data + pos, len );
677 pos += len;
678 ret = SERVER_CALL();
680 SERVER_END_VAR_REQ;
681 } while (!ret && pos < count);
682 return ret;
685 /******************************************************************************
686 * NtUnloadKey [NTDLL.@]
687 * ZwUnloadKey [NTDLL.@]
689 NTSTATUS WINAPI NtUnloadKey(
690 IN HANDLE KeyHandle)
692 FIXME("(0x%08x) stub\n",
693 KeyHandle);
694 return STATUS_SUCCESS;
697 /******************************************************************************
698 * RtlFormatCurrentUserKeyPath [NTDLL.@]
700 NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(
701 IN OUT PUNICODE_STRING KeyPath)
703 /* LPSTR Path = "\\REGISTRY\\USER\\S-1-5-21-0000000000-000000000-0000000000-500";*/
704 LPSTR Path = "\\REGISTRY\\USER\\.DEFAULT";
705 ANSI_STRING AnsiPath;
707 FIXME("(%p) stub\n",KeyPath);
708 RtlInitAnsiString(&AnsiPath, Path);
709 return RtlAnsiStringToUnicodeString(KeyPath, &AnsiPath, TRUE);
712 /******************************************************************************
713 * RtlOpenCurrentUser [NTDLL.@]
715 * if we return just HKEY_CURRENT_USER the advapi tries to find a remote
716 * registry (odd handle) and fails
719 DWORD WINAPI RtlOpenCurrentUser(
720 IN ACCESS_MASK DesiredAccess, /* [in] */
721 OUT PHANDLE KeyHandle) /* [out] handle of HKEY_CURRENT_USER */
723 OBJECT_ATTRIBUTES ObjectAttributes;
724 UNICODE_STRING ObjectName;
725 NTSTATUS ret;
727 TRACE("(0x%08lx, %p) stub\n",DesiredAccess, KeyHandle);
729 RtlFormatCurrentUserKeyPath(&ObjectName);
730 InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
731 ret = NtOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
732 RtlFreeUnicodeString(&ObjectName);
733 return ret;