dvideo.dll forgets to set the DDSD_CAPS flag, just assume it set.
[wine.git] / dlls / ntdll / reg.c
blob351250df72b10e660d7ee06374b1d8cc521e6499
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 "server.h"
20 #include "ntddk.h"
21 #include "ntdll_misc.h"
23 DEFAULT_DEBUG_CHANNEL(reg);
25 static const WCHAR root_name[] = { '\\','R','e','g','i','s','t','r','y','\\',0 };
26 static const UNICODE_STRING root_path =
28 sizeof(root_name)-sizeof(WCHAR), /* Length */
29 sizeof(root_name), /* MaximumLength */
30 (LPWSTR)root_name /* Buffer */
33 /* maximum length of a key/value name in bytes (without terminating null) */
34 #define MAX_NAME_LENGTH ((MAX_PATH-1) * sizeof(WCHAR))
37 /* copy a key name into the request buffer */
38 static inline NTSTATUS copy_nameU( LPWSTR Dest, const UNICODE_STRING *name, UINT max )
40 if (name->Length >= max) return STATUS_BUFFER_OVERFLOW;
41 if (name->Length) memcpy( Dest, name->Buffer, name->Length );
42 Dest[name->Length / sizeof(WCHAR)] = 0;
43 return STATUS_SUCCESS;
47 /******************************************************************************
48 * NtCreateKey [NTDLL]
49 * ZwCreateKey
51 NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
52 ULONG TitleIndex, const UNICODE_STRING *class, ULONG options,
53 PULONG dispos )
55 NTSTATUS ret;
56 DWORD len = attr->ObjectName->Length;
58 TRACE( "(0x%x,%s,%s,%lx,%lx,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
59 debugstr_us(class), options, access, retkey );
61 if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
62 len += sizeof(WCHAR); /* for storing name length */
63 if (class)
65 len += class->Length;
66 if (len > REQUEST_MAX_VAR_SIZE) return STATUS_BUFFER_OVERFLOW;
68 if (!retkey) return STATUS_INVALID_PARAMETER;
70 SERVER_START_REQ
72 struct create_key_request *req = server_alloc_req( sizeof(*req), len );
73 WCHAR *data = server_data_ptr(req);
75 req->parent = attr->RootDirectory;
76 req->access = access;
77 req->options = options;
78 req->modif = 0;
80 *data++ = attr->ObjectName->Length;
81 memcpy( data, attr->ObjectName->Buffer, attr->ObjectName->Length );
82 if (class) memcpy( (char *)data + attr->ObjectName->Length, class->Buffer, class->Length );
83 if (!(ret = server_call_noerr( REQ_CREATE_KEY )))
85 *retkey = req->hkey;
86 if (dispos) *dispos = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
89 SERVER_END_REQ;
90 return ret;
94 /******************************************************************************
95 * NtOpenKey [NTDLL.129]
96 * ZwOpenKey
97 * OUT PHANDLE retkey (returns 0 when failure)
98 * IN ACCESS_MASK access
99 * IN POBJECT_ATTRIBUTES attr
101 NTSTATUS WINAPI NtOpenKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
103 NTSTATUS ret;
104 DWORD len = attr->ObjectName->Length;
106 TRACE( "(0x%x,%s,%lx,%p)\n", attr->RootDirectory,
107 debugstr_us(attr->ObjectName), access, retkey );
109 if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
110 if (!retkey) return STATUS_INVALID_PARAMETER;
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 ret = server_call_noerr( REQ_OPEN_KEY );
119 *retkey = req->hkey;
121 SERVER_END_REQ;
122 return ret;
126 /******************************************************************************
127 * NtDeleteKey [NTDLL]
128 * ZwDeleteKey
130 NTSTATUS WINAPI NtDeleteKey( HANDLE hkey )
132 NTSTATUS ret;
134 TRACE( "(%x)\n", hkey );
136 SERVER_START_REQ
138 struct delete_key_request *req = server_alloc_req( sizeof(*req), 0 );
139 req->hkey = hkey;
140 ret = server_call_noerr( REQ_DELETE_KEY );
142 SERVER_END_REQ;
143 return ret;
147 /******************************************************************************
148 * NtDeleteValueKey [NTDLL]
149 * ZwDeleteValueKey
151 NTSTATUS WINAPI NtDeleteValueKey( HANDLE hkey, const UNICODE_STRING *name )
153 NTSTATUS ret;
155 TRACE( "(0x%x,%s)\n", hkey, debugstr_us(name) );
156 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
158 SERVER_START_REQ
160 struct delete_key_value_request *req = server_alloc_req( sizeof(*req), name->Length );
162 req->hkey = hkey;
163 memcpy( server_data_ptr(req), name->Buffer, name->Length );
164 ret = server_call_noerr( REQ_DELETE_KEY_VALUE );
166 SERVER_END_REQ;
167 return ret;
171 /******************************************************************************
172 * fill_key_info
174 * Helper function for NtQueryKey and NtEnumerateKey
176 static NTSTATUS fill_key_info( KEY_INFORMATION_CLASS info_class, void *info, DWORD length,
177 DWORD *result_len, const struct enum_key_request *req )
179 WCHAR *name_ptr = server_data_ptr(req);
180 int name_size = *name_ptr++;
181 WCHAR *class_ptr = (WCHAR *)((char *)name_ptr + name_size);
182 int class_size = server_data_size(req) - sizeof(WCHAR) - name_size;
183 int fixed_size;
184 FILETIME modif;
186 RtlSecondsSince1970ToTime( req->modif, &modif );
188 switch(info_class)
190 case KeyBasicInformation:
192 KEY_BASIC_INFORMATION keyinfo;
193 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Name);
194 keyinfo.LastWriteTime = modif;
195 keyinfo.TitleIndex = 0;
196 keyinfo.NameLength = name_size;
197 memcpy( info, &keyinfo, min( length, fixed_size ) );
198 class_size = 0;
200 break;
201 case KeyFullInformation:
203 KEY_FULL_INFORMATION keyinfo;
204 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Class);
205 keyinfo.LastWriteTime = modif;
206 keyinfo.TitleIndex = 0;
207 keyinfo.ClassLength = class_size;
208 keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1;
209 keyinfo.SubKeys = req->subkeys;
210 keyinfo.MaxNameLen = req->max_subkey;
211 keyinfo.MaxClassLen = req->max_class;
212 keyinfo.Values = req->values;
213 keyinfo.MaxValueNameLen = req->max_value;
214 keyinfo.MaxValueDataLen = req->max_data;
215 memcpy( info, &keyinfo, min( length, fixed_size ) );
216 name_size = 0;
218 break;
219 case KeyNodeInformation:
221 KEY_NODE_INFORMATION keyinfo;
222 fixed_size = sizeof(keyinfo) - sizeof(keyinfo.Name);
223 keyinfo.LastWriteTime = modif;
224 keyinfo.TitleIndex = 0;
225 keyinfo.ClassLength = class_size;
226 keyinfo.ClassOffset = fixed_size + name_size;
227 if (!keyinfo.ClassLength || keyinfo.ClassOffset > length) keyinfo.ClassOffset = -1;
228 keyinfo.NameLength = name_size;
229 memcpy( info, &keyinfo, min( length, fixed_size ) );
231 break;
232 default:
233 FIXME("Information class not implemented\n");
234 return STATUS_INVALID_PARAMETER;
237 *result_len = fixed_size + name_size + class_size;
238 if (length <= fixed_size) return STATUS_BUFFER_OVERFLOW;
239 length -= fixed_size;
241 /* copy the name */
242 if (name_size)
244 memcpy( (char *)info + fixed_size, name_ptr, min(length,name_size) );
245 if (length < name_size) return STATUS_BUFFER_OVERFLOW;
246 length -= name_size;
249 /* copy the class */
250 if (class_size)
252 memcpy( (char *)info + fixed_size + name_size, class_ptr, min(length,class_size) );
253 if (length < class_size) return STATUS_BUFFER_OVERFLOW;
255 return STATUS_SUCCESS;
260 /******************************************************************************
261 * NtEnumerateKey [NTDLL]
262 * ZwEnumerateKey
264 * NOTES
265 * the name copied into the buffer is NOT 0-terminated
267 NTSTATUS WINAPI NtEnumerateKey( HANDLE handle, ULONG index, KEY_INFORMATION_CLASS info_class,
268 void *info, DWORD length, DWORD *result_len )
270 NTSTATUS ret;
272 /* -1 means query key, so avoid it here */
273 if (index == (ULONG)-1) return STATUS_NO_MORE_ENTRIES;
275 SERVER_START_REQ
277 struct enum_key_request *req = server_alloc_req( sizeof(*req), REQUEST_MAX_VAR_SIZE );
278 req->hkey = handle;
279 req->index = index;
280 req->full = (info_class == KeyFullInformation);
281 if (!(ret = server_call_noerr( REQ_ENUM_KEY )))
283 ret = fill_key_info( info_class, info, length, result_len, req );
286 SERVER_END_REQ;
287 return ret;
291 /******************************************************************************
292 * NtQueryKey [NTDLL]
293 * ZwQueryKey
295 NTSTATUS WINAPI NtQueryKey( HANDLE handle, KEY_INFORMATION_CLASS info_class,
296 void *info, DWORD length, DWORD *result_len )
298 NTSTATUS ret;
300 SERVER_START_REQ
302 struct enum_key_request *req = server_alloc_req( sizeof(*req), REQUEST_MAX_VAR_SIZE );
303 req->hkey = handle;
304 req->index = -1;
305 req->full = (info_class == KeyFullInformation);
306 if (!(ret = server_call_noerr( REQ_ENUM_KEY )))
308 ret = fill_key_info( info_class, info, length, result_len, req );
311 SERVER_END_REQ;
312 return ret;
316 /* fill the key value info structure for a specific info class */
317 static void copy_key_value_info( KEY_VALUE_INFORMATION_CLASS info_class, void *info,
318 DWORD length, int type, int name_len, int data_len )
320 switch(info_class)
322 case KeyValueBasicInformation:
324 KEY_VALUE_BASIC_INFORMATION keyinfo;
325 keyinfo.TitleIndex = 0;
326 keyinfo.Type = type;
327 keyinfo.NameLength = name_len;
328 length = min( length, sizeof(keyinfo) - sizeof(keyinfo.Name) );
329 memcpy( info, &keyinfo, length );
330 break;
332 case KeyValueFullInformation:
334 KEY_VALUE_FULL_INFORMATION keyinfo;
335 keyinfo.TitleIndex = 0;
336 keyinfo.Type = type;
337 keyinfo.DataOffset = sizeof(keyinfo) - sizeof(keyinfo.Name) + name_len;
338 keyinfo.DataLength = data_len;
339 keyinfo.NameLength = name_len;
340 length = min( length, sizeof(keyinfo) - sizeof(keyinfo.Name) );
341 memcpy( info, &keyinfo, length );
342 break;
344 case KeyValuePartialInformation:
346 KEY_VALUE_PARTIAL_INFORMATION keyinfo;
347 keyinfo.TitleIndex = 0;
348 keyinfo.Type = type;
349 keyinfo.DataLength = data_len;
350 length = min( length, sizeof(keyinfo) - sizeof(keyinfo.Data) );
351 memcpy( info, &keyinfo, length );
352 break;
354 default:
355 break;
360 /******************************************************************************
361 * NtEnumerateValueKey [NTDLL]
362 * ZwEnumerateValueKey
364 NTSTATUS WINAPI NtEnumerateValueKey( HANDLE handle, ULONG index,
365 KEY_VALUE_INFORMATION_CLASS info_class,
366 void *info, DWORD length, DWORD *result_len )
368 NTSTATUS ret;
369 char *data_ptr, *name_ptr;
370 int fixed_size = 0, name_len = 0, data_len = 0, offset = 0, type = 0, total_len = 0;
372 TRACE( "(0x%x,%lu,%d,%p,%ld)\n", handle, index, info_class, info, length );
374 /* compute the length we want to retrieve */
375 switch(info_class)
377 case KeyValueBasicInformation:
378 fixed_size = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR);
379 name_ptr = (char *)info + fixed_size;
380 data_ptr = NULL;
381 break;
382 case KeyValueFullInformation:
383 fixed_size = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR);
384 name_ptr = data_ptr = (char *)info + fixed_size;
385 break;
386 case KeyValuePartialInformation:
387 fixed_size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(UCHAR);
388 name_ptr = NULL;
389 data_ptr = (char *)info + fixed_size;
390 break;
391 default:
392 FIXME( "Information class %d not implemented\n", info_class );
393 return STATUS_INVALID_PARAMETER;
395 if (length > fixed_size) data_len = length - fixed_size;
399 size_t reqlen = data_len + sizeof(WCHAR);
400 if (name_ptr && !offset) reqlen += MAX_PATH*sizeof(WCHAR);
401 reqlen = min( reqlen, REQUEST_MAX_VAR_SIZE );
403 SERVER_START_REQ
405 struct enum_key_value_request *req = server_alloc_req( sizeof(*req), reqlen );
407 req->hkey = handle;
408 req->index = index;
409 req->offset = offset;
411 if (!(ret = server_call_noerr( REQ_ENUM_KEY_VALUE )))
413 size_t size = server_data_size(req) - sizeof(WCHAR);
414 WCHAR *name = server_data_ptr(req);
415 if (!offset) /* name is only present on the first request */
417 name_len = *name++;
418 size -= name_len;
419 if (name_ptr)
421 if (name_len > data_len) /* overflow */
423 memcpy( name_ptr, name, data_len );
424 data_len = 0;
425 ret = STATUS_BUFFER_OVERFLOW;
427 else
429 memcpy( name_ptr, name, name_len );
430 data_len -= name_len;
431 if (data_ptr) data_ptr += name_len;
434 name += name_len / sizeof(WCHAR);
436 else name++; /* skip 0 length */
438 if (data_ptr)
440 size = min( size, data_len );
441 memcpy( data_ptr + offset, name, size );
442 offset += size;
443 data_len -= size;
445 type = req->type;
446 total_len = req->len;
449 SERVER_END_REQ;
450 if (ret) return ret;
451 } while (data_len && data_ptr && offset < total_len);
453 *result_len = total_len + fixed_size + (name_ptr ? name_len : 0);
455 if (data_ptr && offset < total_len) ret = STATUS_BUFFER_OVERFLOW;
456 if (length < fixed_size) ret = STATUS_BUFFER_OVERFLOW;
458 copy_key_value_info( info_class, info, length, type, name_len, total_len );
459 return ret;
464 /******************************************************************************
465 * NtQueryValueKey [NTDLL]
466 * ZwQueryValueKey
468 * NOTES
469 * the name in the KeyValueInformation is never set
471 NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name,
472 KEY_VALUE_INFORMATION_CLASS info_class,
473 void *info, DWORD length, DWORD *result_len )
475 NTSTATUS ret;
476 char *data_ptr;
477 int fixed_size = 0, data_len = 0, offset = 0, type = 0, total_len = 0;
479 TRACE( "(0x%x,%s,%d,%p,%ld)\n", handle, debugstr_us(name), info_class, info, length );
481 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
483 /* compute the length we want to retrieve */
484 switch(info_class)
486 case KeyValueBasicInformation:
487 fixed_size = sizeof(KEY_VALUE_BASIC_INFORMATION) - sizeof(WCHAR);
488 data_ptr = NULL;
489 break;
490 case KeyValueFullInformation:
491 fixed_size = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR);
492 data_ptr = (char *)info + fixed_size;
493 break;
494 case KeyValuePartialInformation:
495 fixed_size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) - sizeof(UCHAR);
496 data_ptr = (char *)info + fixed_size;
497 break;
498 default:
499 FIXME( "Information class %d not implemented\n", info_class );
500 return STATUS_INVALID_PARAMETER;
502 if (data_ptr && length > fixed_size) data_len = length - fixed_size;
506 size_t reqlen = min( data_len, REQUEST_MAX_VAR_SIZE );
507 reqlen = max( reqlen, name->Length + sizeof(WCHAR) );
509 SERVER_START_REQ
511 struct get_key_value_request *req = server_alloc_req( sizeof(*req), reqlen );
512 WCHAR *nameptr = server_data_ptr(req);
514 req->hkey = handle;
515 req->offset = offset;
516 *nameptr++ = name->Length;
517 memcpy( nameptr, name->Buffer, name->Length );
519 if (!(ret = server_call_noerr( REQ_GET_KEY_VALUE )))
521 size_t size = min( server_data_size(req), data_len );
522 type = req->type;
523 total_len = req->len;
524 if (size)
526 memcpy( data_ptr + offset, server_data_ptr(req), size );
527 offset += size;
528 data_len -= size;
532 SERVER_END_REQ;
533 if (ret) return ret;
534 } while (data_len && offset < total_len);
536 *result_len = total_len + fixed_size;
538 if (offset < total_len) ret = STATUS_BUFFER_OVERFLOW;
539 if (length < fixed_size) ret = STATUS_BUFFER_OVERFLOW;
541 copy_key_value_info( info_class, info, length, type, 0, total_len );
542 return ret;
546 /******************************************************************************
547 * NtFlushKey [NTDLL]
548 * ZwFlushKey
550 NTSTATUS WINAPI NtFlushKey(HANDLE KeyHandle)
552 FIXME("(0x%08x) stub!\n",
553 KeyHandle);
554 return 1;
557 /******************************************************************************
558 * NtLoadKey [NTDLL]
559 * ZwLoadKey
561 NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, const OBJECT_ATTRIBUTES *file )
563 FIXME("stub!\n");
564 dump_ObjectAttributes(attr);
565 dump_ObjectAttributes(file);
566 return STATUS_SUCCESS;
569 /******************************************************************************
570 * NtNotifyChangeKey [NTDLL]
571 * ZwNotifyChangeKey
573 NTSTATUS WINAPI NtNotifyChangeKey(
574 IN HANDLE KeyHandle,
575 IN HANDLE Event,
576 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
577 IN PVOID ApcContext OPTIONAL,
578 OUT PIO_STATUS_BLOCK IoStatusBlock,
579 IN ULONG CompletionFilter,
580 IN BOOLEAN Asynchroneous,
581 OUT PVOID ChangeBuffer,
582 IN ULONG Length,
583 IN BOOLEAN WatchSubtree)
585 FIXME("(0x%08x,0x%08x,%p,%p,%p,0x%08lx, 0x%08x,%p,0x%08lx,0x%08x) stub!\n",
586 KeyHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter,
587 Asynchroneous, ChangeBuffer, Length, WatchSubtree);
588 return STATUS_SUCCESS;
591 /******************************************************************************
592 * NtQueryMultipleValueKey [NTDLL]
593 * ZwQueryMultipleValueKey
596 NTSTATUS WINAPI NtQueryMultipleValueKey(
597 HANDLE KeyHandle,
598 PVALENTW ListOfValuesToQuery,
599 ULONG NumberOfItems,
600 PVOID MultipleValueInformation,
601 ULONG Length,
602 PULONG ReturnLength)
604 FIXME("(0x%08x,%p,0x%08lx,%p,0x%08lx,%p) stub!\n",
605 KeyHandle, ListOfValuesToQuery, NumberOfItems, MultipleValueInformation,
606 Length,ReturnLength);
607 return STATUS_SUCCESS;
610 /******************************************************************************
611 * NtReplaceKey [NTDLL]
612 * ZwReplaceKey
614 NTSTATUS WINAPI NtReplaceKey(
615 IN POBJECT_ATTRIBUTES ObjectAttributes,
616 IN HANDLE Key,
617 IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
619 FIXME("(0x%08x),stub!\n", Key);
620 dump_ObjectAttributes(ObjectAttributes);
621 dump_ObjectAttributes(ReplacedObjectAttributes);
622 return STATUS_SUCCESS;
624 /******************************************************************************
625 * NtRestoreKey [NTDLL]
626 * ZwRestoreKey
628 NTSTATUS WINAPI NtRestoreKey(
629 HANDLE KeyHandle,
630 HANDLE FileHandle,
631 ULONG RestoreFlags)
633 FIXME("(0x%08x,0x%08x,0x%08lx) stub\n",
634 KeyHandle, FileHandle, RestoreFlags);
635 return STATUS_SUCCESS;
637 /******************************************************************************
638 * NtSaveKey [NTDLL]
639 * ZwSaveKey
641 NTSTATUS WINAPI NtSaveKey(
642 IN HANDLE KeyHandle,
643 IN HANDLE FileHandle)
645 FIXME("(0x%08x,0x%08x) stub\n",
646 KeyHandle, FileHandle);
647 return STATUS_SUCCESS;
649 /******************************************************************************
650 * NtSetInformationKey [NTDLL]
651 * ZwSetInformationKey
653 NTSTATUS WINAPI NtSetInformationKey(
654 IN HANDLE KeyHandle,
655 IN const int KeyInformationClass,
656 IN PVOID KeyInformation,
657 IN ULONG KeyInformationLength)
659 FIXME("(0x%08x,0x%08x,%p,0x%08lx) stub\n",
660 KeyHandle, KeyInformationClass, KeyInformation, KeyInformationLength);
661 return STATUS_SUCCESS;
665 /******************************************************************************
666 * NtSetValueKey [NTDLL]
667 * ZwSetValueKey
669 * NOTES
670 * win95 does not care about count for REG_SZ and finds out the len by itself (js)
671 * NT does definitely care (aj)
673 NTSTATUS WINAPI NtSetValueKey( HANDLE hkey, const UNICODE_STRING *name, ULONG TitleIndex,
674 ULONG type, const void *data, ULONG count )
676 NTSTATUS ret;
677 ULONG namelen, pos;
679 TRACE( "(0x%x,%s,%ld,%p,%ld)\n", hkey, debugstr_us(name), type, data, count );
681 if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
683 namelen = name->Length + sizeof(WCHAR); /* for storing length */
684 pos = 0;
688 ULONG len = count - pos;
689 if (len > REQUEST_MAX_VAR_SIZE - namelen) len = REQUEST_MAX_VAR_SIZE - namelen;
691 SERVER_START_REQ
693 struct set_key_value_request *req = server_alloc_req( sizeof(*req), namelen + len );
694 WCHAR *name_ptr = server_data_ptr(req);
696 req->hkey = hkey;
697 req->type = type;
698 req->total = count;
699 req->offset = pos;
700 *name_ptr++ = name->Length;
701 memcpy( name_ptr, name->Buffer, name->Length );
702 memcpy( (char *)name_ptr + name->Length, (char *)data + pos, len );
703 pos += len;
704 ret = server_call_noerr( REQ_SET_KEY_VALUE );
706 SERVER_END_REQ;
707 } while (!ret && pos < count);
708 return ret;
711 /******************************************************************************
712 * NtUnloadKey [NTDLL]
713 * ZwUnloadKey
715 NTSTATUS WINAPI NtUnloadKey(
716 IN HANDLE KeyHandle)
718 FIXME("(0x%08x) stub\n",
719 KeyHandle);
720 return STATUS_SUCCESS;
723 /******************************************************************************
724 * RtlFormatCurrentUserKeyPath [NTDLL.371]
726 NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(
727 IN OUT PUNICODE_STRING KeyPath)
729 /* LPSTR Path = "\\REGISTRY\\USER\\S-1-5-21-0000000000-000000000-0000000000-500";*/
730 LPSTR Path = "\\REGISTRY\\USER\\.DEFAULT";
731 ANSI_STRING AnsiPath;
733 FIXME("(%p) stub\n",KeyPath);
734 RtlInitAnsiString(&AnsiPath, Path);
735 return RtlAnsiStringToUnicodeString(KeyPath, &AnsiPath, TRUE);
738 /******************************************************************************
739 * RtlOpenCurrentUser [NTDLL]
741 * if we return just HKEY_CURRENT_USER the advapi try's to find a remote
742 * registry (odd handle) and fails
745 DWORD WINAPI RtlOpenCurrentUser(
746 IN ACCESS_MASK DesiredAccess, /* [in] */
747 OUT PHANDLE KeyHandle) /* [out] handle of HKEY_CURRENT_USER */
749 OBJECT_ATTRIBUTES ObjectAttributes;
750 UNICODE_STRING ObjectName;
751 NTSTATUS ret;
753 TRACE("(0x%08lx, %p) stub\n",DesiredAccess, KeyHandle);
755 RtlFormatCurrentUserKeyPath(&ObjectName);
756 InitializeObjectAttributes(&ObjectAttributes,&ObjectName,OBJ_CASE_INSENSITIVE,0, NULL);
757 ret = NtOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
758 RtlFreeUnicodeString(&ObjectName);
759 return ret;