Skip to content
Snippets Groups Projects
Commit 8a26c088 authored by Rémi Bernon's avatar Rémi Bernon :speech_balloon: Committed by Alexandre Julliard
Browse files

hidclass: Allocate child PDOs array dynamically.

parent 6f4167a1
No related branches found
No related tags found
No related merge requests found
...@@ -51,7 +51,8 @@ typedef struct _BASE_DEVICE_EXTENSION ...@@ -51,7 +51,8 @@ typedef struct _BASE_DEVICE_EXTENSION
HID_DEVICE_ATTRIBUTES attrs; HID_DEVICE_ATTRIBUTES attrs;
HIDP_DEVICE_DESC device_desc; HIDP_DEVICE_DESC device_desc;
DEVICE_OBJECT *child_pdo; DEVICE_OBJECT **child_pdos;
UINT child_count;
} fdo; } fdo;
struct struct
......
...@@ -235,30 +235,37 @@ static NTSTATUS initialize_device( minidriver *minidriver, DEVICE_OBJECT *device ...@@ -235,30 +235,37 @@ static NTSTATUS initialize_device( minidriver *minidriver, DEVICE_OBJECT *device
return status; return status;
} }
if (!(ext->u.fdo.child_pdos = malloc( ext->u.fdo.device_desc.CollectionDescLength * sizeof(ext->u.fdo.child_pdos) )))
{
ERR( "Cannot allocate child PDOs array\n" );
return STATUS_NO_MEMORY;
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static void create_child(minidriver *minidriver, DEVICE_OBJECT *fdo) static NTSTATUS create_child_pdos( minidriver *minidriver, DEVICE_OBJECT *device )
{ {
BASE_DEVICE_EXTENSION *fdo_ext = fdo->DeviceExtension, *pdo_ext; BASE_DEVICE_EXTENSION *fdo_ext = device->DeviceExtension, *pdo_ext;
DEVICE_OBJECT *child_pdo; DEVICE_OBJECT *child_pdo;
UNICODE_STRING string; UNICODE_STRING string;
WCHAR pdo_name[255]; WCHAR pdo_name[255];
USAGE page, usage; USAGE page, usage;
NTSTATUS status; NTSTATUS status;
swprintf(pdo_name, ARRAY_SIZE(pdo_name), L"\\Device\\HID#%p&%p", fdo->DriverObject, swprintf( pdo_name, ARRAY_SIZE(pdo_name), L"\\Device\\HID#%p&%p", device->DriverObject,
fdo_ext->u.fdo.hid_ext.PhysicalDeviceObject); fdo_ext->u.fdo.hid_ext.PhysicalDeviceObject );
RtlInitUnicodeString(&string, pdo_name); RtlInitUnicodeString(&string, pdo_name);
if ((status = IoCreateDevice(fdo->DriverObject, sizeof(*pdo_ext), &string, 0, 0, FALSE, &child_pdo))) if ((status = IoCreateDevice( device->DriverObject, sizeof(*pdo_ext), &string, 0, 0, FALSE, &child_pdo )))
{ {
ERR( "Failed to create child PDO, status %#lx.\n", status ); ERR( "Failed to create child PDO, status %#lx.\n", status );
return; return status;
} }
fdo_ext->u.fdo.child_pdo = child_pdo; fdo_ext->u.fdo.child_pdos[0] = child_pdo;
fdo_ext->u.fdo.child_count++;
pdo_ext = child_pdo->DeviceExtension; pdo_ext = child_pdo->DeviceExtension;
pdo_ext->u.pdo.parent_fdo = fdo; pdo_ext->u.pdo.parent_fdo = device;
list_init( &pdo_ext->u.pdo.queues ); list_init( &pdo_ext->u.pdo.queues );
KeInitializeSpinLock( &pdo_ext->u.pdo.queues_lock ); KeInitializeSpinLock( &pdo_ext->u.pdo.queues_lock );
...@@ -285,9 +292,10 @@ static void create_child(minidriver *minidriver, DEVICE_OBJECT *fdo) ...@@ -285,9 +292,10 @@ static void create_child(minidriver *minidriver, DEVICE_OBJECT *fdo)
pdo_ext->u.pdo.rawinput_handle = alloc_rawinput_handle(); pdo_ext->u.pdo.rawinput_handle = alloc_rawinput_handle();
pdo_ext->u.pdo.poll_interval = DEFAULT_POLL_INTERVAL; pdo_ext->u.pdo.poll_interval = DEFAULT_POLL_INTERVAL;
IoInvalidateDeviceRelations( fdo_ext->u.fdo.hid_ext.PhysicalDeviceObject, BusRelations );
TRACE( "created device %p, rawinput handle %#x\n", pdo_ext, pdo_ext->u.pdo.rawinput_handle ); TRACE( "created device %p, rawinput handle %#x\n", pdo_ext, pdo_ext->u.pdo.rawinput_handle );
IoInvalidateDeviceRelations( fdo_ext->u.fdo.hid_ext.PhysicalDeviceObject, BusRelations );
return STATUS_SUCCESS;
} }
static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp)
...@@ -304,27 +312,23 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) ...@@ -304,27 +312,23 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp)
case IRP_MN_QUERY_DEVICE_RELATIONS: case IRP_MN_QUERY_DEVICE_RELATIONS:
{ {
DEVICE_RELATIONS *devices; DEVICE_RELATIONS *devices;
DEVICE_OBJECT *child; UINT32 i;
if (stack->Parameters.QueryDeviceRelations.Type != BusRelations) if (stack->Parameters.QueryDeviceRelations.Type != BusRelations)
return minidriver->PNPDispatch(device, irp); return minidriver->PNPDispatch(device, irp);
if (!(devices = ExAllocatePool(PagedPool, offsetof(DEVICE_RELATIONS, Objects[1])))) if (!(devices = ExAllocatePool(PagedPool, offsetof(DEVICE_RELATIONS, Objects[ext->u.fdo.child_count]))))
{ {
irp->IoStatus.Status = STATUS_NO_MEMORY; irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(irp, IO_NO_INCREMENT); IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
if ((child = ext->u.fdo.child_pdo)) for (i = 0, devices->Count = 0; i < ext->u.fdo.child_count; ++i)
{
devices->Objects[0] = ext->u.fdo.child_pdo;
call_fastcall_func1(ObfReferenceObject, ext->u.fdo.child_pdo);
devices->Count = 1;
}
else
{ {
devices->Count = 0; devices->Objects[i] = ext->u.fdo.child_pdos[i];
call_fastcall_func1(ObfReferenceObject, ext->u.fdo.child_pdos[i]);
devices->Count++;
} }
irp->IoStatus.Information = (ULONG_PTR)devices; irp->IoStatus.Information = (ULONG_PTR)devices;
...@@ -336,12 +340,13 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp) ...@@ -336,12 +340,13 @@ static NTSTATUS fdo_pnp(DEVICE_OBJECT *device, IRP *irp)
case IRP_MN_START_DEVICE: case IRP_MN_START_DEVICE:
status = minidriver->PNPDispatch( device, irp ); status = minidriver->PNPDispatch( device, irp );
if (!status) status = initialize_device( minidriver, device ); if (!status) status = initialize_device( minidriver, device );
if (!status) create_child( minidriver, device ); if (!status) status = create_child_pdos( minidriver, device );
return status; return status;
case IRP_MN_REMOVE_DEVICE: case IRP_MN_REMOVE_DEVICE:
status = minidriver->PNPDispatch( device, irp ); status = minidriver->PNPDispatch( device, irp );
HidP_FreeCollectionDescription( &ext->u.fdo.device_desc ); HidP_FreeCollectionDescription( &ext->u.fdo.device_desc );
free( ext->u.fdo.child_pdos );
IoDetachDevice( ext->u.fdo.hid_ext.NextDeviceObject ); IoDetachDevice( ext->u.fdo.hid_ext.NextDeviceObject );
IoDeleteDevice( device ); IoDeleteDevice( device );
return status; return status;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment