ntoskrnl.exe/tests: Add object reference tests.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2019-02-26 13:38:50 +01:00 committed by Alexandre Julliard
parent c64d73c829
commit 99876873b8
2 changed files with 140 additions and 5 deletions

View File

@ -1313,8 +1313,8 @@
@ stub ZwCloseObjectAuditAlarm
@ stdcall -private ZwConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr) NtConnectPort
@ stdcall -private ZwCreateDirectoryObject(ptr long ptr) NtCreateDirectoryObject
@ stdcall -private ZwCreateEvent(ptr long ptr long long) NtCreateEvent
@ stdcall -private ZwCreateFile(ptr long ptr ptr ptr long long long long ptr long) NtCreateFile
@ stdcall ZwCreateEvent(ptr long ptr long long) NtCreateEvent
@ stdcall ZwCreateFile(ptr long ptr ptr ptr long long long long ptr long) NtCreateFile
@ stdcall -private ZwCreateJobObject(ptr long ptr) NtCreateJobObject
@ stdcall -private ZwCreateKey(ptr long ptr long ptr long ptr) NtCreateKey
@ stdcall -private ZwCreateSection(ptr long ptr ptr long long long) NtCreateSection
@ -1326,7 +1326,7 @@
@ stdcall -private ZwDeleteValueKey(long ptr) NtDeleteValueKey
@ stdcall -private ZwDeviceIoControlFile(long long ptr ptr ptr long ptr long ptr long) NtDeviceIoControlFile
@ stdcall -private ZwDisplayString(ptr) NtDisplayString
@ stdcall -private ZwDuplicateObject(long long long ptr long long long) NtDuplicateObject
@ stdcall ZwDuplicateObject(long long long ptr long long long) NtDuplicateObject
@ stdcall -private ZwDuplicateToken(long long ptr long long ptr) NtDuplicateToken
@ stub ZwEnumerateBootEntries
@ stdcall -private ZwEnumerateKey(long long long ptr long ptr) NtEnumerateKey

View File

