Minor cleanup.

Implement RegRestoreKeyW().

svn path=/trunk/; revision=8311
This commit is contained in:
Eric Kohl 2004-02-22 14:26:07 +00:00
parent 2d6b7b1255
commit a1eebee733

View file

@ -1,4 +1,4 @@
/* $Id: reg.c,v 1.42 2003/12/29 23:04:55 gvg Exp $ /* $Id: reg.c,v 1.43 2004/02/22 14:26:07 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -393,15 +393,15 @@ RegCreateKeyExA (HKEY hKey,
* @implemented * @implemented
*/ */
LONG STDCALL LONG STDCALL
RegCreateKeyExW(HKEY hKey, RegCreateKeyExW (HKEY hKey,
LPCWSTR lpSubKey, LPCWSTR lpSubKey,
DWORD Reserved, DWORD Reserved,
LPWSTR lpClass, LPWSTR lpClass,
DWORD dwOptions, DWORD dwOptions,
REGSAM samDesired, REGSAM samDesired,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult, PHKEY phkResult,
LPDWORD lpdwDisposition) LPDWORD lpdwDisposition)
{ {
UNICODE_STRING SubKeyString; UNICODE_STRING SubKeyString;
UNICODE_STRING ClassString; UNICODE_STRING ClassString;
@ -774,6 +774,7 @@ RegEnumKeyExA (HKEY hKey,
SetLastError (ERROR_INVALID_PARAMETER); SetLastError (ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
Status = MapDefaultKey(&KeyHandle, Status = MapDefaultKey(&KeyHandle,
hKey); hKey);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -791,16 +792,18 @@ RegEnumKeyExA (HKEY hKey,
{ {
NameLength = 0; NameLength = 0;
} }
if (lpClass) if (lpClass)
{ {
if (*lpcbClass > 0) if (*lpcbClass > 0)
{ {
ClassLength = min (*lpcbClass -1, REG_MAX_NAME_SIZE) * sizeof(WCHAR); ClassLength = min (*lpcbClass -1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
} }
else else
{ {
ClassLength = 0; ClassLength = 0;
} }
/* The class name should start at a dword boundary */ /* The class name should start at a dword boundary */
BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength; BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
} }
@ -812,7 +815,6 @@ RegEnumKeyExA (HKEY hKey,
KeyInfo = RtlAllocateHeap (ProcessHeap, KeyInfo = RtlAllocateHeap (ProcessHeap,
0, 0,
BufferSize); BufferSize);
if (KeyInfo == NULL) if (KeyInfo == NULL)
{ {
SetLastError (ERROR_OUTOFMEMORY); SetLastError (ERROR_OUTOFMEMORY);
@ -833,7 +835,7 @@ RegEnumKeyExA (HKEY hKey,
else else
{ {
if (lpClass == NULL) if (lpClass == NULL)
{ {
if (KeyInfo->Basic.NameLength > NameLength) if (KeyInfo->Basic.NameLength > NameLength)
{ {
ErrorCode = ERROR_BUFFER_OVERFLOW; ErrorCode = ERROR_BUFFER_OVERFLOW;
@ -846,7 +848,7 @@ RegEnumKeyExA (HKEY hKey,
} }
} }
else else
{ {
if (KeyInfo->Node.NameLength > NameLength || if (KeyInfo->Node.NameLength > NameLength ||
KeyInfo->Node.ClassLength > ClassLength) KeyInfo->Node.ClassLength > ClassLength)
{ {
@ -854,13 +856,13 @@ RegEnumKeyExA (HKEY hKey,
} }
else else
{ {
StringA.Buffer = lpClass; StringA.Buffer = lpClass;
StringA.Length = 0; StringA.Length = 0;
StringA.MaximumLength = *lpcbClass; StringA.MaximumLength = *lpcbClass;
StringU.Buffer = (PWCHAR)((ULONG_PTR)KeyInfo->Node.Name + KeyInfo->Node.ClassOffset); StringU.Buffer = (PWCHAR)((ULONG_PTR)KeyInfo->Node.Name + KeyInfo->Node.ClassOffset);
StringU.Length = KeyInfo->Node.ClassLength; StringU.Length = KeyInfo->Node.ClassLength;
StringU.MaximumLength = KeyInfo->Node.ClassLength; StringU.MaximumLength = KeyInfo->Node.ClassLength;
RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE); RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
lpClass[StringA.Length] = 0; lpClass[StringA.Length] = 0;
*lpcbClass = StringA.Length; *lpcbClass = StringA.Length;
StringU.Buffer = KeyInfo->Node.Name; StringU.Buffer = KeyInfo->Node.Name;
@ -868,26 +870,27 @@ RegEnumKeyExA (HKEY hKey,
StringU.MaximumLength = KeyInfo->Node.NameLength; StringU.MaximumLength = KeyInfo->Node.NameLength;
} }
} }
if (ErrorCode == ERROR_SUCCESS) if (ErrorCode == ERROR_SUCCESS)
{ {
StringA.Buffer = lpName; StringA.Buffer = lpName;
StringA.Length = 0; StringA.Length = 0;
StringA.MaximumLength = *lpcbName; StringA.MaximumLength = *lpcbName;
RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE); RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
lpName[StringA.Length] = 0; lpName[StringA.Length] = 0;
*lpcbName = StringA.Length; *lpcbName = StringA.Length;
if (lpftLastWriteTime != NULL) if (lpftLastWriteTime != NULL)
{ {
if (lpClass == NULL) if (lpClass == NULL)
{ {
lpftLastWriteTime->dwLowDateTime = KeyInfo->Basic.LastWriteTime.u.LowPart; lpftLastWriteTime->dwLowDateTime = KeyInfo->Basic.LastWriteTime.u.LowPart;
lpftLastWriteTime->dwHighDateTime = KeyInfo->Basic.LastWriteTime.u.HighPart; lpftLastWriteTime->dwHighDateTime = KeyInfo->Basic.LastWriteTime.u.HighPart;
} }
else else
{ {
lpftLastWriteTime->dwLowDateTime = KeyInfo->Node.LastWriteTime.u.LowPart; lpftLastWriteTime->dwLowDateTime = KeyInfo->Node.LastWriteTime.u.LowPart;
lpftLastWriteTime->dwHighDateTime = KeyInfo->Node.LastWriteTime.u.HighPart; lpftLastWriteTime->dwHighDateTime = KeyInfo->Node.LastWriteTime.u.HighPart;
} }
} }
} }
} }
@ -947,6 +950,7 @@ RegEnumKeyExW (HKEY hKey,
SetLastError (ErrorCode); SetLastError (ErrorCode);
return ErrorCode; return ErrorCode;
} }
if (*lpcbName > 0) if (*lpcbName > 0)
{ {
NameLength = min (*lpcbName - 1, REG_MAX_NAME_SIZE) * sizeof (WCHAR); NameLength = min (*lpcbName - 1, REG_MAX_NAME_SIZE) * sizeof (WCHAR);
@ -955,22 +959,25 @@ RegEnumKeyExW (HKEY hKey,
{ {
NameLength = 0; NameLength = 0;
} }
if (lpClass) if (lpClass)
{ {
if (*lpcbClass > 0) if (*lpcbClass > 0)
{ {
ClassLength = min (*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR); ClassLength = min (*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
} }
else else
{ {
ClassLength = 0; ClassLength = 0;
} }
BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength; BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
} }
else else
{ {
BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength; BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength;
} }
KeyInfo = RtlAllocateHeap (ProcessHeap, KeyInfo = RtlAllocateHeap (ProcessHeap,
0, 0,
BufferSize); BufferSize);
@ -994,7 +1001,7 @@ RegEnumKeyExW (HKEY hKey,
else else
{ {
if (lpClass == NULL) if (lpClass == NULL)
{ {
if (KeyInfo->Basic.NameLength > NameLength) if (KeyInfo->Basic.NameLength > NameLength)
{ {
ErrorCode = ERROR_BUFFER_OVERFLOW; ErrorCode = ERROR_BUFFER_OVERFLOW;
@ -1009,7 +1016,7 @@ RegEnumKeyExW (HKEY hKey,
} }
} }
else else
{ {
if (KeyInfo->Node.NameLength > NameLength || if (KeyInfo->Node.NameLength > NameLength ||
KeyInfo->Node.ClassLength > ClassLength) KeyInfo->Node.ClassLength > ClassLength)
{ {
@ -1018,7 +1025,7 @@ RegEnumKeyExW (HKEY hKey,
else else
{ {
RtlCopyMemory (lpName, RtlCopyMemory (lpName,
KeyInfo->Node.Name, KeyInfo->Node.Name,
KeyInfo->Node.NameLength); KeyInfo->Node.NameLength);
*lpcbName = KeyInfo->Node.NameLength / sizeof(WCHAR); *lpcbName = KeyInfo->Node.NameLength / sizeof(WCHAR);
lpName[*lpcbName] = 0; lpName[*lpcbName] = 0;
@ -1029,6 +1036,7 @@ RegEnumKeyExW (HKEY hKey,
lpClass[*lpcbClass] = 0; lpClass[*lpcbClass] = 0;
} }
} }
if (ErrorCode == ERROR_SUCCESS && lpftLastWriteTime != NULL) if (ErrorCode == ERROR_SUCCESS && lpftLastWriteTime != NULL)
{ {
if (lpClass == NULL) if (lpClass == NULL)
@ -1052,6 +1060,7 @@ RegEnumKeyExW (HKEY hKey,
{ {
SetLastError(ErrorCode); SetLastError(ErrorCode);
} }
return ErrorCode; return ErrorCode;
} }
@ -1107,6 +1116,7 @@ RegEnumValueA (HKEY hKey,
{ {
NameLength = 0; NameLength = 0;
} }
if (lpData) if (lpData)
{ {
DataLength = min (*lpcbData * sizeof(WCHAR), REG_MAX_DATA_SIZE); DataLength = min (*lpcbData * sizeof(WCHAR), REG_MAX_DATA_SIZE);
@ -1118,7 +1128,7 @@ RegEnumValueA (HKEY hKey,
} }
ValueInfo = RtlAllocateHeap (ProcessHeap, ValueInfo = RtlAllocateHeap (ProcessHeap,
0, 0,
BufferSize); BufferSize);
if (ValueInfo == NULL) if (ValueInfo == NULL)
{ {
@ -1142,8 +1152,8 @@ RegEnumValueA (HKEY hKey,
{ {
if (lpData) if (lpData)
{ {
IsStringType = (ValueInfo->Full.Type == REG_SZ) || IsStringType = (ValueInfo->Full.Type == REG_SZ) ||
(ValueInfo->Full.Type == REG_MULTI_SZ) || (ValueInfo->Full.Type == REG_MULTI_SZ) ||
(ValueInfo->Full.Type == REG_EXPAND_SZ); (ValueInfo->Full.Type == REG_EXPAND_SZ);
if (ValueInfo->Full.NameLength > NameLength || if (ValueInfo->Full.NameLength > NameLength ||
(!IsStringType && ValueInfo->Full.DataLength > *lpcbData) || (!IsStringType && ValueInfo->Full.DataLength > *lpcbData) ||
@ -1161,45 +1171,47 @@ RegEnumValueA (HKEY hKey,
StringA.Buffer = (PCHAR)lpData; StringA.Buffer = (PCHAR)lpData;
StringA.Length = 0; StringA.Length = 0;
StringA.MaximumLength = *lpcbData; StringA.MaximumLength = *lpcbData;
RtlUnicodeStringToAnsiString (&StringA, RtlUnicodeStringToAnsiString (&StringA,
&StringU, &StringU,
FALSE); FALSE);
*lpcbData = StringA.Length; *lpcbData = StringA.Length;
} }
else else
{ {
RtlCopyMemory(lpData, RtlCopyMemory (lpData,
(PVOID)((ULONG_PTR)ValueInfo + ValueInfo->Full.DataOffset), (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->Full.DataOffset),
ValueInfo->Full.DataLength); ValueInfo->Full.DataLength);
*lpcbData = ValueInfo->Full.DataLength; *lpcbData = ValueInfo->Full.DataLength;
} }
StringU.Buffer = ValueInfo->Full.Name;
StringU.Buffer = ValueInfo->Full.Name;
StringU.Length = ValueInfo->Full.NameLength; StringU.Length = ValueInfo->Full.NameLength;
StringU.MaximumLength = NameLength; StringU.MaximumLength = NameLength;
} }
} }
else else
{ {
if (ValueInfo->Basic.NameLength > NameLength) if (ValueInfo->Basic.NameLength > NameLength)
{ {
ErrorCode = ERROR_BUFFER_OVERFLOW; ErrorCode = ERROR_BUFFER_OVERFLOW;
} }
else else
{ {
StringU.Buffer = ValueInfo->Basic.Name; StringU.Buffer = ValueInfo->Basic.Name;
StringU.Length = ValueInfo->Basic.NameLength; StringU.Length = ValueInfo->Basic.NameLength;
StringU.MaximumLength = NameLength; StringU.MaximumLength = NameLength;
} }
} }
if (ErrorCode == ERROR_SUCCESS) if (ErrorCode == ERROR_SUCCESS)
{ {
StringA.Buffer = (PCHAR)lpValueName; StringA.Buffer = (PCHAR)lpValueName;
StringA.Length = 0; StringA.Length = 0;
StringA.MaximumLength = *lpcbValueName; StringA.MaximumLength = *lpcbValueName;
RtlUnicodeStringToAnsiString (&StringA, RtlUnicodeStringToAnsiString (&StringA,
&StringU, &StringU,
FALSE); FALSE);
StringA.Buffer[StringA.Length] = 0; StringA.Buffer[StringA.Length] = 0;
*lpcbValueName = StringA.Length; *lpcbValueName = StringA.Length;
if (lpType) if (lpType)
{ {
@ -1207,13 +1219,15 @@ RegEnumValueA (HKEY hKey,
} }
} }
} }
RtlFreeHeap (ProcessHeap, RtlFreeHeap (ProcessHeap,
0, 0,
ValueInfo); ValueInfo);
if (ErrorCode != ERROR_SUCCESS) if (ErrorCode != ERROR_SUCCESS)
{ {
SetLastError(ErrorCode); SetLastError(ErrorCode);
} }
return ErrorCode; return ErrorCode;
} }
@ -1266,6 +1280,7 @@ RegEnumValueW (HKEY hKey,
{ {
NameLength = 0; NameLength = 0;
} }
if (lpData) if (lpData)
{ {
DataLength = min(*lpcbData, REG_MAX_DATA_SIZE); DataLength = min(*lpcbData, REG_MAX_DATA_SIZE);
@ -1298,13 +1313,13 @@ RegEnumValueW (HKEY hKey,
else else
{ {
if (lpData) if (lpData)
{ {
if (ValueInfo->Full.DataLength > DataLength || if (ValueInfo->Full.DataLength > DataLength ||
ValueInfo->Full.NameLength > NameLength) ValueInfo->Full.NameLength > NameLength)
{ {
ErrorCode = ERROR_BUFFER_OVERFLOW; ErrorCode = ERROR_BUFFER_OVERFLOW;
} }
else else
{ {
RtlCopyMemory (lpValueName, RtlCopyMemory (lpValueName,
ValueInfo->Full.Name, ValueInfo->Full.Name,
@ -1318,7 +1333,7 @@ RegEnumValueW (HKEY hKey,
} }
} }
else else
{ {
if (ValueInfo->Basic.NameLength > NameLength) if (ValueInfo->Basic.NameLength > NameLength)
{ {
ErrorCode = ERROR_BUFFER_OVERFLOW; ErrorCode = ERROR_BUFFER_OVERFLOW;
@ -1332,18 +1347,22 @@ RegEnumValueW (HKEY hKey,
lpValueName[*lpcbValueName] = 0; lpValueName[*lpcbValueName] = 0;
} }
} }
if (ErrorCode == ERROR_SUCCESS && lpType != NULL) if (ErrorCode == ERROR_SUCCESS && lpType != NULL)
{ {
*lpType = lpData ? ValueInfo->Full.Type : ValueInfo->Basic.Type; *lpType = lpData ? ValueInfo->Full.Type : ValueInfo->Basic.Type;
} }
} }
RtlFreeHeap (ProcessHeap, RtlFreeHeap (ProcessHeap,
0, 0,
ValueInfo); ValueInfo);
if (ErrorCode != ERROR_SUCCESS) if (ErrorCode != ERROR_SUCCESS)
{ {
SetLastError(ErrorCode); SetLastError (ErrorCode);
} }
return ErrorCode; return ErrorCode;
} }
@ -1445,7 +1464,7 @@ RegLoadKeyA (HKEY hKey,
{ {
UNICODE_STRING FileName; UNICODE_STRING FileName;
UNICODE_STRING KeyName; UNICODE_STRING KeyName;
DWORD ErrorCode; LONG ErrorCode;
RtlCreateUnicodeStringFromAsciiz (&KeyName, RtlCreateUnicodeStringFromAsciiz (&KeyName,
(LPSTR)lpSubKey); (LPSTR)lpSubKey);
@ -1478,7 +1497,7 @@ RegLoadKeyW (HKEY hKey,
UNICODE_STRING FileName; UNICODE_STRING FileName;
UNICODE_STRING KeyName; UNICODE_STRING KeyName;
HANDLE KeyHandle; HANDLE KeyHandle;
DWORD ErrorCode; LONG ErrorCode;
NTSTATUS Status; NTSTATUS Status;
if (hKey == HKEY_PERFORMANCE_DATA) if (hKey == HKEY_PERFORMANCE_DATA)
@ -1898,13 +1917,14 @@ RegQueryInfoKeyW (HKEY hKey,
if (lpClass != NULL) if (lpClass != NULL)
{ {
if (*lpcbClass > 0) if (*lpcbClass > 0)
{ {
ClassLength = min(*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR); ClassLength = min(*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
} }
else else
{ {
ClassLength = 0; ClassLength = 0;
} }
FullInfoSize = sizeof(KEY_FULL_INFORMATION) + ((ClassLength + 3) & ~3); FullInfoSize = sizeof(KEY_FULL_INFORMATION) + ((ClassLength + 3) & ~3);
FullInfo = RtlAllocateHeap (ProcessHeap, FullInfo = RtlAllocateHeap (ProcessHeap,
0, 0,
@ -1914,6 +1934,7 @@ RegQueryInfoKeyW (HKEY hKey,
SetLastError (ERROR_OUTOFMEMORY); SetLastError (ERROR_OUTOFMEMORY);
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
FullInfo->ClassLength = ClassLength; FullInfo->ClassLength = ClassLength;
} }
else else
@ -1932,83 +1953,89 @@ RegQueryInfoKeyW (HKEY hKey,
DPRINT("NtQueryKey() returned status 0x%X\n", Status); DPRINT("NtQueryKey() returned status 0x%X\n", Status);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ErrorCode = RtlNtStatusToDosError (Status);
}
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("MaxClassLen %lu\n", FullInfo->MaxClassLen);
if (lpcbMaxClassLen != NULL)
{
*lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1;
}
DPRINT("Values %lu\n", FullInfo->Values);
if (lpcValues)
{
*lpcValues = FullInfo->Values;
}
DPRINT("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
if (lpcbMaxValueNameLen)
{
*lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1;
}
DPRINT("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
if (lpcbMaxValueLen)
{
*lpcbMaxValueLen = FullInfo->MaxValueDataLen;
}
if (lpcbSecurityDescriptor)
{
*lpcbSecurityDescriptor = 0;
/* FIXME */
}
if (lpftLastWriteTime != NULL)
{
lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
}
if (lpClass != NULL) if (lpClass != NULL)
{ {
if (FullInfo->ClassLength > ClassLength) RtlFreeHeap (ProcessHeap,
{ 0,
ErrorCode = ERROR_BUFFER_OVERFLOW; FullInfo);
}
else
{
RtlCopyMemory (lpClass,
FullInfo->Class,
FullInfo->ClassLength);
*lpcbClass = FullInfo->ClassLength / sizeof(WCHAR);
lpClass[*lpcbClass] = 0;
}
} }
ErrorCode = RtlNtStatusToDosError (Status);
SetLastError (ErrorCode);
return ErrorCode;
} }
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("MaxClassLen %lu\n", FullInfo->MaxClassLen);
if (lpcbMaxClassLen != NULL)
{
*lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1;
}
DPRINT("Values %lu\n", FullInfo->Values);
if (lpcValues != NULL)
{
*lpcValues = FullInfo->Values;
}
DPRINT("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
if (lpcbMaxValueNameLen != NULL)
{
*lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1;
}
DPRINT("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
if (lpcbMaxValueLen != NULL)
{
*lpcbMaxValueLen = FullInfo->MaxValueDataLen;
}
if (lpcbSecurityDescriptor != NULL)
{
/* FIXME */
*lpcbSecurityDescriptor = 0;
}
if (lpftLastWriteTime != NULL)
{
lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
}
if (lpClass != NULL) 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, RtlFreeHeap (ProcessHeap,
0, 0,
FullInfo); FullInfo);
} }
if (ErrorCode != ERROR_SUCCESS) if (ErrorCode != ERROR_SUCCESS)
{ {
SetLastError(ErrorCode); SetLastError (ErrorCode);
} }
return ErrorCode; return ErrorCode;
@ -2047,32 +2074,42 @@ RegQueryMultipleValuesW (HKEY hKey,
{ {
ULONG i; ULONG i;
DWORD maxBytes = *ldwTotsize; DWORD maxBytes = *ldwTotsize;
HRESULT status;
LPSTR bufptr = (LPSTR)lpValueBuf; LPSTR bufptr = (LPSTR)lpValueBuf;
LONG ErrorCode;
if ( maxBytes >= (1024*1024) ) if (maxBytes >= (1024*1024))
return ERROR_TRANSFER_TOO_LONG; return ERROR_TRANSFER_TOO_LONG;
*ldwTotsize = 0; *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; val_list[i].ve_valuelen = 0;
status = RegQueryValueExW(hKey, val_list[i].ve_valuename, NULL, NULL, NULL, &val_list[i].ve_valuelen); ErrorCode = RegQueryValueExW (hKey,
if(status != ERROR_SUCCESS) 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, ErrorCode = RegQueryValueExW (hKey,
bufptr, &val_list[i].ve_valuelen); val_list[i].ve_valuename,
if(status != ERROR_SUCCESS) 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; val_list[i].ve_valueptr = (DWORD_PTR)bufptr;
@ -2082,7 +2119,8 @@ RegQueryMultipleValuesW (HKEY hKey,
*ldwTotsize += val_list[i].ve_valuelen; *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;
} }
@ -2205,15 +2243,13 @@ RegQueryValueExW (HKEY hKey,
* *
* @implemented * @implemented
*/ */
LONG LONG STDCALL
STDCALL RegQueryValueExA (HKEY hKey,
RegQueryValueExA( LPCSTR lpValueName,
HKEY hKey, LPDWORD lpReserved,
LPCSTR lpValueName, LPDWORD lpType,
LPDWORD lpReserved, LPBYTE lpData,
LPDWORD lpType, LPDWORD lpcbData)
LPBYTE lpData,
LPDWORD lpcbData)
{ {
UNICODE_STRING ValueName; UNICODE_STRING ValueName;
UNICODE_STRING ValueData; UNICODE_STRING ValueData;
@ -2232,10 +2268,9 @@ RegQueryValueExA(
{ {
ValueData.Length = *lpcbData * sizeof(WCHAR); ValueData.Length = *lpcbData * sizeof(WCHAR);
ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR); ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
ValueData.Buffer = RtlAllocateHeap( ValueData.Buffer = RtlAllocateHeap (ProcessHeap,
ProcessHeap, 0,
0, ValueData.MaximumLength);
ValueData.MaximumLength);
if (!ValueData.Buffer) if (!ValueData.Buffer)
{ {
SetLastError(ERROR_OUTOFMEMORY); SetLastError(ERROR_OUTOFMEMORY);
@ -2249,36 +2284,40 @@ RegQueryValueExA(
ValueData.MaximumLength = 0; ValueData.MaximumLength = 0;
} }
RtlCreateUnicodeStringFromAsciiz(&ValueName, (LPSTR)lpValueName); RtlCreateUnicodeStringFromAsciiz (&ValueName,
(LPSTR)lpValueName);
/* Convert length from USHORT to DWORD */ /* Convert length from USHORT to DWORD */
Length = ValueData.Length; Length = ValueData.Length;
ErrorCode = RegQueryValueExW ErrorCode = RegQueryValueExW (hKey,
(hKey, ValueName.Buffer,
ValueName.Buffer, lpReserved,
lpReserved, &Type,
&Type, (LPBYTE)ValueData.Buffer,
(LPBYTE)ValueData.Buffer, &Length);
&Length); if (lpType != NULL)
if (lpType) *lpType = Type; *lpType = Type;
if ((ErrorCode == ERROR_SUCCESS) && (ValueData.Buffer != NULL)) if ((ErrorCode == ERROR_SUCCESS) && (ValueData.Buffer != NULL))
{ {
if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ)) if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ))
{ {
RtlInitAnsiString(&AnsiString, NULL); RtlInitAnsiString(&AnsiString, NULL);
AnsiString.Buffer = lpData; AnsiString.Buffer = lpData;
AnsiString.MaximumLength = *lpcbData; AnsiString.MaximumLength = *lpcbData;
ValueData.Length = Length; ValueData.Length = Length;
ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR); ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE); RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
Length = Length / sizeof(WCHAR); Length = Length / sizeof(WCHAR);
} else { }
Length = min(*lpcbData, Length); else
RtlMoveMemory(lpData, ValueData.Buffer, Length); {
} Length = min(*lpcbData, Length);
RtlMoveMemory(lpData, ValueData.Buffer, Length);
}
} }
if (NULL != lpcbData) if (lpcbData != NULL)
{ {
*lpcbData = Length; *lpcbData = Length;
} }
@ -2460,19 +2499,28 @@ RegReplaceKeyA (HKEY hKey,
LPCSTR lpNewFile, LPCSTR lpNewFile,
LPCSTR lpOldFile) LPCSTR lpOldFile)
{ {
UNICODE_STRING lpSubKeyW; UNICODE_STRING SubKey;
UNICODE_STRING lpNewFileW; UNICODE_STRING NewFile;
UNICODE_STRING lpOldFileW; UNICODE_STRING OldFile;
LONG ret; LONG ErrorCode;
RtlCreateUnicodeStringFromAsciiz( &lpSubKeyW, (PCSZ)lpSubKey ); RtlCreateUnicodeStringFromAsciiz (&SubKey,
RtlCreateUnicodeStringFromAsciiz( &lpOldFileW, (PCSZ)lpOldFile ); (PCSZ)lpSubKey);
RtlCreateUnicodeStringFromAsciiz( &lpNewFileW, (PCSZ)lpNewFile ); RtlCreateUnicodeStringFromAsciiz (&OldFile,
ret = RegReplaceKeyW( hKey, lpSubKeyW.Buffer, lpNewFileW.Buffer, lpOldFileW.Buffer ); (PCSZ)lpOldFile);
RtlFreeUnicodeString( &lpOldFileW ); RtlCreateUnicodeStringFromAsciiz (&NewFile,
RtlFreeUnicodeString( &lpNewFileW ); (PCSZ)lpNewFile);
RtlFreeUnicodeString( &lpSubKeyW );
return ret; ErrorCode = RegReplaceKeyW (hKey,
SubKey.Buffer,
NewFile.Buffer,
OldFile.Buffer);
RtlFreeUnicodeString (&OldFile);
RtlFreeUnicodeString (&NewFile);
RtlFreeUnicodeString (&SubKey);
return ErrorCode;
} }
@ -2503,29 +2551,95 @@ RegRestoreKeyA (HKEY hKey,
LPCSTR lpFile, LPCSTR lpFile,
DWORD dwFlags) DWORD dwFlags)
{ {
UNICODE_STRING lpFileW; UNICODE_STRING FileName;
LONG ret; LONG ErrorCode;
RtlCreateUnicodeStringFromAsciiz( &lpFileW, (PCSZ)lpFile ); RtlCreateUnicodeStringFromAsciiz (&FileName,
ret = RegRestoreKeyW( hKey, lpFileW.Buffer, dwFlags ); (PCSZ)lpFile);
RtlFreeUnicodeString( &lpFileW );
return ret; ErrorCode = RegRestoreKeyW (hKey,
FileName.Buffer,
dwFlags);
RtlFreeUnicodeString (&FileName);
return ErrorCode;
} }
/************************************************************************ /************************************************************************
* RegRestoreKeyW * RegRestoreKeyW
* *
* @unimplemented * @implemented
*/ */
LONG STDCALL LONG STDCALL
RegRestoreKeyW (HKEY hKey, RegRestoreKeyW (HKEY hKey,
LPCWSTR lpFile, LPCWSTR lpFile,
DWORD dwFlags) DWORD dwFlags)
{ {
UNIMPLEMENTED; OBJECT_ATTRIBUTES ObjectAttributes;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); IO_STATUS_BLOCK IoStatusBlock;
return ERROR_CALL_NOT_IMPLEMENTED; 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;
} }
@ -2565,7 +2679,7 @@ RegSaveKeyW (HKEY hKey,
{ {
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL; PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING NtName; UNICODE_STRING FileName;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle; HANDLE FileHandle;
HKEY KeyHandle; HKEY KeyHandle;
@ -2582,7 +2696,7 @@ RegSaveKeyW (HKEY hKey,
} }
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile, if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile,
&NtName, &FileName,
NULL, NULL,
NULL)) NULL))
{ {
@ -2596,7 +2710,7 @@ RegSaveKeyW (HKEY hKey,
} }
InitializeObjectAttributes (&ObjectAttributes, InitializeObjectAttributes (&ObjectAttributes,
&NtName, &FileName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
NULL, NULL,
SecurityDescriptor); SecurityDescriptor);
@ -2611,7 +2725,7 @@ RegSaveKeyW (HKEY hKey,
FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT, FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
NULL, NULL,
0); 0);
RtlFreeUnicodeString (&NtName); RtlFreeUnicodeString (&FileName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ErrorCode = RtlNtStatusToDosError (Status); ErrorCode = RtlNtStatusToDosError (Status);
@ -2644,11 +2758,13 @@ RegSetKeySecurity (HKEY hKey,
PSECURITY_DESCRIPTOR pSecurityDescriptor) PSECURITY_DESCRIPTOR pSecurityDescriptor)
{ {
HKEY KeyHandle; HKEY KeyHandle;
NTSTATUS Status;
LONG ErrorCode; LONG ErrorCode;
NTSTATUS Status;
if (hKey == HKEY_PERFORMANCE_DATA) if (hKey == HKEY_PERFORMANCE_DATA)
return ERROR_INVALID_HANDLE; {
return ERROR_INVALID_HANDLE;
}
Status = MapDefaultKey (&KeyHandle, Status = MapDefaultKey (&KeyHandle,
hKey); hKey);
@ -2866,6 +2982,7 @@ RegSetValueA (HKEY hKey,
dwType, dwType,
Data.Buffer, Data.Buffer,
DataSize); DataSize);
RtlFreeHeap (ProcessHeap, RtlFreeHeap (ProcessHeap,
0, 0,
Data.Buffer); Data.Buffer);