Converted some of the registry server requests to the new request
[wine/dcerpc.git] / dlls / ntdll / reg.c
blob41b3005abbb2f0c674fb8e432c02fb699cddda02
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(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 /******************************************************************************
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 * NtEnumerateKey [NTDLL]
172 * ZwEnumerateKey
174 * NOTES
175 * the name copied into the buffer is NOT 0-terminated
177 NTSTATUS WINAPI NtEnumerateKey(
178 HANDLE KeyHandle,
179 ULONG Index,
180 KEY_INFORMATION_CLASS KeyInformationClass,
181 PVOID KeyInformation,
182 ULONG Length,
183 PULONG ResultLength)
185 struct enum_key_request *req = get_req_buffer();
186 NTSTATUS ret;
188 TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
189 KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
191 req->hkey = KeyHandle;
192 req->index = Index;
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);
205 kbi->TitleIndex = 0;
206 kbi->NameLength = NameLength;
207 memcpy (kbi->Name, req->name, NameLength);
209 break;
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);
220 kfi->TitleIndex = 0;
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);
231 break;
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);
244 kni->TitleIndex = 0;
245 memcpy (kni->Name, req->name, kni->NameLength);
246 if (kni->ClassLength) memcpy ((char *) KeyInformation + kni->ClassOffset, req->class, kni->ClassLength);
248 break;
249 default:
250 FIXME("KeyInformationClass not implemented\n");
251 return STATUS_UNSUCCESSFUL;
253 TRACE("buf=%lu len=%lu\n", Length, *ResultLength);
254 return ret;
257 /******************************************************************************
258 * NtQueryKey [NTDLL]
259 * ZwQueryKey
261 NTSTATUS WINAPI NtQueryKey(
262 HANDLE KeyHandle,
263 KEY_INFORMATION_CLASS KeyInformationClass,
264 PVOID KeyInformation,
265 ULONG Length,
266 PULONG ResultLength)
268 struct query_key_info_request *req = get_req_buffer();
269 NTSTATUS ret;
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);
287 kbi->TitleIndex = 0;
288 kbi->NameLength = NameLength;
289 memcpy (kbi->Name, req->name, NameLength);
291 break;
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);
303 kfi->TitleIndex = 0;
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);
312 break;
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);
325 kni->TitleIndex = 0;
326 memcpy (kni->Name, req->name, kni->NameLength);
327 if(kni->ClassLength) memcpy ((char *) KeyInformation + kni->ClassOffset, req->class, kni->ClassLength);
329 break;
330 default:
331 FIXME("KeyInformationClass not implemented\n");
332 return STATUS_UNSUCCESSFUL;
334 return ret;
337 /******************************************************************************
338 * NtEnumerateValueKey [NTDLL]
339 * ZwEnumerateValueKey
341 NTSTATUS WINAPI NtEnumerateValueKey(
342 HANDLE KeyHandle,
343 ULONG Index,
344 KEY_VALUE_INFORMATION_CLASS KeyInformationClass,
345 PVOID KeyInformation,
346 ULONG Length,
347 PULONG ResultLength)
349 struct enum_key_value_request *req = get_req_buffer();
350 UINT NameLength;
351 NTSTATUS ret;
353 TRACE("(0x%08x,0x%08lx,0x%08x,%p,0x%08lx,%p)\n",
354 KeyHandle, Index, KeyInformationClass, KeyInformation, Length, ResultLength);
356 req->hkey = KeyHandle;
357 req->index = Index;
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;
370 kbi->TitleIndex = 0;
371 kbi->Type = req->type;
372 kbi->NameLength = NameLength;
373 memcpy(kbi->Name, req->name, kbi->NameLength);
375 break;
376 case KeyValueFullInformation:
378 PKEY_VALUE_FULL_INFORMATION kbi = KeyInformation;
379 UINT DataOffset;
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;
387 kbi->TitleIndex = 0;
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);
395 break;
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;
404 kbi->TitleIndex = 0;
405 kbi->Type = req->type;
406 kbi->DataLength = req->len;
407 memcpy(kbi->Data, req->data, req->len);
409 break;
410 default:
411 FIXME("not implemented\n");
413 return STATUS_SUCCESS;
416 /******************************************************************************
417 * NtFlushKey [NTDLL]
418 * ZwFlushKey
420 NTSTATUS WINAPI NtFlushKey(HANDLE KeyHandle)
422 FIXME("(0x%08x) stub!\n",
423 KeyHandle);
424 return 1;
427 /******************************************************************************
428 * NtLoadKey [NTDLL]
429 * ZwLoadKey
431 NTSTATUS WINAPI NtLoadKey(
432 PHANDLE KeyHandle,
433 POBJECT_ATTRIBUTES ObjectAttributes)
435 FIXME("(%p),stub!\n", KeyHandle);
436 dump_ObjectAttributes(ObjectAttributes);
437 return STATUS_SUCCESS;
440 /******************************************************************************
441 * NtNotifyChangeKey [NTDLL]
442 * ZwNotifyChangeKey
444 NTSTATUS WINAPI NtNotifyChangeKey(
445 IN HANDLE KeyHandle,
446 IN HANDLE Event,
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,
453 IN ULONG Length,
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(
468 HANDLE KeyHandle,
469 PVALENTW ListOfValuesToQuery,
470 ULONG NumberOfItems,
471 PVOID MultipleValueInformation,
472 ULONG Length,
473 PULONG ReturnLength)
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]
483 * ZwQueryValueKey
485 * NOTES
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 )
494 NTSTATUS ret;
495 char *data_ptr;
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 */
503 switch(info_class)
505 case KeyValueBasicInformation:
506 fixed_size = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR);
507 data_ptr = NULL;
508 break;
509 case KeyValueFullInformation:
510 fixed_size = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR);
511 data_ptr = (char *)info + fixed_size;
512 break;
513 case KeyValuePartialInformation:
514 fixed_size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(UCHAR);
515 data_ptr = (char *)info + fixed_size;
516 break;
517 default:
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 );
528 SERVER_START_REQ
530 struct get_key_value_request *req = server_alloc_req( sizeof(*req), reqlen );
531 WCHAR *nameptr = server_data_ptr(req);
533 req->hkey = handle;
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 );
541 type = req->type;
542 total_len = req->len;
543 if (size)
545 memcpy( data_ptr + offset, server_data_ptr(req), size );
546 offset += size;
547 data_len -= size;
551 SERVER_END_REQ;
552 if (ret) return ret;
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;
560 switch(info_class)
562 case KeyValueBasicInformation:
564 KEY_VALUE_BASIC_INFORMATION keyinfo;
565 keyinfo.TitleIndex = 0;
566 keyinfo.Type = type;
567 keyinfo.NameLength = 0;
568 memcpy( info, &keyinfo, min(fixed_size,length) );
569 break;
571 case KeyValueFullInformation:
573 KEY_VALUE_FULL_INFORMATION keyinfo;
574 keyinfo.TitleIndex = 0;
575 keyinfo.Type = type;
576 keyinfo.DataOffset = fixed_size;
577 keyinfo.DataLength = total_len;
578 keyinfo.NameLength = 0;
579 memcpy( info, &keyinfo, min(fixed_size,length) );
580 break;
582 case KeyValuePartialInformation:
584 KEY_VALUE_PARTIAL_INFORMATION keyinfo;
585 keyinfo.TitleIndex = 0;
586 keyinfo.Type = type;
587 keyinfo.DataLength = total_len;
588 memcpy( info, &keyinfo, min(fixed_size,length) );
589 break;
591 default:
592 break;
594 return ret;
597 /******************************************************************************
598 * NtReplaceKey [NTDLL]
599 * ZwReplaceKey
601 NTSTATUS WINAPI NtReplaceKey(
602 IN POBJECT_ATTRIBUTES ObjectAttributes,
603 IN HANDLE Key,
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]
613 * ZwRestoreKey
615 NTSTATUS WINAPI NtRestoreKey(
616 HANDLE KeyHandle,
617 HANDLE FileHandle,
618 ULONG RestoreFlags)
620 FIXME("(0x%08x,0x%08x,0x%08lx) stub\n",
621 KeyHandle, FileHandle, RestoreFlags);
622 return STATUS_SUCCESS;
624 /******************************************************************************
625 * NtSaveKey [NTDLL]
626 * ZwSaveKey
628 NTSTATUS WINAPI NtSaveKey(
629 IN HANDLE KeyHandle,
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(
641 IN HANDLE KeyHandle,
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]
654 * ZwSetValueKey
656 * NOTES
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 )
663 NTSTATUS ret;
664 ULONG namelen, pos;
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 */
671 pos = 0;
675 ULONG len = count - pos;
676 if (len > REQUEST_MAX_VAR_SIZE - namelen) len = REQUEST_MAX_VAR_SIZE - namelen;
678 SERVER_START_REQ
680 struct set_key_value_request *req = server_alloc_req( sizeof(*req), namelen + len );
681 WCHAR *name_ptr = server_data_ptr(req);
683 req->hkey = hkey;
684 req->type = type;
685 req->total = count;
686 req->offset = pos;
687 *name_ptr++ = name->Length;
688 memcpy( name_ptr, name->Buffer, name->Length );
689 memcpy( (char *)name_ptr + name->Length, (char *)data + pos, len );
690 pos += len;
691 ret = server_call_noerr( REQ_SET_KEY_VALUE );
693 SERVER_END_REQ;
694 } while (!ret && pos < count);
695 return ret;
698 /******************************************************************************
699 * NtUnloadKey [NTDLL]
700 * ZwUnloadKey
702 NTSTATUS WINAPI NtUnloadKey(
703 IN HANDLE KeyHandle)
705 FIXME("(0x%08x) stub\n",
706 KeyHandle);
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;
738 NTSTATUS ret;
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);
746 return ret;