kbdclass and mouclass:

- Better synchronization of code between kbdclass and mouclass
- Better cleanup in ClassAddDevice in case of error
- Better support of legacy devices
kbdclass only:
- Send IOCTLs to lower device

svn path=/trunk/; revision=21599
This commit is contained in:
Hervé Poussineau 2006-04-16 07:17:34 +00:00
parent 286a4f2f82
commit 31dc05f5f1
4 changed files with 94 additions and 52 deletions

View file

@ -107,7 +107,6 @@ ClassDeviceControl(
switch (IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode) switch (IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode)
{ {
#if 0
case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
case IOCTL_KEYBOARD_QUERY_INDICATORS: case IOCTL_KEYBOARD_QUERY_INDICATORS:
@ -146,10 +145,10 @@ ClassDeviceControl(
} }
break; break;
} }
#endif
default: default:
DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n", DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n",
IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode); IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
ASSERT(FALSE);
break; break;
} }
@ -536,8 +535,8 @@ ClassAddDevice(
IN PDEVICE_OBJECT Pdo) IN PDEVICE_OBJECT Pdo)
{ {
PCLASS_DRIVER_EXTENSION DriverExtension; PCLASS_DRIVER_EXTENSION DriverExtension;
PDEVICE_OBJECT Fdo; PDEVICE_OBJECT Fdo = NULL;
PPORT_DEVICE_EXTENSION DeviceExtension; PPORT_DEVICE_EXTENSION DeviceExtension = NULL;
NTSTATUS Status; NTSTATUS Status;
DPRINT("ClassAddDevice called. Pdo = 0x%p\n", Pdo); DPRINT("ClassAddDevice called. Pdo = 0x%p\n", Pdo);
@ -561,7 +560,7 @@ ClassAddDevice(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
return Status; goto cleanup;
} }
DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension; DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension;
@ -573,8 +572,7 @@ ClassAddDevice(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status); DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
IoDeleteDevice(Fdo); goto cleanup;
return Status;
} }
if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE) if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
Fdo->Flags |= DO_POWER_PAGABLE; Fdo->Flags |= DO_POWER_PAGABLE;
@ -582,16 +580,25 @@ ClassAddDevice(
Fdo->Flags |= DO_BUFFERED_IO; Fdo->Flags |= DO_BUFFERED_IO;
if (DriverExtension->ConnectMultiplePorts) if (DriverExtension->ConnectMultiplePorts)
Status = ConnectPortDriver(Fdo, DriverExtension->MainClassDeviceObject); DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject;
else else
Status = ConnectPortDriver(Fdo, Fdo); {
/* We need a new class device object for this Fdo */
Status = CreateClassDeviceObject(
DriverObject,
&DeviceExtension->ClassDO);
if (!NT_SUCCESS(Status))
{
DPRINT("CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
goto cleanup;
}
}
Status = ConnectPortDriver(Fdo, DeviceExtension->ClassDO);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status); DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
IoDetachDevice(DeviceExtension->LowerDevice);
ObDereferenceObject(Fdo); ObDereferenceObject(Fdo);
IoDeleteDevice(Fdo); goto cleanup;
return Status;
} }
Fdo->Flags &= ~DO_DEVICE_INITIALIZING; Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
@ -601,13 +608,35 @@ ClassAddDevice(
&GUID_DEVINTERFACE_KEYBOARD, &GUID_DEVINTERFACE_KEYBOARD,
NULL, NULL,
&DeviceExtension->InterfaceName); &DeviceExtension->InterfaceName);
if (!NT_SUCCESS(Status)) if (Status == STATUS_INVALID_PARAMETER_1)
{
/* The Pdo was a strange one ; maybe it is a legacy device.
* Ignore the error. */
return STATUS_SUCCESS;
}
else if (!NT_SUCCESS(Status))
{ {
DPRINT("IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status); DPRINT("IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
return Status; goto cleanup;
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
cleanup:
if (DeviceExtension)
{
if (DeviceExtension->LowerDevice)
IoDetachDevice(DeviceExtension->LowerDevice);
if (DriverExtension->ConnectMultiplePorts && DeviceExtension->ClassDO)
{
PCLASS_DEVICE_EXTENSION ClassDeviceExtension;
ClassDeviceExtension = (PCLASS_DEVICE_EXTENSION)DeviceExtension->ClassDO->DeviceExtension;
ExFreePool(ClassDeviceExtension->PortData);
}
}
if (Fdo)
IoDeleteDevice(Fdo);
return Status;
} }
static VOID NTAPI static VOID NTAPI
@ -748,34 +777,13 @@ SearchForLegacyDrivers(
DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status); DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status);
continue; continue;
} }
DPRINT("Legacy driver found: %wZ\n", &PortDeviceObject->DriverObject->DriverName);
/* Connect the port device object */ Status = ClassAddDevice(DriverObject, PortDeviceObject);
if (DriverExtension->ConnectMultiplePorts) if (!NT_SUCCESS(Status))
{ {
Status = ConnectPortDriver(PortDeviceObject, DriverExtension->MainClassDeviceObject); /* FIXME: Log the error */
if (!NT_SUCCESS(Status)) DPRINT("ClassAddDevice() failed with status 0x%08lx\n", Status);
{
/* FIXME: Log the error */
DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
}
}
else
{
PDEVICE_OBJECT ClassDO;
Status = CreateClassDeviceObject(DriverObject, &ClassDO);
if (!NT_SUCCESS(Status))
{
/* FIXME: Log the error */
DPRINT("CreatePointerClassDeviceObject() failed with status 0x%08lx\n", Status);
continue;
}
Status = ConnectPortDriver(PortDeviceObject, ClassDO);
if (!NT_SUCCESS(Status))
{
/* FIXME: Log the error */
DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
IoDeleteDevice(ClassDO);
}
} }
} }
if (Status == STATUS_NO_MORE_ENTRIES) if (Status == STATUS_NO_MORE_ENTRIES)

