-/* $Id: reg.c,v 1.31 2003/10/14 18:18:27 navaraf Exp $
+/* $Id: reg.c,v 1.56 2004/09/13 11:41:26 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
/* INCLUDES *****************************************************************/
-#define NTOS_MODE_USER
-#include <ntos.h>
-#include <ddk/ntddk.h>
-#include <ntdll/rtl.h>
-#include <windows.h>
-#include <wchar.h>
-
-//#define NDEBUG
+#include "advapi32.h"
+#define NDEBUG
#include <debug.h>
/* DEFINES ******************************************************************/
#define MAX_DEFAULT_HANDLES 6
#define REG_MAX_NAME_SIZE 256
-#define REG_MAX_DATA_SIZE 2048
+#define REG_MAX_DATA_SIZE 2048
/* GLOBALS ******************************************************************/
/* PROTOTYPES ***************************************************************/
-static NTSTATUS MapDefaultKey (PHKEY ParentKey, HKEY Key);
+static NTSTATUS MapDefaultKey (PHANDLE ParentKey, HKEY Key);
static VOID CloseDefaultKeys(VOID);
static NTSTATUS OpenClassesRootKey(PHANDLE KeyHandle);
static NTSTATUS
-MapDefaultKey (PHKEY RealKey,
+MapDefaultKey (PHANDLE RealKey,
HKEY Key)
{
PHANDLE Handle;
if (((ULONG)Key & 0xF0000000) != 0x80000000)
{
- *RealKey = Key;
+ *RealKey = (HANDLE)Key;
return STATUS_SUCCESS;
}
if (NT_SUCCESS(Status))
{
- *RealKey = (HKEY)*Handle;
+ *RealKey = *Handle;
}
return Status;
OpenClassesRootKey (PHANDLE KeyHandle)
{
OBJECT_ATTRIBUTES Attributes;
- UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine\\Software\\CLASSES");
+ UNICODE_STRING KeyName = ROS_STRING_INITIALIZER(L"\\Registry\\Machine\\Software\\CLASSES");
DPRINT("OpenClassesRootKey()\n");
OpenLocalMachineKey (PHANDLE KeyHandle)
{
OBJECT_ATTRIBUTES Attributes;
- UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine");
+ UNICODE_STRING KeyName = ROS_STRING_INITIALIZER(L"\\Registry\\Machine");
+ NTSTATUS Status;
DPRINT("OpenLocalMachineKey()\n");
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
- return NtOpenKey (KeyHandle,
- MAXIMUM_ALLOWED,
- &Attributes);
+ Status = NtOpenKey (KeyHandle,
+ MAXIMUM_ALLOWED,
+ &Attributes);
+
+ DPRINT("NtOpenKey(%wZ) => %08x\n", &KeyName, Status);
+ return Status;
}
OpenUsersKey (PHANDLE KeyHandle)
{
OBJECT_ATTRIBUTES Attributes;
- UNICODE_STRING KeyName = UNICODE_STRING_INITIALIZER(L"\\Registry\\User");
+ UNICODE_STRING KeyName = ROS_STRING_INITIALIZER(L"\\Registry\\User");
DPRINT("OpenUsersKey()\n");
{
OBJECT_ATTRIBUTES Attributes;
UNICODE_STRING KeyName =
- UNICODE_STRING_INITIALIZER(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
+ ROS_STRING_INITIALIZER(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
DPRINT("OpenCurrentConfigKey()\n");
}
+/************************************************************************
+ * CreateNestedKey
+ *
+ * Create key and all necessary intermediate keys
+ */
+static NTSTATUS
+CreateNestedKey(PHKEY KeyHandle,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ PUNICODE_STRING ClassString,
+ DWORD dwOptions,
+ REGSAM samDesired,
+ DWORD *lpdwDisposition)
+{
+ OBJECT_ATTRIBUTES LocalObjectAttributes;
+ UNICODE_STRING LocalKeyName;
+ ULONG Disposition;
+ NTSTATUS Status;
+ ULONG FullNameLength;
+ ULONG Length;
+ PWCHAR Ptr;
+ HANDLE LocalKeyHandle;
+
+ Status = NtCreateKey((PHANDLE) KeyHandle,
+ samDesired,
+ ObjectAttributes,
+ 0,
+ ClassString,
+ dwOptions,
+ (PULONG)lpdwDisposition);
+ DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status);
+ if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
+ return Status;
+
+ /* Copy object attributes */
+ RtlCopyMemory (&LocalObjectAttributes,
+ ObjectAttributes,
+ sizeof(OBJECT_ATTRIBUTES));
+ RtlCreateUnicodeString (&LocalKeyName,
+ ObjectAttributes->ObjectName->Buffer);
+ LocalObjectAttributes.ObjectName = &LocalKeyName;
+ FullNameLength = LocalKeyName.Length / sizeof(WCHAR);
+
+ /* Remove the last part of the key name and try to create the key again. */
+ while (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ Ptr = wcsrchr (LocalKeyName.Buffer, '\\');
+ if (Ptr == NULL || Ptr == LocalKeyName.Buffer)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ break;
+ }
+ *Ptr = (WCHAR)0;
+ LocalKeyName.Length = wcslen (LocalKeyName.Buffer) * sizeof(WCHAR);
+
+ Status = NtCreateKey (&LocalKeyHandle,
+ KEY_ALL_ACCESS,
+ &LocalObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ &Disposition);
+ DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString (&LocalKeyName);
+ return Status;
+ }
+
+ /* Add removed parts of the key name and create them too. */
+ Length = wcslen (LocalKeyName.Buffer);
+ while (TRUE)
+ {
+ NtClose (LocalKeyHandle);
+
+ LocalKeyName.Buffer[Length] = L'\\';
+ Length = wcslen (LocalKeyName.Buffer);
+ LocalKeyName.Length = Length * sizeof(WCHAR);
+
+ if (Length == FullNameLength)
+ {
+ Status = NtCreateKey((PHANDLE) KeyHandle,
+ samDesired,
+ ObjectAttributes,
+ 0,
+ ClassString,
+ dwOptions,
+ (PULONG)lpdwDisposition);
+ break;
+ }
+ Status = NtCreateKey (&LocalKeyHandle,
+ KEY_ALL_ACCESS,
+ &LocalObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ &Disposition);
+ DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
+ if (!NT_SUCCESS(Status))
+ break;
+ }
+
+ RtlFreeUnicodeString (&LocalKeyName);
+
+ return Status;
+}
+
+
/************************************************************************
* RegCreateKeyExA
*
UNICODE_STRING SubKeyString;
UNICODE_STRING ClassString;
OBJECT_ATTRIBUTES Attributes;
- HKEY ParentKey;
+ HANDLE ParentKey;
LONG ErrorCode;
NTSTATUS Status;
OBJ_CASE_INSENSITIVE,
(HANDLE)ParentKey,
(PSECURITY_DESCRIPTOR)lpSecurityAttributes);
- Status = NtCreateKey (phkResult,
- samDesired,
- &Attributes,
- 0,
- (lpClass == NULL)? NULL : &ClassString,
- dwOptions,
- (PULONG)lpdwDisposition);
+ Status = CreateNestedKey(phkResult,
+ &Attributes,
+ (lpClass == NULL)? NULL : &ClassString,
+ dwOptions,
+ samDesired,
+ lpdwDisposition);
RtlFreeUnicodeString (&SubKeyString);
if (lpClass != NULL)
{
* @implemented
*/
LONG STDCALL
-RegCreateKeyExW(HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD Reserved,
- LPWSTR lpClass,
- DWORD dwOptions,
- REGSAM samDesired,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- PHKEY phkResult,
- LPDWORD lpdwDisposition)
+RegCreateKeyExW (HKEY hKey,
+ LPCWSTR lpSubKey,
+ DWORD Reserved,
+ LPWSTR lpClass,
+ DWORD dwOptions,
+ REGSAM samDesired,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ PHKEY phkResult,
+ LPDWORD lpdwDisposition)
{
UNICODE_STRING SubKeyString;
UNICODE_STRING ClassString;
OBJECT_ATTRIBUTES Attributes;
- HKEY ParentKey;
+ HANDLE ParentKey;
LONG ErrorCode;
NTSTATUS Status;
OBJ_CASE_INSENSITIVE,
(HANDLE)ParentKey,
(PSECURITY_DESCRIPTOR)lpSecurityAttributes);
- Status = NtCreateKey (phkResult,
- samDesired,
- &Attributes,
- 0,
- (lpClass == NULL)? NULL : &ClassString,
- dwOptions,
- (PULONG)lpdwDisposition);
+ Status = CreateNestedKey(phkResult,
+ &Attributes,
+ (lpClass == NULL)? NULL : &ClassString,
+ dwOptions,
+ samDesired,
+ lpdwDisposition);
DPRINT("Status %x\n", Status);
if (!NT_SUCCESS(Status))
{
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyName;
- HKEY ParentKey;
+ HANDLE ParentKey;
HANDLE TargetKey;
NTSTATUS Status;
LONG ErrorCode;
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyName;
- HKEY ParentKey;
+ HANDLE ParentKey;
HANDLE TargetKey;
NTSTATUS Status;
LONG ErrorCode;
LPCSTR lpValueName)
{
UNICODE_STRING ValueName;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
UNICODE_STRING ValueName;
NTSTATUS Status;
LONG ErrorCode;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
Status = MapDefaultKey (&KeyHandle,
hKey);
ANSI_STRING StringA;
LONG ErrorCode = ERROR_SUCCESS;
DWORD NameLength;
- DWORD ClassLength;
+ DWORD ClassLength = 0;
DWORD BufferSize;
DWORD ResultSize;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
NTSTATUS Status;
DPRINT("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n",
SetLastError (ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER;
}
+
Status = MapDefaultKey(&KeyHandle,
hKey);
if (!NT_SUCCESS(Status))
{
NameLength = 0;
}
+
if (lpClass)
{
if (*lpcbClass > 0)
- {
- ClassLength = min (*lpcbClass -1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
+ {
+ ClassLength = min (*lpcbClass -1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
}
else
- {
+ {
ClassLength = 0;
}
+
/* The class name should start at a dword boundary */
BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
}
{
BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength;
}
-
+
KeyInfo = RtlAllocateHeap (ProcessHeap,
0,
BufferSize);
-
if (KeyInfo == NULL)
{
SetLastError (ERROR_OUTOFMEMORY);
else
{
if (lpClass == NULL)
- {
+ {
if (KeyInfo->Basic.NameLength > NameLength)
{
ErrorCode = ERROR_BUFFER_OVERFLOW;
}
}
else
- {
+ {
if (KeyInfo->Node.NameLength > NameLength ||
KeyInfo->Node.ClassLength > ClassLength)
{
}
else
{
- StringA.Buffer = lpClass;
+ StringA.Buffer = lpClass;
StringA.Length = 0;
StringA.MaximumLength = *lpcbClass;
StringU.Buffer = (PWCHAR)((ULONG_PTR)KeyInfo->Node.Name + KeyInfo->Node.ClassOffset);
StringU.Length = KeyInfo->Node.ClassLength;
StringU.MaximumLength = KeyInfo->Node.ClassLength;
- RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
+ RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
lpClass[StringA.Length] = 0;
*lpcbClass = StringA.Length;
StringU.Buffer = KeyInfo->Node.Name;
StringU.MaximumLength = KeyInfo->Node.NameLength;
}
}
+
if (ErrorCode == ERROR_SUCCESS)
- {
- StringA.Buffer = lpName;
+ {
+ StringA.Buffer = lpName;
StringA.Length = 0;
StringA.MaximumLength = *lpcbName;
- RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
+ RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
lpName[StringA.Length] = 0;
*lpcbName = StringA.Length;
if (lpftLastWriteTime != NULL)
{
if (lpClass == NULL)
- {
- lpftLastWriteTime->dwLowDateTime = KeyInfo->Basic.LastWriteTime.u.LowPart;
- lpftLastWriteTime->dwHighDateTime = KeyInfo->Basic.LastWriteTime.u.HighPart;
- }
+ {
+ lpftLastWriteTime->dwLowDateTime = KeyInfo->Basic.LastWriteTime.u.LowPart;
+ lpftLastWriteTime->dwHighDateTime = KeyInfo->Basic.LastWriteTime.u.HighPart;
+ }
else
- {
- lpftLastWriteTime->dwLowDateTime = KeyInfo->Node.LastWriteTime.u.LowPart;
- lpftLastWriteTime->dwHighDateTime = KeyInfo->Node.LastWriteTime.u.HighPart;
- }
+ {
+ lpftLastWriteTime->dwLowDateTime = KeyInfo->Node.LastWriteTime.u.LowPart;
+ lpftLastWriteTime->dwHighDateTime = KeyInfo->Node.LastWriteTime.u.HighPart;
+ }
}
}
}
ULONG BufferSize;
ULONG ResultSize;
ULONG NameLength;
- ULONG ClassLength;
- HKEY KeyHandle;
+ ULONG ClassLength = 0;
+ HANDLE KeyHandle;
LONG ErrorCode = ERROR_SUCCESS;
NTSTATUS Status;
SetLastError (ErrorCode);
return ErrorCode;
}
+
if (*lpcbName > 0)
{
NameLength = min (*lpcbName - 1, REG_MAX_NAME_SIZE) * sizeof (WCHAR);
{
NameLength = 0;
}
+
if (lpClass)
{
if (*lpcbClass > 0)
- {
- ClassLength = min (*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
+ {
+ ClassLength = min (*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
}
else
- {
+ {
ClassLength = 0;
}
+
BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
}
else
{
BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength;
}
+
KeyInfo = RtlAllocateHeap (ProcessHeap,
0,
BufferSize);
else
{
if (lpClass == NULL)
- {
+ {
if (KeyInfo->Basic.NameLength > NameLength)
{
ErrorCode = ERROR_BUFFER_OVERFLOW;
}
}
else
- {
+ {
if (KeyInfo->Node.NameLength > NameLength ||
KeyInfo->Node.ClassLength > ClassLength)
{
else
{
RtlCopyMemory (lpName,
- KeyInfo->Node.Name,
+ KeyInfo->Node.Name,
KeyInfo->Node.NameLength);
*lpcbName = KeyInfo->Node.NameLength / sizeof(WCHAR);
lpName[*lpcbName] = 0;
lpClass[*lpcbClass] = 0;
}
}
+
if (ErrorCode == ERROR_SUCCESS && lpftLastWriteTime != NULL)
{
if (lpClass == NULL)
{
SetLastError(ErrorCode);
}
+
return ErrorCode;
}
ULONG NameLength;
ULONG BufferSize;
- ULONG DataLength;
+ ULONG DataLength = 0;
ULONG ResultSize;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
UNICODE_STRING StringU;
{
NameLength = 0;
}
+
if (lpData)
{
DataLength = min (*lpcbData * sizeof(WCHAR), REG_MAX_DATA_SIZE);
}
ValueInfo = RtlAllocateHeap (ProcessHeap,
- 0,
+ 0,
BufferSize);
if (ValueInfo == NULL)
{
{
if (lpData)
{
- IsStringType = (ValueInfo->Full.Type == REG_SZ) ||
- (ValueInfo->Full.Type == REG_MULTI_SZ) ||
+ IsStringType = (ValueInfo->Full.Type == REG_SZ) ||
+ (ValueInfo->Full.Type == REG_MULTI_SZ) ||
(ValueInfo->Full.Type == REG_EXPAND_SZ);
if (ValueInfo->Full.NameLength > NameLength ||
(!IsStringType && ValueInfo->Full.DataLength > *lpcbData) ||
StringA.Buffer = (PCHAR)lpData;
StringA.Length = 0;
StringA.MaximumLength = *lpcbData;
- RtlUnicodeStringToAnsiString (&StringA,
- &StringU,
- FALSE);
- *lpcbData = StringA.Length;
+ RtlUnicodeStringToAnsiString (&StringA,
+ &StringU,
+ FALSE);
+ *lpcbData = StringA.Length;
}
else
- {
- RtlCopyMemory(lpData,
- (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->Full.DataOffset),
- ValueInfo->Full.DataLength);
+ {
+ RtlCopyMemory (lpData,
+ (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->Full.DataOffset),
+ ValueInfo->Full.DataLength);
*lpcbData = ValueInfo->Full.DataLength;
}
- StringU.Buffer = ValueInfo->Full.Name;
+
+ StringU.Buffer = ValueInfo->Full.Name;
StringU.Length = ValueInfo->Full.NameLength;
StringU.MaximumLength = NameLength;
}
}
else
- {
+ {
if (ValueInfo->Basic.NameLength > NameLength)
{
ErrorCode = ERROR_BUFFER_OVERFLOW;
}
else
{
- StringU.Buffer = ValueInfo->Basic.Name;
+ StringU.Buffer = ValueInfo->Basic.Name;
StringU.Length = ValueInfo->Basic.NameLength;
StringU.MaximumLength = NameLength;
}
}
+
if (ErrorCode == ERROR_SUCCESS)
{
StringA.Buffer = (PCHAR)lpValueName;
StringA.Length = 0;
StringA.MaximumLength = *lpcbValueName;
RtlUnicodeStringToAnsiString (&StringA,
- &StringU,
+ &StringU,
FALSE);
- StringA.Buffer[StringA.Length] = 0;
+ StringA.Buffer[StringA.Length] = 0;
*lpcbValueName = StringA.Length;
if (lpType)
{
}
}
}
+
RtlFreeHeap (ProcessHeap,
- 0,
+ 0,
ValueInfo);
if (ErrorCode != ERROR_SUCCESS)
{
SetLastError(ErrorCode);
}
+
return ErrorCode;
}
ULONG NameLength;
ULONG BufferSize;
- ULONG DataLength;
+ ULONG DataLength = 0;
ULONG ResultSize;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
-
+
ErrorCode = ERROR_SUCCESS;
Status = MapDefaultKey (&KeyHandle,
SetLastError (ErrorCode);
return ErrorCode;
}
-
+
if (*lpcbValueName > 0)
{
NameLength = min (*lpcbValueName - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
{
NameLength = 0;
}
+
if (lpData)
{
DataLength = min(*lpcbData, REG_MAX_DATA_SIZE);
else
{
if (lpData)
- {
- if (ValueInfo->Full.DataLength > DataLength ||
+ {
+ if (ValueInfo->Full.DataLength > DataLength ||
ValueInfo->Full.NameLength > NameLength)
- {
+ {
ErrorCode = ERROR_BUFFER_OVERFLOW;
}
- else
+ else
{
RtlCopyMemory (lpValueName,
ValueInfo->Full.Name,
}
}
else
- {
+ {
if (ValueInfo->Basic.NameLength > NameLength)
{
ErrorCode = ERROR_BUFFER_OVERFLOW;
*lpcbValueName = (DWORD)(ValueInfo->Basic.NameLength / sizeof(WCHAR));
lpValueName[*lpcbValueName] = 0;
}
+ *lpcbData = (DWORD)ValueInfo->Full.DataLength;
}
+
if (ErrorCode == ERROR_SUCCESS && lpType != NULL)
{
*lpType = lpData ? ValueInfo->Full.Type : ValueInfo->Basic.Type;
}
}
+
RtlFreeHeap (ProcessHeap,
0,
ValueInfo);
+
if (ErrorCode != ERROR_SUCCESS)
{
- SetLastError(ErrorCode);
+ SetLastError (ErrorCode);
}
+
return ErrorCode;
}
LONG STDCALL
RegFlushKey(HKEY hKey)
{
- HKEY KeyHandle;
+ HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
/************************************************************************
* RegGetKeySecurity
*
- * @unimplemented
+ * @implemented
*/
LONG STDCALL
-RegGetKeySecurity (HKEY hKey,
- SECURITY_INFORMATION SecurityInformation,
- PSECURITY_DESCRIPTOR pSecurityDescriptor,
- LPDWORD lpcbSecurityDescriptor)
+RegGetKeySecurity(HKEY hKey,
+ SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ LPDWORD lpcbSecurityDescriptor)
{
-#if 0
- HKEY KeyHandle;
+ HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
- if (hKey = HKEY_PERFORMANCE_DATA)
+ if (hKey == HKEY_PERFORMANCE_DATA)
{
+ SetLastError(ERROR_INVALID_HANDLE);
return ERROR_INVALID_HANDLE;
}
- Status = MapDefaultKey (&KeyHandle,
- hKey);
+ Status = MapDefaultKey(&KeyHandle,
+ hKey);
if (!NT_SUCCESS(Status))
{
- ErrorCode = RtlNtStatusToDosError (Status);
- SetLastError (ErrorCode);
+ DPRINT("MapDefaultKey() failed (Status %lx)\n", Status);
+ ErrorCode = RtlNtStatusToDosError(Status);
+ SetLastError(ErrorCode);
return ErrorCode;
}
- Status = NtQuerySecurityObject ()
+ Status = NtQuerySecurityObject(KeyHandle,
+ SecurityInformation,
+ pSecurityDescriptor,
+ *lpcbSecurityDescriptor,
+ lpcbSecurityDescriptor);
if (!NT_SUCCESS(Status))
{
- ErrorCode = RtlNtStatusToDosError (Status);
- SetLastError (ErrorCode);
+ DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status);
+ ErrorCode = RtlNtStatusToDosError(Status);
+ SetLastError(ErrorCode);
return ErrorCode;
}
return ERROR_SUCCESS;
-#endif
-
- UNIMPLEMENTED;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
}
{
UNICODE_STRING FileName;
UNICODE_STRING KeyName;
- DWORD ErrorCode;
+ LONG ErrorCode;
RtlCreateUnicodeStringFromAsciiz (&KeyName,
(LPSTR)lpSubKey);
UNICODE_STRING FileName;
UNICODE_STRING KeyName;
HANDLE KeyHandle;
- DWORD ErrorCode;
+ LONG ErrorCode;
NTSTATUS Status;
if (hKey == HKEY_PERFORMANCE_DATA)
{
+ SetLastError(ERROR_INVALID_HANDLE);
return ERROR_INVALID_HANDLE;
}
}
-
/************************************************************************
* RegOpenKeyA
*
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyString;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
OBJ_CASE_INSENSITIVE,
KeyHandle,
NULL);
- Status = NtOpenKey (phkResult,
+ Status = NtOpenKey ((PHANDLE)phkResult,
MAXIMUM_ALLOWED,
&ObjectAttributes);
RtlFreeUnicodeString (&SubKeyString);
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyString;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
OBJ_CASE_INSENSITIVE,
KeyHandle,
NULL);
- Status = NtOpenKey (phkResult,
+ Status = NtOpenKey ((PHANDLE)phkResult,
MAXIMUM_ALLOWED,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyString;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
OBJ_CASE_INSENSITIVE,
KeyHandle,
NULL);
- Status = NtOpenKey (phkResult,
+ Status = NtOpenKey ((PHANDLE)phkResult,
samDesired,
&ObjectAttributes);
RtlFreeUnicodeString (&SubKeyString);
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyString;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
LONG ErrorCode;
NTSTATUS Status;
OBJ_CASE_INSENSITIVE,
KeyHandle,
NULL);
- Status = NtOpenKey (phkResult,
+ Status = NtOpenKey ((PHANDLE)phkResult,
samDesired,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
KEY_FULL_INFORMATION FullInfoBuffer;
PKEY_FULL_INFORMATION FullInfo;
ULONG FullInfoSize;
- ULONG ClassLength;
- HKEY KeyHandle;
+ ULONG ClassLength = 0;
+ HANDLE KeyHandle;
NTSTATUS Status;
LONG ErrorCode = ERROR_SUCCESS;
ULONG Length;
if (lpClass != NULL)
{
if (*lpcbClass > 0)
- {
- ClassLength = min(*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
+ {
+ ClassLength = min(*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
}
else
- {
+ {
ClassLength = 0;
}
+
FullInfoSize = sizeof(KEY_FULL_INFORMATION) + ((ClassLength + 3) & ~3);
FullInfo = RtlAllocateHeap (ProcessHeap,
0,
SetLastError (ERROR_OUTOFMEMORY);
return ERROR_OUTOFMEMORY;
}
+
FullInfo->ClassLength = ClassLength;
}
else
DPRINT("NtQueryKey() returned status 0x%X\n", Status);
if (!NT_SUCCESS(Status))
{
+ if (lpClass != NULL)
+ {
+ RtlFreeHeap (ProcessHeap,
+ 0,
+ FullInfo);
+ }
+
ErrorCode = RtlNtStatusToDosError (Status);
+ SetLastError (ErrorCode);
+ return ErrorCode;
}
- else
- {
- DPRINT("SubKeys %d\n", FullInfo->SubKeys);
- if (lpcSubKeys != NULL)
- {
- *lpcSubKeys = FullInfo->SubKeys;
- }
- DPRINT("MaxNameLen %lu\n", FullInfo->MaxNameLen);
- if (lpcbMaxSubKeyLen != NULL)
- {
- *lpcbMaxSubKeyLen = FullInfo->MaxNameLen / sizeof(WCHAR) + 1;
- }
+ DPRINT("SubKeys %d\n", FullInfo->SubKeys);
+ if (lpcSubKeys != NULL)
+ {
+ *lpcSubKeys = FullInfo->SubKeys;
+ }
- DPRINT("MaxClassLen %lu\n", FullInfo->MaxClassLen);
- if (lpcbMaxClassLen != NULL)
- {
- *lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1;
- }
+ DPRINT("MaxNameLen %lu\n", FullInfo->MaxNameLen);
+ if (lpcbMaxSubKeyLen != NULL)
+ {
+ *lpcbMaxSubKeyLen = FullInfo->MaxNameLen / sizeof(WCHAR) + 1;
+ }
- DPRINT("Values %lu\n", FullInfo->Values);
- if (lpcValues)
- {
- *lpcValues = FullInfo->Values;
- }
+ DPRINT("MaxClassLen %lu\n", FullInfo->MaxClassLen);
+ if (lpcbMaxClassLen != NULL)
+ {
+ *lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1;
+ }
- DPRINT("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
- if (lpcbMaxValueNameLen)
- {
- *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1;
- }
+ DPRINT("Values %lu\n", FullInfo->Values);
+ if (lpcValues != NULL)
+ {
+ *lpcValues = FullInfo->Values;
+ }
- DPRINT("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
- if (lpcbMaxValueLen)
- {
- *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
- }
+ DPRINT("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
+ if (lpcbMaxValueNameLen != NULL)
+ {
+ *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1;
+ }
- if (lpcbSecurityDescriptor)
- {
- *lpcbSecurityDescriptor = 0;
- /* FIXME */
- }
+ DPRINT("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
+ if (lpcbMaxValueLen != NULL)
+ {
+ *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
+ }
- if (lpftLastWriteTime != NULL)
- {
- lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
- lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
- }
+ if (lpcbSecurityDescriptor != NULL)
+ {
+ /* FIXME */
+ *lpcbSecurityDescriptor = 0;
+ }
- if (lpClass != NULL)
- {
- if (FullInfo->ClassLength > ClassLength)
- {
- ErrorCode = ERROR_BUFFER_OVERFLOW;
- }
- else
- {
- RtlCopyMemory (lpClass,
- FullInfo->Class,
- FullInfo->ClassLength);
- *lpcbClass = FullInfo->ClassLength / sizeof(WCHAR);
- lpClass[*lpcbClass] = 0;
- }
- }
+ if (lpftLastWriteTime != NULL)
+ {
+ lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
+ lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
}
+
if (lpClass != NULL)
{
+ if (FullInfo->ClassLength > ClassLength)
+ {
+ ErrorCode = ERROR_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ RtlCopyMemory (lpClass,
+ FullInfo->Class,
+ FullInfo->ClassLength);
+ *lpcbClass = FullInfo->ClassLength / sizeof(WCHAR);
+ lpClass[*lpcbClass] = 0;
+ }
+
RtlFreeHeap (ProcessHeap,
- 0,
+ 0,
FullInfo);
}
+
if (ErrorCode != ERROR_SUCCESS)
{
- SetLastError(ErrorCode);
+ SetLastError (ErrorCode);
}
return ErrorCode;
{
ULONG i;
DWORD maxBytes = *ldwTotsize;
- HRESULT status;
LPSTR bufptr = (LPSTR)lpValueBuf;
+ LONG ErrorCode;
- if ( maxBytes >= (1024*1024) )
+ if (maxBytes >= (1024*1024))
return ERROR_TRANSFER_TOO_LONG;
*ldwTotsize = 0;
- //TRACE("(%p,%p,%ld,%p,%p=%ld)\n", hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
+ DPRINT ("RegQueryMultipleValuesW(%p,%p,%ld,%p,%p=%ld)\n",
+ hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
- for(i=0; i < num_vals; ++i)
+ for (i = 0; i < num_vals; ++i)
{
- val_list[i].ve_valuelen=0;
- status = RegQueryValueExW(hKey, val_list[i].ve_valuename, NULL, NULL, NULL, &val_list[i].ve_valuelen);
- if(status != ERROR_SUCCESS)
+ val_list[i].ve_valuelen = 0;
+ ErrorCode = RegQueryValueExW (hKey,
+ val_list[i].ve_valuename,
+ NULL,
+ NULL,
+ NULL,
+ &val_list[i].ve_valuelen);
+ if (ErrorCode != ERROR_SUCCESS)
{
- return status;
+ return ErrorCode;
}
- if(lpValueBuf != NULL && *ldwTotsize + val_list[i].ve_valuelen <= maxBytes)
+ if (lpValueBuf != NULL && *ldwTotsize + val_list[i].ve_valuelen <= maxBytes)
{
- status = RegQueryValueExW(hKey, val_list[i].ve_valuename, NULL, &val_list[i].ve_type,
- bufptr, &val_list[i].ve_valuelen);
- if(status != ERROR_SUCCESS)
+ ErrorCode = RegQueryValueExW (hKey,
+ val_list[i].ve_valuename,
+ NULL,
+ &val_list[i].ve_type,
+ bufptr,
+ &val_list[i].ve_valuelen);
+ if (ErrorCode != ERROR_SUCCESS)
{
- return status;
+ return ErrorCode;
}
val_list[i].ve_valueptr = (DWORD_PTR)bufptr;
*ldwTotsize += val_list[i].ve_valuelen;
}
- return lpValueBuf != NULL && *ldwTotsize <= maxBytes ? ERROR_SUCCESS : ERROR_MORE_DATA;
+
+ return (lpValueBuf != NULL && *ldwTotsize <= maxBytes) ? ERROR_SUCCESS : ERROR_MORE_DATA;
}
LONG ErrorCode = ERROR_SUCCESS;
ULONG BufferSize;
ULONG ResultSize;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
+ ULONG MaxCopy = lpcbData != NULL && lpData != NULL ? *lpcbData : 0;
DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
RtlInitUnicodeString (&ValueName,
lpValueName);
- BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + *lpcbData;
+ BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + MaxCopy;
ValueInfo = RtlAllocateHeap (ProcessHeap,
0,
BufferSize);
if (Status == STATUS_BUFFER_TOO_SMALL)
{
/* Return ERROR_SUCCESS and the buffer space needed for a successful call */
- ErrorCode = ERROR_SUCCESS;
+ MaxCopy = 0;
+ ErrorCode = lpData ? ERROR_MORE_DATA : ERROR_SUCCESS;
}
else if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError (Status);
SetLastError (ErrorCode);
- }
- else
- {
- if (lpType != NULL)
+ MaxCopy = 0;
+ if (lpcbData != NULL)
{
- *lpType = ValueInfo->Type;
+ ResultSize = sizeof(*ValueInfo) + *lpcbData;
}
+ }
+
+ if (lpType != NULL)
+ {
+ *lpType = ValueInfo->Type;
+ }
+
+ if (NT_SUCCESS(Status) && lpData != NULL)
+ {
RtlMoveMemory (lpData,
ValueInfo->Data,
- ValueInfo->DataLength);
- if ((ValueInfo->Type == REG_SZ) ||
- (ValueInfo->Type == REG_MULTI_SZ) ||
- (ValueInfo->Type == REG_EXPAND_SZ))
+ min(ValueInfo->DataLength, MaxCopy));
+ }
+
+ if ((ValueInfo->Type == REG_SZ) ||
+ (ValueInfo->Type == REG_MULTI_SZ) ||
+ (ValueInfo->Type == REG_EXPAND_SZ))
+ {
+ if (lpData != NULL && MaxCopy > ValueInfo->DataLength)
{
((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0;
}
- }
- DPRINT("Type %d Size %d\n", ValueInfo->Type, ValueInfo->DataLength);
- if (NULL != lpcbData)
+ if (lpcbData != NULL)
+ {
+ *lpcbData = (ResultSize - sizeof(*ValueInfo));
+ DPRINT("(string) Returning Size: %lu\n", *lpcbData);
+ }
+ }
+ else
{
- *lpcbData = (DWORD)ValueInfo->DataLength;
+ if (lpcbData != NULL)
+ {
+ *lpcbData = ResultSize - sizeof(*ValueInfo);
+ DPRINT("(other) Returning Size: %lu\n", *lpcbData);
+ }
}
+
+ DPRINT("Type %d Size %d\n", ValueInfo->Type, ValueInfo->DataLength);
+
RtlFreeHeap (ProcessHeap,
0,
ValueInfo);
*
* @implemented
*/
-LONG
-STDCALL
-RegQueryValueExA(
- HKEY hKey,
- LPCSTR lpValueName,
- LPDWORD lpReserved,
- LPDWORD lpType,
- LPBYTE lpData,
- LPDWORD lpcbData)
+LONG STDCALL
+RegQueryValueExA (HKEY hKey,
+ LPCSTR lpValueName,
+ LPDWORD lpReserved,
+ LPDWORD lpType,
+ LPBYTE lpData,
+ LPDWORD lpcbData)
{
UNICODE_STRING ValueName;
UNICODE_STRING ValueData;
ANSI_STRING AnsiString;
LONG ErrorCode;
+ DWORD Length;
+ DWORD Type;
- if ((lpData) && (!lpcbData))
+ if (lpData != NULL && lpcbData == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER;
if (lpData)
{
- ValueData.Length = ValueData.MaximumLength = *lpcbData * sizeof(WCHAR);
- ValueData.Buffer = RtlAllocateHeap(
- ProcessHeap,
- 0,
- ValueData.Length);
+ ValueData.Length = *lpcbData * sizeof(WCHAR);
+ ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
+ ValueData.Buffer = RtlAllocateHeap (ProcessHeap,
+ 0,
+ ValueData.MaximumLength);
if (!ValueData.Buffer)
- {
- SetLastError(ERROR_OUTOFMEMORY);
- return ERROR_OUTOFMEMORY;
- }
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
}
else
{
ValueData.Buffer = NULL;
+ ValueData.Length = 0;
+ ValueData.MaximumLength = 0;
}
- RtlCreateUnicodeStringFromAsciiz(&ValueName, (LPSTR)lpValueName);
+ RtlCreateUnicodeStringFromAsciiz (&ValueName,
+ (LPSTR)lpValueName);
- ErrorCode = RegQueryValueExW(
- hKey,
- ValueName.Buffer,
- lpReserved,
- lpType,
- (LPBYTE)ValueData.Buffer,
- (LPDWORD)&ValueData.Length);
+ if (NULL != lpcbData)
+ {
+ Length = *lpcbData * sizeof(WCHAR);
+ }
+ ErrorCode = RegQueryValueExW (hKey,
+ ValueName.Buffer,
+ lpReserved,
+ &Type,
+ (LPBYTE)ValueData.Buffer,
+ NULL == lpcbData ? NULL : &Length);
+ DPRINT("ErrorCode %lu\n", ErrorCode);
- if ((ErrorCode == ERROR_SUCCESS) && (ValueData.Buffer != NULL))
+ if (ErrorCode == ERROR_SUCCESS ||
+ ErrorCode == ERROR_MORE_DATA)
{
- if (lpType && ((*lpType == REG_SZ) || (*lpType == REG_MULTI_SZ) || (*lpType == REG_EXPAND_SZ)))
- {
- RtlInitAnsiString(&AnsiString, NULL);
- AnsiString.Buffer = lpData;
- AnsiString.MaximumLength = *lpcbData;
- RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
- *lpcbData = ValueData.Length / sizeof(WCHAR);
- } else {
- RtlMoveMemory(lpData, ValueData.Buffer, *lpcbData);
- *lpcbData = ValueData.Length;
- }
- }
+ if (lpType != NULL)
+ {
+ *lpType = Type;
+ }
+
+ if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ))
+ {
+ if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+ {
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpData;
+ AnsiString.MaximumLength = *lpcbData;
+ ValueData.Length = Length;
+ ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
+ RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
+ }
+ Length = Length / sizeof(WCHAR);
+ }
+ else if (lpcbData != NULL)
+ {
+ Length = min(*lpcbData, Length);
+ if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+ {
+ RtlMoveMemory(lpData, ValueData.Buffer, Length);
+ }
+ }
- if (ValueData.Buffer)
+ if (lpcbData != NULL)
+ {
+ *lpcbData = Length;
+ }
+ }
+
+ if (ValueData.Buffer != NULL)
{
RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer);
}
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyString;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
HANDLE RealKey;
LONG ErrorCode;
BOOL CloseRealKey;
LPCSTR lpNewFile,
LPCSTR lpOldFile)
{
- UNICODE_STRING lpSubKeyW;
- UNICODE_STRING lpNewFileW;
- UNICODE_STRING lpOldFileW;
- LONG ret;
-
- RtlCreateUnicodeStringFromAsciiz( &lpSubKeyW, (PCSZ)lpSubKey );
- RtlCreateUnicodeStringFromAsciiz( &lpOldFileW, (PCSZ)lpOldFile );
- RtlCreateUnicodeStringFromAsciiz( &lpNewFileW, (PCSZ)lpNewFile );
- ret = RegReplaceKeyW( hKey, lpSubKeyW.Buffer, lpNewFileW.Buffer, lpOldFileW.Buffer );
- RtlFreeUnicodeString( &lpOldFileW );
- RtlFreeUnicodeString( &lpNewFileW );
- RtlFreeUnicodeString( &lpSubKeyW );
- return ret;
+ UNICODE_STRING SubKey;
+ UNICODE_STRING NewFile;
+ UNICODE_STRING OldFile;
+ LONG ErrorCode;
+
+ RtlCreateUnicodeStringFromAsciiz (&SubKey,
+ (PCSZ)lpSubKey);
+ RtlCreateUnicodeStringFromAsciiz (&OldFile,
+ (PCSZ)lpOldFile);
+ RtlCreateUnicodeStringFromAsciiz (&NewFile,
+ (PCSZ)lpNewFile);
+
+ ErrorCode = RegReplaceKeyW (hKey,
+ SubKey.Buffer,
+ NewFile.Buffer,
+ OldFile.Buffer);
+
+ RtlFreeUnicodeString (&OldFile);
+ RtlFreeUnicodeString (&NewFile);
+ RtlFreeUnicodeString (&SubKey);
+
+ return ErrorCode;
}
LPCWSTR lpNewFile,
LPCWSTR lpOldFile)
{
- UNIMPLEMENTED;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ OBJECT_ATTRIBUTES KeyObjectAttributes;
+ OBJECT_ATTRIBUTES NewObjectAttributes;
+ OBJECT_ATTRIBUTES OldObjectAttributes;
+ UNICODE_STRING SubKeyName;
+ UNICODE_STRING NewFileName;
+ UNICODE_STRING OldFileName;
+ BOOLEAN CloseRealKey;
+ HANDLE RealKeyHandle;
+ HANDLE KeyHandle;
+ LONG ErrorCode;
+ NTSTATUS Status;
+
+ if (hKey == HKEY_PERFORMANCE_DATA)
+ {
+ return ERROR_INVALID_HANDLE;
+ }
+
+ Status = MapDefaultKey (&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError (Status);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ /* Open the real key */
+ if (lpSubKey != NULL && *lpSubKey != (WCHAR)0)
+ {
+ RtlInitUnicodeString (&SubKeyName,
+ (PWSTR)lpSubKey);
+ InitializeObjectAttributes (&KeyObjectAttributes,
+ &SubKeyName,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
+ Status = NtOpenKey (&RealKeyHandle,
+ KEY_ALL_ACCESS,
+ &KeyObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError (Status);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+ CloseRealKey = TRUE;
+ }
+ else
+ {
+ RealKeyHandle = KeyHandle;
+ CloseRealKey = FALSE;
+ }
+
+ /* Convert new file name */
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpNewFile,
+ &NewFileName,
+ NULL,
+ NULL))
+ {
+ if (CloseRealKey)
+ {
+ NtClose (RealKeyHandle);
+ }
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ InitializeObjectAttributes (&NewObjectAttributes,
+ &NewFileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ /* Convert old file name */
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpOldFile,
+ &OldFileName,
+ NULL,
+ NULL))
+ {
+ RtlFreeUnicodeString (&NewFileName);
+ if (CloseRealKey)
+ {
+ NtClose (RealKeyHandle);
+ }
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ InitializeObjectAttributes (&OldObjectAttributes,
+ &OldFileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtReplaceKey (&NewObjectAttributes,
+ RealKeyHandle,
+ &OldObjectAttributes);
+
+ RtlFreeUnicodeString (&OldFileName);
+ RtlFreeUnicodeString (&NewFileName);
+
+ if (CloseRealKey)
+ {
+ NtClose (RealKeyHandle);
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError (Status);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ return ERROR_SUCCESS;
}
LPCSTR lpFile,
DWORD dwFlags)
{
- UNICODE_STRING lpFileW;
- LONG ret;
+ UNICODE_STRING FileName;
+ LONG ErrorCode;
+
+ RtlCreateUnicodeStringFromAsciiz (&FileName,
+ (PCSZ)lpFile);
+
+ ErrorCode = RegRestoreKeyW (hKey,
+ FileName.Buffer,
+ dwFlags);
- RtlCreateUnicodeStringFromAsciiz( &lpFileW, (PCSZ)lpFile );
- ret = RegRestoreKeyW( hKey, lpFileW.Buffer, dwFlags );
- RtlFreeUnicodeString( &lpFileW );
- return ret;
+ RtlFreeUnicodeString (&FileName);
+
+ return ErrorCode;
}
/************************************************************************
* RegRestoreKeyW
*
- * @unimplemented
+ * @implemented
*/
LONG STDCALL
RegRestoreKeyW (HKEY hKey,
LPCWSTR lpFile,
DWORD dwFlags)
{
- UNIMPLEMENTED;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING FileName;
+ HANDLE FileHandle;
+ HANDLE KeyHandle;
+ LONG ErrorCode;
+ NTSTATUS Status;
+
+ if (hKey == HKEY_PERFORMANCE_DATA)
+ {
+ return ERROR_INVALID_HANDLE;
+ }
+
+ Status = MapDefaultKey (&KeyHandle,
+ hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError (Status);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile,
+ &FileName,
+ NULL,
+ NULL))
+ {
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ InitializeObjectAttributes (&ObjectAttributes,
+ &FileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenFile (&FileHandle,
+ FILE_GENERIC_READ,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ RtlFreeUnicodeString (&FileName);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError (Status);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ Status = NtRestoreKey (KeyHandle,
+ FileHandle,
+ (ULONG)dwFlags);
+ NtClose (FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError (Status);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ return ERROR_SUCCESS;
}
* @implemented
*/
LONG STDCALL
-RegSaveKeyA(HKEY hKey,
- LPCSTR lpFile,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes)
+RegSaveKeyA (HKEY hKey,
+ LPCSTR lpFile,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
UNICODE_STRING FileName;
LONG ErrorCode;
{
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING NtName;
+ UNICODE_STRING FileName;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
NTSTATUS Status;
LONG ErrorCode;
return ErrorCode;
}
- if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile,
- &NtName,
+ if (!RtlDosPathNameToNtPathName_U ((PWSTR)lpFile,
+ &FileName,
NULL,
NULL))
{
}
InitializeObjectAttributes (&ObjectAttributes,
- &NtName,
+ &FileName,
OBJ_CASE_INSENSITIVE,
NULL,
SecurityDescriptor);
FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
- RtlFreeUnicodeString (&NtName);
+ RtlFreeUnicodeString (&FileName);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError (Status);
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
- HKEY KeyHandle;
- NTSTATUS Status;
+ HANDLE KeyHandle;
LONG ErrorCode;
+ NTSTATUS Status;
if (hKey == HKEY_PERFORMANCE_DATA)
- return ERROR_INVALID_HANDLE;
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return ERROR_INVALID_HANDLE;
+ }
Status = MapDefaultKey (&KeyHandle,
hKey);
strlen(lpValueName) != 0)
{
RtlCreateUnicodeStringFromAsciiz (&ValueName,
- (LPSTR)lpValueName);
+ (PSTR)lpValueName);
pValueName = (LPWSTR)ValueName.Buffer;
}
else
{
RtlInitAnsiString (&AnsiString,
NULL);
- AnsiString.Buffer = (LPSTR)lpData;
+ AnsiString.Buffer = (PSTR)lpData;
AnsiString.Length = cbData;
AnsiString.MaximumLength = cbData;
RtlAnsiStringToUnicodeString (&Data,
{
UNICODE_STRING ValueName;
PUNICODE_STRING pValueName;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
NTSTATUS Status;
LONG ErrorCode;
{
RtlInitUnicodeString (&ValueName,
lpValueName);
- pValueName = &ValueName;
}
else
{
- pValueName = NULL;
+ RtlInitUnicodeString (&ValueName, L"");
}
+ pValueName = &ValueName;
Status = NtSetValueKey (KeyHandle,
pValueName,
dwType,
Data.Buffer,
DataSize);
+
RtlFreeHeap (ProcessHeap,
0,
Data.Buffer);
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyString;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
HANDLE RealKey;
LONG ErrorCode;
BOOL CloseRealKey;
* @implemented
*/
LONG STDCALL
-RegUnLoadKeyW (HKEY hKey,
+RegUnLoadKeyW (HKEY hKey,
LPCWSTR lpSubKey)
{
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
if (hKey == HKEY_PERFORMANCE_DATA)
- return ERROR_INVALID_HANDLE;
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return ERROR_INVALID_HANDLE;
+ }
Status = MapDefaultKey (&KeyHandle, hKey);
if (!NT_SUCCESS(Status))