ntoskrnl.exe: Introduce common kernel object allocator and use it for driver object.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
38eebddc1d
commit
bb94d94bb0
|
@ -98,11 +98,10 @@ static DWORD client_pid;
|
||||||
|
|
||||||
struct wine_driver
|
struct wine_driver
|
||||||
{
|
{
|
||||||
struct wine_rb_entry entry;
|
|
||||||
|
|
||||||
DRIVER_OBJECT driver_obj;
|
DRIVER_OBJECT driver_obj;
|
||||||
DRIVER_EXTENSION driver_extension;
|
DRIVER_EXTENSION driver_extension;
|
||||||
SERVICE_STATUS_HANDLE service_handle;
|
SERVICE_STATUS_HANDLE service_handle;
|
||||||
|
struct wine_rb_entry entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct device_interface
|
struct device_interface
|
||||||
|
@ -252,6 +251,38 @@ static HANDLE get_device_manager(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct object_header
|
||||||
|
{
|
||||||
|
LONG ref;
|
||||||
|
POBJECT_TYPE type;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void free_kernel_object( void *obj )
|
||||||
|
{
|
||||||
|
struct object_header *header = (struct object_header *)obj - 1;
|
||||||
|
HeapFree( GetProcessHeap(), 0, header );
|
||||||
|
}
|
||||||
|
|
||||||
|
void *alloc_kernel_object( POBJECT_TYPE type, SIZE_T size, LONG ref )
|
||||||
|
{
|
||||||
|
struct object_header *header;
|
||||||
|
|
||||||
|
if (!(header = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*header) + size)) )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
header->ref = ref;
|
||||||
|
header->type = type;
|
||||||
|
return header + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Use ObDereferenceObject instead. */
|
||||||
|
static void dereference_kernel_object( void *obj )
|
||||||
|
{
|
||||||
|
struct object_header *header = (struct object_header*)obj - 1;
|
||||||
|
if (!InterlockedDecrement( &header->ref ) && header->type->release)
|
||||||
|
header->type->release( obj );
|
||||||
|
}
|
||||||
|
|
||||||
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 = {
|
||||||
|
@ -1100,11 +1131,20 @@ static NTSTATUS WINAPI unhandled_irp( DEVICE_OBJECT *device, IRP *irp )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void free_driver_object( void *obj )
|
||||||
|
{
|
||||||
|
struct wine_driver *driver = obj;
|
||||||
|
RtlFreeUnicodeString( &driver->driver_obj.DriverName );
|
||||||
|
RtlFreeUnicodeString( &driver->driver_obj.DriverExtension->ServiceKeyName );
|
||||||
|
free_kernel_object( driver );
|
||||||
|
}
|
||||||
|
|
||||||
static const WCHAR driver_type_name[] = {'D','r','i','v','e','r',0};
|
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,
|
||||||
|
free_driver_object
|
||||||
};
|
};
|
||||||
|
|
||||||
POBJECT_TYPE IoDriverObjectType = &driver_type;
|
POBJECT_TYPE IoDriverObjectType = &driver_type;
|
||||||
|
@ -1121,13 +1161,12 @@ NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init )
|
||||||
|
|
||||||
TRACE("(%s, %p)\n", debugstr_us(name), init);
|
TRACE("(%s, %p)\n", debugstr_us(name), init);
|
||||||
|
|
||||||
if (!(driver = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
if (!(driver = alloc_kernel_object( IoDriverObjectType, sizeof(*driver), 1 )))
|
||||||
sizeof(*driver) )))
|
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
if ((status = RtlDuplicateUnicodeString( 1, name, &driver->driver_obj.DriverName )))
|
if ((status = RtlDuplicateUnicodeString( 1, name, &driver->driver_obj.DriverName )))
|
||||||
{
|
{
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, driver );
|
free_kernel_object( driver );
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1142,9 +1181,7 @@ NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init )
|
||||||
status = driver->driver_obj.DriverInit( &driver->driver_obj, &driver->driver_extension.ServiceKeyName );
|
status = driver->driver_obj.DriverInit( &driver->driver_obj, &driver->driver_extension.ServiceKeyName );
|
||||||
if (status)
|
if (status)
|
||||||
{
|
{
|
||||||
RtlFreeUnicodeString( &driver->driver_obj.DriverName );
|
dereference_kernel_object( driver );
|
||||||
RtlFreeUnicodeString( &driver->driver_extension.ServiceKeyName );
|
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, driver );
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1173,9 +1210,7 @@ void WINAPI IoDeleteDriver( DRIVER_OBJECT *driver_object )
|
||||||
wine_rb_remove_key( &wine_drivers, &driver_object->DriverName );
|
wine_rb_remove_key( &wine_drivers, &driver_object->DriverName );
|
||||||
LeaveCriticalSection( &drivers_cs );
|
LeaveCriticalSection( &drivers_cs );
|
||||||
|
|
||||||
RtlFreeUnicodeString( &driver_object->DriverName );
|
dereference_kernel_object( driver_object );
|
||||||
RtlFreeUnicodeString( &driver_object->DriverExtension->ServiceKeyName );
|
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, CONTAINING_RECORD( driver_object, struct wine_driver, driver_obj ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 (*release)(void*); /* called when the last reference is released */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
|
|
Loading…
Reference in New Issue