@ -49,6 +49,10 @@ static int running_under_wine;
static int winetest_debug;
static int winetest_report_success;
static POBJECT_TYPE *pExEventObjectType, *pIoFileObjectType, *pPsThreadType;
void WINAPI ObfReferenceObject( void *obj );
extern int CDECL _vsnprintf(char *str, size_t len, const char *format, __ms_va_list argptr);
static void kvprintf(const char *format, __ms_va_list ap)
@ -174,6 +178,21 @@ static void winetest_end_todo(void)
#define todo_wine_if(is_todo) todo_if((is_todo) && running_under_wine)
#define win_skip(...) win_skip_(__FILE__, __LINE__, __VA_ARGS__)
static unsigned int strlenW( const WCHAR *str )
{
const WCHAR *s = str;
while (*s) s++;
return s - str;
}
void *kmemcpy(void *dest, const void *src, SIZE_T n)
{
const char *s = src;
char *d = dest;
while (n--) *d++ = *s++;
return dest;
}
static void *get_proc_address(const char *name)
{
UNICODE_STRING name_u;
@ -636,6 +655,113 @@ static void test_version(void)
ok(*pNtBuildNumber == build, "Expected build number %u, got %u\n", build, *pNtBuildNumber);
}
static void WINAPI thread_proc(void *arg)
{
PsTerminateSystemThread(STATUS_SUCCESS);
}
static void test_ob_reference(const WCHAR *test_path)
{
OBJECT_ATTRIBUTES attr = { sizeof(attr) };
HANDLE event_handle, file_handle, file_handle2, thread_handle;
void *obj1, *obj2;
UNICODE_STRING pathU;
IO_STATUS_BLOCK io;
WCHAR *tmp_path;
SIZE_T len;
NTSTATUS status;
static const WCHAR tmpW[] = {'.','t','m','p',0};
InitializeObjectAttributes(&attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwCreateEvent(&event_handle, SYNCHRONIZE, &attr, NotificationEvent, TRUE);
ok(!status, "ZwCreateEvent failed: %#x\n", status);
len = strlenW(test_path);
tmp_path = ExAllocatePool(PagedPool, len * sizeof(WCHAR) + sizeof(tmpW));
kmemcpy(tmp_path, test_path, len * sizeof(WCHAR));
kmemcpy(tmp_path + len, tmpW, sizeof(tmpW));
RtlInitUnicodeString(&pathU, tmp_path);
attr.ObjectName = &pathU;
attr.Attributes = OBJ_KERNEL_HANDLE;
status = ZwCreateFile(&file_handle, DELETE | FILE_WRITE_DATA | SYNCHRONIZE, &attr, &io, NULL, 0, 0, FILE_CREATE,
FILE_DELETE_ON_CLOSE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
ok(!status, "ZwCreateFile failed: %#x\n", status);
ExFreePool(tmp_path);
status = ZwDuplicateObject(NtCurrentProcess(), file_handle, NtCurrentProcess(), &file_handle2,
0, OBJ_KERNEL_HANDLE, DUPLICATE_SAME_ACCESS);
ok(!status, "ZwDuplicateObject failed: %#x\n", status);
InitializeObjectAttributes(&attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
status = PsCreateSystemThread(&thread_handle, SYNCHRONIZE, &attr, NULL, NULL, thread_proc, NULL);
ok(!status, "PsCreateSystemThread returned: %#x\n", status);
status = ObReferenceObjectByHandle(NULL, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj1, NULL);
todo_wine
ok(status == STATUS_INVALID_HANDLE, "ObReferenceObjectByHandle failed: %#x\n", status);
if (!status) ObDereferenceObject(obj1);
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj1, NULL);
todo_wine
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "ObReferenceObjectByHandle returned: %#x\n", status);
if (!status) ObDereferenceObject(obj1);
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj1, NULL);
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
if (sizeof(void *) != 4) /* avoid dealing with fastcall */
{
ObfReferenceObject(obj1);
ObDereferenceObject(obj1);
}
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj2, NULL);
todo_wine
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "ObReferenceObjectByHandle returned: %#x\n", status);
if (!status) ObDereferenceObject(obj2);
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj2, NULL);
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
ok(obj1 == obj2, "obj1 != obj2\n");
ObDereferenceObject(obj1);
ObDereferenceObject(obj2);
status = ObReferenceObjectByHandle(file_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj1, NULL);
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
status = ObReferenceObjectByHandle(file_handle2, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj2, NULL);
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
ok(obj1 == obj2, "obj1 != obj2\n");
ObDereferenceObject(obj1);
ObDereferenceObject(obj2);
status = ObReferenceObjectByHandle(thread_handle, SYNCHRONIZE, *pPsThreadType, KernelMode, &obj1, NULL);
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
status = ObReferenceObjectByHandle(thread_handle, SYNCHRONIZE, *pPsThreadType, KernelMode, &obj2, NULL);
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
ok(obj1 == obj2, "obj1 != obj2\n");
ObDereferenceObject(obj1);
ObDereferenceObject(obj2);
status = ZwClose(thread_handle);
ok(!status, "ZwClose failed: %#x\n", status);
status = ZwClose(event_handle);
ok(!status, "ZwClose failed: %#x\n", status);
status = ZwClose(file_handle);
ok(!status, "ZwClose failed: %#x\n", status);
status = ZwClose(file_handle2);
ok(!status, "ZwClose failed: %#x\n", status);
}
static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
{
ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
@ -647,7 +773,6 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
if (!buffer)
return STATUS_ACCESS_VIOLATION;
if (length < sizeof(failures))
return STATUS_BUFFER_TOO_SMALL;
@ -660,6 +785,15 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
attr.Attributes = OBJ_KERNEL_HANDLE; /* needed to be accessible from system threads */
ZwOpenFile(&okfile, FILE_APPEND_DATA | SYNCHRONIZE, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT);
pExEventObjectType = get_proc_address("ExEventObjectType");
ok(!!pExEventObjectType, "ExEventObjectType not found\n");
pIoFileObjectType = get_proc_address("IoFileObjectType");
ok(!!pIoFileObjectType, "IofileObjectType not found\n");
pPsThreadType = get_proc_address("PsThreadType");
ok(!!pPsThreadType, "IofileObjectType not found\n");
test_irp_struct(irp, device);
test_currentprocess();
test_mdl_map();
@ -669,9 +803,10 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
test_version();
test_stack_callout();
test_lookaside_list();
test_ob_reference(test_input->path);
/* print process report */
if (test_input->winetest_debug)
if (winetest_debug)
{
kprintf("%04x:ntoskrnl: %d tests executed (%d marked as todo, %d %s), %d skipped.\n",
PsGetCurrentProcessId(), successes + failures + todo_successes + todo_failures,