ntoskrnl.exe: Add partial ObReferenceObjectByHandle implementation.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
916c5f2edb
commit
ad7c1392ce
|
@ -275,6 +275,13 @@ void *alloc_kernel_object( POBJECT_TYPE type, SIZE_T size, LONG ref )
|
||||||
return header + 1;
|
return header + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: Use ObReferenceObject instead. */
|
||||||
|
static void reference_kernel_object( void *obj )
|
||||||
|
{
|
||||||
|
struct object_header *header = (struct object_header*)obj - 1;
|
||||||
|
InterlockedIncrement( &header->ref );
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: Use ObDereferenceObject instead. */
|
/* FIXME: Use ObDereferenceObject instead. */
|
||||||
static void dereference_kernel_object( void *obj )
|
static void dereference_kernel_object( void *obj )
|
||||||
{
|
{
|
||||||
|
@ -288,11 +295,66 @@ static void ObReferenceObject( void *obj )
|
||||||
TRACE( "(%p): stub\n", obj );
|
TRACE( "(%p): stub\n", obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS kernel_object_from_handle( HANDLE handle, POBJECT_TYPE type, void **ret )
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
OBJECT_TYPE_INFORMATION *type_info = (OBJECT_TYPE_INFORMATION *)buf;
|
||||||
|
ULONG size;
|
||||||
|
void *obj;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
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))
|
||||||
|
return STATUS_OBJECT_TYPE_MISMATCH;
|
||||||
|
|
||||||
|
FIXME( "semi-stub: returning new %s object instance\n", debugstr_w(type->name) );
|
||||||
|
|
||||||
|
if (type->constructor)
|
||||||
|
obj = type->constructor( handle );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj = alloc_kernel_object( type, 0, 0 );
|
||||||
|
FIXME( "No constructor for type %s returning empty %p object\n", debugstr_w(type->name), obj );
|
||||||
|
}
|
||||||
|
if (!obj) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
TRACE( "%p -> %p\n", handle, obj );
|
||||||
|
*ret = obj;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* ObReferenceObjectByHandle (NTOSKRNL.EXE.@)
|
||||||
|
*/
|
||||||
|
NTSTATUS WINAPI ObReferenceObjectByHandle( HANDLE handle, ACCESS_MASK access,
|
||||||
|
POBJECT_TYPE type,
|
||||||
|
KPROCESSOR_MODE mode, void **ptr,
|
||||||
|
POBJECT_HANDLE_INFORMATION info )
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
TRACE( "%p %x %p %d %p %p\n", handle, access, type, mode, ptr, info );
|
||||||
|
|
||||||
|
if (mode != KernelMode)
|
||||||
|
{
|
||||||
|
FIXME("UserMode access not implemented\n");
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = kernel_object_from_handle( handle, type, ptr );
|
||||||
|
if (!status) reference_kernel_object( *ptr );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const WCHAR file_type_name[] = {'F','i','l','e',0};
|
static const WCHAR file_type_name[] = {'F','i','l','e',0};
|
||||||
|
|
||||||
static struct _OBJECT_TYPE file_type = {
|
static struct _OBJECT_TYPE file_type = {
|
||||||
file_type_name,
|
file_type_name,
|
||||||
|
NULL,
|
||||||
free_kernel_object
|
free_kernel_object
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1151,6 +1213,7 @@ static const WCHAR driver_type_name[] = {'D','r','i','v','e','r',0};
|
||||||
static struct _OBJECT_TYPE driver_type =
|
static struct _OBJECT_TYPE driver_type =
|
||||||
{
|
{
|
||||||
driver_type_name,
|
driver_type_name,
|
||||||
|
NULL,
|
||||||
free_driver_object
|
free_driver_object
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1226,6 +1289,7 @@ static const WCHAR device_type_name[] = {'D','e','v','i','c','e',0};
|
||||||
static struct _OBJECT_TYPE device_type =
|
static struct _OBJECT_TYPE device_type =
|
||||||
{
|
{
|
||||||
device_type_name,
|
device_type_name,
|
||||||
|
NULL,
|
||||||
free_kernel_object
|
free_kernel_object
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2582,22 +2646,6 @@ VOID WINAPI MmUnmapIoSpace( PVOID BaseAddress, SIZE_T NumberOfBytes )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* ObReferenceObjectByHandle (NTOSKRNL.EXE.@)
|
|
||||||
*/
|
|
||||||
NTSTATUS WINAPI ObReferenceObjectByHandle( HANDLE obj, ACCESS_MASK access,
|
|
||||||
POBJECT_TYPE type,
|
|
||||||
KPROCESSOR_MODE mode, PVOID* ptr,
|
|
||||||
POBJECT_HANDLE_INFORMATION info)
|
|
||||||
{
|
|
||||||
FIXME( "stub: %p %x %p %d %p %p\n", obj, access, type, mode, ptr, info);
|
|
||||||
|
|
||||||
if(ptr)
|
|
||||||
*ptr = UlongToHandle(0xdeadbeaf);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ObReferenceObjectByName (NTOSKRNL.EXE.@)
|
* ObReferenceObjectByName (NTOSKRNL.EXE.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
struct _OBJECT_TYPE {
|
struct _OBJECT_TYPE {
|
||||||
const WCHAR *name; /* object type name used for type validation */
|
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 */
|
void (*release)(void*); /* called when the last reference is released */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -699,14 +699,10 @@ static void test_ob_reference(const WCHAR *test_path)
|
||||||
ok(!status, "PsCreateSystemThread returned: %#x\n", status);
|
ok(!status, "PsCreateSystemThread returned: %#x\n", status);
|
||||||
|
|
||||||
status = ObReferenceObjectByHandle(NULL, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj1, NULL);
|
status = ObReferenceObjectByHandle(NULL, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj1, NULL);
|
||||||
todo_wine
|
|
||||||
ok(status == STATUS_INVALID_HANDLE, "ObReferenceObjectByHandle failed: %#x\n", status);
|
ok(status == STATUS_INVALID_HANDLE, "ObReferenceObjectByHandle failed: %#x\n", status);
|
||||||
if (!status) ObDereferenceObject(obj1);
|
|
||||||
|
|
||||||
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj1, NULL);
|
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj1, NULL);
|
||||||
todo_wine
|
|
||||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "ObReferenceObjectByHandle returned: %#x\n", status);
|
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "ObReferenceObjectByHandle returned: %#x\n", status);
|
||||||
if (!status) ObDereferenceObject(obj1);
|
|
||||||
|
|
||||||
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj1, NULL);
|
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj1, NULL);
|
||||||
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
|
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
|
||||||
|
@ -718,12 +714,11 @@ static void test_ob_reference(const WCHAR *test_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj2, NULL);
|
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj2, NULL);
|
||||||
todo_wine
|
|
||||||
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "ObReferenceObjectByHandle returned: %#x\n", status);
|
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "ObReferenceObjectByHandle returned: %#x\n", status);
|
||||||
if (!status) ObDereferenceObject(obj2);
|
|
||||||
|
|
||||||
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj2, NULL);
|
status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj2, NULL);
|
||||||
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
|
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
|
||||||
|
todo_wine
|
||||||
ok(obj1 == obj2, "obj1 != obj2\n");
|
ok(obj1 == obj2, "obj1 != obj2\n");
|
||||||
|
|
||||||
ObDereferenceObject(obj1);
|
ObDereferenceObject(obj1);
|
||||||
|
@ -734,6 +729,7 @@ static void test_ob_reference(const WCHAR *test_path)
|
||||||
|
|
||||||
status = ObReferenceObjectByHandle(file_handle2, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj2, NULL);
|
status = ObReferenceObjectByHandle(file_handle2, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj2, NULL);
|
||||||
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
|
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
|
||||||
|
todo_wine
|
||||||
ok(obj1 == obj2, "obj1 != obj2\n");
|
ok(obj1 == obj2, "obj1 != obj2\n");
|
||||||
|
|
||||||
ObDereferenceObject(obj1);
|
ObDereferenceObject(obj1);
|
||||||
|
@ -744,6 +740,7 @@ static void test_ob_reference(const WCHAR *test_path)
|
||||||
|
|
||||||
status = ObReferenceObjectByHandle(thread_handle, SYNCHRONIZE, *pPsThreadType, KernelMode, &obj2, NULL);
|
status = ObReferenceObjectByHandle(thread_handle, SYNCHRONIZE, *pPsThreadType, KernelMode, &obj2, NULL);
|
||||||
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
|
ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
|
||||||
|
todo_wine
|
||||||
ok(obj1 == obj2, "obj1 != obj2\n");
|
ok(obj1 == obj2, "obj1 != obj2\n");
|
||||||
|
|
||||||
ObDereferenceObject(obj1);
|
ObDereferenceObject(obj1);
|
||||||
|
|
Loading…
Reference in New Issue