2 * PROJECT: ReactOS USB Drivers
3 * COPYRIGHT: GPL - See COPYING in the top level directory
5 * PURPOSE: Generic USB keyboard driver
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
12 AddRegistryEntry(IN PCWSTR PortTypeName
,
13 IN PUNICODE_STRING DeviceName
,
14 IN PCWSTR RegistryPath
);
16 BOOLEAN
kbd_connect(PDEV_CONNECT_DATA dev_mgr
, DEV_HANDLE dev_handle
);
17 BOOLEAN
kbd_disconnect(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
);
18 BOOLEAN
kbd_stop(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
);
19 VOID
kbd_irq(PURB purb
, PVOID pcontext
);
21 KeyboardCreateDevice(IN PDRIVER_OBJECT DriverObject
, IN PKEYBOARD_DRVR_EXTENSION DriverExtension
);
22 void * memscan(void * addr
, int c
, size_t size
);
24 static UCHAR usb_kbd_keycode
[256] =
26 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
27 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
28 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
29 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
30 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
31 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
32 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
33 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
34 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
35 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
41 150,158,159,128,136,177,178,176,142,152,173,140
44 /* This structure starts with the same layout as KEYBOARD_INDICATOR_TRANSLATION */
45 typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION
{
46 USHORT NumberOfIndicatorKeys
;
47 INDICATOR_LIST IndicatorList
[3];
48 } LOCAL_KEYBOARD_INDICATOR_TRANSLATION
, *PLOCAL_KEYBOARD_INDICATOR_TRANSLATION
;
50 static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation
= { 3, {
51 {0x3A, KEYBOARD_CAPS_LOCK_ON
},
52 {0x45, KEYBOARD_NUM_LOCK_ON
},
53 {0x46, KEYBOARD_SCROLL_LOCK_ON
}}};
57 kbd_driver_init(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
)
59 PKEYBOARD_DRVR_EXTENSION pdrvr_ext
;
61 if (dev_mgr
== NULL
|| pdriver
== NULL
)
64 //init driver structure, no PNP table functions
65 pdriver
->driver_desc
.flags
= USB_DRIVER_FLAG_IF_CAPABLE
;
66 pdriver
->driver_desc
.vendor_id
= 0xffff; // USB Vendor ID
67 pdriver
->driver_desc
.product_id
= 0xffff; // USB Product ID.
68 pdriver
->driver_desc
.release_num
= 0x100; // Release Number of Device
70 pdriver
->driver_desc
.config_val
= 0; // Configuration Value
71 pdriver
->driver_desc
.if_num
= 0; // Interface Number
72 pdriver
->driver_desc
.if_class
= USB_CLASS_HID
; // Interface Class
73 pdriver
->driver_desc
.if_sub_class
= 1; // Interface SubClass
74 pdriver
->driver_desc
.if_protocol
= 1; // Interface Protocol
76 pdriver
->driver_desc
.driver_name
= "USB Keyboard driver"; // Driver name for Name Registry
77 pdriver
->driver_desc
.dev_class
= USB_CLASS_HID
;
78 pdriver
->driver_desc
.dev_sub_class
= 1; // Device Subclass
79 pdriver
->driver_desc
.dev_protocol
= 1; // Protocol Info.
81 pdriver
->driver_ext
= usb_alloc_mem(NonPagedPool
, sizeof(KEYBOARD_DRVR_EXTENSION
));
82 if (!pdriver
->driver_ext
) return FALSE
;
83 pdriver
->driver_ext_size
= sizeof(KEYBOARD_DRVR_EXTENSION
);
85 RtlZeroMemory(pdriver
->driver_ext
, sizeof(KEYBOARD_DRVR_EXTENSION
));
86 pdrvr_ext
= (PKEYBOARD_DRVR_EXTENSION
) pdriver
->driver_ext
;
87 pdrvr_ext
->dev_mgr
= dev_mgr
;
89 pdriver
->disp_tbl
.version
= 1;
90 pdriver
->disp_tbl
.dev_connect
= kbd_connect
;
91 pdriver
->disp_tbl
.dev_disconnect
= kbd_disconnect
;
92 pdriver
->disp_tbl
.dev_stop
= kbd_stop
;
93 pdriver
->disp_tbl
.dev_reserved
= NULL
;
96 KeyboardCreateDevice(dev_mgr
->usb_driver_obj
, pdrvr_ext
);
98 usb_dbg_print(DBGLVL_MAXIMUM
, ("kbd_driver_init(): keyboard driver is initialized\n"));
103 kbd_driver_destroy(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
)
105 //PMOUSE_DRVR_EXTENSION pdrvr_ext;
106 if (dev_mgr
== NULL
|| pdriver
== NULL
)
109 //pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdriver->driver_ext;
110 //umss_delete_port_device(pdrvr_ext->port_dev_obj);
111 //pdrvr_ext->port_dev_obj = NULL;
113 //ASSERT(IsListEmpty(&pdrvr_ext->dev_list) == TRUE);
114 usb_free_mem(pdriver
->driver_ext
);
115 pdriver
->driver_ext
= NULL
;
116 pdriver
->driver_ext_size
= 0;
117 usb_dbg_print(DBGLVL_MAXIMUM
, ("kbd_driver_destroy(): keyboard driver is destroyed\n"));
122 kbd_connect(PDEV_CONNECT_DATA param
, DEV_HANDLE dev_handle
)
126 PUSB_DEV_MANAGER dev_mgr
;
129 PKEYBOARD_DRVR_EXTENSION pdev_ext
;
130 PUSB_ENDPOINT_DESC pendp_desc
= NULL
;
133 usb_dbg_print(DBGLVL_MAXIMUM
, ("kbd_connect(): entering...\n"));
135 dev_mgr
= param
->dev_mgr
;
136 pdrvr
= param
->pdriver
;
137 pdev_ext
= (PKEYBOARD_DRVR_EXTENSION
)pdrvr
->driver_ext
;
138 pdev_ext
->dev_handle
= dev_handle
;
141 status
= usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
);
142 if (status
!= STATUS_SUCCESS
)
144 usb_dbg_print(DBGLVL_MEDIUM
, ("kbd_connect(): unable to query&lock device, status=0x%x\n", status
));
148 // Get pointer to the endpoint descriptor
149 pendp_desc
= pdev
->usb_config
->interf
[0].endp
[0].pusb_endp_desc
;
151 // Store max packet size
152 MaxPacketSize
= pendp_desc
->wMaxPacketSize
;
153 if (MaxPacketSize
> 8)
157 usb_unlock_dev(pdev
);
159 // Send interrupt URB
160 purb
= usb_alloc_mem(NonPagedPool
, sizeof(URB
));
163 RtlZeroMemory(purb
, sizeof(URB
));
165 RtlZeroMemory(pdev_ext
->kbd_old
, 8);
167 // Build a URB for our interrupt transfer
168 UsbBuildInterruptOrBulkTransferRequest(purb
,
169 usb_make_handle((dev_handle
>> 16), 0, 0),
170 (PUCHAR
)&pdev_ext
->kbd_data
,
171 MaxPacketSize
, //use max packet size
173 pdev_ext
->device_ext
,
176 // Call USB driver stack
177 status
= usb_submit_urb(pdev_ext
->dev_mgr
, purb
);
178 if (status
!= STATUS_PENDING
)
188 kbd_irq(PURB purb
, PVOID pcontext
)
190 KEYBOARD_INPUT_DATA KeyboardInputData
[20];
191 ULONG DataPrepared
=0, DataConsumed
, i
;
194 PKEYBOARD_DRVR_EXTENSION pdev_ext
;
195 PKEYBOARD_DEVICE_EXTENSION DeviceExtension
= (PKEYBOARD_DEVICE_EXTENSION
)pcontext
;
196 PUCHAR data
, data_old
;
197 usb_dbg_print(DBGLVL_MAXIMUM
, ("kbd_irq(): called\n"));
201 if (purb
->status
!= STATUS_SUCCESS
)
203 usb_dbg_print(DBGLVL_MAXIMUM
, ("kbd_irq(): purb->status 0x%08X\n", purb
->status
));
207 pdev_ext
= DeviceExtension
->DriverExtension
;
208 data
= pdev_ext
->kbd_data
;
209 data_old
= pdev_ext
->kbd_old
;
211 usb_dbg_print(DBGLVL_MAXIMUM
, ("Kbd input: %d %d %d %d %d %d %d %d\n", data
[0], data
[1], data
[2], data
[3],
212 data
[4], data
[5], data
[6], data
[7]));
214 // Zero initial kbd data array
215 RtlZeroMemory(&KeyboardInputData
[0], sizeof(KeyboardInputData
));
217 // Scan modifier keys
220 ScanCode
= usb_kbd_keycode
[i
+ 224];
222 if (((data
[0] >> i
) & 1) != ((data_old
[0] >> i
) & 1))
224 usb_dbg_print(DBGLVL_MAXIMUM
, ("Scan %d key p/r %d\n", ScanCode
, (data
[0] >> i
) & 1));
226 KeyboardInputData
[DataPrepared
].MakeCode
= ScanCode
;
227 if ((data
[0] >> i
) & 1)
228 KeyboardInputData
[DataPrepared
].Flags
|= KEY_MAKE
;
230 KeyboardInputData
[DataPrepared
].Flags
|= KEY_BREAK
;
238 if (data_old
[i
] > 3 && memscan(data
+ 2, data_old
[i
], 6) == data
+ 8)
240 if (usb_kbd_keycode
[data_old
[i
]])
243 usb_dbg_print(DBGLVL_MAXIMUM
, ("Scan %d key released 1\n", usb_kbd_keycode
[data_old
[i
]]));
245 KeyboardInputData
[DataPrepared
].MakeCode
= usb_kbd_keycode
[data_old
[i
]];
246 KeyboardInputData
[DataPrepared
].Flags
|= KEY_BREAK
;
251 if (data
[i
] > 3 && memscan(data_old
+ 2, data
[i
], 6) == data_old
+ 8)
253 if (usb_kbd_keycode
[data
[i
]])
256 usb_dbg_print(DBGLVL_MAXIMUM
, ("Scan %d key pressed 1\n", usb_kbd_keycode
[data
[i
]]));
258 KeyboardInputData
[DataPrepared
].MakeCode
= usb_kbd_keycode
[data
[i
]];
259 KeyboardInputData
[DataPrepared
].Flags
|= KEY_MAKE
;
265 // Commit the input data somewhere...
266 if (DeviceExtension
->ConnectData
.ClassService
&& DataPrepared
> 0)
270 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
271 (*(PSERVICE_CALLBACK_ROUTINE
)DeviceExtension
->ConnectData
.ClassService
)(
272 DeviceExtension
->ConnectData
.ClassDeviceObject
,
273 &KeyboardInputData
[0],
274 (&KeyboardInputData
[0])+DataPrepared
,
276 KeLowerIrql(OldIrql
);
279 // Save old keyboard data
280 RtlCopyMemory(pdev_ext
->kbd_old
, data
, sizeof(data
));
283 status
= usb_submit_urb(pdev_ext
->dev_mgr
, purb
);
287 kbd_stop(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
)
289 UNREFERENCED_PARAMETER(dev_handle
);
290 UNREFERENCED_PARAMETER(dev_mgr
);
295 kbd_disconnect(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
)
297 PDEVICE_OBJECT dev_obj
;
302 if (dev_mgr
== NULL
|| dev_handle
== 0)
306 //special use of the lock dev, simply use this routine to get the dev
307 status
= usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
);
312 if (status
== STATUS_SUCCESS
)
316 usb_unlock_dev(pdev
);
318 pdrvr
= pdev
->dev_driver
;
319 dev_obj
= pdev
->dev_obj
;
322 return TRUE
;//umss_delete_device(dev_mgr, pdrvr, dev_obj, FALSE);
326 kbd_setleds(PKEYBOARD_DEVICE_EXTENSION DeviceExtension
)
329 PUSB_CTRL_SETUP_PACKET Setup
;
333 Urb
= usb_alloc_mem(NonPagedPool
, sizeof(URB
));
335 RtlZeroMemory(Urb
, sizeof(URB
));
337 DeviceExtension
->DriverExtension
->leds_old
= 0;
338 DeviceExtension
->DriverExtension
->leds
= 7;
340 // Convert from LedFlags to USB format
341 //DeviceExtension->KeyboardIndicators.LedFlags
343 // Build a URB for setting LEDs
344 Setup
= (PUSB_CTRL_SETUP_PACKET
)Urb
->setup_packet
;
347 Urb
->endp_handle
= usb_make_handle((DeviceExtension
->DriverExtension
->dev_handle
>> 16), 0, 0) | 0xffff;
348 Urb
->data_buffer
= &DeviceExtension
->DriverExtension
->leds
;
349 Urb
->data_length
= 1;
350 Urb
->completion
= NULL
;
353 Setup
->bmRequestType
= USB_DT_HID
;
354 Setup
->bRequest
= USB_REQ_SET_CONFIGURATION
;
355 Setup
->wValue
= USB_DT_CONFIG
<< 8;
359 // Call USB driver stack
360 Status
= usb_submit_urb(DeviceExtension
->DriverExtension
->dev_mgr
, Urb
);
361 if (Status
!= STATUS_PENDING
)
367 // Dispatch routine for our IRPs
369 KbdDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
371 NTSTATUS Status
= STATUS_INVALID_DEVICE_REQUEST
;
372 PKEYBOARD_DEVICE_EXTENSION DeviceExtension
;
374 DeviceExtension
= DeviceObject
->DeviceExtension
;
376 usb_dbg_print(DBGLVL_MAXIMUM
, ("KbdDispatch(DO %p, code 0x%lx) called\n",
378 IoGetCurrentIrpStackLocation(Irp
)->Parameters
.DeviceIoControl
.IoControlCode
));
380 if (DeviceObject
== DeviceExtension
->Fdo
)
382 // it's keyboard's IOCTL
383 PIO_STACK_LOCATION Stack
;
385 Irp
->IoStatus
.Information
= 0;
386 Stack
= IoGetCurrentIrpStackLocation(Irp
);
388 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
390 case IOCTL_INTERNAL_KEYBOARD_CONNECT
:
391 usb_dbg_print(DBGLVL_MAXIMUM
, ("IOCTL_INTERNAL_KEYBOARD_CONNECT\n"));
392 if (Stack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(CONNECT_DATA
)) {
393 usb_dbg_print(DBGLVL_MAXIMUM
, ("Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT "
394 "invalid buffer size\n"));
395 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
399 RtlCopyMemory(&DeviceExtension
->ConnectData
,
400 Stack
->Parameters
.DeviceIoControl
.Type3InputBuffer
,
401 sizeof(CONNECT_DATA
));
403 Status
= STATUS_SUCCESS
;
405 case IOCTL_KEYBOARD_QUERY_ATTRIBUTES
:
406 usb_dbg_print(DBGLVL_MAXIMUM
, ("IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n"));
407 if (Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
<
408 sizeof(KEYBOARD_ATTRIBUTES
)) {
409 usb_dbg_print(DBGLVL_MAXIMUM
, ("Keyboard IOCTL_KEYBOARD_QUERY_ATTRIBUTES: "
410 "invalid buffer size\n"));
411 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
414 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
415 &DevExt->KeyboardAttributes,
416 sizeof(KEYBOARD_ATTRIBUTES));*/
418 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
420 case IOCTL_KEYBOARD_QUERY_INDICATORS
:
421 usb_dbg_print(DBGLVL_MAXIMUM
, ("IOCTL_KEYBOARD_QUERY_INDICATORS\n"));
422 if (Stack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(KEYBOARD_INDICATOR_PARAMETERS
))
424 Status
= STATUS_BUFFER_TOO_SMALL
;
429 Irp
->AssociatedIrp
.SystemBuffer
,
430 &DeviceExtension
->KeyboardIndicators
,
431 sizeof(KEYBOARD_INDICATOR_PARAMETERS
));
432 Irp
->IoStatus
.Information
= sizeof(KEYBOARD_INDICATOR_PARAMETERS
);
433 Status
= STATUS_SUCCESS
;
436 case IOCTL_KEYBOARD_QUERY_TYPEMATIC
:
437 usb_dbg_print(DBGLVL_MAXIMUM
, ("IOCTL_KEYBOARD_QUERY_TYPEMATIC\n"));
438 if (Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
<
439 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS
)) {
440 usb_dbg_print(DBGLVL_MAXIMUM
, ("Keyboard IOCTL_KEYBOARD_QUERY_TYPEMATIC: "
441 "invalid buffer size\n"));
442 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
445 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
446 &DevExt->KeyboardTypematic,
447 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
449 Status
= STATUS_SUCCESS
;
451 case IOCTL_KEYBOARD_SET_INDICATORS
:
452 usb_dbg_print(DBGLVL_MAXIMUM
, ("IOCTL_KEYBOARD_SET_INDICATORS\n"));
453 if (Stack
->Parameters
.DeviceIoControl
.InputBufferLength
<
454 sizeof(KEYBOARD_INDICATOR_PARAMETERS
)) {
455 usb_dbg_print(DBGLVL_MAXIMUM
, ("Keyboard IOCTL_KEYBOARD_SET_INDICTATORS: "
456 "invalid buffer size\n"));
457 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
461 RtlCopyMemory(&DeviceExtension
->KeyboardIndicators
,
462 Irp
->AssociatedIrp
.SystemBuffer
,
463 sizeof(KEYBOARD_INDICATOR_PARAMETERS
));
465 //DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags);
466 kbd_setleds(DeviceExtension
);
467 Status
= STATUS_SUCCESS
;
469 case IOCTL_KEYBOARD_SET_TYPEMATIC
:
470 usb_dbg_print(DBGLVL_MAXIMUM
, ("IOCTL_KEYBOARD_SET_TYPEMATIC\n"));
471 if (Stack
->Parameters
.DeviceIoControl
.InputBufferLength
<
472 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS
)) {
473 usb_dbg_print(DBGLVL_MAXIMUM
, ("Keyboard IOCTL_KEYBOARD_SET_TYPEMATIC "
474 "invalid buffer size\n"));
475 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
479 /*RtlCopyMemory(&DevExt->KeyboardTypematic,
480 Irp->AssociatedIrp.SystemBuffer,
481 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
483 Status
= STATUS_SUCCESS
;
485 case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION
:
486 if (Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION
))
488 Status
= STATUS_BUFFER_TOO_SMALL
;
493 Irp
->AssociatedIrp
.SystemBuffer
,
494 &IndicatorTranslation
,
495 sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION
));
496 Irp
->IoStatus
.Information
= sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION
);
497 Status
= STATUS_SUCCESS
;
501 Status
= STATUS_SUCCESS
;//STATUS_INVALID_DEVICE_REQUEST;
505 Status
= Irp
->IoStatus
.Status
;
509 if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
511 usb_dbg_print(DBGLVL_MINIMUM
, ("Invalid internal device request!\n"));
514 Irp
->IoStatus
.Status
= Status
;
515 if (Status
!= STATUS_PENDING
)
516 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
522 KeyboardCreateDevice(IN PDRIVER_OBJECT DriverObject
, IN PKEYBOARD_DRVR_EXTENSION DriverExtension
)
524 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\KeyboardPortUSB");
525 PKEYBOARD_DEVICE_EXTENSION DeviceExtension
;
529 Status
= AddRegistryEntry(L
"KeyboardPort", &DeviceName
, L
"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbdriver");
530 if (!NT_SUCCESS(Status
))
532 usb_dbg_print(DBGLVL_MINIMUM
, ("AddRegistryEntry() for usb keyboard driver failed with status 0x%08lx\n", Status
));
536 Status
= IoCreateDevice(DriverObject
,
537 sizeof(KEYBOARD_DEVICE_EXTENSION
),
539 FILE_DEVICE_KEYBOARD
,
540 FILE_DEVICE_SECURE_OPEN
,
544 if (!NT_SUCCESS(Status
))
546 usb_dbg_print(DBGLVL_MINIMUM
, ("IoCreateDevice() for usb keyboard driver failed with status 0x%08lx\n", Status
));
549 DeviceExtension
= (PKEYBOARD_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
550 RtlZeroMemory(DeviceExtension
, sizeof(KEYBOARD_DEVICE_EXTENSION
));
552 DeviceExtension
->hdr
.dispatch
= KbdDispatch
;
553 DeviceExtension
->DriverExtension
= DriverExtension
;
554 DriverExtension
->device_ext
= DeviceExtension
;
556 DeviceExtension
->Fdo
= Fdo
;
557 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
558 usb_dbg_print(DBGLVL_MEDIUM
, ("Created keyboard Fdo: %p\n", Fdo
));
560 return STATUS_SUCCESS
;
564 * memscan - Find a character in an area of memory.
565 * @addr: The memory area
566 * @c: The byte to search for
567 * @size: The size of the area.
569 * returns the address of the first occurrence of @c, or 1 byte past
570 * the area if @c is not found
572 void * memscan(void * addr
, int c
, size_t size
)
574 unsigned char * p
= (unsigned char *) addr
;