diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 804c7f647da..a02dc1c720f 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -2479,11 +2479,23 @@ PEPROCESS WINAPI IoGetCurrentProcess(void) } +static void *create_thread_object( HANDLE handle ) +{ + struct _KTHREAD *thread; + + if (!(thread = alloc_kernel_object( PsThreadType, handle, sizeof(*thread), 0 ))) return NULL; + + thread->header.Type = 6; + thread->header.WaitListHead.Blink = INVALID_HANDLE_VALUE; /* mark as kernel object */ + return thread; +} + static const WCHAR thread_type_name[] = {'T','h','r','e','a','d',0}; static struct _OBJECT_TYPE thread_type = { thread_type_name, + create_thread_object }; POBJECT_TYPE PsThreadType = &thread_type; diff --git a/dlls/ntoskrnl.exe/ntoskrnl_private.h b/dlls/ntoskrnl.exe/ntoskrnl_private.h index 5215b432cef..4b58182abc3 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl_private.h +++ b/dlls/ntoskrnl.exe/ntoskrnl_private.h @@ -21,12 +21,18 @@ #ifndef __WINE_NTOSKRNL_PRIVATE_H #define __WINE_NTOSKRNL_PRIVATE_H -struct _OBJECT_TYPE { +struct _OBJECT_TYPE +{ const WCHAR *name; /* object type name used for type validation */ void *(*constructor)(HANDLE); /* used for creating an object from server handle */ void (*release)(void*); /* called when the last reference is released */ }; +struct _KTHREAD +{ + DISPATCHER_HEADER header; +}; + void *alloc_kernel_object( POBJECT_TYPE type, HANDLE handle, SIZE_T size, LONG ref ) DECLSPEC_HIDDEN; HANDLE kernel_object_handle( void *obj, unsigned int access ) DECLSPEC_HIDDEN; NTSTATUS kernel_object_from_handle( HANDLE handle, POBJECT_TYPE type, void **ret ) DECLSPEC_HIDDEN; diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index 50a1b99fec5..ac6568f424b 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -726,6 +726,7 @@ static void test_ob_reference(const WCHAR *test_path) POBJECT_TYPE (WINAPI *pObGetObjectType)(void*); OBJECT_ATTRIBUTES attr = { sizeof(attr) }; HANDLE event_handle, file_handle, file_handle2, thread_handle; + DISPATCHER_HEADER *header; FILE_OBJECT *file; void *obj1, *obj2; POBJECT_TYPE obj1_type; @@ -824,6 +825,12 @@ static void test_ob_reference(const WCHAR *test_path) ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status); ok(obj1 == obj2, "obj1 != obj2\n"); + header = obj1; + ok(header->Type == 6, "Type = %u\n", header->Type); + + status = wait_single(header, 0); + ok(status == 0 || status == STATUS_TIMEOUT, "got %#x\n", status); + ObDereferenceObject(obj1); ObDereferenceObject(obj2);