ReactOS  0.4.13-dev-100-gc8611ae
keyboard.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: drivers/input/i8042prt/keyboard.c
5  * PURPOSE: Keyboard specific functions
6  * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com)
7  Copyright Jason Filby (jasonfilby@yahoo.com)
8  Copyright Martijn Vernooij (o112w8r02@sneakemail.com)
9  Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
10  */
11 
12 /* INCLUDES ****************************************************************/
13 
14 #include "i8042prt.h"
15 
16 #include <poclass.h>
17 #include <ndk/kdfuncs.h>
18 
19 #include <debug.h>
20 
21 /* GLOBALS *******************************************************************/
22 
23 static IO_WORKITEM_ROUTINE i8042PowerWorkItem;
24 static KDEFERRED_ROUTINE i8042KbdDpcRoutine;
25 
26 /* This structure starts with the same layout as KEYBOARD_INDICATOR_TRANSLATION */
31 
33  {0x3A, KEYBOARD_CAPS_LOCK_ON},
34  {0x45, KEYBOARD_NUM_LOCK_ON},
35  {0x46, KEYBOARD_SCROLL_LOCK_ON}}};
36 
37 /* FUNCTIONS *****************************************************************/
38 
39 /*
40  * These functions are callbacks for filter driver custom interrupt
41  * service routines.
42  */
43 /*static VOID NTAPI
44 i8042KbdIsrWritePort(
45  IN PVOID Context,
46  IN UCHAR Value)
47 {
48  PI8042_KEYBOARD_EXTENSION DeviceExtension;
49 
50  DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context;
51 
52  if (DeviceExtension->KeyboardHook.IsrWritePort)
53  {
54  DeviceExtension->KeyboardHook.IsrWritePort(
55  DeviceExtension->KeyboardHook.CallContext,
56  Value);
57  }
58  else
59  i8042IsrWritePort(Context, Value, 0);
60 }*/
61 
62 static VOID NTAPI
65 {
66  PI8042_KEYBOARD_EXTENSION DeviceExtension;
67 
68  DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context;
69 
70  DeviceExtension->KeyComplete = TRUE;
71  DeviceExtension->KeysInBuffer++;
72  if (DeviceExtension->KeysInBuffer > DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize)
73  {
74  WARN_(I8042PRT, "Keyboard buffer overflow\n");
75  DeviceExtension->KeysInBuffer--;
76  }
77 
78  TRACE_(I8042PRT, "Irq completes key\n");
79  KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL);
80 }
81 
82 /*
83  * These functions are callbacks for filter driver custom
84  * initialization routines.
85  */
89  IN UCHAR Value,
90  IN BOOLEAN WaitForAck)
91 {
92  return i8042SynchWritePort(
94  0,
95  Value,
96  WaitForAck);
97 }
98 
99 /*
100  * Process the keyboard internal device requests
101  */
102 VOID NTAPI
105  IN PIRP Irp)
106 {
107  PIO_STACK_LOCATION Stack;
108  PI8042_KEYBOARD_EXTENSION DeviceExtension;
109  PPORT_DEVICE_EXTENSION PortDeviceExtension;
110 
113  PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
114 
115  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
116  {
118  {
119  TRACE_(I8042PRT, "IOCTL_KEYBOARD_SET_INDICATORS\n");
120  INFO_(I8042PRT, "Leds: {%s%s%s }\n",
121  DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON ? " CAPSLOCK" : "",
122  DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON ? " NUMLOCK" : "",
123  DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON ? " SCROLLLOCK" : "");
124 
125  PortDeviceExtension->PacketBuffer[0] = KBD_CMD_SET_LEDS;
126  PortDeviceExtension->PacketBuffer[1] = 0;
127  if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON)
128  PortDeviceExtension->PacketBuffer[1] |= KBD_LED_CAPS;
129 
130  if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON)
131  PortDeviceExtension->PacketBuffer[1] |= KBD_LED_NUM;
132 
133  if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON)
134  PortDeviceExtension->PacketBuffer[1] |= KBD_LED_SCROLL;
135 
137  PortDeviceExtension,
138  &DeviceExtension->Common,
139  PortDeviceExtension->PacketBuffer,
140  2,
141  Irp);
142  break;
143  }
144  default:
145  {
146  ERR_(I8042PRT, "Unknown ioctl code 0x%lx\n",
147  Stack->Parameters.DeviceIoControl.IoControlCode);
148  ASSERT(FALSE);
149  }
150  }
151 }
152 
153 static VOID
155  IN PPORT_DEVICE_EXTENSION DeviceExtension)
156 {
157  BOOLEAN FinishIrp = FALSE;
158  KIRQL Irql;
159  NTSTATUS Result = STATUS_INTERNAL_ERROR; /* Shouldn't happen */
160 
161  /* If the interrupt happens before this is setup, the key
162  * was already in the buffer. Too bad! */
163  if (!DeviceExtension->HighestDIRQLInterrupt)
164  return;
165 
166  Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt);
167 
168  if (DeviceExtension->Packet.State == Idle
169  && DeviceExtension->PacketComplete)
170  {
171  FinishIrp = TRUE;
172  Result = DeviceExtension->PacketResult;
173  DeviceExtension->PacketComplete = FALSE;
174  }
175 
176  KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql);
177 
178  if (!FinishIrp)
179  return;
180 
181  if (DeviceExtension->CurrentIrp)
182  {
183  DeviceExtension->CurrentIrp->IoStatus.Status = Result;
184  IoCompleteRequest(DeviceExtension->CurrentIrp, IO_NO_INCREMENT);
185  IoStartNextPacket(DeviceExtension->CurrentIrpDevice, FALSE);
186  DeviceExtension->CurrentIrp = NULL;
187  DeviceExtension->CurrentIrpDevice = NULL;
188  }
189 }
190 
191 static VOID NTAPI
194  IN PVOID Context)
195 {
196  PI8042_KEYBOARD_EXTENSION DeviceExtension;
197  PIRP WaitingIrp;
199 
201 
203  DeviceExtension = Context;
204 
205  /* See http://blogs.msdn.com/doronh/archive/2006/09/08/746961.aspx */
206 
207  /* Register GUID_DEVICE_SYS_BUTTON interface and report capability */
208  if (DeviceExtension->NewCaps != DeviceExtension->ReportedCaps)
209  {
210  WaitingIrp = InterlockedExchangePointer((PVOID)&DeviceExtension->PowerIrp, NULL);
211  if (WaitingIrp)
212  {
213  /* Cancel the current power irp, as capability changed */
214  WaitingIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
215  WaitingIrp->IoStatus.Information = sizeof(ULONG);
216  IoCompleteRequest(WaitingIrp, IO_NO_INCREMENT);
217  }
218 
219  if (DeviceExtension->PowerInterfaceName.MaximumLength == 0)
220  {
221  /* We have never registered this interface ; do it */
223  DeviceExtension->Common.Pdo,
224  &GUID_DEVICE_SYS_BUTTON,
225  NULL,
226  &DeviceExtension->PowerInterfaceName);
227  if (!NT_SUCCESS(Status))
228  {
229  /* We can't do more yet, ignore the keypress... */
230  WARN_(I8042PRT, "IoRegisterDeviceInterface(GUID_DEVICE_SYS_BUTTON) failed with status 0x%08lx\n",
231  Status);
232  DeviceExtension->PowerInterfaceName.MaximumLength = 0;
233  return;
234  }
235  }
236  else
237  {
238  /* Disable the interface. Once activated again, capabilities would be asked again */
240  &DeviceExtension->PowerInterfaceName,
241  FALSE);
242  if (!NT_SUCCESS(Status))
243  {
244  /* Ignore the key press... */
245  WARN_(I8042PRT, "Disabling interface %wZ failed with status 0x%08lx\n",
246  &DeviceExtension->PowerInterfaceName, Status);
247  return;
248  }
249  }
250  /* Enable the interface. This leads to receiving a IOCTL_GET_SYS_BUTTON_CAPS,
251  * so we can report new capability */
253  &DeviceExtension->PowerInterfaceName,
254  TRUE);
255  if (!NT_SUCCESS(Status))
256  {
257  /* Ignore the key press... */
258  WARN_(I8042PRT, "Enabling interface %wZ failed with status 0x%08lx\n",
259  &DeviceExtension->PowerInterfaceName, Status);
260  return;
261  }
262  }
263 
264  /* Directly complete the IOCTL_GET_SYS_BUTTON_EVENT Irp (if any) */
265  WaitingIrp = InterlockedExchangePointer((PVOID)&DeviceExtension->PowerIrp, NULL);
266  if (WaitingIrp)
267  {
268  PULONG pEvent = (PULONG)WaitingIrp->AssociatedIrp.SystemBuffer;
269 
270  WaitingIrp->IoStatus.Status = STATUS_SUCCESS;
271  WaitingIrp->IoStatus.Information = sizeof(ULONG);
272  *pEvent = InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, 0);
273  IoCompleteRequest(WaitingIrp, IO_NO_INCREMENT);
274  }
275 }
276 
277 /* Return TRUE if it was a power key */
278 static BOOLEAN
280  IN PI8042_KEYBOARD_EXTENSION DeviceExtension)
281 {
282  PKEYBOARD_INPUT_DATA InputData;
283  ULONG KeyPress;
284 
285  InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer - 1;
286  if (!(InputData->Flags & KEY_E0))
287  return FALSE;
288 
289  switch (InputData->MakeCode)
290  {
291  case KEYBOARD_POWER_CODE:
292  KeyPress = SYS_BUTTON_POWER;
293  break;
294  case KEYBOARD_SLEEP_CODE:
295  KeyPress = SYS_BUTTON_SLEEP;
296  break;
297  case KEYBOARD_WAKE_CODE:
298  KeyPress = SYS_BUTTON_WAKE;
299  break;
300  default:
301  return FALSE;
302  }
303 
304  if (InputData->Flags & KEY_BREAK)
305  /* We already took care of the key press */
306  return TRUE;
307 
308  /* Our work can only be done at passive level, so use a workitem */
309  DeviceExtension->NewCaps |= KeyPress;
310  InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, KeyPress);
312  DeviceExtension->PowerWorkItem,
315  DeviceExtension);
316  return TRUE;
317 }
318 
319 static VOID NTAPI
321  IN PKDPC Dpc,
325 {
326  PI8042_KEYBOARD_EXTENSION DeviceExtension;
327  PPORT_DEVICE_EXTENSION PortDeviceExtension;
328  ULONG KeysTransferred = 0;
329  ULONG KeysInBufferCopy;
330  KIRQL Irql;
331 
335 
337  DeviceExtension = DeferredContext;
338  PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
339 
340  if (HandlePowerKeys(DeviceExtension))
341  {
342  DeviceExtension->KeyComplete = FALSE;
343  return;
344  }
345 
346  i8042PacketDpc(PortDeviceExtension);
347  if (!DeviceExtension->KeyComplete)
348  return;
349  /* We got the interrupt as it was being enabled, too bad */
350  if (!PortDeviceExtension->HighestDIRQLInterrupt)
351  return;
352 
353  Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt);
354 
355  DeviceExtension->KeyComplete = FALSE;
356  KeysInBufferCopy = DeviceExtension->KeysInBuffer;
357 
359 
360  TRACE_(I8042PRT, "Send a key\n");
361 
362  if (!DeviceExtension->KeyboardData.ClassService)
363  return;
364 
365  INFO_(I8042PRT, "Sending %lu key(s)\n", KeysInBufferCopy);
367  DeviceExtension->KeyboardData.ClassDeviceObject,
368  DeviceExtension->KeyboardBuffer,
369  DeviceExtension->KeyboardBuffer + KeysInBufferCopy,
370  &KeysTransferred);
371 
372  /* Validate that the callback didn't change the Irql. */
374 
375  Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt);
376  DeviceExtension->KeysInBuffer -= KeysTransferred;
378 }
379 
380 /*
381  * Runs the keyboard IOCTL dispatch.
382  */
386  IN PIRP Irp)
387 {
388  PIO_STACK_LOCATION Stack;
389  PI8042_KEYBOARD_EXTENSION DeviceExtension;
391 
393  Irp->IoStatus.Information = 0;
395 
396  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
397  {
399  {
400  /* Part of GUID_DEVICE_SYS_BUTTON interface */
401  PULONG pCaps;
402  TRACE_(I8042PRT, "IOCTL_GET_SYS_BUTTON_CAPS\n");
403 
404  if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG))
406  else
407  {
408  pCaps = (PULONG)Irp->AssociatedIrp.SystemBuffer;
409  *pCaps = DeviceExtension->NewCaps;
410  DeviceExtension->ReportedCaps = DeviceExtension->NewCaps;
411  Irp->IoStatus.Information = sizeof(ULONG);
413  }
414  break;
415  }
417  {
418  /* Part of GUID_DEVICE_SYS_BUTTON interface */
419  PIRP WaitingIrp;
420  TRACE_(I8042PRT, "IOCTL_GET_SYS_BUTTON_EVENT\n");
421 
422  if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG))
424  else
425  {
427  (PVOID)&DeviceExtension->PowerIrp,
428  Irp,
429  NULL);
430  /* Check if an Irp is already pending */
431  if (WaitingIrp)
432  {
433  /* Unable to have a 2nd pending IRP for this IOCTL */
434  WARN_(I8042PRT, "Unable to pend a second IRP for IOCTL_GET_SYS_BUTTON_EVENT\n");
436  Irp->IoStatus.Status = Status;
438  }
439  else
440  {
441  ULONG PowerKey;
442  PowerKey = InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, 0);
443  if (PowerKey != 0)
444  {
446  *(PULONG)Irp->AssociatedIrp.SystemBuffer = PowerKey;
448  Irp->IoStatus.Status = Status;
449  Irp->IoStatus.Information = sizeof(ULONG);
451  }
452  else
453  {
454  TRACE_(I8042PRT, "Pending IOCTL_GET_SYS_BUTTON_EVENT\n");
456  Irp->IoStatus.Status = Status;
458  }
459  }
460  return Status;
461  }
462  break;
463  }
464  default:
465  {
466  ERR_(I8042PRT, "IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
467  Stack->Parameters.DeviceIoControl.IoControlCode);
468  ASSERT(FALSE);
470  }
471  }
472 
473  if (Status != STATUS_PENDING)
474  {
475  Irp->IoStatus.Status = Status;
477  }
478 
479  return Status;
480 }
481 
482 VOID
483 NTAPI
485  PI8042_KEYBOARD_EXTENSION DeviceExtension)
486 {
487  PPORT_DEVICE_EXTENSION PortDeviceExtension;
489  PKEYBOARD_ATTRIBUTES KeyboardAttributes;
490 
491  PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
492  Settings = &PortDeviceExtension->Settings;
493 
494  KeyboardAttributes = &DeviceExtension->KeyboardAttributes;
495 
496  KeyboardAttributes->KeyboardIdentifier.Type = (UCHAR)Settings->OverrideKeyboardType;
497  KeyboardAttributes->KeyboardIdentifier.Subtype = (UCHAR)Settings->OverrideKeyboardSubtype;
498  KeyboardAttributes->NumberOfFunctionKeys = 4;
499  KeyboardAttributes->NumberOfIndicators = 3;
500  KeyboardAttributes->NumberOfKeysTotal = 101;
501  KeyboardAttributes->InputDataQueueLength = Settings->KeyboardDataQueueSize;
502  KeyboardAttributes->KeyRepeatMinimum.UnitId = 0;
503  KeyboardAttributes->KeyRepeatMinimum.Rate = (USHORT)Settings->SampleRate;
504  KeyboardAttributes->KeyRepeatMinimum.Delay = 0;
505  KeyboardAttributes->KeyRepeatMinimum.UnitId = 0;
506  KeyboardAttributes->KeyRepeatMinimum.Rate = (USHORT)Settings->SampleRate;
507  KeyboardAttributes->KeyRepeatMinimum.Delay = 0;
508 }
509 
510 /*
511  * Runs the keyboard IOCTL_INTERNAL dispatch.
512  */
516  IN PIRP Irp)
517 {
518  PIO_STACK_LOCATION Stack;
519  PI8042_KEYBOARD_EXTENSION DeviceExtension;
521 
523  Irp->IoStatus.Information = 0;
525 
526  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
527  {
529  {
530  SIZE_T Size;
531  PIO_WORKITEM WorkItem = NULL;
532  PI8042_HOOK_WORKITEM WorkItemData = NULL;
533 
534  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n");
535  if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA))
536  {
538  goto cleanup;
539  }
540 
541  DeviceExtension->KeyboardData =
542  *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
543 
544  /* Send IOCTL_INTERNAL_I8042_HOOK_KEYBOARD to device stack */
545  WorkItem = IoAllocateWorkItem(DeviceObject);
546  if (!WorkItem)
547  {
548  WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
550  goto cleanup;
551  }
552  WorkItemData = ExAllocatePoolWithTag(
553  NonPagedPool,
554  sizeof(I8042_HOOK_WORKITEM),
555  I8042PRT_TAG);
556  if (!WorkItemData)
557  {
558  WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
560  goto cleanup;
561  }
562  WorkItemData->WorkItem = WorkItem;
563  WorkItemData->Irp = Irp;
564 
565  /* Initialize extension */
566  DeviceExtension->Common.Type = Keyboard;
567  Size = DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA);
568  DeviceExtension->KeyboardBuffer = ExAllocatePoolWithTag(
569  NonPagedPool,
570  Size,
571  I8042PRT_TAG);
572  if (!DeviceExtension->KeyboardBuffer)
573  {
574  WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n");
576  goto cleanup;
577  }
578  RtlZeroMemory(DeviceExtension->KeyboardBuffer, Size);
580  &DeviceExtension->DpcKeyboard,
582  DeviceExtension);
583  DeviceExtension->PowerWorkItem = IoAllocateWorkItem(DeviceObject);
584  if (!DeviceExtension->PowerWorkItem)
585  {
586  WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
588  goto cleanup;
589  }
590  DeviceExtension->DebugWorkItem = IoAllocateWorkItem(DeviceObject);
591  if (!DeviceExtension->DebugWorkItem)
592  {
593  WARN_(I8042PRT, "IoAllocateWorkItem() failed\n");
595  goto cleanup;
596  }
597  DeviceExtension->Common.PortDeviceExtension->KeyboardExtension = DeviceExtension;
598  DeviceExtension->Common.PortDeviceExtension->Flags |= KEYBOARD_CONNECTED;
599 
600  i8042InitializeKeyboardAttributes(DeviceExtension);
601 
603  /* FIXME: DeviceExtension->KeyboardHook.IsrWritePort = ; */
605  DeviceExtension->KeyboardHook.CallContext = DeviceExtension;
606  IoQueueWorkItem(WorkItem,
609  WorkItemData);
611  break;
612 
613 cleanup:
614  if (DeviceExtension->KeyboardBuffer)
615  ExFreePoolWithTag(DeviceExtension->KeyboardBuffer, I8042PRT_TAG);
616  if (DeviceExtension->PowerWorkItem)
617  IoFreeWorkItem(DeviceExtension->PowerWorkItem);
618  if (DeviceExtension->DebugWorkItem)
619  IoFreeWorkItem(DeviceExtension->DebugWorkItem);
620  if (WorkItem)
621  IoFreeWorkItem(WorkItem);
622  if (WorkItemData)
623  ExFreePoolWithTag(WorkItemData, I8042PRT_TAG);
624  break;
625  }
627  {
628  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_DISCONNECT\n");
629  /* MSDN says that operation is to implemented.
630  * To implement it, we just have to do:
631  * DeviceExtension->KeyboardData.ClassService = NULL;
632  */
634  break;
635  }
637  {
638  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_KEYBOARD\n");
639  /* Nothing to do here */
641  break;
642  }
644  {
645  PKEYBOARD_ATTRIBUTES KeyboardAttributes;
646 
647  /* FIXME: KeyboardAttributes are not initialized anywhere */
648  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n");
649  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES))
650  {
652  break;
653  }
654 
655  KeyboardAttributes = Irp->AssociatedIrp.SystemBuffer;
656  *KeyboardAttributes = DeviceExtension->KeyboardAttributes;
657 
658  Irp->IoStatus.Information = sizeof(KEYBOARD_ATTRIBUTES);
660  break;
661  }
663  {
664  DPRINT1("IOCTL_KEYBOARD_QUERY_TYPEMATIC not implemented\n");
666  break;
667  }
669  {
670  DPRINT1("IOCTL_KEYBOARD_SET_TYPEMATIC not implemented\n");
672  break;
673  }
675  {
676  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION\n");
677 
678  /* We should check the UnitID, but it's kind of pointless as
679  * all keyboards are supposed to have the same one
680  */
681  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION))
682  {
684  }
685  else
686  {
688  Irp->AssociatedIrp.SystemBuffer,
691  Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION);
693  }
694  break;
695  }
697  {
698  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATORS\n");
699 
700  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
701  {
703  }
704  else
705  {
707  Irp->AssociatedIrp.SystemBuffer,
708  &DeviceExtension->KeyboardIndicators,
710  Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
712  }
713  break;
714  }
716  {
717  TRACE_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_SET_INDICATORS\n");
718 
719  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
720  {
722  }
723  else
724  {
726  &DeviceExtension->KeyboardIndicators,
727  Irp->AssociatedIrp.SystemBuffer,
732  }
733  break;
734  }
735  default:
736  {
737  ERR_(I8042PRT, "IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
738  Stack->Parameters.DeviceIoControl.IoControlCode);
739  ASSERT(FALSE);
741  }
742  }
743 
744  if (Status != STATUS_PENDING)
745  {
746  Irp->IoStatus.Status = Status;
748  }
749  return Status;
750 }
751 
752 /*
753  * Call the customization hook. The ToReturn parameter is about whether
754  * we should go on with the interrupt. The return value is what
755  * we should return (indicating to the system whether someone else
756  * should try to handle the interrupt)
757  */
758 static BOOLEAN
760  IN PI8042_KEYBOARD_EXTENSION DeviceExtension,
761  IN UCHAR Status,
762  IN UCHAR Input,
763  OUT PBOOLEAN ToReturn)
764 {
765  BOOLEAN HookReturn, HookContinue;
766 
767  HookContinue = FALSE;
768 
769  if (DeviceExtension->KeyboardHook.IsrRoutine)
770  {
771  HookReturn = DeviceExtension->KeyboardHook.IsrRoutine(
772  DeviceExtension->KeyboardHook.Context,
773  DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer,
774  &DeviceExtension->Common.PortDeviceExtension->Packet,
775  Status,
776  &Input,
777  &HookContinue,
778  &DeviceExtension->KeyboardScanState);
779 
780  if (!HookContinue)
781  {
782  *ToReturn = HookReturn;
783  return TRUE;
784  }
785  }
786  return FALSE;
787 }
788 
791  IN PKINTERRUPT Interrupt,
792  PVOID Context)
793 {
794  PI8042_KEYBOARD_EXTENSION DeviceExtension;
795  PPORT_DEVICE_EXTENSION PortDeviceExtension;
796  PKEYBOARD_INPUT_DATA InputData;
797  ULONG Counter;
798  UCHAR PortStatus = 0, Output = 0;
799  BOOLEAN ToReturn = FALSE;
801 
802  UNREFERENCED_PARAMETER(Interrupt);
803 
805  DeviceExtension = Context;
806  PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
807  InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer;
808  Counter = PortDeviceExtension->Settings.PollStatusIterations;
809 
810  while (Counter)
811  {
812  Status = i8042ReadStatus(PortDeviceExtension, &PortStatus);
813  if (!NT_SUCCESS(Status))
814  {
815  WARN_(I8042PRT, "i8042ReadStatus() failed with status 0x%08lx\n", Status);
816  return FALSE;
817  }
818  Status = i8042ReadKeyboardData(PortDeviceExtension, &Output);
819  if (NT_SUCCESS(Status))
820  break;
822  Counter--;
823  }
824  if (Counter == 0)
825  {
826  WARN_(I8042PRT, "Spurious i8042 keyboard interrupt\n");
827  return FALSE;
828  }
829 
830  INFO_(I8042PRT, "Got: 0x%02x\n", Output);
831 
832  if (PortDeviceExtension->Settings.CrashOnCtrlScroll)
833  {
834  /* Test for CTRL + SCROLL LOCK twice */
835  static const UCHAR ScanCodes[] = { 0x1d, 0x46, 0xc6, 0x46, 0 };
836 
837  if (Output == ScanCodes[DeviceExtension->ComboPosition])
838  {
839  DeviceExtension->ComboPosition++;
840  if (ScanCodes[DeviceExtension->ComboPosition] == 0)
841  KeBugCheck(MANUALLY_INITIATED_CRASH);
842  }
843  else if (Output == 0xfa)
844  {
845  /* Ignore ACK */
846  }
847  else if (Output == ScanCodes[0])
848  DeviceExtension->ComboPosition = 1;
849  else
850  DeviceExtension->ComboPosition = 0;
851 
852  /* Test for TAB + key combination */
853  if (InputData->MakeCode == 0x0F)
854  DeviceExtension->TabPressed = !(InputData->Flags & KEY_BREAK);
855  else if (DeviceExtension->TabPressed)
856  {
857  DeviceExtension->TabPressed = FALSE;
858 
859  /* Check which action to do */
860  if (InputData->MakeCode == 0x25)
861  {
862  /* k - Breakpoint */
864  }
865  else if (InputData->MakeCode == 0x30)
866  {
867  /* b - Bugcheck */
868  KeBugCheck(MANUALLY_INITIATED_CRASH);
869  }
870 #if defined(KDBG)
871  else
872  {
873  /* Send request to the kernel debugger.
874  * Unknown requests will be ignored. */
875  KdSystemDebugControl(' soR',
876  (PVOID)(ULONG_PTR)InputData->MakeCode,
877  0,
878  NULL,
879  0,
880  NULL,
881  KernelMode);
882  }
883 #endif
884  }
885  }
886 
887  if (i8042KbdCallIsrHook(DeviceExtension, PortStatus, Output, &ToReturn))
888  return ToReturn;
889 
890  if (i8042PacketIsr(PortDeviceExtension, Output))
891  {
892  if (PortDeviceExtension->PacketComplete)
893  {
894  TRACE_(I8042PRT, "Packet complete\n");
895  KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL);
896  }
897  TRACE_(I8042PRT, "Irq eaten by packet\n");
898  return TRUE;
899  }
900 
901  TRACE_(I8042PRT, "Irq is keyboard input\n");
902 
903  if (DeviceExtension->KeyboardScanState == Normal)
904  {
905  switch (Output)
906  {
907  case 0xe0:
908  DeviceExtension->KeyboardScanState = GotE0;
909  return TRUE;
910  case 0xe1:
911  DeviceExtension->KeyboardScanState = GotE1;
912  return TRUE;
913  default:
914  break;
915  }
916  }
917 
918  /* Update InputData */
919  InputData->Flags = 0;
920  switch (DeviceExtension->KeyboardScanState)
921  {
922  case GotE0:
923  InputData->Flags |= KEY_E0;
924  break;
925  case GotE1:
926  InputData->Flags |= KEY_E1;
927  break;
928  default:
929  break;
930  }
931  DeviceExtension->KeyboardScanState = Normal;
932  if (Output & 0x80)
933  InputData->Flags |= KEY_BREAK;
934  else
935  InputData->Flags |= KEY_MAKE;
936  InputData->MakeCode = Output & 0x7f;
937  InputData->Reserved = 0;
938 
939  DeviceExtension->KeyboardHook.QueueKeyboardPacket(DeviceExtension->KeyboardHook.CallContext);
940 
941  return TRUE;
942 }
KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators
Definition: i8042prt.h:146
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
#define IOCTL_GET_SYS_BUTTON_CAPS
Definition: poclass.h:57
NTSTATUS i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Status)
Definition: readwrite.c:82
#define IN
Definition: typedefs.h:38
#define IOCTL_KEYBOARD_QUERY_TYPEMATIC
Definition: ntddkbd.h:41
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION
Definition: ntddkbd.h:38
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
UCHAR Type
Definition: ntddkbd.h:101
#define INFO_(ch,...)
Definition: debug.h:159
#define KBD_LED_SCROLL
Definition: i8042prt.h:270
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define KBD_LED_NUM
Definition: i8042prt.h:271
PIO_WORKITEM WorkItem
Definition: i8042prt.h:203
static IO_WORKITEM_ROUTINE i8042PowerWorkItem
Definition: keyboard.c:23
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define SYS_BUTTON_SLEEP
Definition: poclass.h:82
ULONG CrashOnCtrlScroll
Definition: i8042prt.h:40
#define KEYBOARD_WAKE_CODE
Definition: i8042prt.h:215
PKINTERRUPT HighestDIRQLInterrupt
Definition: i8042prt.h:88
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define ERR_(ch,...)
Definition: debug.h:156
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:724
LONG NTSTATUS
Definition: precomp.h:26
Definition: arc.h:84
static BOOLEAN i8042KbdCallIsrHook(IN PI8042_KEYBOARD_EXTENSION DeviceExtension, IN UCHAR Status, IN UCHAR Input, OUT PBOOLEAN ToReturn)
Definition: keyboard.c:759
I8042_SETTINGS Settings
Definition: i8042prt.h:81
#define KEYBOARD_CAPS_LOCK_ON
Definition: ntddkbd.h:81
VOID NTAPI i8042InitializeKeyboardAttributes(PI8042_KEYBOARD_EXTENSION DeviceExtension)
Definition: keyboard.c:484
#define KEY_BREAK
Definition: ntddkbd.h:71
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
_Out_ PKIRQL Irql
Definition: csq.h:179
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
USHORT NumberOfKeysTotal
Definition: ntddkbd.h:128
struct _I8042_KEYBOARD_EXTENSION * PI8042_KEYBOARD_EXTENSION
Definition: i8042prt.h:63
#define I8042PRT_TAG
Definition: i8042prt.h:12
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
struct _KEYBOARD_INDICATOR_PARAMETERS KEYBOARD_INDICATOR_PARAMETERS
UCHAR KIRQL
Definition: env_spec_w32.h:591
PKEYBOARD_INPUT_DATA KeyboardBuffer
Definition: i8042prt.h:150
#define SYS_BUTTON_WAKE
Definition: poclass.h:84
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define IOCTL_KEYBOARD_SET_TYPEMATIC
Definition: ntddkbd.h:44
Definition: ntdd8042.h:75
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION LOCAL_KEYBOARD_INDICATOR_TRANSLATION
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
Definition: spinlock.c:165
NTSTATUS i8042StartPacket(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, IN PUCHAR Bytes, IN ULONG ByteCount, IN PIRP Irp)
Definition: i8042prt.c:330
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1875
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define __analysis_assume(expr)
Definition: sal.h:1111
static BOOLEAN HandlePowerKeys(IN PI8042_KEYBOARD_EXTENSION DeviceExtension)
Definition: keyboard.c:279
UNICODE_STRING PowerInterfaceName
Definition: i8042prt.h:157
smooth NULL
Definition: ftsmooth.c:416
struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION * PLOCAL_KEYBOARD_INDICATOR_TRANSLATION
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
#define IOCTL_GET_SYS_BUTTON_EVENT
Definition: poclass.h:60
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
switch(r->id)
Definition: btrfs.c:2691
Definition: ntdd8042.h:62
struct _KEYBOARD_INPUT_DATA KEYBOARD_INPUT_DATA
static VOID i8042PacketDpc(IN PPORT_DEVICE_EXTENSION DeviceExtension)
Definition: keyboard.c:154
NTSTATUS NTAPI i8042KbdInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: keyboard.c:514
BOOLEAN i8042PacketIsr(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Output)
Definition: i8042prt.c:272
KEYBOARD_TYPEMATIC_PARAMETERS KeyRepeatMinimum
Definition: ntddkbd.h:130
NTSTATUS NTAPI KdSystemDebugControl(IN SYSDBG_COMMAND Command, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN OUT PULONG ReturnLength, IN KPROCESSOR_MODE PreviousMode)
Definition: kdmain.c:489
PIO_WORKITEM DebugWorkItem
Definition: i8042prt.h:163
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
UCHAR PacketBuffer[16]
Definition: i8042prt.h:96
#define TRACE_(x)
Definition: compat.h:66
#define IOCTL_KEYBOARD_QUERY_INDICATORS
Definition: ntddkbd.h:35
#define IOCTL_INTERNAL_KEYBOARD_DISCONNECT
Definition: kbdmou.h:59
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation
Definition: keyboard.c:32
KEYBOARD_SCAN_STATE KeyboardScanState
Definition: i8042prt.h:148
INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook
Definition: i8042prt.h:141
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
FDO_DEVICE_EXTENSION Common
Definition: i8042prt.h:139
USHORT NumberOfIndicators
Definition: ntddkbd.h:127
KEYBOARD_ATTRIBUTES KeyboardAttributes
Definition: i8042prt.h:144
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
Definition: spinlock.c:148
#define KBD_CMD_SET_LEDS
Definition: i8042prt.h:234
static VOID NTAPI i8042KbdQueuePacket(IN PVOID Context)
Definition: keyboard.c:63
SETTINGS Settings
Definition: charmap.c:26
PVOID ClassService
Definition: kbdmou.h:82
#define IOCTL_INTERNAL_KEYBOARD_CONNECT
Definition: kbdmou.h:56
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
IO_WORKITEM_ROUTINE i8042SendHookWorkItem
Definition: i8042prt.h:295
unsigned char UCHAR
Definition: xmlstorage.h:181
char * PBOOLEAN
Definition: retypes.h:11
VOID(STDAPICALLTYPE * PSERVICE_CALLBACK_ROUTINE)(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN OUT PVOID SystemArgument3)
Definition: kbdmou.h:86
struct _KEYBOARD_ATTRIBUTES KEYBOARD_ATTRIBUTES
Definition: ketypes.h:687
Definition: arc.h:85
#define VOID
Definition: acefi.h:82
#define i8042ReadKeyboardData(DeviceExtension, Data)
Definition: i8042prt.h:405
NTSTATUS NTAPI i8042SynchWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Port, IN UCHAR Value, IN BOOLEAN WaitForAck)
Definition: readwrite.c:144
CONNECT_DATA KeyboardData
Definition: i8042prt.h:140
KEYBOARD_ID KeyboardIdentifier
Definition: ntddkbd.h:124
IN PI8042_QUEUE_PACKET QueueKeyboardPacket
Definition: ntdd8042.h:181
#define SYS_BUTTON_POWER
Definition: poclass.h:81
UCHAR Subtype
Definition: ntddkbd.h:102
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:40
#define KEY_E1
Definition: ntddkbd.h:73
#define InterlockedExchange
Definition: armddk.h:54
NTSTATUS NTAPI i8042SynchWritePortKbd(IN PVOID Context, IN UCHAR Value, IN BOOLEAN WaitForAck)
Definition: keyboard.c:87
BOOLEAN PacketComplete
Definition: i8042prt.h:94
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ULONG_PTR SIZE_T
Definition: typedefs.h:78
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
Definition: ntdd8042.h:76
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
USHORT NumberOfFunctionKeys
Definition: ntddkbd.h:126
NTSTATUS NTAPI i8042KbdDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: keyboard.c:384
unsigned short USHORT
Definition: pedump.c:61
VOID NTAPI i8042KbdStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: keyboard.c:103
#define KEY_E0
Definition: ntddkbd.h:72
#define KEYBOARD_SCROLL_LOCK_ON
Definition: ntddkbd.h:83
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define KBD_LED_CAPS
Definition: i8042prt.h:272
ULONG InputDataQueueLength
Definition: ntddkbd.h:129
#define DBG_STATUS_SYSRQ
Definition: kdtypes.h:40
unsigned int * PULONG
Definition: retypes.h:1
#define DPRINT1
Definition: precomp.h:8
static LARGE_INTEGER Counter
Definition: clock.c:43
BOOLEAN NTAPI i8042KbdInterruptService(IN PKINTERRUPT Interrupt, PVOID Context)
Definition: keyboard.c:790
ULONG PollStatusIterations
Definition: i8042prt.h:33
#define KEYBOARD_CONNECTED
Definition: i8042prt.h:69
#define OUT
Definition: typedefs.h:39
#define KEYBOARD_POWER_CODE
Definition: i8042prt.h:213
#define IOCTL_KEYBOARD_QUERY_ATTRIBUTES
Definition: ntddkbd.h:32
#define KEYBOARD_NUM_LOCK_ON
Definition: ntddkbd.h:82
#define IOCTL_INTERNAL_I8042_HOOK_KEYBOARD
Definition: ntdd8042.h:36
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
char * cleanup(char *str)
Definition: wpickclick.c:99
static KDEFERRED_ROUTINE i8042KbdDpcRoutine
Definition: keyboard.c:24
__analysis_noreturn NTSYSAPI VOID NTAPI DbgBreakPointWithStatus(_In_ ULONG Status)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
#define IOCTL_KEYBOARD_SET_INDICATORS
Definition: ntddkbd.h:47
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
struct _CONNECT_DATA * PCONNECT_DATA
return STATUS_SUCCESS
Definition: btrfs.c:2725
IoMarkIrpPending(Irp)
signed int * PLONG
Definition: retypes.h:5
#define KEYBOARD_SLEEP_CODE
Definition: i8042prt.h:214
#define KEY_MAKE
Definition: ntddkbd.h:70
#define WARN_(ch,...)
Definition: debug.h:157
PIO_WORKITEM PowerWorkItem
Definition: i8042prt.h:158
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:99
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1846
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675