[1/2] ntdll: Fix NtQueryValueKey ret. value for insufficient buffer
Nikolay Sivov
bunglehead at gmail.com
Thu Jan 15 12:59:05 CST 2009
Changelog:
- Fix NtQueryValueKey ret. value for insufficient buffer
- Added some tests for NULL arguments and a fix for them
>From 89c908d7c575882b3a447c1738a2fbf9dd4f41e7 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Thu, 15 Jan 2009 21:25:44 +0300
Subject: Fix ret. value for NtQueryValueKey. Added some tests for NULL arguments.
---
dlls/ntdll/reg.c | 5 ++++-
dlls/ntdll/tests/reg.c | 31 ++++++++++++++++++++++++++++++-
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c
index 0d6a137..c1b81ec 100644
--- a/dlls/ntdll/reg.c
+++ b/dlls/ntdll/reg.c
@@ -470,6 +470,8 @@ NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name,
TRACE( "(%p,%s,%d,%p,%d)\n", handle, debugstr_us(name), info_class, info, length );
+ if (!name || !result_len) return STATUS_ACCESS_VIOLATION;
+
if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW;
/* compute the length we want to retrieve */
@@ -518,7 +520,8 @@ NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name,
copy_key_value_info( info_class, info, length, reply->type,
name->Length, reply->total );
*result_len = fixed_size + (info_class == KeyValueBasicInformation ? 0 : reply->total);
- if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
+ if (length < *result_len)
+ ret = info ? STATUS_BUFFER_OVERFLOW: STATUS_BUFFER_TOO_SMALL;
}
}
SERVER_END_REQ;
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c
index 0e25c06..2230be3 100644
--- a/dlls/ntdll/tests/reg.c
+++ b/dlls/ntdll/tests/reg.c
@@ -481,12 +481,41 @@ static void test_NtQueryValueKey(void)
KEY_VALUE_PARTIAL_INFORMATION *partial_info;
KEY_VALUE_FULL_INFORMATION *full_info;
DWORD len;
+ USHORT namelength;
pRtlCreateUnicodeStringFromAsciiz(&ValName, "deletetest");
+ namelength = ValName.Length;
InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
status = pNtOpenKey(&key, KEY_READ, &attr);
ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status);
+
+ /* NULL arguments */
+ len = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[0]);
+ basic_info = HeapAlloc(GetProcessHeap(), 0, len);
+ status = pNtQueryValueKey(key, NULL, KeyValueBasicInformation, NULL, 0, NULL);
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryValueKey should have returned STATUS_ACCESS_VIOLATION instead of 0x%08x\n", status);
+ status = pNtQueryValueKey(key, NULL, KeyValueBasicInformation, NULL, len, NULL);
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryValueKey should have returned STATUS_ACCESS_VIOLATION instead of 0x%08x\n", status);
+ status = pNtQueryValueKey(key, &ValName, KeyValueBasicInformation, NULL, len, NULL);
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryValueKey should have returned STATUS_ACCESS_VIOLATION instead of 0x%08x\n", status);
+ status = pNtQueryValueKey(key, NULL, KeyValueBasicInformation, NULL, len, &len);
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryValueKey should have returned STATUS_ACCESS_VIOLATION instead of 0x%08x\n", status);
+ ok(len == FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[0]), "NtQueryValueKey returned wrong len %d\n", len);
+ status = pNtQueryValueKey(key, NULL, KeyValueBasicInformation, basic_info, len, &len);
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryValueKey should have returned STATUS_ACCESS_VIOLATION instead of 0x%08x\n", status);
+ ok(len == FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[0]), "NtQueryValueKey returned wrong len %d\n", len);
+ status = pNtQueryValueKey(key, NULL, KeyValueBasicInformation, basic_info, len, NULL);
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryValueKey should have returned STATUS_ACCESS_VIOLATION instead of 0x%08x\n", status);
+ ok(len == FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[0]), "NtQueryValueKey returned wrong len %d\n", len);
+ status = pNtQueryValueKey(key, &ValName, KeyValueBasicInformation, basic_info, len, NULL);
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryValueKey should have returned STATUS_ACCESS_VIOLATION instead of 0x%08x\n", status);
+ HeapFree(GetProcessHeap(), 0, basic_info);
+ /* Test the order of argument checking */
+ ValName.Length = MAX_PATH*sizeof(WCHAR);
+ status = pNtQueryValueKey(key, &ValName, KeyValueBasicInformation, NULL, len, NULL);
+ ValName.Length = namelength;
+ ok(status == STATUS_ACCESS_VIOLATION, "NtQueryValueKey should have returned STATUS_ACCESS_VIOLATION instead of 0x%08x\n", status);
len = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name[0]);
basic_info = HeapAlloc(GetProcessHeap(), 0, len);
@@ -554,7 +583,7 @@ static void test_NtQueryValueKey(void)
pRtlCreateUnicodeStringFromAsciiz(&ValName, "stringtest");
status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, NULL, 0, &len);
- todo_wine ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryValueKey should have returned STATUS_BUFFER_TOO_SMALL instead of 0x%08x\n", status);
+ ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryValueKey should have returned STATUS_BUFFER_TOO_SMALL instead of 0x%08x\n", status);
partial_info = HeapAlloc(GetProcessHeap(), 0, len+1);
memset((BYTE*)partial_info, 0xbd, len+1);
status = pNtQueryValueKey(key, &ValName, KeyValuePartialInformation, partial_info, len, &len);
--
1.5.6.5
More information about the wine-patches
mailing list