[CMAKE]
[reactos.git] / drivers / usb / nt4compat / usbdriver / keyboard.c
1 /*
2 * PROJECT: ReactOS USB Drivers
3 * COPYRIGHT: GPL - See COPYING in the top level directory
4 * FILE: keyboard.c
5 * PURPOSE: Generic USB keyboard driver
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
7 */
8
9 #include "usbdriver.h"
10
11 NTSTATUS
12 AddRegistryEntry(IN PCWSTR PortTypeName,
13 IN PUNICODE_STRING DeviceName,
14 IN PCWSTR RegistryPath);
15
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);
20 static NTSTATUS
21 KeyboardCreateDevice(IN PDRIVER_OBJECT DriverObject, IN PKEYBOARD_DRVR_EXTENSION DriverExtension);
22 void * memscan(void * addr, int c, size_t size);
23
24 static UCHAR usb_kbd_keycode[256] =
25 {
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
42 };
43
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;
49
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}}};
54
55
56 BOOLEAN
57 kbd_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
58 {
59 PKEYBOARD_DRVR_EXTENSION pdrvr_ext;
60
61 if (dev_mgr == NULL || pdriver == NULL)
62 return FALSE;
63
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
69
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
75
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.
80
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);
84
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;
88
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;
94
95 // Create the device
96 KeyboardCreateDevice(dev_mgr->usb_driver_obj, pdrvr_ext);
97
98 usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_driver_init(): keyboard driver is initialized\n"));
99 return TRUE;
100 }
101
102 BOOLEAN
103 kbd_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
104 {
105 //PMOUSE_DRVR_EXTENSION pdrvr_ext;
106 if (dev_mgr == NULL || pdriver == NULL)
107 return FALSE;
108
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;
112
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"));
118 return TRUE;
119 }
120
121 BOOLEAN
122 kbd_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle)
123 {
124 PURB purb;
125 NTSTATUS status;
126 PUSB_DEV_MANAGER dev_mgr;
127 PUSB_DRIVER pdrvr;
128 PUSB_DEV pdev;
129 PKEYBOARD_DRVR_EXTENSION pdev_ext;
130 PUSB_ENDPOINT_DESC pendp_desc = NULL;
131 ULONG MaxPacketSize;
132
133 usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_connect(): entering...\n"));
134
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;
139
140 // Lock USB Device
141 status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
142 if (status != STATUS_SUCCESS)
143 {
144 usb_dbg_print(DBGLVL_MEDIUM, ("kbd_connect(): unable to query&lock device, status=0x%x\n", status));
145 return FALSE;
146 }
147
148 // Get pointer to the endpoint descriptor
149 pendp_desc = pdev->usb_config->interf[0].endp[0].pusb_endp_desc;
150
151 // Store max packet size
152 MaxPacketSize = pendp_desc->wMaxPacketSize;
153 if (MaxPacketSize > 8)
154 MaxPacketSize = 8;
155
156 // Unlock USB Device
157 usb_unlock_dev(pdev);
158
159 // Send interrupt URB
160 purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
161 if (purb == NULL)
162 return FALSE;
163 RtlZeroMemory(purb, sizeof(URB));
164
165 RtlZeroMemory(pdev_ext->kbd_old, 8);
166
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
172 kbd_irq,
173 pdev_ext->device_ext,
174 0);
175
176 // Call USB driver stack
177 status = usb_submit_urb(pdev_ext->dev_mgr, purb);
178 if (status != STATUS_PENDING)
179 {
180 usb_free_mem(purb);
181 purb = NULL;
182 }
183
184 return TRUE;
185 }
186
187 VOID
188 kbd_irq(PURB purb, PVOID pcontext)
189 {
190 KEYBOARD_INPUT_DATA KeyboardInputData[20];
191 ULONG DataPrepared=0, DataConsumed, i;
192 UCHAR ScanCode;
193 NTSTATUS status;
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"));
198
199 ASSERT(purb);
200
201 if (purb->status != STATUS_SUCCESS)
202 {
203 usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_irq(): purb->status 0x%08X\n", purb->status));
204 return;
205 }
206
207 pdev_ext = DeviceExtension->DriverExtension;
208 data = pdev_ext->kbd_data;
209 data_old = pdev_ext->kbd_old;
210
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]));
213
214 // Zero initial kbd data array
215 RtlZeroMemory(&KeyboardInputData[0], sizeof(KeyboardInputData));
216
217 // Scan modifier keys
218 for (i=0; i<8; i++)
219 {
220 ScanCode = usb_kbd_keycode[i + 224];
221
222 if (((data[0] >> i) & 1) != ((data_old[0] >> i) & 1))
223 {
224 usb_dbg_print(DBGLVL_MAXIMUM, ("Scan %d key p/r %d\n", ScanCode, (data[0] >> i) & 1));
225
226 KeyboardInputData[DataPrepared].MakeCode = ScanCode;
227 if ((data[0] >> i) & 1)
228 KeyboardInputData[DataPrepared].Flags |= KEY_MAKE;
229 else
230 KeyboardInputData[DataPrepared].Flags |= KEY_BREAK;
231 DataPrepared++;
232 }
233 }
234
235 // Scan normal keys
236 for (i=2; i<8; i++)
237 {
238 if (data_old[i] > 3 && memscan(data + 2, data_old[i], 6) == data + 8)
239 {
240 if (usb_kbd_keycode[data_old[i]])
241 {
242 // key released
243 usb_dbg_print(DBGLVL_MAXIMUM, ("Scan %d key released 1\n", usb_kbd_keycode[data_old[i]]));
244
245 KeyboardInputData[DataPrepared].MakeCode = usb_kbd_keycode[data_old[i]];
246 KeyboardInputData[DataPrepared].Flags |= KEY_BREAK;
247 DataPrepared++;
248 }
249 }
250
251 if (data[i] > 3 && memscan(data_old + 2, data[i], 6) == data_old + 8)
252 {
253 if (usb_kbd_keycode[data[i]])
254 {
255 // key pressed
256 usb_dbg_print(DBGLVL_MAXIMUM, ("Scan %d key pressed 1\n", usb_kbd_keycode[data[i]]));
257
258 KeyboardInputData[DataPrepared].MakeCode = usb_kbd_keycode[data[i]];
259 KeyboardInputData[DataPrepared].Flags |= KEY_MAKE;
260 DataPrepared++;
261 }
262 }
263 }
264
265 // Commit the input data somewhere...
266 if (DeviceExtension->ConnectData.ClassService && DataPrepared > 0)
267 {
268 KIRQL OldIrql;
269
270 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
271 (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ConnectData.ClassService)(
272 DeviceExtension->ConnectData.ClassDeviceObject,
273 &KeyboardInputData[0],
274 (&KeyboardInputData[0])+DataPrepared,
275 &DataConsumed);
276 KeLowerIrql(OldIrql);
277 }
278
279 // Save old keyboard data
280 RtlCopyMemory(pdev_ext->kbd_old, data, 8);
281
282 // resubmit the urb
283 status = usb_submit_urb(pdev_ext->dev_mgr, purb);
284 }
285
286 BOOLEAN
287 kbd_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
288 {
289 UNREFERENCED_PARAMETER(dev_handle);
290 UNREFERENCED_PARAMETER(dev_mgr);
291 return TRUE;
292 }
293
294 BOOLEAN
295 kbd_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
296 {
297 PDEVICE_OBJECT dev_obj;
298 NTSTATUS status;
299 PUSB_DEV pdev;
300 PUSB_DRIVER pdrvr;
301
302 if (dev_mgr == NULL || dev_handle == 0)
303 return FALSE;
304
305 pdev = NULL;
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);
308 if (pdev == NULL)
309 {
310 return FALSE;
311 }
312 if (status == STATUS_SUCCESS)
313 {
314 // must be a bug
315 TRAP();
316 usb_unlock_dev(pdev);
317 }
318 pdrvr = pdev->dev_driver;
319 dev_obj = pdev->dev_obj;
320 pdev = NULL;
321
322 return TRUE;//umss_delete_device(dev_mgr, pdrvr, dev_obj, FALSE);
323 }
324
325 VOID
326 kbd_setleds(PKEYBOARD_DEVICE_EXTENSION DeviceExtension)
327 {
328 PURB Urb;
329 PUSB_CTRL_SETUP_PACKET Setup;
330 NTSTATUS Status;
331
332 // Set LEDs request
333 Urb = usb_alloc_mem(NonPagedPool, sizeof(URB));
334 if (!Urb) return;
335 RtlZeroMemory(Urb, sizeof(URB));
336
337 DeviceExtension->DriverExtension->leds_old = 0;
338 DeviceExtension->DriverExtension->leds = 7;
339
340 // Convert from LedFlags to USB format
341 //DeviceExtension->KeyboardIndicators.LedFlags
342
343 // Build a URB for setting LEDs
344 Setup = (PUSB_CTRL_SETUP_PACKET)Urb->setup_packet;
345 urb_init((Urb));
346
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;
351 Urb->context = NULL;
352 Urb->reference = 0;
353 Setup->bmRequestType = USB_DT_HID;
354 Setup->bRequest = USB_REQ_SET_CONFIGURATION;
355 Setup->wValue = USB_DT_CONFIG << 8;
356 Setup->wIndex = 0;
357 Setup->wLength = 1;
358
359 // Call USB driver stack
360 Status = usb_submit_urb(DeviceExtension->DriverExtension->dev_mgr, Urb);
361 if (Status != STATUS_PENDING)
362 {
363 usb_free_mem(Urb);
364 }
365 }
366
367 // Dispatch routine for our IRPs
368 NTSTATUS
369 KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
370 {
371 NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
372 PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
373
374 DeviceExtension = DeviceObject->DeviceExtension;
375
376 usb_dbg_print(DBGLVL_MAXIMUM, ("KbdDispatch(DO %p, code 0x%lx) called\n",
377 DeviceObject,
378 IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode));
379
380 if (DeviceObject == DeviceExtension->Fdo)
381 {
382 // it's keyboard's IOCTL
383 PIO_STACK_LOCATION Stack;
384
385 Irp->IoStatus.Information = 0;
386 Stack = IoGetCurrentIrpStackLocation(Irp);
387
388 switch (Stack->Parameters.DeviceIoControl.IoControlCode)
389 {
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;
396 goto intcontfailure;
397 }
398
399 RtlCopyMemory(&DeviceExtension->ConnectData,
400 Stack->Parameters.DeviceIoControl.Type3InputBuffer,
401 sizeof(CONNECT_DATA));
402
403 Status = STATUS_SUCCESS;
404 break;
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;
412 goto intcontfailure;
413 }
414 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
415 &DevExt->KeyboardAttributes,
416 sizeof(KEYBOARD_ATTRIBUTES));*/
417
418 Irp->IoStatus.Status = STATUS_SUCCESS;
419 break;
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))
423 {
424 Status = STATUS_BUFFER_TOO_SMALL;
425 }
426 else
427 {
428 RtlCopyMemory(
429 Irp->AssociatedIrp.SystemBuffer,
430 &DeviceExtension->KeyboardIndicators,
431 sizeof(KEYBOARD_INDICATOR_PARAMETERS));
432 Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
433 Status = STATUS_SUCCESS;
434 }
435 break;
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;
443 goto intcontfailure;
444 }
445 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
446 &DevExt->KeyboardTypematic,
447 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
448
449 Status = STATUS_SUCCESS;
450 break;
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;
458 goto intcontfailure;
459 }
460
461 RtlCopyMemory(&DeviceExtension->KeyboardIndicators,
462 Irp->AssociatedIrp.SystemBuffer,
463 sizeof(KEYBOARD_INDICATOR_PARAMETERS));
464
465 //DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags);
466 kbd_setleds(DeviceExtension);
467 Status = STATUS_SUCCESS;
468 break;
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;
476 goto intcontfailure;
477 }
478
479 /*RtlCopyMemory(&DevExt->KeyboardTypematic,
480 Irp->AssociatedIrp.SystemBuffer,
481 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
482
483 Status = STATUS_SUCCESS;
484 break;
485 case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
486 if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION))
487 {
488 Status = STATUS_BUFFER_TOO_SMALL;
489 }
490 else
491 {
492 RtlCopyMemory(
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;
498 }
499 break;
500 default:
501 Status = STATUS_SUCCESS;//STATUS_INVALID_DEVICE_REQUEST;
502 break;
503 }
504 intcontfailure:
505 Status = Irp->IoStatus.Status;
506 }
507
508
509 if (Status == STATUS_INVALID_DEVICE_REQUEST)
510 {
511 usb_dbg_print(DBGLVL_MINIMUM, ("Invalid internal device request!\n"));
512 }
513
514 Irp->IoStatus.Status = Status;
515 if (Status != STATUS_PENDING)
516 IoCompleteRequest(Irp, IO_NO_INCREMENT);
517
518 return Status;
519 }
520
521 static NTSTATUS
522 KeyboardCreateDevice(IN PDRIVER_OBJECT DriverObject, IN PKEYBOARD_DRVR_EXTENSION DriverExtension)
523 {
524 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPortUSB");
525 PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
526 PDEVICE_OBJECT Fdo;
527 NTSTATUS Status;
528
529 Status = AddRegistryEntry(L"KeyboardPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbdriver");
530 if (!NT_SUCCESS(Status))
531 {
532 usb_dbg_print(DBGLVL_MINIMUM, ("AddRegistryEntry() for usb keyboard driver failed with status 0x%08lx\n", Status));
533 return Status;
534 }
535
536 Status = IoCreateDevice(DriverObject,
537 sizeof(KEYBOARD_DEVICE_EXTENSION),
538 &DeviceName,
539 FILE_DEVICE_KEYBOARD,
540 FILE_DEVICE_SECURE_OPEN,
541 TRUE,
542 &Fdo);
543
544 if (!NT_SUCCESS(Status))
545 {
546 usb_dbg_print(DBGLVL_MINIMUM, ("IoCreateDevice() for usb keyboard driver failed with status 0x%08lx\n", Status));
547 return Status;
548 }
549 DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)Fdo->DeviceExtension;
550 RtlZeroMemory(DeviceExtension, sizeof(KEYBOARD_DEVICE_EXTENSION));
551
552 DeviceExtension->hdr.dispatch = KbdDispatch;
553 DeviceExtension->DriverExtension = DriverExtension;
554 DriverExtension->device_ext = DeviceExtension;
555
556 DeviceExtension->Fdo = Fdo;
557 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
558 usb_dbg_print(DBGLVL_MEDIUM, ("Created keyboard Fdo: %p\n", Fdo));
559
560 return STATUS_SUCCESS;
561 }
562
563 /**
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.
568 *
569 * returns the address of the first occurrence of @c, or 1 byte past
570 * the area if @c is not found
571 */
572 void * memscan(void * addr, int c, size_t size)
573 {
574 unsigned char * p = (unsigned char *) addr;
575
576 while (size) {
577 if (*p == c)
578 return (void *) p;
579 p++;
580 size--;
581 }
582 return (void *) p;
583 }
584