mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:52:59 +00:00
[ADVAPI32]
- Rewrite RegQueryValueExA as a wrapper arount RegQueryValueExW CORE-8582 svn path=/trunk/; revision=64441
This commit is contained in:
parent
cd4b86a398
commit
7478b71bc8
1 changed files with 66 additions and 82 deletions
|
@ -3942,102 +3942,86 @@ RegQueryReflectionKey(IN HKEY hBase,
|
||||||
*/
|
*/
|
||||||
LONG
|
LONG
|
||||||
WINAPI
|
WINAPI
|
||||||
RegQueryValueExA(HKEY hkeyorg,
|
RegQueryValueExA(
|
||||||
LPCSTR name,
|
_In_ HKEY hkeyorg,
|
||||||
LPDWORD reserved,
|
_In_ LPCSTR name,
|
||||||
LPDWORD type,
|
_In_ LPDWORD reserved,
|
||||||
LPBYTE data,
|
_Out_opt_ LPDWORD type,
|
||||||
LPDWORD count)
|
_Out_opt_ LPBYTE data,
|
||||||
|
_Inout_opt_ LPDWORD count)
|
||||||
{
|
{
|
||||||
HANDLE hkey;
|
|
||||||
NTSTATUS status;
|
|
||||||
ANSI_STRING nameA;
|
|
||||||
UNICODE_STRING nameW;
|
UNICODE_STRING nameW;
|
||||||
DWORD total_size, datalen = 0;
|
DWORD DataLength;
|
||||||
char buffer[256], *buf_ptr = buffer;
|
DWORD ErrorCode;
|
||||||
KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
|
DWORD BufferSize = 0;
|
||||||
static const int info_size = offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data );
|
WCHAR* Buffer;
|
||||||
|
CHAR* DataStr = (CHAR*)data;
|
||||||
|
DWORD LocalType;
|
||||||
|
|
||||||
TRACE("(%p,%s,%p,%p,%p,%p=%d)\n",
|
/* Validate those parameters, the rest will be done with the first RegQueryValueExW call */
|
||||||
hkeyorg, debugstr_a(name), reserved, type, data, count, count ? *count : 0 );
|
if ((data && !count) || reserved)
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
|
if (name)
|
||||||
status = MapDefaultKey(&hkey, hkeyorg);
|
RtlCreateUnicodeStringFromAsciiz(&nameW, name);
|
||||||
if (!NT_SUCCESS(status))
|
else
|
||||||
|
RtlInitEmptyUnicodeString(&nameW, NULL, 0);
|
||||||
|
|
||||||
|
ErrorCode = RegQueryValueExW(hkeyorg, nameW.Buffer, NULL, &LocalType, NULL, &BufferSize);
|
||||||
|
if (ErrorCode != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
return RtlNtStatusToDosError(status);
|
if (!data)
|
||||||
|
*count = 0;
|
||||||
|
RtlFreeUnicodeString(&nameW);
|
||||||
|
return ErrorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count) datalen = *count;
|
/* See if we can directly handle the call without caring for conversion */
|
||||||
if (!data && count) *count = 0;
|
if (!is_string(LocalType) || !count)
|
||||||
|
|
||||||
RtlInitAnsiString( &nameA, name );
|
|
||||||
if ((status = RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE )))
|
|
||||||
{
|
{
|
||||||
ClosePredefKey(hkey);
|
ErrorCode = RegQueryValueExW(hkeyorg, nameW.Buffer, reserved, type, data, count);
|
||||||
return RtlNtStatusToDosError(status);
|
RtlFreeUnicodeString(&nameW);
|
||||||
|
return ErrorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
|
/* Allocate a unicode string to get the data */
|
||||||
buffer, sizeof(buffer), &total_size );
|
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
|
||||||
if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
|
if (!Buffer)
|
||||||
|
|
||||||
/* we need to fetch the contents for a string type even if not requested,
|
|
||||||
* because we need to compute the length of the ASCII string. */
|
|
||||||
if (data || is_string(info->Type))
|
|
||||||
{
|
{
|
||||||
/* retry with a dynamically allocated buffer */
|
RtlFreeUnicodeString(&nameW);
|
||||||
while (status == STATUS_BUFFER_OVERFLOW)
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
{
|
|
||||||
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
|
|
||||||
if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
|
|
||||||
{
|
|
||||||
status = STATUS_NO_MEMORY;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
|
|
||||||
status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
|
|
||||||
buf_ptr, total_size, &total_size );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status) goto done;
|
|
||||||
|
|
||||||
if (is_string(info->Type))
|
|
||||||
{
|
|
||||||
DWORD len;
|
|
||||||
|
|
||||||
RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr + info_size),
|
|
||||||
total_size - info_size );
|
|
||||||
if (data && len)
|
|
||||||
{
|
|
||||||
if (len > datalen) status = STATUS_BUFFER_OVERFLOW;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RtlUnicodeToMultiByteN( (char*)data, len, NULL, (WCHAR *)(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 (len < datalen && data[len-1]) data[len] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
total_size = len + info_size;
|
|
||||||
}
|
|
||||||
else if (data)
|
|
||||||
{
|
|
||||||
if (total_size - info_size > datalen) status = STATUS_BUFFER_OVERFLOW;
|
|
||||||
else memcpy( data, buf_ptr + info_size, total_size - info_size );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (type) *type = info->Type;
|
ErrorCode = RegQueryValueExW(hkeyorg, nameW.Buffer, reserved, type, (LPBYTE)Buffer, &BufferSize);
|
||||||
if (count) *count = total_size - info_size;
|
if (ErrorCode != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
|
RtlFreeUnicodeString(&nameW);
|
||||||
|
return ErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
/* We don't need this anymore */
|
||||||
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
|
RtlFreeUnicodeString(&nameW);
|
||||||
RtlFreeUnicodeString( &nameW );
|
|
||||||
ClosePredefKey(hkey);
|
DataLength = *count;
|
||||||
return RtlNtStatusToDosError(status);
|
RtlUnicodeToMultiByteSize(count, Buffer, BufferSize);
|
||||||
|
|
||||||
|
if ((!data) || (DataLength < *count))
|
||||||
|
{
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
|
return data ? ERROR_MORE_DATA : ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We can finally do the conversion */
|
||||||
|
RtlUnicodeToMultiByteN(DataStr, DataLength, NULL, Buffer, BufferSize);
|
||||||
|
|
||||||
|
/* NULL-terminate if there is enough room */
|
||||||
|
if ((DataLength > *count) && (DataStr[*count - 1] != '\0'))
|
||||||
|
DataStr[*count] = '\0';
|
||||||
|
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue