Jacek Caban : ntoskrnl.exe: Support NULL type in ObReferenceObjectByHandle.

Alexandre Julliard julliard at winehq.org
Mon Mar 11 16:29:53 CDT 2019


Module: wine
Branch: master
Commit: fdcd9ee712736550543aebdb03794c2c809e14f7
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=fdcd9ee712736550543aebdb03794c2c809e14f7

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Mar 11 14:59:57 2019 +0100

ntoskrnl.exe: Support NULL type in ObReferenceObjectByHandle.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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);
 




More information about the wine-cvs mailing list