View file

@ -39,6 +39,7 @@ typedef struct _PORT_DEVICE_EXTENSION
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PORT_DEVICE_STATE PnpState; PORT_DEVICE_STATE PnpState;
PDEVICE_OBJECT LowerDevice; PDEVICE_OBJECT LowerDevice;
PDEVICE_OBJECT ClassDO;
UNICODE_STRING InterfaceName; UNICODE_STRING InterfaceName;
} PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION; } PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION;

View file

@ -125,6 +125,7 @@ ClassDeviceControl(
default: default:
DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n", DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n",
IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode); IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
ASSERT(FALSE);
break; break;
} }
@ -506,8 +507,8 @@ ClassAddDevice(
IN PDEVICE_OBJECT Pdo) IN PDEVICE_OBJECT Pdo)
{ {
PCLASS_DRIVER_EXTENSION DriverExtension; PCLASS_DRIVER_EXTENSION DriverExtension;
PDEVICE_OBJECT Fdo; PDEVICE_OBJECT Fdo = NULL;
PPORT_DEVICE_EXTENSION DeviceExtension; PPORT_DEVICE_EXTENSION DeviceExtension = NULL;
NTSTATUS Status; NTSTATUS Status;
DPRINT("ClassAddDevice called. Pdo = 0x%p\n", Pdo); DPRINT("ClassAddDevice called. Pdo = 0x%p\n", Pdo);
@ -531,7 +532,7 @@ ClassAddDevice(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
return Status; goto cleanup;
} }
DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension; DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension;
@ -543,8 +544,7 @@ ClassAddDevice(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status); DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
IoDeleteDevice(Fdo); goto cleanup;
return Status;
} }
if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE) if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
Fdo->Flags |= DO_POWER_PAGABLE; Fdo->Flags |= DO_POWER_PAGABLE;
@ -552,16 +552,25 @@ ClassAddDevice(
Fdo->Flags |= DO_BUFFERED_IO; Fdo->Flags |= DO_BUFFERED_IO;
if (DriverExtension->ConnectMultiplePorts) if (DriverExtension->ConnectMultiplePorts)
Status = ConnectPortDriver(Fdo, DriverExtension->MainClassDeviceObject); DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject;
else else
Status = ConnectPortDriver(Fdo, Fdo); {
/* We need a new class device object for this Fdo */
Status = CreateClassDeviceObject(
DriverObject,
&DeviceExtension->ClassDO);
if (!NT_SUCCESS(Status))
{
DPRINT("CreateClassDeviceObject() failed with status 0x%08lx\n", Status);
goto cleanup;
}
}
Status = ConnectPortDriver(Fdo, DeviceExtension->ClassDO);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status); DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
IoDetachDevice(DeviceExtension->LowerDevice);
ObDereferenceObject(Fdo); ObDereferenceObject(Fdo);
IoDeleteDevice(Fdo); goto cleanup;
return Status;
} }
Fdo->Flags &= ~DO_DEVICE_INITIALIZING; Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
@ -571,13 +580,35 @@ ClassAddDevice(
&GUID_DEVINTERFACE_MOUSE, &GUID_DEVINTERFACE_MOUSE,
NULL, NULL,
&DeviceExtension->InterfaceName); &DeviceExtension->InterfaceName);
if (!NT_SUCCESS(Status)) if (Status == STATUS_INVALID_PARAMETER_1)
{
/* The Pdo was a strange one ; maybe it is a legacy device.
* Ignore the error. */
return STATUS_SUCCESS;
}
else if (!NT_SUCCESS(Status))
{ {
DPRINT("IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status); DPRINT("IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
return Status; goto cleanup;
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
cleanup:
if (DeviceExtension)
{
if (DeviceExtension->LowerDevice)
IoDetachDevice(DeviceExtension->LowerDevice);
if (DriverExtension->ConnectMultiplePorts && DeviceExtension->ClassDO)
{
PCLASS_DEVICE_EXTENSION ClassDeviceExtension;
ClassDeviceExtension = (PCLASS_DEVICE_EXTENSION)DeviceExtension->ClassDO->DeviceExtension;
ExFreePool(ClassDeviceExtension->PortData);
}
}
if (Fdo)
IoDeleteDevice(Fdo);
return Status;
} }
static VOID NTAPI static VOID NTAPI
@ -718,6 +749,7 @@ SearchForLegacyDrivers(
DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status); DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status);
continue; continue;
} }
DPRINT("Legacy driver found: %wZ\n", &PortDeviceObject->DriverObject->DriverName);
Status = ClassAddDevice(DriverObject, PortDeviceObject); Status = ClassAddDevice(DriverObject, PortDeviceObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))

View file

@ -39,6 +39,7 @@ typedef struct _PORT_DEVICE_EXTENSION
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PORT_DEVICE_STATE PnpState; PORT_DEVICE_STATE PnpState;
PDEVICE_OBJECT LowerDevice; PDEVICE_OBJECT LowerDevice;
PDEVICE_OBJECT ClassDO;
UNICODE_STRING InterfaceName; UNICODE_STRING InterfaceName;
} PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION; } PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION;