Module: wine Branch: master Commit: fdcd9ee712736550543aebdb03794c2c809e14f7 URL: https://source.winehq.org/git/wine.git/?a=commit;h=fdcd9ee712736550543aebdb0...
Author: Jacek Caban jacek@codeweavers.com Date: Mon Mar 11 14:59:57 2019 +0100
ntoskrnl.exe: Support NULL type in ObReferenceObjectByHandle.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntoskrnl.exe/ntoskrnl.c | 32 ++++++++++++++++++++++++++++++-- dlls/ntoskrnl.exe/ntoskrnl_private.h | 9 +++++++++ dlls/ntoskrnl.exe/tests/driver.c | 11 +++++++++-- 3 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 52e0228..67024b9 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -315,6 +315,18 @@ static void ObReferenceObject( void *obj ) TRACE( "(%p) ref=%u\n", obj, ref ); }
+static const POBJECT_TYPE *known_types[] = +{ + &ExEventObjectType, + &ExSemaphoreObjectType, + &IoDeviceObjectType, + &IoDriverObjectType, + &IoFileObjectType, + &PsProcessType, + &PsThreadType, + &SeTokenObjectType +}; + static NTSTATUS kernel_object_from_handle( HANDLE handle, POBJECT_TYPE type, void **ret ) { char buf[256]; @@ -326,8 +338,24 @@ static NTSTATUS kernel_object_from_handle( HANDLE handle, POBJECT_TYPE type, voi status = NtQueryObject(handle, ObjectTypeInformation, buf, sizeof(buf), &size); if (status) return status;
- if (!!RtlCompareUnicodeStrings(type->name, strlenW(type->name), type_info->TypeName.Buffer, - type_info->TypeName.Length / sizeof(WCHAR), FALSE)) + if (!type) + { + size_t i; + for (i = 0; i < ARRAY_SIZE(known_types); i++) + { + type = *known_types[i]; + if (!RtlCompareUnicodeStrings( type->name, strlenW(type->name), type_info->TypeName.Buffer, + type_info->TypeName.Length / sizeof(WCHAR), FALSE )) + break; + } + if (i == ARRAY_SIZE(known_types)) + { + FIXME("Unsupported type %s\n", debugstr_us(&type_info->TypeName)); + return STATUS_INVALID_HANDLE; + } + } + else if (!!RtlCompareUnicodeStrings( type->name, strlenW(type->name), type_info->TypeName.Buffer, + type_info->TypeName.Length / sizeof(WCHAR), FALSE )) return STATUS_OBJECT_TYPE_MISMATCH;
FIXME( "semi-stub: returning new %s object instance\n", debugstr_w(type->name) ); diff --git a/dlls/ntoskrnl.exe/ntoskrnl_private.h b/dlls/ntoskrnl.exe/ntoskrnl_private.h index 440e638..58ecf0c 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl_private.h +++ b/dlls/ntoskrnl.exe/ntoskrnl_private.h @@ -27,6 +27,15 @@ struct _OBJECT_TYPE { void (*release)(void*); /* called when the last reference is released */ };
+extern POBJECT_TYPE ExEventObjectType; +extern POBJECT_TYPE ExSemaphoreObjectType; +extern POBJECT_TYPE IoDeviceObjectType; +extern POBJECT_TYPE IoDriverObjectType; +extern POBJECT_TYPE IoFileObjectType; +extern POBJECT_TYPE PsProcessType; +extern POBJECT_TYPE PsThreadType; +extern POBJECT_TYPE SeTokenObjectType; +
#ifdef __i386__ #define DEFINE_FASTCALL1_WRAPPER(func) \ diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index 2fbe493..7f2e68c 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -705,7 +705,7 @@ static void test_ob_reference(const WCHAR *test_path) status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj1, NULL); ok(status == STATUS_OBJECT_TYPE_MISMATCH, "ObReferenceObjectByHandle returned: %#x\n", status);
- status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj1, NULL); + status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, NULL, KernelMode, &obj1, NULL); ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
if (sizeof(void *) != 4) /* avoid dealing with fastcall */ @@ -722,9 +722,16 @@ static void test_ob_reference(const WCHAR *test_path) todo_wine ok(obj1 == obj2, "obj1 != obj2\n");
- ObDereferenceObject(obj1); ObDereferenceObject(obj2);
+ status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, NULL, KernelMode, &obj2, NULL); + ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status); + todo_wine + ok(obj1 == obj2, "obj1 != obj2\n"); + + ObDereferenceObject(obj2); + ObDereferenceObject(obj1); + status = ObReferenceObjectByHandle(file_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj1, NULL); ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);