hidclass.sys: Don't leak report queues on device removal.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Aric Stewart <aric@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8f1f061349
commit
9421dd2b3c
|
@ -116,9 +116,10 @@ static struct hid_report_queue *hid_report_queue_create( void )
|
|||
return queue;
|
||||
}
|
||||
|
||||
static void hid_report_queue_destroy( struct hid_report_queue *queue )
|
||||
void hid_report_queue_destroy( struct hid_report_queue *queue )
|
||||
{
|
||||
while (queue->length--) hid_report_decref( queue->reports[queue->length] );
|
||||
list_remove( &queue->entry );
|
||||
free( queue );
|
||||
}
|
||||
|
||||
|
@ -654,10 +655,22 @@ NTSTATUS WINAPI pdo_create(DEVICE_OBJECT *device, IRP *irp)
|
|||
{
|
||||
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
|
||||
struct hid_report_queue *queue;
|
||||
BOOL removed;
|
||||
KIRQL irql;
|
||||
|
||||
TRACE("Open handle on device %p\n", device);
|
||||
|
||||
KeAcquireSpinLock( &ext->u.pdo.lock, &irql );
|
||||
removed = ext->u.pdo.removed;
|
||||
KeReleaseSpinLock( &ext->u.pdo.lock, irql );
|
||||
|
||||
if (removed)
|
||||
{
|
||||
irp->IoStatus.Status = STATUS_DELETE_PENDING;
|
||||
IoCompleteRequest( irp, IO_NO_INCREMENT );
|
||||
return STATUS_DELETE_PENDING;
|
||||
}
|
||||
|
||||
if (!(queue = hid_report_queue_create())) irp->IoStatus.Status = STATUS_NO_MEMORY;
|
||||
else
|
||||
{
|
||||
|
@ -677,10 +690,22 @@ NTSTATUS WINAPI pdo_close(DEVICE_OBJECT *device, IRP *irp)
|
|||
{
|
||||
struct hid_report_queue *queue = irp->Tail.Overlay.OriginalFileObject->FsContext;
|
||||
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
|
||||
BOOL removed;
|
||||
KIRQL irql;
|
||||
|
||||
TRACE("Close handle on device %p\n", device);
|
||||
|
||||
KeAcquireSpinLock( &ext->u.pdo.lock, &irql );
|
||||
removed = ext->u.pdo.removed;
|
||||
KeReleaseSpinLock( &ext->u.pdo.lock, irql );
|
||||
|
||||
if (removed)
|
||||
{
|
||||
irp->IoStatus.Status = STATUS_DELETE_PENDING;
|
||||
IoCompleteRequest( irp, IO_NO_INCREMENT );
|
||||
return STATUS_DELETE_PENDING;
|
||||
}
|
||||
|
||||
if (queue)
|
||||
{
|
||||
KeAcquireSpinLock( &ext->u.pdo.report_queues_lock, &irql );
|
||||
|
|
|
@ -123,7 +123,7 @@ void call_minidriver( ULONG code, DEVICE_OBJECT *device, void *in_buff, ULONG in
|
|||
|
||||
/* Internal device functions */
|
||||
void HID_StartDeviceThread(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
|
||||
|
||||
void hid_report_queue_destroy( struct hid_report_queue *queue );
|
||||
IRP *pop_irp_from_queue(BASE_DEVICE_EXTENSION *ext) DECLSPEC_HIDDEN;
|
||||
|
||||
NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -387,6 +387,7 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp)
|
|||
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
|
||||
HIDP_COLLECTION_DESC *desc = ext->u.pdo.device_desc.CollectionDesc;
|
||||
NTSTATUS status = irp->IoStatus.Status;
|
||||
struct hid_report_queue *queue, *next;
|
||||
KIRQL irql;
|
||||
|
||||
TRACE("irp %p, minor function %#x.\n", irp, irpsp->MinorFunction);
|
||||
|
@ -498,6 +499,11 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device, IRP *irp)
|
|||
}
|
||||
CloseHandle(ext->u.pdo.halt_event);
|
||||
|
||||
KeAcquireSpinLock( &ext->u.pdo.report_queues_lock, &irql );
|
||||
LIST_FOR_EACH_ENTRY_SAFE( queue, next, &ext->u.pdo.report_queues, struct hid_report_queue, entry )
|
||||
hid_report_queue_destroy( queue );
|
||||
KeReleaseSpinLock( &ext->u.pdo.report_queues_lock, irql );
|
||||
|
||||
HidP_FreeCollectionDescription(&ext->u.pdo.device_desc);
|
||||
|
||||
RtlFreeUnicodeString(&ext->u.pdo.link_name);
|
||||
|
|
Loading…
Reference in New Issue