mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 16:36:07 +00:00
Minor cleanup.
Implement RegRestoreKeyW(). svn path=/trunk/; revision=8311
This commit is contained in:
parent
2d6b7b1255
commit
a1eebee733
1 changed files with 325 additions and 208 deletions
|
@ -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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -393,15 +393,15 @@ RegCreateKeyExA (HKEY hKey,
|
|||
* @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;
|
||||
|
@ -774,6 +774,7 @@ RegEnumKeyExA (HKEY hKey,
|
|||
SetLastError (ERROR_INVALID_PARAMETER);
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = MapDefaultKey(&KeyHandle,
|
||||
hKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -791,16 +792,18 @@ RegEnumKeyExA (HKEY hKey,
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
@ -812,7 +815,6 @@ RegEnumKeyExA (HKEY hKey,
|
|||
KeyInfo = RtlAllocateHeap (ProcessHeap,
|
||||
0,
|
||||
BufferSize);
|
||||
|
||||
if (KeyInfo == NULL)
|
||||
{
|
||||
SetLastError (ERROR_OUTOFMEMORY);
|
||||
|
@ -833,7 +835,7 @@ RegEnumKeyExA (HKEY hKey,
|
|||
else
|
||||
{
|
||||
if (lpClass == NULL)
|
||||
{
|
||||
{
|
||||
if (KeyInfo->Basic.NameLength > NameLength)
|
||||
{
|
||||
ErrorCode = ERROR_BUFFER_OVERFLOW;
|
||||
|
@ -846,7 +848,7 @@ RegEnumKeyExA (HKEY hKey,
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if (KeyInfo->Node.NameLength > NameLength ||
|
||||
KeyInfo->Node.ClassLength > ClassLength)
|
||||
{
|
||||
|
@ -854,13 +856,13 @@ RegEnumKeyExA (HKEY hKey,
|
|||
}
|
||||
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;
|
||||
|
@ -868,26 +870,27 @@ RegEnumKeyExA (HKEY hKey,
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -947,6 +950,7 @@ RegEnumKeyExW (HKEY hKey,
|
|||
SetLastError (ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
if (*lpcbName > 0)
|
||||
{
|
||||
NameLength = min (*lpcbName - 1, REG_MAX_NAME_SIZE) * sizeof (WCHAR);
|
||||
|
@ -955,22 +959,25 @@ RegEnumKeyExW (HKEY hKey,
|
|||
{
|
||||
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);
|
||||
|
@ -994,7 +1001,7 @@ RegEnumKeyExW (HKEY hKey,
|
|||
else
|
||||
{
|
||||
if (lpClass == NULL)
|
||||
{
|
||||
{
|
||||
if (KeyInfo->Basic.NameLength > NameLength)
|
||||
{
|
||||
ErrorCode = ERROR_BUFFER_OVERFLOW;
|
||||
|
@ -1009,7 +1016,7 @@ RegEnumKeyExW (HKEY hKey,
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if (KeyInfo->Node.NameLength > NameLength ||
|
||||
KeyInfo->Node.ClassLength > ClassLength)
|
||||
{
|
||||
|
@ -1018,7 +1025,7 @@ RegEnumKeyExW (HKEY hKey,
|
|||
else
|
||||
{
|
||||
RtlCopyMemory (lpName,
|
||||
KeyInfo->Node.Name,
|
||||
KeyInfo->Node.Name,
|
||||
KeyInfo->Node.NameLength);
|
||||
*lpcbName = KeyInfo->Node.NameLength / sizeof(WCHAR);
|
||||
lpName[*lpcbName] = 0;
|
||||
|
@ -1029,6 +1036,7 @@ RegEnumKeyExW (HKEY hKey,
|
|||
lpClass[*lpcbClass] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ErrorCode == ERROR_SUCCESS && lpftLastWriteTime != NULL)
|
||||
{
|
||||
if (lpClass == NULL)
|
||||
|
@ -1052,6 +1060,7 @@ RegEnumKeyExW (HKEY hKey,
|
|||
{
|
||||
SetLastError(ErrorCode);
|
||||
}
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
|
@ -1107,6 +1116,7 @@ RegEnumValueA (HKEY hKey,
|
|||
{
|
||||
NameLength = 0;
|
||||
}
|
||||
|
||||
if (lpData)
|
||||
{
|
||||
DataLength = min (*lpcbData * sizeof(WCHAR), REG_MAX_DATA_SIZE);
|
||||
|
@ -1118,7 +1128,7 @@ RegEnumValueA (HKEY hKey,
|
|||
}
|
||||
|
||||
ValueInfo = RtlAllocateHeap (ProcessHeap,
|
||||
0,
|
||||
0,
|
||||
BufferSize);
|
||||
if (ValueInfo == NULL)
|
||||
{
|
||||
|
@ -1142,8 +1152,8 @@ RegEnumValueA (HKEY hKey,
|
|||
{
|
||||
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) ||
|
||||
|
@ -1161,45 +1171,47 @@ RegEnumValueA (HKEY hKey,
|
|||
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)
|
||||
{
|
||||
|
@ -1207,13 +1219,15 @@ RegEnumValueA (HKEY hKey,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
RtlFreeHeap (ProcessHeap,
|
||||
0,
|
||||
0,
|
||||
ValueInfo);
|
||||
if (ErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(ErrorCode);
|
||||
}
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
|
@ -1266,6 +1280,7 @@ RegEnumValueW (HKEY hKey,
|
|||
{
|
||||
NameLength = 0;
|
||||
}
|
||||
|
||||
if (lpData)
|
||||
{
|
||||
DataLength = min(*lpcbData, REG_MAX_DATA_SIZE);
|
||||
|
@ -1298,13 +1313,13 @@ RegEnumValueW (HKEY hKey,
|
|||
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,
|
||||
|
@ -1318,7 +1333,7 @@ RegEnumValueW (HKEY hKey,
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if (ValueInfo->Basic.NameLength > NameLength)
|
||||
{
|
||||
ErrorCode = ERROR_BUFFER_OVERFLOW;
|
||||
|
@ -1332,18 +1347,22 @@ RegEnumValueW (HKEY hKey,
|
|||
lpValueName[*lpcbValueName] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1445,7 +1464,7 @@ RegLoadKeyA (HKEY hKey,
|
|||
{
|
||||
UNICODE_STRING FileName;
|
||||
UNICODE_STRING KeyName;
|
||||
DWORD ErrorCode;
|
||||
LONG ErrorCode;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz (&KeyName,
|
||||
(LPSTR)lpSubKey);
|
||||
|
@ -1478,7 +1497,7 @@ RegLoadKeyW (HKEY hKey,
|
|||
UNICODE_STRING FileName;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE KeyHandle;
|
||||
DWORD ErrorCode;
|
||||
LONG ErrorCode;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (hKey == HKEY_PERFORMANCE_DATA)
|
||||
|
@ -1898,13 +1917,14 @@ RegQueryInfoKeyW (HKEY hKey,
|
|||
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,
|
||||
|
@ -1914,6 +1934,7 @@ RegQueryInfoKeyW (HKEY hKey,
|
|||
SetLastError (ERROR_OUTOFMEMORY);
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
FullInfo->ClassLength = ClassLength;
|
||||
}
|
||||
else
|
||||
|
@ -1932,83 +1953,89 @@ RegQueryInfoKeyW (HKEY hKey,
|
|||
DPRINT("NtQueryKey() returned status 0x%X\n", 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 (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,
|
||||
FullInfo);
|
||||
}
|
||||
|
||||
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 (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;
|
||||
|
@ -2047,32 +2074,42 @@ RegQueryMultipleValuesW (HKEY hKey,
|
|||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
@ -2082,7 +2119,8 @@ RegQueryMultipleValuesW (HKEY hKey,
|
|||
|
||||
*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
|
||||
*/
|
||||
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;
|
||||
|
@ -2232,10 +2268,9 @@ RegQueryValueExA(
|
|||
{
|
||||
ValueData.Length = *lpcbData * sizeof(WCHAR);
|
||||
ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
|
||||
ValueData.Buffer = RtlAllocateHeap(
|
||||
ProcessHeap,
|
||||
0,
|
||||
ValueData.MaximumLength);
|
||||
ValueData.Buffer = RtlAllocateHeap (ProcessHeap,
|
||||
0,
|
||||
ValueData.MaximumLength);
|
||||
if (!ValueData.Buffer)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
|
@ -2249,36 +2284,40 @@ RegQueryValueExA(
|
|||
ValueData.MaximumLength = 0;
|
||||
}
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&ValueName, (LPSTR)lpValueName);
|
||||
RtlCreateUnicodeStringFromAsciiz (&ValueName,
|
||||
(LPSTR)lpValueName);
|
||||
|
||||
/* Convert length from USHORT to DWORD */
|
||||
Length = ValueData.Length;
|
||||
ErrorCode = RegQueryValueExW
|
||||
(hKey,
|
||||
ValueName.Buffer,
|
||||
lpReserved,
|
||||
&Type,
|
||||
(LPBYTE)ValueData.Buffer,
|
||||
&Length);
|
||||
if (lpType) *lpType = Type;
|
||||
ErrorCode = RegQueryValueExW (hKey,
|
||||
ValueName.Buffer,
|
||||
lpReserved,
|
||||
&Type,
|
||||
(LPBYTE)ValueData.Buffer,
|
||||
&Length);
|
||||
if (lpType != NULL)
|
||||
*lpType = Type;
|
||||
|
||||
if ((ErrorCode == ERROR_SUCCESS) && (ValueData.Buffer != NULL))
|
||||
{
|
||||
if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ))
|
||||
{
|
||||
RtlInitAnsiString(&AnsiString, NULL);
|
||||
AnsiString.Buffer = lpData;
|
||||
AnsiString.MaximumLength = *lpcbData;
|
||||
{
|
||||
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 {
|
||||
Length = min(*lpcbData, Length);
|
||||
RtlMoveMemory(lpData, ValueData.Buffer, Length);
|
||||
}
|
||||
RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
|
||||
Length = Length / sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
Length = min(*lpcbData, Length);
|
||||
RtlMoveMemory(lpData, ValueData.Buffer, Length);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != lpcbData)
|
||||
if (lpcbData != NULL)
|
||||
{
|
||||
*lpcbData = Length;
|
||||
}
|
||||
|
@ -2460,19 +2499,28 @@ RegReplaceKeyA (HKEY hKey,
|
|||
LPCSTR lpNewFile,
|
||||
LPCSTR lpOldFile)
|
||||
{
|
||||
UNICODE_STRING lpSubKeyW;
|
||||
UNICODE_STRING lpNewFileW;
|
||||
UNICODE_STRING lpOldFileW;
|
||||
LONG ret;
|
||||
UNICODE_STRING SubKey;
|
||||
UNICODE_STRING NewFile;
|
||||
UNICODE_STRING OldFile;
|
||||
LONG ErrorCode;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2503,29 +2551,95 @@ RegRestoreKeyA (HKEY hKey,
|
|||
LPCSTR lpFile,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
UNICODE_STRING lpFileW;
|
||||
LONG ret;
|
||||
UNICODE_STRING FileName;
|
||||
LONG ErrorCode;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz( &lpFileW, (PCSZ)lpFile );
|
||||
ret = RegRestoreKeyW( hKey, lpFileW.Buffer, dwFlags );
|
||||
RtlFreeUnicodeString( &lpFileW );
|
||||
return ret;
|
||||
RtlCreateUnicodeStringFromAsciiz (&FileName,
|
||||
(PCSZ)lpFile);
|
||||
|
||||
ErrorCode = RegRestoreKeyW (hKey,
|
||||
FileName.Buffer,
|
||||
dwFlags);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2565,7 +2679,7 @@ RegSaveKeyW (HKEY hKey,
|
|||
{
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING NtName;
|
||||
UNICODE_STRING FileName;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE FileHandle;
|
||||
HKEY KeyHandle;
|
||||
|
@ -2582,7 +2696,7 @@ RegSaveKeyW (HKEY hKey,
|
|||
}
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile,
|
||||
&NtName,
|
||||
&FileName,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
|
@ -2596,7 +2710,7 @@ RegSaveKeyW (HKEY hKey,
|
|||
}
|
||||
|
||||
InitializeObjectAttributes (&ObjectAttributes,
|
||||
&NtName,
|
||||
&FileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
SecurityDescriptor);
|
||||
|
@ -2611,7 +2725,7 @@ RegSaveKeyW (HKEY hKey,
|
|||
FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||
NULL,
|
||||
0);
|
||||
RtlFreeUnicodeString (&NtName);
|
||||
RtlFreeUnicodeString (&FileName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError (Status);
|
||||
|
@ -2644,11 +2758,13 @@ RegSetKeySecurity (HKEY hKey,
|
|||
PSECURITY_DESCRIPTOR pSecurityDescriptor)
|
||||
{
|
||||
HKEY KeyHandle;
|
||||
NTSTATUS Status;
|
||||
LONG ErrorCode;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (hKey == HKEY_PERFORMANCE_DATA)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
{
|
||||
return ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
Status = MapDefaultKey (&KeyHandle,
|
||||
hKey);
|
||||
|
@ -2866,6 +2982,7 @@ RegSetValueA (HKEY hKey,
|
|||
dwType,
|
||||
Data.Buffer,
|
||||
DataSize);
|
||||
|
||||
RtlFreeHeap (ProcessHeap,
|
||||
0,
|
||||
Data.Buffer);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue