From 4027ccab600ed88d0c35e7952a37d6b5d3a5fbf6 Mon Sep 17 00:00:00 2001 From: David Welch Date: Mon, 30 Aug 1999 15:20:14 +0000 Subject: [PATCH] Correct keyboard bug with multiple readers svn path=/trunk/; revision=634 --- reactos/drivers/dd/keyboard/keyboard.c | 46 ++++++++++++++++++-------- reactos/ntoskrnl/rtl/list.c | 34 +++++++++++++++++-- 2 files changed, 64 insertions(+), 16 deletions(-) diff --git a/reactos/drivers/dd/keyboard/keyboard.c b/reactos/drivers/dd/keyboard/keyboard.c index b88ef5bde84..fedddc97dcd 100644 --- a/reactos/drivers/dd/keyboard/keyboard.c +++ b/reactos/drivers/dd/keyboard/keyboard.c @@ -4,7 +4,7 @@ * FILE: services/dd/keyboard/keyboard.c * PURPOSE: Keyboard driver * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com); + * Jason Filby (jasonfilby@yahoo.com) */ /* INCLUDES ****************************************************************/ @@ -36,6 +36,7 @@ static BYTE capsDown,numDown,scrollDown; static DWORD ctrlKeyState; static PKINTERRUPT KbdInterrupt; static KDPC KbdDpc; +static BOOLEAN AlreadyOpened = FALSE; /* * PURPOSE: Current irp being processed @@ -623,7 +624,15 @@ VOID KbdStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp) #endif DPRINT("KeyboardStartIo(DeviceObject %x Irp %x)\n",DeviceObject,Irp); - + + if (KeSynchronizeExecution(KbdInterrupt, KbdSynchronizeRoutine, Irp)) + { + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoStartNextPacket(DeviceObject, FALSE); + } + DPRINT("stk->Parameters.Read.Length %d\n",stk->Parameters.Read.Length); DPRINT("KeysRequired %d\n",KeysRequired); } @@ -635,26 +644,37 @@ NTSTATUS KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) DPRINT("DeviceObject %x\n",DeviceObject); DPRINT("Irp %x\n",Irp); - + + DPRINT("IRP_MJ_CREATE %d stk->MajorFunction %d\n", + IRP_MJ_CREATE, stk->MajorFunction); + DPRINT("AlreadyOpened %d\n",AlreadyOpened); + switch (stk->MajorFunction) { case IRP_MJ_CREATE: + if (AlreadyOpened == TRUE) + { + CHECKPOINT; +// Status = STATUS_UNSUCCESSFUL; + Status = STATUS_SUCCESS; + } + else + { + CHECKPOINT; + Status = STATUS_SUCCESS; + AlreadyOpened = TRUE; + } + break; + case IRP_MJ_CLOSE: Status = STATUS_SUCCESS; break; case IRP_MJ_READ: DPRINT("Handling Read request\n"); - if (KeSynchronizeExecution(KbdInterrupt,KbdSynchronizeRoutine,Irp)) - { - Status = STATUS_SUCCESS; - } - else - { - DPRINT("Queueing packet\n"); - IoStartPacket(DeviceObject,Irp,NULL,NULL); - Status = STATUS_PENDING; - } + DPRINT("Queueing packet\n"); + IoStartPacket(DeviceObject,Irp,NULL,NULL); + Status = STATUS_PENDING; break; default: diff --git a/reactos/ntoskrnl/rtl/list.c b/reactos/ntoskrnl/rtl/list.c index 1018f6ee451..32da5004ba0 100644 --- a/reactos/ntoskrnl/rtl/list.c +++ b/reactos/ntoskrnl/rtl/list.c @@ -16,6 +16,16 @@ /* FUNCTIONS *************************************************************/ +static BOOLEAN CheckEntry(PLIST_ENTRY ListEntry) +{ + assert(ListEntry!=NULL); + assert(ListEntry->Blink!=NULL); + assert(ListEntry->Blink->Flink!=NULL); + assert(ListEntry->Flink!=NULL); + assert(ListEntry->Flink->Blink!=NULL); + return(TRUE); +} + BOOLEAN IsListEmpty(PLIST_ENTRY ListHead) /* * FUNCTION: Determines if a list is empty @@ -31,12 +41,20 @@ VOID RemoveEntryList(PLIST_ENTRY ListEntry) { PLIST_ENTRY OldFlink; PLIST_ENTRY OldBlink; - DPRINT("RemoveEntryList(ListEntry %x)\n",ListEntry); + + DPRINT("RemoveEntryList(ListEntry %x)\n", ListEntry); + + assert(CheckEntry(ListEntry)); + OldFlink=ListEntry->Flink; OldBlink=ListEntry->Blink; - DPRINT("OldFlink %x OldBlink %x\n",OldFlink,OldBlink); + OldFlink->Blink=OldBlink; OldBlink->Flink=OldFlink; + + assert(CheckEntry(ListEntry)); + + DPRINT("RemoveEntryList()\n"); } PLIST_ENTRY RemoveTailList(PLIST_ENTRY ListHead) @@ -54,9 +72,19 @@ PLIST_ENTRY RemoveTailList(PLIST_ENTRY ListHead) PLIST_ENTRY RemoveHeadList(PLIST_ENTRY ListHead) { - PLIST_ENTRY Old = ListHead->Flink; + PLIST_ENTRY Old; + DPRINT("RemoveHeadList(ListHead %x)\n",ListHead); + + assert(CheckEntry(ListHead)); + + Old = ListHead->Flink; RemoveEntryList(ListHead->Flink); + + assert(CheckEntry(ListHead)); + + DPRINT("RemoveHeadList()\n"); + return(Old); }