return ForwardIrpAndForget(DeviceObject, Irp);
/* FIXME: open all associated Port devices */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
return ForwardIrpAndForget(DeviceObject, Irp);
/* FIXME: close all associated Port devices */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
return ForwardIrpAndForget(DeviceObject, Irp);
/* FIXME: cleanup all associated Port devices */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
default:
DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n",
IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
+ ASSERT(FALSE);
break;
}
OUT PDEVICE_OBJECT *ClassDO OPTIONAL)
{
PCLASS_DRIVER_EXTENSION DriverExtension;
- UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\Keyboard");
ULONG DeviceId = 0;
ULONG PrefixLength;
UNICODE_STRING DeviceNameU;
DeviceExtension->ReadIsPending = FALSE;
DeviceExtension->InputCount = 0;
DeviceExtension->PortData = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->DataQueueSize * sizeof(KEYBOARD_INPUT_DATA));
- Fdo->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO;
+ Fdo->Flags |= DO_POWER_PAGABLE;
+ Fdo->Flags |= DO_BUFFERED_IO; /* FIXME: Why is it needed for 1st stage setup? */
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
/* Add entry entry to HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\[DeviceBaseName] */
DriverExtension->RegistryPath.Buffer,
DriverExtension->RegistryPath.MaximumLength);
- /* HACK: 1st stage setup needs a keyboard to open it in user-mode
- * Create a link to user space... */
- IoCreateSymbolicLink(&SymbolicLinkName, &DeviceNameU);
-
ExFreePool(DeviceNameU.Buffer);
if (ClassDO)
return STATUS_SUCCESS;
}
+static NTSTATUS
+FillOneEntry(
+ IN PDEVICE_OBJECT ClassDeviceObject,
+ IN PIRP Irp,
+ IN PKEYBOARD_INPUT_DATA DataStart)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (ClassDeviceObject->Flags & DO_BUFFERED_IO)
+ {
+ RtlCopyMemory(
+ Irp->AssociatedIrp.SystemBuffer,
+ DataStart,
+ sizeof(KEYBOARD_INPUT_DATA));
+ }
+ else if (ClassDeviceObject->Flags & DO_DIRECT_IO)
+ {
+ PVOID DestAddress = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
+ if (DestAddress)
+ {
+ RtlCopyMemory(
+ DestAddress,
+ DataStart,
+ sizeof(KEYBOARD_INPUT_DATA));
+ }
+ else
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ else
+ {
+ _SEH_TRY
+ {
+ RtlCopyMemory(
+ Irp->UserBuffer,
+ DataStart,
+ sizeof(KEYBOARD_INPUT_DATA));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+
+ return Status;
+}
+
static BOOLEAN
ClassCallback(
IN PDEVICE_OBJECT ClassDeviceObject,
*/
if (ClassDeviceExtension->ReadIsPending == TRUE && InputCount)
{
+ NTSTATUS Status;
+
Irp = ClassDeviceObject->CurrentIrp;
ClassDeviceObject->CurrentIrp = NULL;
Stack = IoGetCurrentIrpStackLocation(Irp);
/* A read request is waiting for input, so go straight to it */
- /* FIXME: use SEH */
- RtlCopyMemory(
- Irp->MdlAddress ? MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority) : Irp->AssociatedIrp.SystemBuffer,
- DataStart,
- sizeof(KEYBOARD_INPUT_DATA));
+ Status = FillOneEntry(
+ ClassDeviceObject,
+ Irp,
+ DataStart);
- /* Go to next packet and complete this request with STATUS_SUCCESS */
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA);
- Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA);
+ if (NT_SUCCESS(Status))
+ {
+ /* Go to next packet and complete this request with STATUS_SUCCESS */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA);
+ Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA);
- ClassDeviceExtension->ReadIsPending = FALSE;
+ ClassDeviceExtension->ReadIsPending = FALSE;
- /* Skip the packet we just sent away */
- DataStart++;
- (*ConsumedCount)++;
- InputCount--;
+ /* Skip the packet we just sent away */
+ DataStart++;
+ (*ConsumedCount)++;
+ InputCount--;
+ }
}
/* If we have data from the port driver and a higher service to send the data to */
if (InputCount != 0)
{
if (ClassDeviceExtension->InputCount + InputCount > ClassDeviceExtension->DriverExtension->DataQueueSize)
+ {
+ /*
+ * We're exceeding the buffer, and data will be thrown away...
+ * FIXME: What could we do, as we are at DISPATCH_LEVEL?
+ */
ReadSize = ClassDeviceExtension->DriverExtension->DataQueueSize - ClassDeviceExtension->InputCount;
+ }
else
ReadSize = InputCount;
- /*
- * FIXME: If we exceed the buffer, data gets thrown away.. better
- * solution?
- */
-
/*
* Move the input data from the port data queue to our class data
* queue.
IN PDEVICE_OBJECT Pdo)
{
PCLASS_DRIVER_EXTENSION DriverExtension;
- PDEVICE_OBJECT Fdo;
- PPORT_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_OBJECT Fdo = NULL;
+ PPORT_DEVICE_EXTENSION DeviceExtension = NULL;
NTSTATUS Status;
DPRINT("ClassAddDevice called. Pdo = 0x%p\n", Pdo);
sizeof(PORT_DEVICE_EXTENSION),
NULL,
Pdo->DeviceType,
- FILE_DEVICE_SECURE_OPEN,
+ Pdo->Characteristics & FILE_DEVICE_SECURE_OPEN ? FILE_DEVICE_SECURE_OPEN : 0,
TRUE,
&Fdo);
if (!NT_SUCCESS(Status))
{
DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
- return Status;
+ goto cleanup;
}
DeviceExtension = (PPORT_DEVICE_EXTENSION)Fdo->DeviceExtension;
if (!NT_SUCCESS(Status))
{
DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
- IoDeleteDevice(Fdo);
- return Status;
+ goto cleanup;
}
if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
Fdo->Flags |= DO_POWER_PAGABLE;
if (DeviceExtension->LowerDevice->Flags & DO_BUFFERED_IO)
Fdo->Flags |= DO_BUFFERED_IO;
+ if (DeviceExtension->LowerDevice->Flags & DO_DIRECT_IO)
+ Fdo->Flags |= DO_DIRECT_IO;
if (DriverExtension->ConnectMultiplePorts)
- Status = ConnectPortDriver(Fdo, DriverExtension->MainClassDeviceObject);
+ DeviceExtension->ClassDO = DriverExtension->MainClassDeviceObject;
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))
{
DPRINT("ConnectPortDriver() failed with status 0x%08lx\n", Status);
- IoDetachDevice(DeviceExtension->LowerDevice);
- ObDereferenceObject(Fdo);
- IoDeleteDevice(Fdo);
- return Status;
+ goto cleanup;
}
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
&GUID_DEVINTERFACE_KEYBOARD,
NULL,
&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);
- return Status;
+ goto cleanup;
}
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
if (DeviceExtension->InputCount > 0)
{
KIRQL oldIrql;
+ NTSTATUS Status;
KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
- DPRINT("Mdl: %p, UserBuffer: %p, InputCount: %lu\n",
- Irp->MdlAddress,
- Irp->UserBuffer,
- DeviceExtension->InputCount);
+ Status = FillOneEntry(
+ DeviceObject,
+ Irp,
+ DeviceExtension->PortData - DeviceExtension->InputCount);
- /* FIXME: use SEH */
- RtlCopyMemory(
- Irp->AssociatedIrp.SystemBuffer,
- DeviceExtension->PortData - DeviceExtension->InputCount,
- sizeof(KEYBOARD_INPUT_DATA));
-
- if (DeviceExtension->InputCount > 1)
+ if (NT_SUCCESS(Status))
{
- RtlMoveMemory(
- DeviceExtension->PortData - DeviceExtension->InputCount,
- DeviceExtension->PortData - DeviceExtension->InputCount + 1,
- (DeviceExtension->InputCount - 1) * sizeof(KEYBOARD_INPUT_DATA));
+ if (DeviceExtension->InputCount > 1)
+ {
+ RtlMoveMemory(
+ DeviceExtension->PortData - DeviceExtension->InputCount,
+ DeviceExtension->PortData - DeviceExtension->InputCount + 1,
+ (DeviceExtension->InputCount - 1) * sizeof(KEYBOARD_INPUT_DATA));
+ }
+
+ DeviceExtension->PortData--;
+ DeviceExtension->InputCount--;
+ DeviceExtension->ReadIsPending = FALSE;
+
+ Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA);
+ Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA);
}
- DeviceExtension->PortData--;
- DeviceExtension->InputCount--;
- DeviceExtension->ReadIsPending = FALSE;
-
- /* Go to next packet and complete this request with STATUS_SUCCESS */
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = sizeof(KEYBOARD_INPUT_DATA);
- Stack->Parameters.Read.Length = sizeof(KEYBOARD_INPUT_DATA);
+
+ /* Go to next packet and complete this request */
+ Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_KEYBOARD_INCREMENT);
IoStartNextPacket(DeviceObject, FALSE);
DPRINT("IoGetDeviceObjectPointer(%wZ) failed with status 0x%08lx\n", Status);
continue;
}
+ DPRINT("Legacy driver found: %wZ\n", &PortDeviceObject->DriverObject->DriverName);
Status = ClassAddDevice(DriverObject, PortDeviceObject);
if (!NT_SUCCESS(Status))