Fixed a few prototypes.
[wine/dcerpc.git] / dlls / ntdll / reg.c
blob45148b4c258c9122304b216abb5b3f1c9b32b5d3
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 "debugtools.h"
15 #include "winreg.h"
16 #include "winerror.h"
17 #include "wine/unicode.h"
18 #include "server.h"
19 #include "ntddk.h"
20 #include "ntdll_misc.h"
22 DEFAULT_DEBUG_CHANNEL(reg);
24 static const WCHAR root_name[] = { '\\','R','e','g','i','s','t','r','y','\\',0 };
25 static const UNICODE_STRING root_path =
27 sizeof(root_name)-sizeof(WCHAR), /* Length */
28 sizeof(root_name), /* MaximumLength */
29 (LPWSTR)root_name /* Buffer */
32 /* maximum length of a key/value name in bytes (without terminating null) */
33 #define MAX_NAME_LENGTH ((MAX_PATH-1) * sizeof(WCHAR))
36 /* copy a key name into the request buffer */
37 static inline NTSTATUS copy_nameU( LPWSTR Dest, const UNICODE_STRING *name, UINT max )
39 if (name->Length >= max) return STATUS_BUFFER_OVERFLOW;
40 if (name->Length) memcpy( Dest, name->Buffer, name->Length );
41 Dest[name->Length / sizeof(WCHAR)] = 0;
42 return STATUS_SUCCESS;
46 /******************************************************************************
47 * NtCreateKey [NTDLL]
48 * ZwCreateKey
50 NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
51 ULONG TitleIndex, const UNICODE_STRING *class, ULONG options,
52 PULONG dispos )
54 NTSTATUS ret;
55 DWORD len = attr->ObjectName->Length;
57 TRACE( "(0x%x,%s,%s,%lx,%lx,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
58 debugstr_us(class), options, access, retkey );
60 if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
61 len += sizeof(WCHAR); /* for storing name length */
62 if (class)
64 len += class->Length;
65 if (len > REQUEST_MAX_VAR_SIZE) return STATUS_BUFFER_OVERFLOW;
67 if (!retkey) return STATUS_INVALID_PARAMETER;
69 SERVER_START_REQ
71 struct create_key_request *req = server_alloc_req( sizeof(*req), 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_noerr( REQ_CREATE_KEY )))
84 *retkey = req->hkey;
85 if (dispos) *dispos = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
88 SERVER_END_REQ;
89 return ret;
93 /******************************************************************************
94 * NtOpenKey [NTDLL.129]
95 * ZwOpenKey
96 * OUT PHANDLE retkey (returns 0 when failure)
97 * IN ACCESS_MASK access
98 * IN POBJECT_ATTRIBUTES attr
100 NTSTATUS WINAPI NtOpenKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
102 NTSTATUS ret;
103 DWORD len = attr->ObjectName->Length;
105 TRACE( "(0x%x,%s,%lx,%p)\n", attr->RootDirectory,
106 debugstr_us(attr->ObjectName), access, retkey );
108 if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
109 if (!retkey) return STATUS_INVALID_PARAMETER;
110 *retkey = 0;
112 SERVER_START_REQ
114 struct open_key_request *req = server_alloc_req( sizeof(*req), len );
115 req->parent = attr->RootDirectory;
116 req->access = access;
117 memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len );
118 if (!(ret = server_call_noerr( REQ_OPEN_KEY ))) *retkey = req->hkey;
120 SERVER_END_REQ;
121 return ret;
125 /******************************************************************************
126 * NtDeleteKey [NTDLL]
127 * ZwDeleteKey
129 NTSTATUS WINAPI NtDeleteKey( HANDLE hkey )
131 NTSTATUS ret;
133 TRACE( "(%x)\n", hkey );
135 SERVER_START_REQ
137 struct delete_key_request *req = server_alloc_req( sizeof(*req), 0 );
138 req->hkey = hkey;
139 ret = server_call_noerr( REQ_DELETE_KEY );
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_REQ
159 struct delete_key_value_request *req = server_alloc_req( sizeof(*req), name->Length );
161 req->hkey = hkey;
162 memcpy( server_data_ptr(req), name->Buffer, name->Length );
163 ret = server_call_noerr( REQ_DELETE_KEY_VALUE );
165 SERVER_END_REQ;
166 return ret;
170 /******************************************************************************
171 * fill_key_info
173 * Helper function for NtQueryKey and NtEnumerateKey
175 static NTSTATUS fill_key_info( KEY_INFORMATION_CLASS info_class, void *info, DWORD length,
176 DWORD *result_len, const struct enum_key_request *req )
178 WCHAR *name_ptr = server_data_ptr(req);
179 int name_size = *name_ptr++;
180 WCHAR *class_ptr = (WCHAR *)((char *)name_ptr + name_size);
181 int class_size = server_data_size(req) - sizeof(WCHAR) - name_size;
182 int fixed_size;
183 FILETIME modif;
185 RtlSecondsSince1970ToTime( req->modif, &modif );
187 switch(info_class)
189 case KeyBasicInformation:
191 KEY_BASIC_INFORMATION keyinfo;
192 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Name);
193 keyinfo.LastWriteTime = modif;
194 keyinfo.TitleIndex = 0;
195 keyinfo.NameLength = name_size;
196 memcpy( info, &keyinfo, min( length, fixed_size ) );
197 class_size = 0;
199 break;
200 case KeyFullInformation:
202 KEY_FULL_INFORMATION keyinfo;
203 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Class);
204 keyinfo.LastWriteTime = modif;
205 keyinfo.TitleIndex = 0;
206 keyinfo.ClassLength = class_size;
207 keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1;
208 keyinfo.SubKeys = req->subkeys;
209 keyinfo.MaxNameLen = req->max_subkey;
210 keyinfo.MaxClassLen = req->max_class;
211 keyinfo.Values = req->values;
212 keyinfo.MaxValueNameLen = req->max_value;
213 keyinfo.MaxValueDataLen = req->max_data;
214 memcpy( info, &keyinfo, min( length, fixed_size ) );
215 name_size = 0;
217 break;
218 case KeyNodeInformation:
220 KEY_NODE_INFORMATION keyinfo;
221 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Name);
222 keyinfo.LastWriteTime = modif;
223 keyinfo.TitleIndex = 0;
224 keyinfo.ClassLength = class_size;
225 keyinfo.ClassOffset = fixed_size + name_size;
226 if (!keyinfo.ClassLength || keyinfo.ClassOffset > length) keyinfo.ClassOffset = -1;
227 keyinfo.NameLength = name_size;
228 memcpy( info, &keyinfo, min( length, fixed_size ) );
230 break;
231 default:
232 FIXME("Information class not implemented\n");
233 return STATUS_INVALID_PARAMETER;
236 *result_len = fixed_size + name_size + class_size;
237 if (length <= fixed_size) return STATUS_BUFFER_OVERFLOW;
238 length -= fixed_size;
240 /* copy the name */
241 if (name_size)
243 memcpy( (char *)info + fixed_size, name_ptr, min(length,name_size) );
244 if (length < name_size) return STATUS_BUFFER_OVERFLOW;
245 length -= name_size;
248 /* copy the class */
249 if (class_size)
251 memcpy( (char *)info + fixed_size + name_size, class_ptr, min(length,class_size) );
252 if (length < class_size) return STATUS_BUFFER_OVERFLOW;
254 return STATUS_SUCCESS;
259 /******************************************************************************
260 * NtEnumerateKey [NTDLL]
261 * ZwEnumerateKey
263 * NOTES
264 * the name copied into the buffer is NOT 0-terminated
266 NTSTATUS WINAPI NtEnumerateKey( HANDLE handle, ULONG index, KEY_INFORMATION_CLASS info_class,
267 void *info, DWORD length, DWORD *result_len )
269 NTSTATUS ret;
271 /* -1 means query key, so avoid it here */
272 if (index == (ULONG)-1) return STATUS_NO_MORE_ENTRIES;
274 SERVER_START_REQ
276 struct enum_key_request *req = server_alloc_req( sizeof(*req), REQUEST_MAX_VAR_SIZE );
277 req->hkey = handle;
278 req->index = index;
279 req->full = (info_class == KeyFullInformation);
280 if (!(ret = server_call_noerr( REQ_ENUM_KEY )))
282 ret = fill_key_info( info_class, info, length, result_len, req );
285 SERVER_END_REQ;
286 return ret;
290 /******************************************************************************
291 * NtQueryKey [NTDLL]
292 * ZwQueryKey
294 NTSTATUS WINAPI NtQueryKey( HANDLE handle, KEY_INFORMATION_CLASS info_class,
295 void *info, DWORD length, DWORD *result_len )
297 NTSTATUS ret;
299 SERVER_START_REQ
301 struct enum_key_request *req = server_alloc_req( sizeof(*req), REQUEST_MAX_VAR_SIZE );
302 req->hkey = handle;
303 req->index = -1;
304 req->full = (info_class == KeyFullInformation);
305 if (!(ret = server_call_noerr( REQ_ENUM_KEY )))
307 ret = fill_key_info( info_class, info, length, result_len, req );
310 SERVER_END_REQ;
311 return ret;
314 /******************************************************************************
315 * NtEnumerateValueKey [NTDLL]
316 * ZwEnumerateValueKey
318 NTSTATUS WINAPI NtEnumerateValueKey(
319 HANDLE KeyHandle,
320 ULONG Index,
321 KEY_VALUE_INFORMATION_CLASS KeyInformationClass,
322 PVOID KeyInformation,
323 ULONG Length,
324 PULONG ResultLength)
326 struct enum_key_value_request *req = get_req_buffer();
327 UINT NameLength;
328 NTSTATUS ret;
330 TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
331 KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
333 req->hkey = KeyHandle;
334 req->index = Index;
335 if ((ret = server_call_noerr(REQ_ENUM_KEY_VALUE)) != STATUS_SUCCESS) return ret;
337 switch (KeyInformationClass)
339 case KeyBasicInformation:
341 PKEY_VALUE_BASIC_INFORMATION kbi = KeyInformation;
343 NameLength = strlenW(req->name) * sizeof(WCHAR);
344 *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR) + NameLength;
345 if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
347 kbi->TitleIndex = 0;
348 kbi->Type = req->type;
349 kbi->NameLength = NameLength;
350 memcpy(kbi->Name, req->name, kbi->NameLength);
352 break;
353 case KeyValueFullInformation:
355 PKEY_VALUE_FULL_INFORMATION kbi = KeyInformation;
356 UINT DataOffset;
358 NameLength = strlenW(req->name) * sizeof(WCHAR);
359 DataOffset = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR) + NameLength;
360 *ResultLength = DataOffset + req->len;
362 if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
364 kbi->TitleIndex = 0;
365 kbi->Type = req->type;
366 kbi->DataOffset = DataOffset;
367 kbi->DataLength = req->len;
368 kbi->NameLength = NameLength;
369 memcpy(kbi->Name, req->name, kbi->NameLength);
370 memcpy(((LPBYTE)kbi) + DataOffset, req->data, req->len);
372 break;
373 case KeyValuePartialInformation:
375 PKEY_VALUE_PARTIAL_INFORMATION kbi = KeyInformation;
377 *ResultLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(WCHAR) + req->len;
379 if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
381 kbi->TitleIndex = 0;
382 kbi->Type = req->type;
383 kbi->DataLength = req->len;
384 memcpy(kbi->Data, req->data, req->len);
386 break;
387 default:
388 FIXME("not implemented\n");
390 return STATUS_SUCCESS;
393 /******************************************************************************
394 * NtFlushKey [NTDLL]
395 * ZwFlushKey
397 NTSTATUS WINAPI NtFlushKey(HANDLE KeyHandle)
399 FIXME("(0x%08x) stub!\n",
400 KeyHandle);
401 return 1;
404 /******************************************************************************
405 * NtLoadKey [NTDLL]
406 * ZwLoadKey
408 NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, const OBJECT_ATTRIBUTES *file )
410 FIXME("stub!\n");
411 dump_ObjectAttributes(attr);
412 dump_ObjectAttributes(file);
413 return STATUS_SUCCESS;
416 /******************************************************************************
417 * NtNotifyChangeKey [NTDLL]
418 * ZwNotifyChangeKey
420 NTSTATUS WINAPI NtNotifyChangeKey(
421 IN HANDLE KeyHandle,
422 IN HANDLE Event,
423 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
424 IN PVOID ApcContext OPTIONAL,
425 OUT PIO_STATUS_BLOCK IoStatusBlock,
426 IN ULONG CompletionFilter,
427 IN BOOLEAN Asynchroneous,
428 OUT PVOID ChangeBuffer,
429 IN ULONG Length,
430 IN BOOLEAN WatchSubtree)
432 FIXME("(0x%08x,0x%08x,%p,%p,%p,0x%08lx, 0x%08x,%p,0x%08lx,0x%08x) stub!\n",
433 KeyHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter,
434 Asynchroneous, ChangeBuffer, Length, WatchSubtree);
435 return STATUS_SUCCESS;
438 /******************************************************************************
439 * NtQueryMultipleValueKey [NTDLL]
440 * ZwQueryMultipleValueKey
443 NTSTATUS WINAPI NtQueryMultipleValueKey(
444 HANDLE KeyHandle,
445 PVALENTW ListOfValuesToQuery,
446 ULONG NumberOfItems,
447 PVOID MultipleValueInformation,
448 ULONG Length,
449 PULONG ReturnLength)
451 FIXME("(0x%08x,%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
452 KeyHandle, ListOfValuesToQuery, NumberOfItems, MultipleValueInformation,
453 Length,ReturnLength);
454 return STATUS_SUCCESS;
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_REQ
504 struct get_key_value_request *req = server_alloc_req( sizeof(*req), reqlen );
505 WCHAR *nameptr = server_data_ptr(req);
507 req->hkey = handle;
508 req->offset = offset;
509 *nameptr++ = name->Length;
510 memcpy( nameptr, name->Buffer, name->Length );
512 if (!(ret = server_call_noerr( REQ_GET_KEY_VALUE )))
514 size_t size = min( server_data_size(req), data_len );
515 type = req->type;
516 total_len = req->len;
517 if (size)
519 memcpy( data_ptr + offset, server_data_ptr(req), size );
520 offset += size;
521 data_len -= size;
525 SERVER_END_REQ;
526 if (ret) return ret;
527 } while (data_len && offset < total_len);
529 *result_len = total_len + fixed_size;
531 if (offset < total_len) ret = STATUS_BUFFER_OVERFLOW;
532 if (length < fixed_size) ret = STATUS_BUFFER_OVERFLOW;
534 switch(info_class)
536 case KeyValueBasicInformation:
538 KEY_VALUE_BASIC_INFORMATION keyinfo;
539 keyinfo.TitleIndex = 0;
540 keyinfo.Type = type;
541 keyinfo.NameLength = 0;
542 memcpy( info, &keyinfo, min(fixed_size,length) );
543 break;
545 case KeyValueFullInformation:
547 KEY_VALUE_FULL_INFORMATION keyinfo;
548 keyinfo.TitleIndex = 0;
549 keyinfo.Type = type;
550 keyinfo.DataOffset = fixed_size;
551 keyinfo.DataLength = total_len;
552 keyinfo.NameLength = 0;
553 memcpy( info, &keyinfo, min(fixed_size,length) );
554 break;
556 case KeyValuePartialInformation:
558 KEY_VALUE_PARTIAL_INFORMATION keyinfo;
559 keyinfo.TitleIndex = 0;
560 keyinfo.Type = type;
561 keyinfo.DataLength = total_len;
562 memcpy( info, &keyinfo, min(fixed_size,length) );
563 break;
565 default:
566 break;
568 return ret;
571 /******************************************************************************
572 * NtReplaceKey [NTDLL]
573 * ZwReplaceKey
575 NTSTATUS WINAPI NtReplaceKey(
576 IN POBJECT_ATTRIBUTES ObjectAttributes,
577 IN HANDLE Key,
578 IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
580 FIXME("(0x%08x),stub!\n", Key);
581 dump_ObjectAttributes(ObjectAttributes);
582 dump_ObjectAttributes(ReplacedObjectAttributes);
583 return STATUS_SUCCESS;
585 /******************************************************************************
586 * NtRestoreKey [NTDLL]
587 * ZwRestoreKey
589 NTSTATUS WINAPI NtRestoreKey(
590 HANDLE KeyHandle,
591 HANDLE FileHandle,
592 ULONG RestoreFlags)
594 FIXME("(0x%08x,0x%08x,0x%08lx) stub\n",
595 KeyHandle, FileHandle, RestoreFlags);
596 return STATUS_SUCCESS;
598 /******************************************************************************
599 * NtSaveKey [NTDLL]
600 * ZwSaveKey
602 NTSTATUS WINAPI NtSaveKey(
603 IN HANDLE KeyHandle,
604 IN HANDLE FileHandle)
606 FIXME("(0x%08x,0x%08x) stub\n",
607 KeyHandle, FileHandle);
608 return STATUS_SUCCESS;
610 /******************************************************************************
611 * NtSetInformationKey [NTDLL]
612 * ZwSetInformationKey
614 NTSTATUS WINAPI NtSetInformationKey(
615 IN HANDLE KeyHandle,
616 IN const int KeyInformationClass,
617 IN PVOID KeyInformation,
618 IN ULONG KeyInformationLength)
620 FIXME("(0x%08x,0x%08x,%p,0x%08lx) stub\n",
621 KeyHandle, KeyInformationClass, KeyInformation, KeyInformationLength);
622 return STATUS_SUCCESS;
626 /******************************************************************************
627 * NtSetValueKey [NTDLL]
628 * ZwSetValueKey
630 * NOTES
631 * win95 does not care about count for REG_SZ and finds out the len by itself (js)
632 * NT does definitely care (aj)
634 NTSTATUS WINAPI NtSetValueKey( HANDLE hkey, const UNICODE_STRING *name, ULONG TitleIndex,
635 ULONG type, const void *data, ULONG count )
637 NTSTATUS ret;
638 ULONG namelen, pos;
640 TRACE( "(0x%x,%s,%ld,%p,%ld)\n", hkey, debugstr_us(name), type, data, count );
642 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
644 namelen = name->Length + sizeof(WCHAR); /* for storing length */
645 pos = 0;
649 ULONG len = count - pos;
650 if (len > REQUEST_MAX_VAR_SIZE - namelen) len = REQUEST_MAX_VAR_SIZE - namelen;
652 SERVER_START_REQ
654 struct set_key_value_request *req = server_alloc_req( sizeof(*req), namelen + len );
655 WCHAR *name_ptr = server_data_ptr(req);
657 req->hkey = hkey;
658 req->type = type;
659 req->total = count;
660 req->offset = pos;
661 *name_ptr++ = name->Length;
662 memcpy( name_ptr, name->Buffer, name->Length );
663 memcpy( (char *)name_ptr + name->Length, (char *)data + pos, len );
664 pos += len;
665 ret = server_call_noerr( REQ_SET_KEY_VALUE );
667 SERVER_END_REQ;
668 } while (!ret && pos < count);
669 return ret;
672 /******************************************************************************
673 * NtUnloadKey [NTDLL]
674 * ZwUnloadKey
676 NTSTATUS WINAPI NtUnloadKey(
677 IN HANDLE KeyHandle)
679 FIXME("(0x%08x) stub\n",
680 KeyHandle);
681 return STATUS_SUCCESS;
684 /******************************************************************************
685 * RtlFormatCurrentUserKeyPath [NTDLL.371]
687 NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(
688 IN OUT PUNICODE_STRING KeyPath)
690 /* LPSTR Path = "\\REGISTRY\\USER\\S-1-5-21-0000000000-000000000-0000000000-500";*/
691 LPSTR Path = "\\REGISTRY\\USER\\.DEFAULT";
692 ANSI_STRING AnsiPath;
694 FIXME("(%p) stub\n",KeyPath);
695 RtlInitAnsiString(&AnsiPath, Path);
696 return RtlAnsiStringToUnicodeString(KeyPath, &AnsiPath, TRUE);
699 /******************************************************************************
700 * RtlOpenCurrentUser [NTDLL]
702 * if we return just HKEY_CURRENT_USER the advapi try's to find a remote
703 * registry (odd handle) and fails
706 DWORD WINAPI RtlOpenCurrentUser(
707 IN ACCESS_MASK DesiredAccess,
708 OUT PHANDLE KeyHandle) /* handle of HKEY_CURRENT_USER */
710 OBJECT_ATTRIBUTES ObjectAttributes;
711 UNICODE_STRING ObjectName;
712 NTSTATUS ret;
714 TRACE("(0x%08lx, %p) stub\n",DesiredAccess, KeyHandle);
716 RtlFormatCurrentUserKeyPath(&ObjectName);
717 InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
718 ret = NtOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
719 RtlFreeUnicodeString(&ObjectName);
720 return ret;