Fixed definition of the RtlMemory functions. Use macros internally and
[wine.git] / dlls / ntdll / reg.c
blob8fae402c392730f7217fdfffcdfa2345f9202e7d
1 /*
2 * registry functions
4 * NOTES:
5 * HKEY_LOCAL_MACHINE \\REGISTRY\\MACHINE
6 * HKEY_USERS \\REGISTRY\\USER
7 * HKEY_CURRENT_CONFIG \\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\HARDWARE PROFILES\\CURRENT
8 * HKEY_CLASSES \\REGISTRY\\MACHINE\\SOFTWARE\\CLASSES
9 */
11 #include "debugtools.h"
12 #include "winreg.h"
13 #include "winerror.h"
14 #include "file.h"
15 #include "server.h"
16 #include "ntddk.h"
17 #include "crtdll.h"
18 #include "ntdll_misc.h"
20 DEFAULT_DEBUG_CHANNEL(ntdll);
22 /* copy a key name into the request buffer */
23 static inline NTSTATUS copy_nameU( LPWSTR Dest, PUNICODE_STRING Name, UINT Offset )
25 if (Name->Buffer)
27 if ((Name->Length-Offset) > MAX_PATH) return STATUS_BUFFER_OVERFLOW;
28 lstrcpyW( Dest, Name->Buffer+Offset );
30 else Dest[0] = 0;
31 return STATUS_SUCCESS;
34 /* translates predefined paths to HKEY_ constants */
35 static BOOLEAN _NtKeyToWinKey(
36 IN POBJECT_ATTRIBUTES ObjectAttributes,
37 OUT UINT * Offset, /* offset within ObjectName */
38 OUT HKEY * KeyHandle) /* translated handle */
40 static const WCHAR KeyPath_HKLM[] = {
41 '\\','R','E','G','I','S','T','R','Y',
42 '\\','M','A','C','H','I','N','E',0};
43 static const WCHAR KeyPath_HKU [] = {
44 '\\','R','E','G','I','S','T','R','Y',
45 '\\','U','S','E','R',0};
46 static const WCHAR KeyPath_HCC [] = {
47 '\\','R','E','G','I','S','T','R','Y',
48 '\\','M','A','C','H','I','N','E',
49 '\\','S','Y','S','T','E','M',
50 '\\','C','U','R','R','E','N','T','C','O','N','T','R','O','L','S','E','T',
51 '\\','H','A','R','D','W','A','R','E','P','R','O','F','I','L','E','S',
52 '\\','C','U','R','R','E','N','T',0};
53 static const WCHAR KeyPath_HCR [] = {
54 '\\','R','E','G','I','S','T','R','Y',
55 '\\','M','A','C','H','I','N','E',
56 '\\','S','O','F','T','W','A','R','E',
57 '\\','C','L','A','S','S','E','S',0};
58 int len;
59 PUNICODE_STRING ObjectName = ObjectAttributes->ObjectName;
61 if(ObjectAttributes->RootDirectory)
63 len = 0;
64 *KeyHandle = ObjectAttributes->RootDirectory;
66 else if((ObjectName->Length > (len=lstrlenW(KeyPath_HKLM)))
67 && (0==CRTDLL__wcsnicmp(ObjectName->Buffer,KeyPath_HKLM,len)))
68 { *KeyHandle = HKEY_LOCAL_MACHINE;
70 else if((ObjectName->Length > (len=lstrlenW(KeyPath_HKU)))
71 && (0==CRTDLL__wcsnicmp(ObjectName->Buffer,KeyPath_HKU,len)))
72 { *KeyHandle = HKEY_USERS;
74 else if((ObjectName->Length > (len=lstrlenW(KeyPath_HCR)))
75 && (0==CRTDLL__wcsnicmp(ObjectName->Buffer,KeyPath_HCR,len)))
76 { *KeyHandle = HKEY_CLASSES_ROOT;
78 else if((ObjectName->Length > (len=lstrlenW(KeyPath_HCC)))
79 && (0==CRTDLL__wcsnicmp(ObjectName->Buffer,KeyPath_HCC,len)))
80 { *KeyHandle = HKEY_CURRENT_CONFIG;
82 else
84 *KeyHandle = 0;
85 *Offset = 0;
86 return FALSE;
89 if (len > 0 && ObjectName->Buffer[len] == (WCHAR)'\\') len++;
90 *Offset = len;
92 TRACE("off=%u hkey=0x%08x\n", *Offset, *KeyHandle);
93 return TRUE;
96 /******************************************************************************
97 * NtCreateKey [NTDLL]
98 * ZwCreateKey
100 NTSTATUS WINAPI NtCreateKey(
101 PHANDLE KeyHandle,
102 ACCESS_MASK DesiredAccess,
103 POBJECT_ATTRIBUTES ObjectAttributes,
104 ULONG TitleIndex,
105 PUNICODE_STRING Class,
106 ULONG CreateOptions,
107 PULONG Disposition)
109 struct create_key_request *req = get_req_buffer();
110 UINT ObjectNameOffset;
111 HKEY RootDirectory;
112 NTSTATUS ret;
114 TRACE("(%p,0x%08lx,0x%08lx,%p(%s),0x%08lx,%p)\n",
115 KeyHandle, DesiredAccess, TitleIndex, Class, debugstr_us(Class), CreateOptions, Disposition);
116 dump_ObjectAttributes(ObjectAttributes);
118 if (!KeyHandle)
119 return STATUS_INVALID_PARAMETER;
121 _NtKeyToWinKey(ObjectAttributes, &ObjectNameOffset, &RootDirectory);
123 req->parent = RootDirectory;
124 req->access = DesiredAccess;
125 req->options = CreateOptions;
126 req->modif = time(NULL);
128 if (copy_nameU( req->name, ObjectAttributes->ObjectName, ObjectNameOffset ) != STATUS_SUCCESS)
129 return STATUS_INVALID_PARAMETER;
131 if (Class)
133 int ClassLen = Class->Length+1;
134 if ( ClassLen*sizeof(WCHAR) > server_remaining(req->class)) return STATUS_BUFFER_OVERFLOW;
135 lstrcpynW( req->class, Class->Buffer, ClassLen);
137 else
138 req->class[0] = 0x0000;
140 if (!(ret = server_call_noerr(REQ_CREATE_KEY)))
142 *KeyHandle = req->hkey;
143 if (Disposition) *Disposition = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
145 return ret;
148 /******************************************************************************
149 * NtOpenKey [NTDLL.129]
150 * ZwOpenKey
151 * OUT PHANDLE KeyHandle (returns 0 when failure)
152 * IN ACCESS_MASK DesiredAccess
153 * IN POBJECT_ATTRIBUTES ObjectAttributes
155 NTSTATUS WINAPI NtOpenKey(
156 PHANDLE KeyHandle,
157 ACCESS_MASK DesiredAccess,
158 POBJECT_ATTRIBUTES ObjectAttributes)
160 struct open_key_request *req = get_req_buffer();
161 UINT ObjectNameOffset;
162 HKEY RootDirectory;
163 NTSTATUS ret;
165 TRACE("(%p,0x%08lx)\n", KeyHandle, DesiredAccess);
166 dump_ObjectAttributes(ObjectAttributes);
168 if (!KeyHandle) return STATUS_INVALID_PARAMETER;
169 *KeyHandle = 0;
171 _NtKeyToWinKey(ObjectAttributes, &ObjectNameOffset, &RootDirectory);
173 req->parent = RootDirectory;
174 req->access = DesiredAccess;
176 if (copy_nameU( req->name, ObjectAttributes->ObjectName, ObjectNameOffset ) != STATUS_SUCCESS)
177 return STATUS_INVALID_PARAMETER;
179 if (!(ret = server_call_noerr(REQ_OPEN_KEY)))
181 *KeyHandle = req->hkey;
183 return ret;
186 /******************************************************************************
187 * NtDeleteKey [NTDLL]
188 * ZwDeleteKey
190 NTSTATUS WINAPI NtDeleteKey(HANDLE KeyHandle)
192 FIXME("(0x%08x) stub!\n",
193 KeyHandle);
194 return STATUS_SUCCESS;
197 /******************************************************************************
198 * NtDeleteValueKey [NTDLL]
199 * ZwDeleteValueKey
201 NTSTATUS WINAPI NtDeleteValueKey(
202 IN HANDLE KeyHandle,
203 IN PUNICODE_STRING ValueName)
205 FIXME("(0x%08x,%p(%s)) stub!\n",
206 KeyHandle, ValueName,debugstr_us(ValueName));
207 return STATUS_SUCCESS;
210 /******************************************************************************
211 * NtEnumerateKey [NTDLL]
212 * ZwEnumerateKey
214 * NOTES
215 * the name copied into the buffer is NOT 0-terminated
217 NTSTATUS WINAPI NtEnumerateKey(
218 HANDLE KeyHandle,
219 ULONG Index,
220 KEY_INFORMATION_CLASS KeyInformationClass,
221 PVOID KeyInformation,
222 ULONG Length,
223 PULONG ResultLength)
225 struct enum_key_request *req = get_req_buffer();
226 NTSTATUS ret;
228 TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
229 KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
231 req->hkey = KeyHandle;
232 req->index = Index;
233 if ((ret = server_call_noerr(REQ_ENUM_KEY)) != STATUS_SUCCESS) return ret;
235 switch (KeyInformationClass)
237 case KeyBasicInformation:
239 PKEY_BASIC_INFORMATION kbi = KeyInformation;
240 UINT NameLength = lstrlenW(req->name) * sizeof(WCHAR);
241 *ResultLength = sizeof(KEY_BASIC_INFORMATION) - sizeof(WCHAR) + NameLength;
242 if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
244 DOSFS_UnixTimeToFileTime(req->modif, &kbi->LastWriteTime, 0);
245 kbi->TitleIndex = 0;
246 kbi->NameLength = NameLength;
247 memcpy (kbi->Name, req->name, NameLength);
249 break;
250 case KeyFullInformation:
252 PKEY_FULL_INFORMATION kfi = KeyInformation;
253 kfi->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
254 kfi->ClassOffset = (kfi->ClassLength) ?
255 sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) : 0xffffffff;
256 *ResultLength = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) + kfi->ClassLength;
257 if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
259 DOSFS_UnixTimeToFileTime(req->modif, &kfi->LastWriteTime, 0);
260 kfi->TitleIndex = 0;
261 /* kfi->SubKeys = req->subkeys;
262 kfi->MaxNameLength = req->max_subkey;
263 kfi->MaxClassLength = req->max_class;
264 kfi->Values = req->values;
265 kfi->MaxValueNameLen = req->max_value;
266 kfi->MaxValueDataLen = req->max_data;
268 FIXME("incomplete\n");
269 if (kfi->ClassLength) memcpy (kfi->Class, req->class, kfi->ClassLength);
271 break;
272 case KeyNodeInformation:
274 PKEY_NODE_INFORMATION kni = KeyInformation;
275 kni->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
276 kni->NameLength = lstrlenW(req->name) * sizeof(WCHAR);
277 kni->ClassOffset = (kni->ClassLength) ?
278 sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength : 0xffffffff;
280 *ResultLength = sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength + kni->ClassLength;
281 if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
283 DOSFS_UnixTimeToFileTime(req->modif, &kni->LastWriteTime, 0);
284 kni->TitleIndex = 0;
285 memcpy (kni->Name, req->name, kni->NameLength);
286 if (kni->ClassLength) memcpy ((char *) KeyInformation + kni->ClassOffset, req->class, kni->ClassLength);
288 break;
289 default:
290 FIXME("KeyInformationClass not implemented\n");
291 return STATUS_UNSUCCESSFUL;
293 TRACE("buf=%lu len=%lu\n", Length, *ResultLength);
294 return ret;
297 /******************************************************************************
298 * NtQueryKey [NTDLL]
299 * ZwQueryKey
301 NTSTATUS WINAPI NtQueryKey(
302 HANDLE KeyHandle,
303 KEY_INFORMATION_CLASS KeyInformationClass,
304 PVOID KeyInformation,
305 ULONG Length,
306 PULONG ResultLength)
308 struct query_key_info_request *req = get_req_buffer();
309 NTSTATUS ret;
311 TRACE("(0x%08x,0x%08x,%p,0x%08lx,%p) stub\n",
312 KeyHandle, KeyInformationClass, KeyInformation, Length, ResultLength);
314 req->hkey = KeyHandle;
315 if ((ret = server_call_noerr(REQ_QUERY_KEY_INFO)) != STATUS_SUCCESS) return ret;
317 switch (KeyInformationClass)
319 case KeyBasicInformation:
321 PKEY_BASIC_INFORMATION kbi = KeyInformation;
322 UINT NameLength = lstrlenW(req->name) * sizeof(WCHAR);
323 *ResultLength = sizeof(KEY_BASIC_INFORMATION) - sizeof(WCHAR) + NameLength;
324 if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
326 DOSFS_UnixTimeToFileTime(req->modif, &kbi->LastWriteTime, 0);
327 kbi->TitleIndex = 0;
328 kbi->NameLength = NameLength;
329 memcpy (kbi->Name, req->name, NameLength);
331 break;
332 case KeyFullInformation:
334 PKEY_FULL_INFORMATION kfi = KeyInformation;
335 kfi->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
336 kfi->ClassOffset = (kfi->ClassLength) ?
337 sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) : 0xffffffff;
339 *ResultLength = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR) + kfi->ClassLength;
340 if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
342 DOSFS_UnixTimeToFileTime(req->modif, &kfi->LastWriteTime, 0);
343 kfi->TitleIndex = 0;
344 kfi->SubKeys = req->subkeys;
345 kfi->MaxNameLen = req->max_subkey;
346 kfi->MaxClassLen = req->max_class;
347 kfi->Values = req->values;
348 kfi->MaxValueNameLen = req->max_value;
349 kfi->MaxValueDataLen = req->max_data;
350 if(kfi->ClassLength) memcpy ((char *) KeyInformation + kfi->ClassOffset, req->class, kfi->ClassLength);
352 break;
353 case KeyNodeInformation:
355 PKEY_NODE_INFORMATION kni = KeyInformation;
356 kni->ClassLength = lstrlenW(req->class) * sizeof(WCHAR);
357 kni->NameLength = lstrlenW(req->name) * sizeof(WCHAR);
358 kni->ClassOffset = (kni->ClassLength) ?
359 sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength : 0xffffffff;
361 *ResultLength = sizeof(KEY_NODE_INFORMATION) - sizeof(WCHAR) + kni->NameLength + kni->ClassLength;
362 if (Length < *ResultLength) return STATUS_BUFFER_OVERFLOW;
364 DOSFS_UnixTimeToFileTime(req->modif, &kni->LastWriteTime, 0);
365 kni->TitleIndex = 0;
366 memcpy (kni->Name, req->name, kni->NameLength);
367 if(kni->ClassLength) memcpy ((char *) KeyInformation + kni->ClassOffset, req->class, kni->ClassLength);
369 break;
370 default:
371 FIXME("KeyInformationClass not implemented\n");
372 return STATUS_UNSUCCESSFUL;
374 return ret;
377 /******************************************************************************
378 * NtEnumerateValueKey [NTDLL]
379 * ZwEnumerateValueKey
381 NTSTATUS WINAPI NtEnumerateValueKey(
382 HANDLE KeyHandle,
383 ULONG Index,
384 KEY_VALUE_INFORMATION_CLASS KeyInformationClass,
385 PVOID KeyInformation,
386 ULONG Length,
387 PULONG ResultLength)
389 struct enum_key_value_request *req = get_req_buffer();
390 UINT NameLength;
391 NTSTATUS ret;
393 TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
394 KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
396 req->hkey = KeyHandle;
397 req->index = Index;
398 if ((ret = server_call_noerr(REQ_ENUM_KEY_VALUE)) != STATUS_SUCCESS) return ret;
400 switch (KeyInformationClass)
402 case KeyBasicInformation:
404 PKEY_VALUE_BASIC_INFORMATION kbi = KeyInformation;
406 NameLength = lstrlenW(req->name) * sizeof(WCHAR);
407 *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR) + NameLength;
408 if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
410 kbi->TitleIndex = 0;
411 kbi->Type = req->type;
412 kbi->NameLength = NameLength;
413 memcpy(kbi->Name, req->name, kbi->NameLength);
415 break;
416 case KeyValueFullInformation:
418 PKEY_VALUE_FULL_INFORMATION kbi = KeyInformation;
419 UINT DataOffset;
421 NameLength = lstrlenW(req->name) * sizeof(WCHAR);
422 DataOffset = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR) + NameLength;
423 *ResultLength = DataOffset + req->len;
425 if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
427 kbi->TitleIndex = 0;
428 kbi->Type = req->type;
429 kbi->DataOffset = DataOffset;
430 kbi->DataLength = req->len;
431 kbi->NameLength = NameLength;
432 memcpy(kbi->Name, req->name, kbi->NameLength);
433 memcpy(((LPBYTE)kbi) + DataOffset, req->data, req->len);
435 break;
436 case KeyValuePartialInformation:
438 PKEY_VALUE_PARTIAL_INFORMATION kbi = KeyInformation;
440 *ResultLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(WCHAR) + req->len;
442 if (*ResultLength > Length) return STATUS_BUFFER_TOO_SMALL;
444 kbi->TitleIndex = 0;
445 kbi->Type = req->type;
446 kbi->DataLength = req->len;
447 memcpy(kbi->Data, req->data, req->len);
449 break;
450 default:
451 FIXME("not implemented\n");
453 return STATUS_SUCCESS;
456 /******************************************************************************
457 * NtFlushKey [NTDLL]
458 * ZwFlushKey
460 NTSTATUS WINAPI NtFlushKey(HANDLE KeyHandle)
462 FIXME("(0x%08x) stub!\n",
463 KeyHandle);
464 return 1;
467 /******************************************************************************
468 * NtLoadKey [NTDLL]
469 * ZwLoadKey
471 NTSTATUS WINAPI NtLoadKey(
472 PHANDLE KeyHandle,
473 POBJECT_ATTRIBUTES ObjectAttributes)
475 FIXME("(%p),stub!\n", KeyHandle);
476 dump_ObjectAttributes(ObjectAttributes);
477 return STATUS_SUCCESS;
480 /******************************************************************************
481 * NtNotifyChangeKey [NTDLL]
482 * ZwNotifyChangeKey
484 NTSTATUS WINAPI NtNotifyChangeKey(
485 IN HANDLE KeyHandle,
486 IN HANDLE Event,
487 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
488 IN PVOID ApcContext OPTIONAL,
489 OUT PIO_STATUS_BLOCK IoStatusBlock,
490 IN ULONG CompletionFilter,
491 IN BOOLEAN Asynchroneous,
492 OUT PVOID ChangeBuffer,
493 IN ULONG Length,
494 IN BOOLEAN WatchSubtree)
496 FIXME("(0x%08x,0x%08x,%p,%p,%p,0x%08lx, 0x%08x,%p,0x%08lx,0x%08x) stub!\n",
497 KeyHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter,
498 Asynchroneous, ChangeBuffer, Length, WatchSubtree);
499 return STATUS_SUCCESS;
502 /******************************************************************************
503 * NtQueryMultipleValueKey [NTDLL]
504 * ZwQueryMultipleValueKey
507 NTSTATUS WINAPI NtQueryMultipleValueKey(
508 HANDLE KeyHandle,
509 PVALENTW ListOfValuesToQuery,
510 ULONG NumberOfItems,
511 PVOID MultipleValueInformation,
512 ULONG Length,
513 PULONG ReturnLength)
515 FIXME("(0x%08x,%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
516 KeyHandle, ListOfValuesToQuery, NumberOfItems, MultipleValueInformation,
517 Length,ReturnLength);
518 return STATUS_SUCCESS;
521 /******************************************************************************
522 * NtQueryValueKey [NTDLL]
523 * ZwQueryValueKey
525 * NOTES
526 * the name in the KeyValueInformation is never set
528 NTSTATUS WINAPI NtQueryValueKey(
529 IN HANDLE KeyHandle,
530 IN PUNICODE_STRING ValueName,
531 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
532 OUT PVOID KeyValueInformation,
533 IN ULONG Length,
534 OUT PULONG ResultLength)
536 struct get_key_value_request *req = get_req_buffer();
537 NTSTATUS ret;
539 TRACE("(0x%08x,%s,0x%08x,%p,0x%08lx,%p)\n",
540 KeyHandle, debugstr_us(ValueName), KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
542 req->hkey = KeyHandle;
543 if (copy_nameU(req->name, ValueName, 0) != STATUS_SUCCESS) return STATUS_BUFFER_OVERFLOW;
544 if ((ret = server_call_noerr(REQ_GET_KEY_VALUE)) != STATUS_SUCCESS) return ret;
546 switch(KeyValueInformationClass)
548 case KeyValueBasicInformation:
550 PKEY_VALUE_BASIC_INFORMATION kbi = (PKEY_VALUE_BASIC_INFORMATION) KeyValueInformation;
551 kbi->Type = req->type;
553 *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION)-sizeof(WCHAR);
554 if (Length <= *ResultLength) return STATUS_BUFFER_OVERFLOW;
555 kbi->NameLength = 0;
557 break;
558 case KeyValueFullInformation:
560 PKEY_VALUE_FULL_INFORMATION kfi = (PKEY_VALUE_FULL_INFORMATION) KeyValueInformation;
561 ULONG DataOffset;
562 kfi->Type = req->type;
564 DataOffset = sizeof(KEY_VALUE_FULL_INFORMATION)-sizeof(WCHAR);
565 *ResultLength = DataOffset + req->len;
566 if (Length <= *ResultLength) return STATUS_BUFFER_OVERFLOW;
568 kfi->NameLength = 0;
569 kfi->DataOffset = DataOffset;
570 kfi->DataLength = req->len;
571 memcpy((char *) KeyValueInformation + DataOffset, req->data, req->len);
573 break;
574 case KeyValuePartialInformation:
576 PKEY_VALUE_PARTIAL_INFORMATION kpi = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation;
577 kpi->Type = req->type;
579 *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION)-sizeof(UCHAR)+req->len;
580 if (Length <= *ResultLength) return STATUS_BUFFER_OVERFLOW;
582 kpi->DataLength = req->len;
583 memcpy(kpi->Data, req->data, req->len);
585 break;
586 default:
587 FIXME("KeyValueInformationClass not implemented\n");
588 return STATUS_UNSUCCESSFUL;
591 return ret;
594 /******************************************************************************
595 * NtReplaceKey [NTDLL]
596 * ZwReplaceKey
598 NTSTATUS WINAPI NtReplaceKey(
599 IN POBJECT_ATTRIBUTES ObjectAttributes,
600 IN HANDLE Key,
601 IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
603 FIXME("(0x%08x),stub!\n", Key);
604 dump_ObjectAttributes(ObjectAttributes);
605 dump_ObjectAttributes(ReplacedObjectAttributes);
606 return STATUS_SUCCESS;
608 /******************************************************************************
609 * NtRestoreKey [NTDLL]
610 * ZwRestoreKey
612 NTSTATUS WINAPI NtRestoreKey(
613 HANDLE KeyHandle,
614 HANDLE FileHandle,
615 ULONG RestoreFlags)
617 FIXME("(0x%08x,0x%08x,0x%08lx) stub\n",
618 KeyHandle, FileHandle, RestoreFlags);
619 return STATUS_SUCCESS;
621 /******************************************************************************
622 * NtSaveKey [NTDLL]
623 * ZwSaveKey
625 NTSTATUS WINAPI NtSaveKey(
626 IN HANDLE KeyHandle,
627 IN HANDLE FileHandle)
629 FIXME("(0x%08x,0x%08x) stub\n",
630 KeyHandle, FileHandle);
631 return STATUS_SUCCESS;
633 /******************************************************************************
634 * NtSetInformationKey [NTDLL]
635 * ZwSetInformationKey
637 NTSTATUS WINAPI NtSetInformationKey(
638 IN HANDLE KeyHandle,
639 IN const int KeyInformationClass,
640 IN PVOID KeyInformation,
641 IN ULONG KeyInformationLength)
643 FIXME("(0x%08x,0x%08x,%p,0x%08lx) stub\n",
644 KeyHandle, KeyInformationClass, KeyInformation, KeyInformationLength);
645 return STATUS_SUCCESS;
647 /******************************************************************************
648 * NtSetValueKey [NTDLL]
649 * ZwSetValueKey
651 NTSTATUS WINAPI NtSetValueKey(
652 HANDLE KeyHandle,
653 PUNICODE_STRING ValueName,
654 ULONG TitleIndex,
655 ULONG Type,
656 PVOID Data,
657 ULONG DataSize)
659 FIXME("(0x%08x,%p(%s), 0x%08lx, 0x%08lx, %p, 0x%08lx) stub!\n",
660 KeyHandle, ValueName,debugstr_us(ValueName), TitleIndex, Type, Data, DataSize);
661 return STATUS_SUCCESS;
665 /******************************************************************************
666 * NtUnloadKey [NTDLL]
667 * ZwUnloadKey
669 NTSTATUS WINAPI NtUnloadKey(
670 IN HANDLE KeyHandle)
672 FIXME("(0x%08x) stub\n",
673 KeyHandle);
674 return STATUS_SUCCESS;
677 /******************************************************************************
678 * RtlFormatCurrentUserKeyPath [NTDLL.371]
680 NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(
681 IN OUT PUNICODE_STRING KeyPath)
683 /* LPSTR Path = "\\REGISTRY\\USER\\S-1-5-21-0000000000-000000000-0000000000-500";*/
684 LPSTR Path = "\\REGISTRY\\USER\\.DEFAULT";
685 ANSI_STRING AnsiPath;
687 FIXME("(%p) stub\n",KeyPath);
688 RtlInitAnsiString(&AnsiPath, Path);
689 return RtlAnsiStringToUnicodeString(KeyPath, &AnsiPath, TRUE);
692 /******************************************************************************
693 * RtlOpenCurrentUser [NTDLL]
695 * if we return just HKEY_CURRENT_USER the advapi try's to find a remote
696 * registry (odd handle) and fails
699 DWORD WINAPI RtlOpenCurrentUser(
700 IN ACCESS_MASK DesiredAccess,
701 OUT PHANDLE KeyHandle) /* handle of HKEY_CURRENT_USER */
703 OBJECT_ATTRIBUTES ObjectAttributes;
704 UNICODE_STRING ObjectName;
705 NTSTATUS ret;
707 TRACE("(0x%08lx, %p) stub\n",DesiredAccess, KeyHandle);
709 RtlFormatCurrentUserKeyPath(&ObjectName);
710 InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
711 ret = NtOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
712 RtlFreeUnicodeString(&ObjectName);
713 return ret;