4 * Copyright (C) 1999 Juergen Schmied
5 * Copyright (C) 2000 Alexandre Julliard
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"
17 #include "wine/unicode.h"
20 #include "ntdll_misc.h"
22 DEFAULT_DEBUG_CHANNEL(ntdll
);
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 /******************************************************************************
50 NTSTATUS WINAPI
NtCreateKey( PHANDLE retkey
, ACCESS_MASK access
, const OBJECT_ATTRIBUTES
*attr
,
51 ULONG TitleIndex
, const UNICODE_STRING
*class, ULONG options
,
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 */
65 if (len
> REQUEST_MAX_VAR_SIZE
) return STATUS_BUFFER_OVERFLOW
;
67 if (!retkey
) return STATUS_INVALID_PARAMETER
;
71 struct create_key_request
*req
= server_alloc_req( sizeof(*req
), len
);
72 WCHAR
*data
= server_data_ptr(req
);
74 req
->parent
= attr
->RootDirectory
;
76 req
->options
= options
;
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
)))
85 if (dispos
) *dispos
= req
->created
? REG_CREATED_NEW_KEY
: REG_OPENED_EXISTING_KEY
;
93 /******************************************************************************
94 * NtOpenKey [NTDLL.129]
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
)
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
;
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
;
125 /******************************************************************************
126 * NtDeleteKey [NTDLL]
129 NTSTATUS WINAPI
NtDeleteKey( HANDLE hkey
)
133 TRACE( "(%x)\n", hkey
);
137 struct delete_key_request
*req
= server_alloc_req( sizeof(*req
), 0 );
139 ret
= server_call_noerr( REQ_DELETE_KEY
);
146 /******************************************************************************
147 * NtDeleteValueKey [NTDLL]
150 NTSTATUS WINAPI
NtDeleteValueKey( HANDLE hkey
, const UNICODE_STRING
*name
)
154 TRACE( "(0x%x,%s)\n", hkey
, debugstr_us(name
) );
155 if (name
->Length
> MAX_NAME_LENGTH
) return STATUS_BUFFER_OVERFLOW
;
159 struct delete_key_value_request
*req
= server_alloc_req( sizeof(*req
), name
->Length
);
162 memcpy( server_data_ptr(req
), name
->Buffer
, name
->Length
);
163 ret
= server_call_noerr( REQ_DELETE_KEY_VALUE
);
170 /******************************************************************************
171 * NtEnumerateKey [NTDLL]
175 * the name copied into the buffer is NOT 0-terminated
177 NTSTATUS WINAPI
NtEnumerateKey(
180 KEY_INFORMATION_CLASS KeyInformationClass
,
181 PVOID KeyInformation
,
185 struct enum_key_request
*req
= get_req_buffer();
188 TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
189 KeyHandle
, Index
, KeyInformationClass
, KeyInformation
, Length
, ResultLength
);
191 req
->hkey
= KeyHandle
;
193 if ((ret
= server_call_noerr(REQ_ENUM_KEY
)) != STATUS_SUCCESS
) return ret
;
195 switch (KeyInformationClass
)
197 case KeyBasicInformation
:
199 PKEY_BASIC_INFORMATION kbi
= KeyInformation
;
200 UINT NameLength
= strlenW(req
->name
) * sizeof(WCHAR
);
201 *ResultLength
= sizeof(KEY_BASIC_INFORMATION
) - sizeof(WCHAR
) + NameLength
;
202 if (Length
< *ResultLength
) return STATUS_BUFFER_OVERFLOW
;
204 RtlSecondsSince1970ToTime(req
->modif
, &kbi
->LastWriteTime
);
206 kbi
->NameLength
= NameLength
;
207 memcpy (kbi
->Name
, req
->name
, NameLength
);
210 case KeyFullInformation
:
212 PKEY_FULL_INFORMATION kfi
= KeyInformation
;
213 kfi
->ClassLength
= strlenW(req
->class) * sizeof(WCHAR
);
214 kfi
->ClassOffset
= (kfi
->ClassLength
) ?
215 sizeof(KEY_FULL_INFORMATION
) - sizeof(WCHAR
) : 0xffffffff;
216 *ResultLength
= sizeof(KEY_FULL_INFORMATION
) - sizeof(WCHAR
) + kfi
->ClassLength
;
217 if (Length
< *ResultLength
) return STATUS_BUFFER_OVERFLOW
;
219 RtlSecondsSince1970ToTime(req
->modif
, &kfi
->LastWriteTime
);
221 /* kfi->SubKeys = req->subkeys;
222 kfi->MaxNameLength = req->max_subkey;
223 kfi->MaxClassLength = req->max_class;
224 kfi->Values = req->values;
225 kfi->MaxValueNameLen = req->max_value;
226 kfi->MaxValueDataLen = req->max_data;
228 FIXME("incomplete\n");
229 if (kfi
->ClassLength
) memcpy (kfi
->Class
, req
->class, kfi
->ClassLength
);
232 case KeyNodeInformation
:
234 PKEY_NODE_INFORMATION kni
= KeyInformation
;
235 kni
->ClassLength
= strlenW(req
->class) * sizeof(WCHAR
);
236 kni
->NameLength
= strlenW(req
->name
) * sizeof(WCHAR
);
237 kni
->ClassOffset
= (kni
->ClassLength
) ?
238 sizeof(KEY_NODE_INFORMATION
) - sizeof(WCHAR
) + kni
->NameLength
: 0xffffffff;
240 *ResultLength
= sizeof(KEY_NODE_INFORMATION
) - sizeof(WCHAR
) + kni
->NameLength
+ kni
->ClassLength
;
241 if (Length
< *ResultLength
) return STATUS_BUFFER_OVERFLOW
;
243 RtlSecondsSince1970ToTime(req
->modif
, &kni
->LastWriteTime
);
245 memcpy (kni
->Name
, req
->name
, kni
->NameLength
);
246 if (kni
->ClassLength
) memcpy ((char *) KeyInformation
+ kni
->ClassOffset
, req
->class, kni
->ClassLength
);
250 FIXME("KeyInformationClass not implemented\n");
251 return STATUS_UNSUCCESSFUL
;
253 TRACE("buf=%lu len=%lu\n", Length
, *ResultLength
);
257 /******************************************************************************
261 NTSTATUS WINAPI
NtQueryKey(
263 KEY_INFORMATION_CLASS KeyInformationClass
,
264 PVOID KeyInformation
,
268 struct query_key_info_request
*req
= get_req_buffer();
271 TRACE("(0x%08x,0x%08x,%p,0x%08lx,%p) stub\n",
272 KeyHandle
, KeyInformationClass
, KeyInformation
, Length
, ResultLength
);
274 req
->hkey
= KeyHandle
;
275 if ((ret
= server_call_noerr(REQ_QUERY_KEY_INFO
)) != STATUS_SUCCESS
) return ret
;
277 switch (KeyInformationClass
)
279 case KeyBasicInformation
:
281 PKEY_BASIC_INFORMATION kbi
= KeyInformation
;
282 UINT NameLength
= strlenW(req
->name
) * sizeof(WCHAR
);
283 *ResultLength
= sizeof(KEY_BASIC_INFORMATION
) - sizeof(WCHAR
) + NameLength
;
284 if (Length
< *ResultLength
) return STATUS_BUFFER_OVERFLOW
;
286 RtlSecondsSince1970ToTime(req
->modif
, &kbi
->LastWriteTime
);
288 kbi
->NameLength
= NameLength
;
289 memcpy (kbi
->Name
, req
->name
, NameLength
);
292 case KeyFullInformation
:
294 PKEY_FULL_INFORMATION kfi
= KeyInformation
;
295 kfi
->ClassLength
= strlenW(req
->class) * sizeof(WCHAR
);
296 kfi
->ClassOffset
= (kfi
->ClassLength
) ?
297 sizeof(KEY_FULL_INFORMATION
) - sizeof(WCHAR
) : 0xffffffff;
299 *ResultLength
= sizeof(KEY_FULL_INFORMATION
) - sizeof(WCHAR
) + kfi
->ClassLength
;
300 if (Length
< *ResultLength
) return STATUS_BUFFER_OVERFLOW
;
302 RtlSecondsSince1970ToTime(req
->modif
, &kfi
->LastWriteTime
);
304 kfi
->SubKeys
= req
->subkeys
;
305 kfi
->MaxNameLen
= req
->max_subkey
;
306 kfi
->MaxClassLen
= req
->max_class
;
307 kfi
->Values
= req
->values
;
308 kfi
->MaxValueNameLen
= req
->max_value
;
309 kfi
->MaxValueDataLen
= req
->max_data
;
310 if(kfi
->ClassLength
) memcpy ((char *) KeyInformation
+ kfi
->ClassOffset
, req
->class, kfi
->ClassLength
);
313 case KeyNodeInformation
:
315 PKEY_NODE_INFORMATION kni
= KeyInformation
;
316 kni
->ClassLength
= strlenW(req
->class) * sizeof(WCHAR
);
317 kni
->NameLength
= strlenW(req
->name
) * sizeof(WCHAR
);
318 kni
->ClassOffset
= (kni
->ClassLength
) ?
319 sizeof(KEY_NODE_INFORMATION
) - sizeof(WCHAR
) + kni
->NameLength
: 0xffffffff;
321 *ResultLength
= sizeof(KEY_NODE_INFORMATION
) - sizeof(WCHAR
) + kni
->NameLength
+ kni
->ClassLength
;
322 if (Length
< *ResultLength
) return STATUS_BUFFER_OVERFLOW
;
324 RtlSecondsSince1970ToTime(req
->modif
, &kni
->LastWriteTime
);
326 memcpy (kni
->Name
, req
->name
, kni
->NameLength
);
327 if(kni
->ClassLength
) memcpy ((char *) KeyInformation
+ kni
->ClassOffset
, req
->class, kni
->ClassLength
);
331 FIXME("KeyInformationClass not implemented\n");
332 return STATUS_UNSUCCESSFUL
;
337 /******************************************************************************
338 * NtEnumerateValueKey [NTDLL]
339 * ZwEnumerateValueKey
341 NTSTATUS WINAPI
NtEnumerateValueKey(
344 KEY_VALUE_INFORMATION_CLASS KeyInformationClass
,
345 PVOID KeyInformation
,
349 struct enum_key_value_request
*req
= get_req_buffer();
353 TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
354 KeyHandle
, Index
, KeyInformationClass
, KeyInformation
, Length
, ResultLength
);
356 req
->hkey
= KeyHandle
;
358 if ((ret
= server_call_noerr(REQ_ENUM_KEY_VALUE
)) != STATUS_SUCCESS
) return ret
;
360 switch (KeyInformationClass
)
362 case KeyBasicInformation
:
364 PKEY_VALUE_BASIC_INFORMATION kbi
= KeyInformation
;
366 NameLength
= strlenW(req
->name
) * sizeof(WCHAR
);
367 *ResultLength
= sizeof(KEY_VALUE_BASIC_INFORMATION
) - sizeof(WCHAR
) + NameLength
;
368 if (*ResultLength
> Length
) return STATUS_BUFFER_TOO_SMALL
;
371 kbi
->Type
= req
->type
;
372 kbi
->NameLength
= NameLength
;
373 memcpy(kbi
->Name
, req
->name
, kbi
->NameLength
);
376 case KeyValueFullInformation
:
378 PKEY_VALUE_FULL_INFORMATION kbi
= KeyInformation
;
381 NameLength
= strlenW(req
->name
) * sizeof(WCHAR
);
382 DataOffset
= sizeof(KEY_VALUE_FULL_INFORMATION
) - sizeof(WCHAR
) + NameLength
;
383 *ResultLength
= DataOffset
+ req
->len
;
385 if (*ResultLength
> Length
) return STATUS_BUFFER_TOO_SMALL
;
388 kbi
->Type
= req
->type
;
389 kbi
->DataOffset
= DataOffset
;
390 kbi
->DataLength
= req
->len
;
391 kbi
->NameLength
= NameLength
;
392 memcpy(kbi
->Name
, req
->name
, kbi
->NameLength
);
393 memcpy(((LPBYTE
)kbi
) + DataOffset
, req
->data
, req
->len
);
396 case KeyValuePartialInformation
:
398 PKEY_VALUE_PARTIAL_INFORMATION kbi
= KeyInformation
;
400 *ResultLength
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) - sizeof(WCHAR
) + req
->len
;
402 if (*ResultLength
> Length
) return STATUS_BUFFER_TOO_SMALL
;
405 kbi
->Type
= req
->type
;
406 kbi
->DataLength
= req
->len
;
407 memcpy(kbi
->Data
, req
->data
, req
->len
);
411 FIXME("not implemented\n");
413 return STATUS_SUCCESS
;
416 /******************************************************************************
420 NTSTATUS WINAPI
NtFlushKey(HANDLE KeyHandle
)
422 FIXME("(0x%08x) stub!\n",
427 /******************************************************************************
431 NTSTATUS WINAPI
NtLoadKey(
433 POBJECT_ATTRIBUTES ObjectAttributes
)
435 FIXME("(%p),stub!\n", KeyHandle
);
436 dump_ObjectAttributes(ObjectAttributes
);
437 return STATUS_SUCCESS
;
440 /******************************************************************************
441 * NtNotifyChangeKey [NTDLL]
444 NTSTATUS WINAPI
NtNotifyChangeKey(
447 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
448 IN PVOID ApcContext OPTIONAL
,
449 OUT PIO_STATUS_BLOCK IoStatusBlock
,
450 IN ULONG CompletionFilter
,
451 IN BOOLEAN Asynchroneous
,
452 OUT PVOID ChangeBuffer
,
454 IN BOOLEAN WatchSubtree
)
456 FIXME("(0x%08x,0x%08x,%p,%p,%p,0x%08lx, 0x%08x,%p,0x%08lx,0x%08x) stub!\n",
457 KeyHandle
, Event
, ApcRoutine
, ApcContext
, IoStatusBlock
, CompletionFilter
,
458 Asynchroneous
, ChangeBuffer
, Length
, WatchSubtree
);
459 return STATUS_SUCCESS
;
462 /******************************************************************************
463 * NtQueryMultipleValueKey [NTDLL]
464 * ZwQueryMultipleValueKey
467 NTSTATUS WINAPI
NtQueryMultipleValueKey(
469 PVALENTW ListOfValuesToQuery
,
471 PVOID MultipleValueInformation
,
475 FIXME("(0x%08x,%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
476 KeyHandle
, ListOfValuesToQuery
, NumberOfItems
, MultipleValueInformation
,
477 Length
,ReturnLength
);
478 return STATUS_SUCCESS
;
481 /******************************************************************************
482 * NtQueryValueKey [NTDLL]
486 * the name in the KeyValueInformation is never set
488 NTSTATUS WINAPI
NtQueryValueKey( HANDLE handle
, const UNICODE_STRING
*name
,
489 KEY_VALUE_INFORMATION_CLASS info_class
,
490 void *info
, DWORD length
, DWORD
*result_len
)
496 int fixed_size
= 0, data_len
= 0, offset
= 0, type
= 0, total_len
= 0;
498 TRACE( "(0x%x,%s,%d,%p,%ld)\n", handle
, debugstr_us(name
), info_class
, info
, length
);
500 if (name
->Length
> MAX_NAME_LENGTH
) return STATUS_BUFFER_OVERFLOW
;
502 /* compute the length we want to retrieve */
505 case KeyValueBasicInformation
:
506 fixed_size
= sizeof(KEY_VALUE_BASIC_INFORMATION
) - sizeof(WCHAR
);
509 case KeyValueFullInformation
:
510 fixed_size
= sizeof(KEY_VALUE_FULL_INFORMATION
) - sizeof(WCHAR
);
511 data_ptr
= (char *)info
+ fixed_size
;
513 case KeyValuePartialInformation
:
514 fixed_size
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) - sizeof(UCHAR
);
515 data_ptr
= (char *)info
+ fixed_size
;
518 FIXME( "Information class %d not implemented\n", info_class
);
519 return STATUS_INVALID_PARAMETER
;
521 if (data_ptr
&& length
> fixed_size
) data_len
= length
- fixed_size
;
525 size_t reqlen
= min( data_len
, REQUEST_MAX_VAR_SIZE
);
526 reqlen
= max( reqlen
, name
->Length
);
530 struct get_key_value_request
*req
= server_alloc_req( sizeof(*req
), reqlen
);
531 WCHAR
*nameptr
= server_data_ptr(req
);
534 req
->offset
= offset
;
535 *nameptr
++ = name
->Length
;
536 memcpy( nameptr
, name
->Buffer
, name
->Length
);
538 if (!(ret
= server_call_noerr( REQ_GET_KEY_VALUE
)))
540 size_t size
= min( server_data_size(req
), data_len
);
542 total_len
= req
->len
;
545 memcpy( data_ptr
+ offset
, server_data_ptr(req
), size
);
553 } while (data_len
&& offset
< total_len
);
555 *result_len
= total_len
+ fixed_size
;
557 if (!data_len
) ret
= STATUS_BUFFER_OVERFLOW
;
558 if (length
< fixed_size
) ret
= STATUS_BUFFER_OVERFLOW
;
562 case KeyValueBasicInformation
:
564 KEY_VALUE_BASIC_INFORMATION keyinfo
;
565 keyinfo
.TitleIndex
= 0;
567 keyinfo
.NameLength
= 0;
568 memcpy( info
, &keyinfo
, min(fixed_size
,length
) );
571 case KeyValueFullInformation
:
573 KEY_VALUE_FULL_INFORMATION keyinfo
;
574 keyinfo
.TitleIndex
= 0;
576 keyinfo
.DataOffset
= fixed_size
;
577 keyinfo
.DataLength
= total_len
;
578 keyinfo
.NameLength
= 0;
579 memcpy( info
, &keyinfo
, min(fixed_size
,length
) );
582 case KeyValuePartialInformation
:
584 KEY_VALUE_PARTIAL_INFORMATION keyinfo
;
585 keyinfo
.TitleIndex
= 0;
587 keyinfo
.DataLength
= total_len
;
588 memcpy( info
, &keyinfo
, min(fixed_size
,length
) );
597 /******************************************************************************
598 * NtReplaceKey [NTDLL]
601 NTSTATUS WINAPI
NtReplaceKey(
602 IN POBJECT_ATTRIBUTES ObjectAttributes
,
604 IN POBJECT_ATTRIBUTES ReplacedObjectAttributes
)
606 FIXME("(0x%08x),stub!\n", Key
);
607 dump_ObjectAttributes(ObjectAttributes
);
608 dump_ObjectAttributes(ReplacedObjectAttributes
);
609 return STATUS_SUCCESS
;
611 /******************************************************************************
612 * NtRestoreKey [NTDLL]
615 NTSTATUS WINAPI
NtRestoreKey(
620 FIXME("(0x%08x,0x%08x,0x%08lx) stub\n",
621 KeyHandle
, FileHandle
, RestoreFlags
);
622 return STATUS_SUCCESS
;
624 /******************************************************************************
628 NTSTATUS WINAPI
NtSaveKey(
630 IN HANDLE FileHandle
)
632 FIXME("(0x%08x,0x%08x) stub\n",
633 KeyHandle
, FileHandle
);
634 return STATUS_SUCCESS
;
636 /******************************************************************************
637 * NtSetInformationKey [NTDLL]
638 * ZwSetInformationKey
640 NTSTATUS WINAPI
NtSetInformationKey(
642 IN
const int KeyInformationClass
,
643 IN PVOID KeyInformation
,
644 IN ULONG KeyInformationLength
)
646 FIXME("(0x%08x,0x%08x,%p,0x%08lx) stub\n",
647 KeyHandle
, KeyInformationClass
, KeyInformation
, KeyInformationLength
);
648 return STATUS_SUCCESS
;
652 /******************************************************************************
653 * NtSetValueKey [NTDLL]
657 * win95 does not care about count for REG_SZ and finds out the len by itself (js)
658 * NT does definitely care (aj)
660 NTSTATUS WINAPI
NtSetValueKey( HANDLE hkey
, const UNICODE_STRING
*name
, ULONG TitleIndex
,
661 ULONG type
, const void *data
, ULONG count
)
666 TRACE( "(0x%x,%s,%ld,%p,%ld)\n", hkey
, debugstr_us(name
), type
, data
, count
);
668 if (name
->Length
> MAX_NAME_LENGTH
) return STATUS_BUFFER_OVERFLOW
;
670 namelen
= name
->Length
+ sizeof(WCHAR
); /* for storing length */
675 ULONG len
= count
- pos
;
676 if (len
> REQUEST_MAX_VAR_SIZE
- namelen
) len
= REQUEST_MAX_VAR_SIZE
- namelen
;
680 struct set_key_value_request
*req
= server_alloc_req( sizeof(*req
), namelen
+ len
);
681 WCHAR
*name_ptr
= server_data_ptr(req
);
687 *name_ptr
++ = name
->Length
;
688 memcpy( name_ptr
, name
->Buffer
, name
->Length
);
689 memcpy( (char *)name_ptr
+ name
->Length
, (char *)data
+ pos
, len
);
691 ret
= server_call_noerr( REQ_SET_KEY_VALUE
);
694 } while (!ret
&& pos
< count
);
698 /******************************************************************************
699 * NtUnloadKey [NTDLL]
702 NTSTATUS WINAPI
NtUnloadKey(
705 FIXME("(0x%08x) stub\n",
707 return STATUS_SUCCESS
;
710 /******************************************************************************
711 * RtlFormatCurrentUserKeyPath [NTDLL.371]
713 NTSTATUS WINAPI
RtlFormatCurrentUserKeyPath(
714 IN OUT PUNICODE_STRING KeyPath
)
716 /* LPSTR Path = "\\REGISTRY\\USER\\S-1-5-21-0000000000-000000000-0000000000-500";*/
717 LPSTR Path
= "\\REGISTRY\\USER\\.DEFAULT";
718 ANSI_STRING AnsiPath
;
720 FIXME("(%p) stub\n",KeyPath
);
721 RtlInitAnsiString(&AnsiPath
, Path
);
722 return RtlAnsiStringToUnicodeString(KeyPath
, &AnsiPath
, TRUE
);
725 /******************************************************************************
726 * RtlOpenCurrentUser [NTDLL]
728 * if we return just HKEY_CURRENT_USER the advapi try's to find a remote
729 * registry (odd handle) and fails
732 DWORD WINAPI
RtlOpenCurrentUser(
733 IN ACCESS_MASK DesiredAccess
,
734 OUT PHANDLE KeyHandle
) /* handle of HKEY_CURRENT_USER */
736 OBJECT_ATTRIBUTES ObjectAttributes
;
737 UNICODE_STRING ObjectName
;
740 TRACE("(0x%08lx, %p) stub\n",DesiredAccess
, KeyHandle
);
742 RtlFormatCurrentUserKeyPath(&ObjectName
);
743 InitializeObjectAttributes(&ObjectAttributes
,&ObjectName
,OBJ_CASE_INSENSITIVE
,0, NULL
);
744 ret
= NtOpenKey(KeyHandle
, DesiredAccess
, &ObjectAttributes
);
745 RtlFreeUnicodeString(&ObjectName
);