mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 16:10:29 +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
1 changed files with 56 additions and 48 deletions
|
@ -3989,10 +3989,11 @@ RegQueryValueExA(HKEY hKey,
|
|||
{
|
||||
UNICODE_STRING ValueName;
|
||||
UNICODE_STRING ValueData;
|
||||
ANSI_STRING AnsiString;
|
||||
LONG ErrorCode;
|
||||
DWORD Length;
|
||||
DWORD Type;
|
||||
NTSTATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
TRACE("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n",
|
||||
hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
|
||||
|
@ -4041,16 +4042,23 @@ RegQueryValueExA(HKEY hKey,
|
|||
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)
|
||||
{
|
||||
RtlInitAnsiString(&AnsiString, NULL);
|
||||
AnsiString.Buffer = (LPSTR)lpData;
|
||||
AnsiString.MaximumLength = *lpcbData;
|
||||
ValueData.Length = Length;
|
||||
ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
|
||||
RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
|
||||
Status = RtlUnicodeToMultiByteN((PCHAR)lpData, *lpcbData, &Index, (PWCHAR)ValueData.Buffer, Length);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
PCHAR szData = (PCHAR)lpData;
|
||||
if(&szData[Index] < (PCHAR)(lpData + *lpcbData))
|
||||
{
|
||||
szData[Index] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
}
|
||||
}
|
||||
|
||||
Length = Length / sizeof(WCHAR);
|
||||
|
@ -4135,7 +4143,7 @@ RegQueryValueExW(HKEY hkeyorg,
|
|||
|
||||
status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
|
||||
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)
|
||||
{
|
||||
|
@ -4153,12 +4161,12 @@ RegQueryValueExW(HKEY hkeyorg,
|
|||
buf_ptr, total_size, &total_size );
|
||||
}
|
||||
|
||||
if (!status)
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
memcpy( data, buf_ptr + info_size, total_size - info_size );
|
||||
/* if the type is REG_SZ and data is not 0-terminated
|
||||
* 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);
|
||||
if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
|
||||
|
@ -4743,12 +4751,16 @@ RegSetValueExA(HKEY hKey,
|
|||
LONG ErrorCode;
|
||||
LPBYTE pData;
|
||||
DWORD DataSize;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (lpValueName != NULL &&
|
||||
strlen(lpValueName) != 0)
|
||||
/* Convert SubKey name to Unicode */
|
||||
if (lpValueName != NULL && lpValueName[0] != '\0')
|
||||
{
|
||||
RtlCreateUnicodeStringFromAsciiz(&ValueName,
|
||||
(PSTR)lpValueName);
|
||||
BOOL bConverted;
|
||||
bConverted = RtlCreateUnicodeStringFromAsciiz(&ValueName,
|
||||
(PSTR)lpValueName);
|
||||
if(!bConverted)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4757,32 +4769,32 @@ RegSetValueExA(HKEY hKey,
|
|||
|
||||
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,
|
||||
NULL);
|
||||
if (is_string(dwType) && (cbData != 0))
|
||||
{
|
||||
/* 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.Length = cbData - 1;
|
||||
AnsiString.MaximumLength = cbData;
|
||||
RtlAnsiStringToUnicodeString(&Data,
|
||||
AnsiString.Length = cbData + bNoNulledStr;
|
||||
AnsiString.MaximumLength = cbData + bNoNulledStr;
|
||||
Status = RtlAnsiStringToUnicodeString(&Data,
|
||||
&AnsiString,
|
||||
TRUE);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (pValueName != NULL)
|
||||
RtlFreeUnicodeString(&ValueName);
|
||||
|
||||
return RtlNtStatusToDosError(Status);
|
||||
}
|
||||
pData = (LPBYTE)Data.Buffer;
|
||||
DataSize = cbData * sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitUnicodeString(&Data,
|
||||
NULL);
|
||||
Data.Buffer = NULL;
|
||||
pData = (LPBYTE)lpData;
|
||||
DataSize = cbData;
|
||||
}
|
||||
|
@ -4793,19 +4805,12 @@ RegSetValueExA(HKEY hKey,
|
|||
dwType,
|
||||
pData,
|
||||
DataSize);
|
||||
|
||||
if (pValueName != NULL)
|
||||
{
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
ValueName.Buffer);
|
||||
}
|
||||
RtlFreeUnicodeString(&ValueName);
|
||||
|
||||
if (Data.Buffer != NULL)
|
||||
{
|
||||
RtlFreeHeap(ProcessHeap,
|
||||
0,
|
||||
Data.Buffer);
|
||||
}
|
||||
RtlFreeUnicodeString(&Data);
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
@ -4847,13 +4852,16 @@ RegSetValueExW(HKEY hKey,
|
|||
}
|
||||
pValueName = &ValueName;
|
||||
|
||||
if (((dwType == REG_SZ) ||
|
||||
(dwType == REG_MULTI_SZ) ||
|
||||
(dwType == REG_EXPAND_SZ)) &&
|
||||
(cbData != 0) && (*(((PWCHAR)lpData) + (cbData / sizeof(WCHAR)) - 1) != L'\0'))
|
||||
if (is_string(dwType) && (cbData != 0))
|
||||
{
|
||||
/* NT adds one if the caller forgot the NULL-termination character */
|
||||
cbData += sizeof(WCHAR);
|
||||
PWSTR pwsData = (PWSTR)lpData;
|
||||
|
||||
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,
|
||||
|
|
Loading…
Reference in a new issue