Author: ion
Date: Thu Jun 29 04:30:36 2006
New Revision: 22682
URL:
http://svn.reactos.org/svn/reactos?rev=22682&view=rev
Log:
- Add some hacks to Cm to allow creating registry keys that finish with a backslash (this
works under NT).
- Also add a REALLY nasty hack that forces OBJ_CASE_INSENSITIVE on all Registry APIs...
this is needed because we seem to completely mess up case sensitivity otherwise and any
user-mode caller that doesn't specify that flag will fail.
- These two fixes fix all the WINE failures for the "ntdll reg" test and should
increase compatibility with some applications.
- Runtime Library Registry Wrappers Fixes and Optimizations:
- Use an array of registry paths instead of duplicating them
- Fix implenmentation of RTL_REGISTRY_HANDLE.
- Verify all Appends for failure before continuing.
- Use the strict minimum key permissions isntead of KEY_ALL_ACCESS.
- Don't use OBJ_OPENIF
- Use CAPS for \\REGISTRY\\USER (required to match a Windows quirk exposed by a WINE
test)
- Use the correct length in RtlpNtQueryValueKey
- Generic cleanups, formatting and commenting.
Modified:
trunk/reactos/lib/rtl/registry.c
trunk/reactos/ntoskrnl/cm/ntfunc.c
trunk/reactos/ntoskrnl/cm/regobj.c
Modified: trunk/reactos/lib/rtl/registry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/registry.c?rev=226…
==============================================================================
--- trunk/reactos/lib/rtl/registry.c (original)
+++ trunk/reactos/lib/rtl/registry.c Thu Jun 29 04:30:36 2006
@@ -21,350 +21,541 @@
#define TAG_RTLREGISTRY TAG('R', 't', 'l', 'R')
-/* FUNCTIONS ***************************************************************/
-
-static NTSTATUS
-RtlpGetRegistryHandle(ULONG RelativeTo,
- PWSTR Path,
- BOOLEAN Create,
- PHANDLE KeyHandle)
-{
- UNICODE_STRING KeyPath;
- UNICODE_STRING KeyName;
- WCHAR KeyBuffer[MAX_PATH];
- OBJECT_ATTRIBUTES ObjectAttributes;
- NTSTATUS Status;
-
- DPRINT("RtlpGetRegistryHandle()\n");
-
- if (RelativeTo & RTL_REGISTRY_HANDLE)
- {
- Status = ZwDuplicateObject(NtCurrentProcess(),
- (HANDLE)Path,
- NtCurrentProcess(),
- KeyHandle,
- 0,
- 0,
- DUPLICATE_SAME_ACCESS);
-#ifndef NDEBUG
- if(!NT_SUCCESS(Status))
- {
- DPRINT("ZwDuplicateObject() failed! Status: 0x%x\n", Status);
- }
-#endif
-
- return(Status);
- }
-
- if (RelativeTo & RTL_REGISTRY_OPTIONAL)
- RelativeTo &= ~RTL_REGISTRY_OPTIONAL;
-
- if (RelativeTo >= RTL_REGISTRY_MAXIMUM)
- {
- DPRINT("Invalid relative flag, parameter invalid!\n");
- return(STATUS_INVALID_PARAMETER);
- }
-
- KeyName.Length = 0;
- KeyName.MaximumLength = sizeof(KeyBuffer);
- KeyName.Buffer = KeyBuffer;
- KeyBuffer[0] = 0;
-
- switch (RelativeTo)
- {
- case RTL_REGISTRY_ABSOLUTE:
- /* nothing to prefix! */
- break;
-
- case RTL_REGISTRY_SERVICES:
- RtlAppendUnicodeToString(&KeyName,
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
- break;
-
- case RTL_REGISTRY_CONTROL:
- RtlAppendUnicodeToString(&KeyName,
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\");
- break;
-
- case RTL_REGISTRY_WINDOWS_NT:
- RtlAppendUnicodeToString(&KeyName,
- L"\\Registry\\Machine\\Software\\Microsoft\\Windows
NT\\CurrentVersion\\");
- break;
-
- case RTL_REGISTRY_DEVICEMAP:
- RtlAppendUnicodeToString(&KeyName,
- L"\\Registry\\Machine\\Hardware\\DeviceMap\\");
- break;
-
- case RTL_REGISTRY_USER:
- Status = RtlFormatCurrentUserKeyPath (&KeyPath);
- if (!NT_SUCCESS(Status))
- return(Status);
- RtlAppendUnicodeStringToString (&KeyName,
- &KeyPath);
- RtlFreeUnicodeString (&KeyPath);
- RtlAppendUnicodeToString (&KeyName,
- L"\\");
- break;
- }
-
- if (Path[0] == L'\\' && RelativeTo != RTL_REGISTRY_ABSOLUTE)
- {
- Path++;
- }
- RtlAppendUnicodeToString(&KeyName,
- Path);
-
- DPRINT("KeyName %wZ\n", &KeyName);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
- NULL,
- NULL);
-
- if (Create)
- {
- Status = ZwCreateKey(KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- 0,
- NULL);
- }
- else
- {
- Status = ZwOpenKey(KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes);
- }
-
-#ifndef NDEBUG
- if(!NT_SUCCESS(Status))
- {
- DPRINT("%s failed! Status: 0x%x\n", (Create ? "ZwCreateKey" :
"ZwOpenKey"), Status);
- }
-#endif
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
+/* DATA **********************************************************************/
+
+PCWSTR RtlpRegPaths[RTL_REGISTRY_MAXIMUM] =
+{
+ NULL,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services",
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Control",
+ L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion",
+ L"\\Registry\\Machine\\Hardware\\DeviceMap",
+ L"\\Registry\\User\\.Default",
+};
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+NTSTATUS
+NTAPI
+RtlpGetRegistryHandle(IN ULONG RelativeTo,
+ IN PCWSTR Path,
+ IN BOOLEAN Create,
+ IN PHANDLE KeyHandle)
+{
+ UNICODE_STRING KeyPath, KeyName;
+ WCHAR KeyBuffer[MAX_PATH];
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
+
+ /* Check if we just want the handle */
+ if (RelativeTo & RTL_REGISTRY_HANDLE)
+ {
+ *KeyHandle = (HANDLE)Path;
+ return STATUS_SUCCESS;
+ }
+
+ /* Check for optional flag */
+ if (RelativeTo & RTL_REGISTRY_OPTIONAL)
+ {
+ /* Mask it out */
+ RelativeTo &= ~RTL_REGISTRY_OPTIONAL;
+ }
+
+ /* Fail on invalid parameter */
+ if (RelativeTo >= RTL_REGISTRY_MAXIMUM) return STATUS_INVALID_PARAMETER;
+
+ /* Initialize the key name */
+ RtlInitEmptyUnicodeString(&KeyName, KeyBuffer, sizeof(KeyBuffer));
+
+ /* Check if we have to lookup a path to prefix */
+ if (RelativeTo != RTL_REGISTRY_ABSOLUTE)
+ {
+ /* Check if we need the current user key */
+ if (RelativeTo == RTL_REGISTRY_USER)
+ {
+ /* Get the path */
+ Status = RtlFormatCurrentUserKeyPath(&KeyPath);
+ if (!NT_SUCCESS(Status)) return(Status);
+
+ /* Append it */
+ Status = RtlAppendUnicodeStringToString(&KeyName, &KeyPath);
+ RtlFreeUnicodeString (&KeyPath);
+ }
+ else
+ {
+ /* Get one of the prefixes */
+ Status = RtlAppendUnicodeToString(&KeyName,
+ RtlpRegPaths[RelativeTo]);
+ }
+
+ /* Check for failure, otherwise, append the path separator */
+ if (!NT_SUCCESS(Status)) return Status;
+ Status = RtlAppendUnicodeToString(&KeyName, L"\\");
+ if (!NT_SUCCESS(Status)) return Status;
+ }
+
+ /* And now append the path */
+ if (Path[0] == L'\\' && RelativeTo != RTL_REGISTRY_ABSOLUTE) Path++;
// HACK!
+ Status = RtlAppendUnicodeToString(&KeyName, Path);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Initialize the object attributes */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ /* Check if we want to create it */
+ if (Create)
+ {
+ /* Create the key with write privileges */
+ Status = ZwCreateKey(KeyHandle,
+ GENERIC_WRITE,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ }
+ else
+ {
+ /* Otherwise, just open it with read access */
+ Status = ZwOpenKey(KeyHandle,
+ MAXIMUM_ALLOWED | GENERIC_READ,
+ &ObjectAttributes);
+ }
+
+ /* Return status */
+ return Status;
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
RtlCheckRegistryKey(IN ULONG RelativeTo,
- IN PWSTR Path)
-{
- HANDLE KeyHandle;
- NTSTATUS Status;
-
- PAGED_CODE_RTL();
-
- Status = RtlpGetRegistryHandle(RelativeTo,
- Path,
- FALSE,
- &KeyHandle);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- ZwClose(KeyHandle);
-
- return(STATUS_SUCCESS);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
+ IN PWSTR Path)
+{
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ PAGED_CODE_RTL();
+
+ /* Call the helper */
+ Status = RtlpGetRegistryHandle(RelativeTo,
+ Path,
+ FALSE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* All went well, close the handle and return success */
+ ZwClose(KeyHandle);
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
RtlCreateRegistryKey(IN ULONG RelativeTo,
- IN PWSTR Path)
-{
- HANDLE KeyHandle;
- NTSTATUS Status;
-
- PAGED_CODE_RTL();
-
- Status = RtlpGetRegistryHandle(RelativeTo,
- Path,
- TRUE,
- &KeyHandle);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- ZwClose(KeyHandle);
-
- return(STATUS_SUCCESS);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
+ IN PWSTR Path)
+{
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ PAGED_CODE_RTL();
+
+ /* Call the helper */
+ Status = RtlpGetRegistryHandle(RelativeTo,
+ Path,
+ TRUE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* All went well, close the handle and return success */
+ ZwClose(KeyHandle);
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
RtlDeleteRegistryValue(IN ULONG RelativeTo,
- IN PCWSTR Path,
- IN PCWSTR ValueName)
-{
- HANDLE KeyHandle;
- NTSTATUS Status;
- UNICODE_STRING Name;
-
- PAGED_CODE_RTL();
-
- Status = RtlpGetRegistryHandle(RelativeTo,
- (PWSTR)Path,
- FALSE,
- &KeyHandle);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- RtlInitUnicodeString(&Name,
- ValueName);
-
- Status = ZwDeleteValueKey(KeyHandle,
- &Name);
-
- ZwClose(KeyHandle);
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-RtlFormatCurrentUserKeyPath (OUT PUNICODE_STRING KeyPath)
-{
- HANDLE TokenHandle;
- UCHAR Buffer[256];
- PSID_AND_ATTRIBUTES SidBuffer;
- ULONG Length;
- UNICODE_STRING SidString;
- NTSTATUS Status;
-
- PAGED_CODE_RTL();
-
- DPRINT ("RtlFormatCurrentUserKeyPath() called\n");
-
- Status = ZwOpenThreadToken (NtCurrentThread (),
- TOKEN_QUERY,
- TRUE,
- &TokenHandle);
- if (!NT_SUCCESS (Status))
- {
- if (Status != STATUS_NO_TOKEN)
- {
- DPRINT1 ("ZwOpenThreadToken() failed (Status %lx)\n", Status);
- return Status;
- }
-
- Status = ZwOpenProcessToken (NtCurrentProcess (),
- TOKEN_QUERY,
- &TokenHandle);
- if (!NT_SUCCESS (Status))
- {
- DPRINT1 ("ZwOpenProcessToken() failed (Status %lx)\n", Status);
- return Status;
- }
- }
-
- SidBuffer = (PSID_AND_ATTRIBUTES)Buffer;
- Status = ZwQueryInformationToken (TokenHandle,
- TokenUser,
- (PVOID)SidBuffer,
- 256,
- &Length);
- ZwClose (TokenHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1 ("ZwQueryInformationToken() failed (Status %lx)\n", Status);
- return Status;
- }
-
- Status = RtlConvertSidToUnicodeString (&SidString,
- SidBuffer[0].Sid,
- TRUE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1 ("RtlConvertSidToUnicodeString() failed (Status %lx)\n",
Status);
- return Status;
- }
-
- DPRINT ("SidString: '%wZ'\n", &SidString);
-
- Length = SidString.Length + sizeof(L"\\Registry\\User\\");
- DPRINT ("Length: %lu\n", Length);
-
- KeyPath->Length = 0;
- KeyPath->MaximumLength = Length;
- KeyPath->Buffer = RtlpAllocateStringMemory(KeyPath->MaximumLength, TAG_USTR);
- if (KeyPath->Buffer == NULL)
- {
- DPRINT1 ("RtlpAllocateMemory() failed\n");
- RtlFreeUnicodeString (&SidString);
- return STATUS_NO_TOKEN;
- }
-
- RtlAppendUnicodeToString (KeyPath,
- L"\\Registry\\User\\");
- RtlAppendUnicodeStringToString (KeyPath,
- &SidString);
- RtlFreeUnicodeString (&SidString);
-
- return STATUS_SUCCESS;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
+ IN PCWSTR Path,
+ IN PCWSTR ValueName)
+{
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ UNICODE_STRING Name;
+ PAGED_CODE_RTL();
+
+ /* Call the helper */
+ Status = RtlpGetRegistryHandle(RelativeTo,
+ Path,
+ TRUE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Initialize the key name and delete it */
+ RtlInitUnicodeString(&Name, ValueName);
+ Status = ZwDeleteValueKey(KeyHandle, &Name);
+
+ /* All went well, close the handle and return status */
+ ZwClose(KeyHandle);
+ return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlWriteRegistryValue(IN ULONG RelativeTo,
+ IN PCWSTR Path,
+ IN PCWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength)
+{
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ UNICODE_STRING Name;
+ PAGED_CODE_RTL();
+
+ /* Call the helper */
+ Status = RtlpGetRegistryHandle(RelativeTo,
+ Path,
+ TRUE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Initialize the key name and set it */
+ RtlInitUnicodeString(&Name, ValueName);
+ Status = ZwSetValueKey(KeyHandle,
+ &Name,
+ 0,
+ ValueType,
+ ValueData,
+ ValueLength);
+
+ /* All went well, close the handle and return status */
+ ZwClose(KeyHandle);
+ return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
RtlOpenCurrentUser(IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE KeyHandle)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyPath;
- NTSTATUS Status;
-
- PAGED_CODE_RTL();
-
- Status = RtlFormatCurrentUserKeyPath(&KeyPath);
- if (NT_SUCCESS(Status))
- {
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyPath,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = ZwOpenKey(KeyHandle,
- DesiredAccess,
- &ObjectAttributes);
- RtlFreeUnicodeString(&KeyPath);
- if (NT_SUCCESS(Status))
- {
- return STATUS_SUCCESS;
- }
- }
-
- RtlInitUnicodeString (&KeyPath,
- L"\\Registry\\User\\.Default");
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyPath,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = ZwOpenKey(KeyHandle,
- DesiredAccess,
- &ObjectAttributes);
-
- return Status;
-}
-
+ OUT PHANDLE KeyHandle)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING KeyPath;
+ NTSTATUS Status;
+ PAGED_CODE_RTL();
+
+ /* Get the user key */
+ Status = RtlFormatCurrentUserKeyPath(&KeyPath);
+ if (NT_SUCCESS(Status))
+ {
+ /* Initialize the attributes and open it */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyPath,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = ZwOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
+
+ /* Free the path and return success if it worked */
+ RtlFreeUnicodeString(&KeyPath);
+ if (NT_SUCCESS(Status)) return STATUS_SUCCESS;
+ }
+
+ /* It didn't work, so use the default key */
+ RtlInitUnicodeString(&KeyPath, RtlpRegPaths[RTL_REGISTRY_USER]);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyPath,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = ZwOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
+
+ /* Return status */
+ return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlFormatCurrentUserKeyPath(OUT PUNICODE_STRING KeyPath)
+{
+ HANDLE TokenHandle;
+ UCHAR Buffer[256];
+ PSID_AND_ATTRIBUTES SidBuffer;
+ ULONG Length;
+ UNICODE_STRING SidString;
+ NTSTATUS Status;
+ PAGED_CODE_RTL();
+
+ /* Open the thread token */
+ Status = ZwOpenThreadToken(NtCurrentThread(),
+ TOKEN_QUERY,
+ TRUE,
+ &TokenHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ /* We failed, is it because we don't have a thread token? */
+ if (Status != STATUS_NO_TOKEN) return Status;
+
+ /* It is, so use the process token */
+ Status = ZwOpenProcessToken(NtCurrentProcess(),
+ TOKEN_QUERY,
+ &TokenHandle);
+ if (!NT_SUCCESS(Status)) return Status;
+ }
+
+ /* Now query the token information */
+ SidBuffer = (PSID_AND_ATTRIBUTES)Buffer;
+ Status = ZwQueryInformationToken(TokenHandle,
+ TokenUser,
+ (PVOID)SidBuffer,
+ sizeof(Buffer),
+ &Length);
+
+ /* Close the handle and handle failure */
+ ZwClose(TokenHandle);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Convert the SID */
+ Status = RtlConvertSidToUnicodeString(&SidString, SidBuffer[0].Sid, TRUE);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Add the length of the prefix */
+ Length = SidString.Length + sizeof(L"\\REGISTRY\\USER\\");
+
+ /* Initialize a string */
+ RtlInitEmptyUnicodeString(KeyPath,
+ RtlpAllocateStringMemory(Length, TAG_USTR),
+ Length);
+ if (!KeyPath->Buffer)
+ {
+ /* Free the string and fail */
+ RtlFreeUnicodeString(&SidString);
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Append the prefix and SID */
+ RtlAppendUnicodeToString(KeyPath, L"\\REGISTRY\\USER\\");
+ RtlAppendUnicodeStringToString(KeyPath, &SidString);
+
+ /* Free the temporary string and return success */
+ RtlFreeUnicodeString(&SidString);
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlpNtCreateKey(OUT HANDLE KeyHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN ULONG TitleIndex,
+ IN PUNICODE_STRING Class,
+ OUT PULONG Disposition)
+{
+ /* Check if we have object attributes */
+ if (ObjectAttributes)
+ {
+ /* Mask out the unsupported flags */
+ ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
+ }
+
+ /* Create the key */
+ return ZwCreateKey(KeyHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ Disposition);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlpNtEnumerateSubKey(IN HANDLE KeyHandle,
+ OUT PUNICODE_STRING SubKeyName,
+ IN ULONG Index,
+ IN ULONG Unused)
+{
+ PKEY_BASIC_INFORMATION KeyInfo = NULL;
+ ULONG BufferLength = 0;
+ ULONG ReturnedLength;
+ NTSTATUS Status;
+
+ /* Check if we have a name */
+ if (SubKeyName->MaximumLength)
+ {
+ /* Allocate a buffer for it */
+ BufferLength = SubKeyName->MaximumLength +
+ sizeof(KEY_BASIC_INFORMATION);
+ KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
+ if (!KeyInfo) return STATUS_NO_MEMORY;
+ }
+
+ /* Enumerate the key */
+ Status = ZwEnumerateKey(KeyHandle,
+ Index,
+ KeyBasicInformation,
+ KeyInfo,
+ BufferLength,
+ &ReturnedLength);
+ if (NT_SUCCESS(Status))
+ {
+ /* Check if the name fits */
+ if (KeyInfo->NameLength <= SubKeyName->MaximumLength)
+ {
+ /* Set the length */
+ SubKeyName->Length = KeyInfo->NameLength;
+
+ /* Copy it */
+ RtlMoveMemory(SubKeyName->Buffer,
+ KeyInfo->Name,
+ SubKeyName->Length);
+ }
+ else
+ {
+ /* Otherwise, we ran out of buffer space */
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ }
+
+ /* Free the buffer and return status */
+ if (KeyInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
+ return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlpNtMakeTemporaryKey(IN HANDLE KeyHandle)
+{
+ /* This just deletes the key */
+ return ZwDeleteKey(KeyHandle);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlpNtOpenKey(OUT HANDLE KeyHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN ULONG Unused)
+{
+ /* Check if we have object attributes */
+ if (ObjectAttributes)
+ {
+ /* Mask out the unsupported flags */
+ ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
+ }
+
+ /* Open the key */
+ return ZwOpenKey(KeyHandle, DesiredAccess, ObjectAttributes);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlpNtQueryValueKey(IN HANDLE KeyHandle,
+ OUT PULONG Type OPTIONAL,
+ OUT PVOID Data OPTIONAL,
+ IN OUT PULONG DataLength OPTIONAL,
+ IN ULONG Unused)
+{
+ PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
+ UNICODE_STRING ValueName;
+ ULONG BufferLength = 0;
+ NTSTATUS Status;
+
+ /* Clear the value name */
+ RtlInitEmptyUnicodeString(&ValueName, NULL, 0);
+
+ /* Check if we were already given a length */
+ if (DataLength) BufferLength = *DataLength;
+
+ /* Add the size of the structure */
+ BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
+
+ /* Allocate memory for the value */
+ ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
+ if (!ValueInfo) return STATUS_NO_MEMORY;
+
+ /* Query the value */
+ Status = ZwQueryValueKey(KeyHandle,
+ &ValueName,
+ KeyValuePartialInformation,
+ ValueInfo,
+ BufferLength,
+ &BufferLength);
+ if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
+ {
+ /* Return the length and type */
+ if (DataLength) *DataLength = ValueInfo->DataLength;
+ if (Type) *Type = ValueInfo->Type;
+ }
+
+ /* Check if the caller wanted data back, and we got it */
+ if ((NT_SUCCESS(Status)) && (Data))
+ {
+ /* Copy it */
+ RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength);
+ }
+
+ /* Free the memory and return status */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
+ return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+RtlpNtSetValueKey(IN HANDLE KeyHandle,
+ IN ULONG Type,
+ IN PVOID Data,
+ IN ULONG DataLength)
+{
+ UNICODE_STRING ValueName;
+
+ /* Set the value */
+ RtlInitEmptyUnicodeString(&ValueName, NULL, 0);
+ return ZwSetValueKey(KeyHandle,
+ &ValueName,
+ 0,
+ Type,
+ Data,
+ DataLength);
+}
/*
* @unimplemented
@@ -869,234 +1060,4 @@
return(Status);
}
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-RtlWriteRegistryValue(IN ULONG RelativeTo,
- IN PCWSTR Path,
- IN PCWSTR ValueName,
- IN ULONG ValueType,
- IN PVOID ValueData,
- IN ULONG ValueLength)
-{
- HANDLE KeyHandle;
- NTSTATUS Status;
- UNICODE_STRING Name;
-
- PAGED_CODE_RTL();
-
- Status = RtlpGetRegistryHandle(RelativeTo,
- (PWSTR)Path,
- TRUE,
- &KeyHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("RtlpGetRegistryHandle() failed! Status: 0x%lx\n", Status);
- return(Status);
- }
-
- RtlInitUnicodeString(&Name,
- ValueName);
-
- Status = ZwSetValueKey(KeyHandle,
- &Name,
- 0,
- ValueType,
- ValueData,
- ValueLength);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ZwSetValueKey() failed! Status: 0x%lx\n", Status);
- }
-
- ZwClose(KeyHandle);
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-RtlpNtCreateKey(OUT HANDLE KeyHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN ULONG Unused1,
- OUT PULONG Disposition,
- IN ULONG Unused2)
-{
- if (ObjectAttributes != NULL)
- ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
-
- return(ZwCreateKey(KeyHandle,
- DesiredAccess,
- ObjectAttributes,
- 0,
- NULL,
- 0,
- Disposition));
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-RtlpNtEnumerateSubKey(IN HANDLE KeyHandle,
- OUT PUNICODE_STRING SubKeyName,
- IN ULONG Index,
- IN ULONG Unused)
-{
- PKEY_BASIC_INFORMATION KeyInfo = NULL;
- ULONG BufferLength = 0;
- ULONG ReturnedLength;
- NTSTATUS Status;
-
- if (SubKeyName->MaximumLength != 0)
- {
- BufferLength = SubKeyName->MaximumLength +
- sizeof(KEY_BASIC_INFORMATION);
- KeyInfo = RtlpAllocateMemory(BufferLength, TAG_RTLREGISTRY);
- if (KeyInfo == NULL)
- return(STATUS_NO_MEMORY);
- }
-
- Status = ZwEnumerateKey(KeyHandle,
- Index,
- KeyBasicInformation,
- KeyInfo,
- BufferLength,
- &ReturnedLength);
- if (NT_SUCCESS(Status))
- {
- if (KeyInfo->NameLength + sizeof(WCHAR) <= SubKeyName->MaximumLength)
- {
- memmove(SubKeyName->Buffer,
- KeyInfo->Name,
- KeyInfo->NameLength);
- SubKeyName->Buffer[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
- SubKeyName->Length = KeyInfo->NameLength;
- }
- else
- {
- Status = STATUS_BUFFER_OVERFLOW;
- }
- }
-
- if (KeyInfo != NULL)
- {
- RtlpFreeMemory(KeyInfo, TAG_RTLREGISTRY);
- }
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-RtlpNtMakeTemporaryKey(IN HANDLE KeyHandle)
-{
- return(ZwDeleteKey(KeyHandle));
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-RtlpNtOpenKey(OUT HANDLE KeyHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN ULONG Unused)
-{
- if (ObjectAttributes != NULL)
- ObjectAttributes->Attributes &= ~(OBJ_PERMANENT | OBJ_EXCLUSIVE);
-
- return(ZwOpenKey(KeyHandle,
- DesiredAccess,
- ObjectAttributes));
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-RtlpNtQueryValueKey(IN HANDLE KeyHandle,
- OUT PULONG Type OPTIONAL,
- OUT PVOID Data OPTIONAL,
- IN OUT PULONG DataLength OPTIONAL,
- IN ULONG Unused)
-{
- PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
- UNICODE_STRING ValueName;
- ULONG BufferLength;
- ULONG ReturnedLength;
- NTSTATUS Status;
-
- RtlInitUnicodeString(&ValueName,
- NULL);
-
- BufferLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION);
- if (DataLength != NULL)
- BufferLength = *DataLength;
-
- ValueInfo = RtlpAllocateMemory(BufferLength, TAG_RTLREGISTRY);
- if (ValueInfo == NULL)
- return(STATUS_NO_MEMORY);
-
- Status = ZwQueryValueKey(KeyHandle,
- &ValueName,
- KeyValuePartialInformation,
- ValueInfo,
- BufferLength,
- &ReturnedLength);
- if (NT_SUCCESS(Status))
- {
- if (DataLength != NULL)
- *DataLength = ValueInfo->DataLength;
-
- if (Type != NULL)
- *Type = ValueInfo->Type;
-
- if (Data != NULL)
- {
- memmove(Data,
- ValueInfo->Data,
- ValueInfo->DataLength);
- }
- }
-
- RtlpFreeMemory(ValueInfo, TAG_RTLREGISTRY);
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-RtlpNtSetValueKey(IN HANDLE KeyHandle,
- IN ULONG Type,
- IN PVOID Data,
- IN ULONG DataLength)
-{
- UNICODE_STRING ValueName;
-
- RtlInitUnicodeString(&ValueName,
- NULL);
- return(ZwSetValueKey(KeyHandle,
- &ValueName,
- 0,
- Type,
- Data,
- DataLength));
-}
-
/* EOF */
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c Thu Jun 29 04:30:36 2006
@@ -411,13 +411,26 @@
because NtCreateKey doesn't create trees */
Start = RemainingPath.Buffer;
if (*Start == L'\\')
+ {
Start++;
+ //RemainingPath.Length -= sizeof(WCHAR);
+ //RemainingPath.MaximumLength -= sizeof(WCHAR);
+ //RemainingPath.Buffer++;
+ //DPRINT1("String: %wZ\n", &RemainingPath);
+ }
+
+ if (RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] == '\\')
+ {
+ RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] = UNICODE_NULL;
+ RemainingPath.Length -= sizeof(WCHAR);
+ RemainingPath.MaximumLength -= sizeof(WCHAR);
+ }
for (i = 1; i < RemainingPath.Length / sizeof(WCHAR); i++)
{
if (L'\\' == RemainingPath.Buffer[i])
{
- DPRINT("NtCreateKey() doesn't create trees! (found \'\\\' in
remaining path: \"%wZ\"!)\n", &RemainingPath);
+ DPRINT1("NtCreateKey() doesn't create trees! (found \'\\\' in
remaining path: \"%wZ\"!)\n", &RemainingPath);
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_OBJECT_NAME_NOT_FOUND;
@@ -1395,6 +1408,13 @@
{
return Status;
}
+ }
+
+ if
(ObjectAttributes->ObjectName->Buffer[(ObjectAttributes->ObjectName->Length /
sizeof(WCHAR)) - 1] == '\\')
+ {
+
ObjectAttributes->ObjectName->Buffer[(ObjectAttributes->ObjectName->Length /
sizeof(WCHAR)) - 1] = UNICODE_NULL;
+ ObjectAttributes->ObjectName->Length -= sizeof(WCHAR);
+ ObjectAttributes->ObjectName->MaximumLength -= sizeof(WCHAR);
}
/* WINE checks for the length also */
Modified: trunk/reactos/ntoskrnl/cm/regobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/regobj.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/regobj.c (original)
+++ trunk/reactos/ntoskrnl/cm/regobj.c Thu Jun 29 04:30:36 2006
@@ -110,6 +110,7 @@
Attributes = ObjectCreateInfo->Attributes;
if (ObjectType == ObSymbolicLinkType)
Attributes |= OBJ_OPENLINK;
+ Attributes |= OBJ_CASE_INSENSITIVE; // hello! My name is ReactOS CM and I'm
brain-dead!
while (TRUE)
{