mirror of
https://github.com/reactos/reactos.git
synced 2024-09-07 11:19:14 +00:00
Alexander Yastrebov <menone7 AT gmail DOT com>:
- Simplify and fix error checking in RegQuery/SetEx functions - Add handling for missing termination characters - Fixes one advapi32 winetest See issue #4993 for more details. svn path=/trunk/; revision=44566
This commit is contained in:
parent
5aadce5c22
commit
190d075d21
|
@ -3989,10 +3989,11 @@ RegQueryValueExA(HKEY hKey,
|
||||||
{
|
{
|
||||||
UNICODE_STRING ValueName;
|
UNICODE_STRING ValueName;
|
||||||
UNICODE_STRING ValueData;
|
UNICODE_STRING ValueData;
|
||||||
ANSI_STRING AnsiString;
|
|
||||||
LONG ErrorCode;
|
LONG ErrorCode;
|
||||||
DWORD Length;
|
DWORD Length;
|
||||||
DWORD Type;
|
DWORD Type;
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
TRACE("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n",
|
TRACE("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n",
|
||||||
hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
|
hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
|
||||||
|
@ -4041,16 +4042,23 @@ RegQueryValueExA(HKEY hKey,
|
||||||
ErrorCode == ERROR_MORE_DATA)
|
ErrorCode == ERROR_MORE_DATA)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ))
|
if (is_string(Type))
|
||||||
{
|
{
|
||||||
if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
|
if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
|
||||||
{
|
{
|
||||||
RtlInitAnsiString(&AnsiString, NULL);
|
Status = RtlUnicodeToMultiByteN((PCHAR)lpData, *lpcbData, &Index, (PWCHAR)ValueData.Buffer, Length);
|
||||||
AnsiString.Buffer = (LPSTR)lpData;
|
if (NT_SUCCESS(Status))
|
||||||
AnsiString.MaximumLength = *lpcbData;
|
{
|
||||||
ValueData.Length = Length;
|
PCHAR szData = (PCHAR)lpData;
|
||||||
ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
|
if(&szData[Index] < (PCHAR)(lpData + *lpcbData))
|
||||||
RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
|
{
|
||||||
|
szData[Index] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorCode = RtlNtStatusToDosError(Status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Length = Length / sizeof(WCHAR);
|
Length = Length / sizeof(WCHAR);
|
||||||
|
@ -4135,7 +4143,7 @@ RegQueryValueExW(HKEY hkeyorg,
|
||||||
|
|
||||||
status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
|
status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
|
||||||
buffer, total_size, &total_size );
|
buffer, total_size, &total_size );
|
||||||
if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
|
if (!NT_SUCCESS(status) && status != STATUS_BUFFER_OVERFLOW) goto done;
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
|
@ -4153,12 +4161,12 @@ RegQueryValueExW(HKEY hkeyorg,
|
||||||
buf_ptr, total_size, &total_size );
|
buf_ptr, total_size, &total_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!status)
|
if (NT_SUCCESS(status))
|
||||||
{
|
{
|
||||||
memcpy( data, buf_ptr + info_size, total_size - info_size );
|
memcpy( data, buf_ptr + info_size, total_size - info_size );
|
||||||
/* if the type is REG_SZ and data is not 0-terminated
|
/* if the type is REG_SZ and data is not 0-terminated
|
||||||
* and there is enough space in the buffer NT appends a \0 */
|
* and there is enough space in the buffer NT appends a \0 */
|
||||||
if (total_size - info_size <= *count-sizeof(WCHAR) && is_string(info->Type))
|
if (is_string(info->Type) && total_size - info_size <= *count-sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
WCHAR *ptr = (WCHAR *)(data + total_size - info_size);
|
WCHAR *ptr = (WCHAR *)(data + total_size - info_size);
|
||||||
if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
|
if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
|
||||||
|
@ -4743,12 +4751,16 @@ RegSetValueExA(HKEY hKey,
|
||||||
LONG ErrorCode;
|
LONG ErrorCode;
|
||||||
LPBYTE pData;
|
LPBYTE pData;
|
||||||
DWORD DataSize;
|
DWORD DataSize;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
if (lpValueName != NULL &&
|
/* Convert SubKey name to Unicode */
|
||||||
strlen(lpValueName) != 0)
|
if (lpValueName != NULL && lpValueName[0] != '\0')
|
||||||
{
|
{
|
||||||
RtlCreateUnicodeStringFromAsciiz(&ValueName,
|
BOOL bConverted;
|
||||||
(PSTR)lpValueName);
|
bConverted = RtlCreateUnicodeStringFromAsciiz(&ValueName,
|
||||||
|
(PSTR)lpValueName);
|
||||||
|
if(!bConverted)
|
||||||
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4757,32 +4769,32 @@ RegSetValueExA(HKEY hKey,
|
||||||
|
|
||||||
pValueName = (LPWSTR)ValueName.Buffer;
|
pValueName = (LPWSTR)ValueName.Buffer;
|
||||||
|
|
||||||
if (((dwType == REG_SZ) ||
|
|
||||||
(dwType == REG_MULTI_SZ) ||
|
|
||||||
(dwType == REG_EXPAND_SZ)) &&
|
|
||||||
(cbData != 0))
|
|
||||||
{
|
|
||||||
/* NT adds one if the caller forgot the NULL-termination character */
|
|
||||||
if (lpData[cbData - 1] != '\0')
|
|
||||||
{
|
|
||||||
cbData++;
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlInitAnsiString(&AnsiString,
|
if (is_string(dwType) && (cbData != 0))
|
||||||
NULL);
|
{
|
||||||
|
/* Convert ANSI string Data to Unicode */
|
||||||
|
/* If last character NOT zero then increment length */
|
||||||
|
LONG bNoNulledStr = ((lpData[cbData-1] != '\0') ? 1 : 0);
|
||||||
AnsiString.Buffer = (PSTR)lpData;
|
AnsiString.Buffer = (PSTR)lpData;
|
||||||
AnsiString.Length = cbData - 1;
|
AnsiString.Length = cbData + bNoNulledStr;
|
||||||
AnsiString.MaximumLength = cbData;
|
AnsiString.MaximumLength = cbData + bNoNulledStr;
|
||||||
RtlAnsiStringToUnicodeString(&Data,
|
Status = RtlAnsiStringToUnicodeString(&Data,
|
||||||
&AnsiString,
|
&AnsiString,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (pValueName != NULL)
|
||||||
|
RtlFreeUnicodeString(&ValueName);
|
||||||
|
|
||||||
|
return RtlNtStatusToDosError(Status);
|
||||||
|
}
|
||||||
pData = (LPBYTE)Data.Buffer;
|
pData = (LPBYTE)Data.Buffer;
|
||||||
DataSize = cbData * sizeof(WCHAR);
|
DataSize = cbData * sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&Data,
|
Data.Buffer = NULL;
|
||||||
NULL);
|
|
||||||
pData = (LPBYTE)lpData;
|
pData = (LPBYTE)lpData;
|
||||||
DataSize = cbData;
|
DataSize = cbData;
|
||||||
}
|
}
|
||||||
|
@ -4793,19 +4805,12 @@ RegSetValueExA(HKEY hKey,
|
||||||
dwType,
|
dwType,
|
||||||
pData,
|
pData,
|
||||||
DataSize);
|
DataSize);
|
||||||
|
|
||||||
if (pValueName != NULL)
|
if (pValueName != NULL)
|
||||||
{
|
RtlFreeUnicodeString(&ValueName);
|
||||||
RtlFreeHeap(ProcessHeap,
|
|
||||||
0,
|
|
||||||
ValueName.Buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Data.Buffer != NULL)
|
if (Data.Buffer != NULL)
|
||||||
{
|
RtlFreeUnicodeString(&Data);
|
||||||
RtlFreeHeap(ProcessHeap,
|
|
||||||
0,
|
|
||||||
Data.Buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ErrorCode;
|
return ErrorCode;
|
||||||
}
|
}
|
||||||
|
@ -4847,13 +4852,16 @@ RegSetValueExW(HKEY hKey,
|
||||||
}
|
}
|
||||||
pValueName = &ValueName;
|
pValueName = &ValueName;
|
||||||
|
|
||||||
if (((dwType == REG_SZ) ||
|
if (is_string(dwType) && (cbData != 0))
|
||||||
(dwType == REG_MULTI_SZ) ||
|
|
||||||
(dwType == REG_EXPAND_SZ)) &&
|
|
||||||
(cbData != 0) && (*(((PWCHAR)lpData) + (cbData / sizeof(WCHAR)) - 1) != L'\0'))
|
|
||||||
{
|
{
|
||||||
/* NT adds one if the caller forgot the NULL-termination character */
|
PWSTR pwsData = (PWSTR)lpData;
|
||||||
cbData += sizeof(WCHAR);
|
|
||||||
|
if((pwsData[cbData / sizeof(WCHAR) - 1] != L'\0') &&
|
||||||
|
(pwsData[cbData / sizeof(WCHAR)] == L'\0'))
|
||||||
|
{
|
||||||
|
/* Increment length if last character is not zero and next is zero */
|
||||||
|
cbData += sizeof(WCHAR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = NtSetValueKey(KeyHandle,
|
Status = NtSetValueKey(KeyHandle,
|
||||||
|
|
Loading…
Reference in a new issue