2 * PROJECT: ReactOS USB Drivers
3 * COPYRIGHT: GPL - See COPYING in the top level directory
5 * PURPOSE: Generic USB mouse driver
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
13 //FIXME: is it needed at all?
14 typedef struct _USBMP_DEVICE_EXTENSION
17 } USBMP_DEVICE_EXTENSION
, *PUSBMP_DEVICE_EXTENSION
;
19 /* Data for embedded drivers */
20 //CONNECT_DATA KbdClassInformation;
21 CONNECT_DATA MouseClassInformation
;
23 PDEVICE_OBJECT MouseFdo
= NULL
;
26 BOOLEAN
mouse_connect(PDEV_CONNECT_DATA dev_mgr
, DEV_HANDLE dev_handle
);
27 BOOLEAN
mouse_disconnect(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
);
28 BOOLEAN
mouse_stop(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
);
29 VOID
mouse_irq(PURB purb
, PVOID pcontext
);
31 MouseCreateDevice(IN PDRIVER_OBJECT DriverObject
);
35 mouse_driver_init(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
)
37 PMOUSE_DRVR_EXTENSION pdrvr_ext
;
39 if (dev_mgr
== NULL
|| pdriver
== NULL
)
42 //init driver structure, no PNP table functions
43 pdriver
->driver_desc
.flags
= USB_DRIVER_FLAG_IF_CAPABLE
;
44 pdriver
->driver_desc
.vendor_id
= 0xffff; // USB Vendor ID
45 pdriver
->driver_desc
.product_id
= 0xffff; // USB Product ID.
46 pdriver
->driver_desc
.release_num
= 0x100; // Release Number of Device
48 pdriver
->driver_desc
.config_val
= 1; // Configuration Value
49 pdriver
->driver_desc
.if_num
= 1; // Interface Number
50 pdriver
->driver_desc
.if_class
= USB_CLASS_HID
; // Interface Class
51 pdriver
->driver_desc
.if_sub_class
= 1; // Interface SubClass
52 pdriver
->driver_desc
.if_protocol
= 2; // Interface Protocol
54 pdriver
->driver_desc
.driver_name
= "USB Mouse driver"; // Driver name for Name Registry
55 pdriver
->driver_desc
.dev_class
= USB_CLASS_HID
;
56 pdriver
->driver_desc
.dev_sub_class
= 1; // Device Subclass
57 pdriver
->driver_desc
.dev_protocol
= 2; // Protocol Info.
59 pdriver
->driver_ext
= usb_alloc_mem(NonPagedPool
, sizeof(MOUSE_DRVR_EXTENSION
));
60 pdriver
->driver_ext_size
= sizeof(MOUSE_DRVR_EXTENSION
);
62 RtlZeroMemory(pdriver
->driver_ext
, sizeof(MOUSE_DRVR_EXTENSION
));
63 pdrvr_ext
= (PMOUSE_DRVR_EXTENSION
) pdriver
->driver_ext
;
64 pdrvr_ext
->dev_mgr
= dev_mgr
;
66 pdriver
->disp_tbl
.version
= 1;
67 pdriver
->disp_tbl
.dev_connect
= mouse_connect
;
68 pdriver
->disp_tbl
.dev_disconnect
= mouse_disconnect
;
69 pdriver
->disp_tbl
.dev_stop
= mouse_stop
;
70 pdriver
->disp_tbl
.dev_reserved
= NULL
;
72 // Zero out the class information structure
73 RtlZeroMemory(&MouseClassInformation
, sizeof(CONNECT_DATA
));
76 MouseCreateDevice(dev_mgr
->usb_driver_obj
);
78 usb_dbg_print(DBGLVL_MAXIMUM
, ("mouse_driver_init(): mouse driver is initialized\n"));
83 mouse_driver_destroy(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
)
85 //PMOUSE_DRVR_EXTENSION pdrvr_ext;
86 if (dev_mgr
== NULL
|| pdriver
== NULL
)
89 //pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdriver->driver_ext;
90 //umss_delete_port_device(pdrvr_ext->port_dev_obj);
91 //pdrvr_ext->port_dev_obj = NULL;
93 //ASSERT(IsListEmpty(&pdrvr_ext->dev_list) == TRUE);
94 usb_free_mem(pdriver
->driver_ext
);
95 pdriver
->driver_ext
= NULL
;
96 pdriver
->driver_ext_size
= 0;
97 usb_dbg_print(DBGLVL_MAXIMUM
, ("mouse_driver_destroy(): mouse driver is destroyed\n"));
102 mouse_connect(PDEV_CONNECT_DATA param
, DEV_HANDLE dev_handle
)
106 PUSB_DEV_MANAGER dev_mgr
;
109 PMOUSE_DRVR_EXTENSION pdev_ext
;
111 PUSB_ENDPOINT_DESC pendp_desc
= NULL
;
114 usb_dbg_print(DBGLVL_MAXIMUM
, ("mouse_connect(): entering...\n"));
116 dev_mgr
= param
->dev_mgr
;
117 pdrvr
= param
->pdriver
;
118 pdev_ext
= (PMOUSE_DRVR_EXTENSION
)pdrvr
->driver_ext
;
121 status
= usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
);
122 if (status
!= STATUS_SUCCESS
)
124 //usb_free_mem(desc_buf);
125 usb_dbg_print(DBGLVL_MEDIUM
, ("mouse_connect(): unable to query&lock device, status=0x%x\n", status
));
129 // Endpoint-finding code
132 // Get a pointer to the config packet from compdev
133 PUCHAR Buffer
= (PUCHAR
)param
->if_desc
;
135 BOOLEAN FoundEndpoint
= FALSE
;
137 // Find our the only needed endpoint descriptor
140 pendp_desc
= (PUSB_ENDPOINT_DESC
)&Buffer
[Offset
];
141 usb_dbg_print(DBGLVL_MAXIMUM
, ("mouse_connect(): DescType=0x%x, Attrs=0x%x, Len=%d\n",
142 pendp_desc
->bDescriptorType
, pendp_desc
->bmAttributes
, pendp_desc
->bLength
));
144 if (pendp_desc
->bDescriptorType
== USB_DT_ENDPOINT
&&
145 pendp_desc
->bLength
== sizeof(USB_ENDPOINT_DESC
))
148 FoundEndpoint
= TRUE
;
152 Offset
+= pendp_desc
->bLength
;
158 // FIXME: Check if it's INT endpoint
159 // (pendp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
161 // endpoint must be IN
162 if ((pendp_desc
->bEndpointAddress
& USB_DIR_IN
) == 0)
167 // Endpoint descriptor substitution code
169 ULONG if_idx
, endp_idx
;
172 //FoundEndpoint = FALSE;
173 for(if_idx
= 0; if_idx
< MAX_INTERFACES_PER_CONFIG
/*pdev->usb_config->if_count*/; if_idx
++)
175 for(endp_idx
= 0; endp_idx
< MAX_ENDPS_PER_IF
/*pdev->usb_config->interf[if_idx].endp_count*/; endp_idx
++)
177 pendp
= &pdev
->usb_config
->interf
[if_idx
].endp
[endp_idx
];
179 if (pendp
->pusb_endp_desc
!= NULL
)
181 //HACKHACK: for some reason this usb driver chooses different and completely wrong
182 // endpoint. Since I don't have time to research this, I just find the
183 // endpoint descriptor myself and copy it
184 memcpy(pendp
->pusb_endp_desc
, pendp_desc
, pendp_desc
->bLength
);
186 usb_dbg_print(DBGLVL_MAXIMUM
, ("mouse_connect(): [%i][%i] DescType=0x%x, Attrs=0x%x, Len=%d\n",if_idx
, endp_idx
,
187 pendp
->pusb_endp_desc
->bDescriptorType
, pendp
->pusb_endp_desc
->bmAttributes
, pendp
->pusb_endp_desc
->bLength
));
194 usb_unlock_dev(pdev
);
197 purb
= usb_alloc_mem(NonPagedPool
, sizeof(URB
));
200 RtlZeroMemory(purb
, sizeof(URB
));
202 MaxPacketSize
= pendp_desc
->wMaxPacketSize
;
203 if (MaxPacketSize
> 8)
206 // Build a URB for our interrupt transfer
207 UsbBuildInterruptOrBulkTransferRequest(purb
,
208 usb_make_handle((dev_handle
>> 16), 0, 0),
209 (PUCHAR
)&pdev_ext
->mouse_data
,
210 MaxPacketSize
, //use max packet size
215 // Call USB driver stack
216 status
= usb_submit_urb(pdev_ext
->dev_mgr
, purb
);
217 if (status
!= STATUS_PENDING
)
227 mouse_irq(PURB purb
, PVOID pcontext
)
229 MOUSE_INPUT_DATA MouseInputData
;
230 ULONG InputDataConsumed
;
232 PMOUSE_DRVR_EXTENSION pdev_ext
= (PMOUSE_DRVR_EXTENSION
)pcontext
;
233 signed char *data
= pdev_ext
->mouse_data
;
234 usb_dbg_print(DBGLVL_MAXIMUM
, ("mouse_irq(): called\n"));
238 if (purb
->status
!= STATUS_SUCCESS
)
240 usb_dbg_print(DBGLVL_MAXIMUM
, ("mouse_irq(): purb->status 0x%08X\n", purb
->status
));
244 usb_dbg_print(DBGLVL_MAXIMUM
, ("Mouse input: x %d, y %d, w %d, btn: 0x%02x\n", data
[1], data
[2], data
[3], data
[0]));
246 // Fill mouse input data structure
247 MouseInputData
.Flags
= MOUSE_MOVE_RELATIVE
;
248 MouseInputData
.LastX
= data
[1];
249 MouseInputData
.LastY
= data
[2];
251 MouseInputData
.ButtonFlags
= 0;
252 MouseInputData
.ButtonData
= 0;
254 if ((data
[0] & 0x01) && ((pdev_ext
->btn_old
& 0x01) != (data
[0] & 0x01)))
255 MouseInputData
.ButtonFlags
|= MOUSE_LEFT_BUTTON_DOWN
;
256 else if (!(data
[0] & 0x01) && ((pdev_ext
->btn_old
& 0x01) != (data
[0] & 0x01)))
257 MouseInputData
.ButtonFlags
|= MOUSE_LEFT_BUTTON_UP
;
259 if ((data
[0] & 0x02) && ((pdev_ext
->btn_old
& 0x02) != (data
[0] & 0x02)))
260 MouseInputData
.ButtonFlags
|= MOUSE_RIGHT_BUTTON_DOWN
;
261 else if (!(data
[0] & 0x02) && ((pdev_ext
->btn_old
& 0x02) != (data
[0] & 0x02)))
262 MouseInputData
.ButtonFlags
|= MOUSE_RIGHT_BUTTON_UP
;
264 if ((data
[0] & 0x04) && ((pdev_ext
->btn_old
& 0x04) != (data
[0] & 0x04)))
265 MouseInputData
.ButtonFlags
|= MOUSE_MIDDLE_BUTTON_DOWN
;
266 else if (!(data
[0] & 0x04) && ((pdev_ext
->btn_old
& 0x04) != (data
[0] & 0x04)))
267 MouseInputData
.ButtonFlags
|= MOUSE_MIDDLE_BUTTON_UP
;
269 if ((data
[0] & 0x08) && ((pdev_ext
->btn_old
& 0x08) != (data
[0] & 0x08)))
270 MouseInputData
.ButtonFlags
|= MOUSE_BUTTON_4_DOWN
;
271 else if (!(data
[0] & 0x08) && ((pdev_ext
->btn_old
& 0x08) != (data
[0] & 0x08)))
272 MouseInputData
.ButtonFlags
|= MOUSE_BUTTON_4_UP
;
274 if ((data
[0] & 0x10) && ((pdev_ext
->btn_old
& 0x10) != (data
[0] & 0x10)))
275 MouseInputData
.ButtonFlags
|= MOUSE_BUTTON_5_DOWN
;
276 else if (!(data
[0] & 0x10) && ((pdev_ext
->btn_old
& 0x10) != (data
[0] & 0x10)))
277 MouseInputData
.ButtonFlags
|= MOUSE_BUTTON_5_UP
;
281 MouseInputData
.ButtonFlags
|= MOUSE_WHEEL
;
282 MouseInputData
.ButtonData
= data
[3];
285 // Commit the input data somewhere...
286 if (MouseClassInformation
.ClassService
)
290 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
291 (*(PSERVICE_CALLBACK_ROUTINE
)MouseClassInformation
.ClassService
)(
292 MouseClassInformation
.ClassDeviceObject
,
296 KeLowerIrql(OldIrql
);
299 // Save old button data
300 pdev_ext
->btn_old
= data
[0];
303 status
= usb_submit_urb(pdev_ext
->dev_mgr
, purb
);
307 mouse_stop(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
)
309 UNREFERENCED_PARAMETER(dev_handle
);
310 UNREFERENCED_PARAMETER(dev_mgr
);
315 mouse_disconnect(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
)
317 PDEVICE_OBJECT dev_obj
;
322 if (dev_mgr
== NULL
|| dev_handle
== 0)
326 //special use of the lock dev, simply use this routine to get the dev
327 status
= usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
);
332 if (status
== STATUS_SUCCESS
)
336 usb_unlock_dev(pdev
);
338 pdrvr
= pdev
->dev_driver
;
339 dev_obj
= pdev
->dev_obj
;
342 return TRUE
;//umss_delete_device(dev_mgr, pdrvr, dev_obj, FALSE);
345 // Dispatch routine for our IRPs
347 MouseDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
349 NTSTATUS Status
= STATUS_INVALID_DEVICE_REQUEST
;
351 usb_dbg_print(DBGLVL_MAXIMUM
, ("MouseDispatch(DO %p, code 0x%lx) called\n",
353 IoGetCurrentIrpStackLocation(Irp
)->Parameters
.DeviceIoControl
.IoControlCode
));
355 if (DeviceObject
== KeyboardFdo
)
357 // it's keyboard's IOCTL
358 PIO_STACK_LOCATION Stk
;
360 Irp
->IoStatus
.Information
= 0;
361 Stk
= IoGetCurrentIrpStackLocation(Irp
);
363 switch (Stk
->Parameters
.DeviceIoControl
.IoControlCode
)
365 case IOCTL_INTERNAL_KEYBOARD_CONNECT
:
366 DPRINT("IOCTL_INTERNAL_KEYBOARD_CONNECT\n");
367 if (Stk
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(DEV_CONNECT_DATA
)) {
368 DPRINT1("Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT "
369 "invalid buffer size\n");
370 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
374 RtlCopyMemory(&KbdClassInformation
,
375 Stk
->Parameters
.DeviceIoControl
.Type3InputBuffer
,
376 sizeof(DEV_CONNECT_DATA
));
378 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
381 case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER
:
382 DPRINT("IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER\n");
383 if (Stk
->Parameters
.DeviceIoControl
.InputBufferLength
< 1) {
384 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
387 /* if (!DevExt->KeyboardInterruptObject) {
388 Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
392 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
394 case IOCTL_KEYBOARD_QUERY_ATTRIBUTES
:
395 DPRINT("IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n");
396 if (Stk
->Parameters
.DeviceIoControl
.OutputBufferLength
<
397 sizeof(KEYBOARD_ATTRIBUTES
)) {
398 DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_ATTRIBUTES: "
399 "invalid buffer size\n");
400 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
403 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
404 &DevExt->KeyboardAttributes,
405 sizeof(KEYBOARD_ATTRIBUTES));*/
407 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
409 case IOCTL_KEYBOARD_QUERY_INDICATORS
:
410 DPRINT("IOCTL_KEYBOARD_QUERY_INDICATORS\n");
411 if (Stk
->Parameters
.DeviceIoControl
.OutputBufferLength
<
412 sizeof(KEYBOARD_INDICATOR_PARAMETERS
)) {
413 DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_INDICATORS: "
414 "invalid buffer size\n");
415 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
418 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
419 &DevExt->KeyboardIndicators,
420 sizeof(KEYBOARD_INDICATOR_PARAMETERS));*/
422 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
424 case IOCTL_KEYBOARD_QUERY_TYPEMATIC
:
425 DPRINT("IOCTL_KEYBOARD_QUERY_TYPEMATIC\n");
426 if (Stk
->Parameters
.DeviceIoControl
.OutputBufferLength
<
427 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS
)) {
428 DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_TYPEMATIC: "
429 "invalid buffer size\n");
430 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
433 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
434 &DevExt->KeyboardTypematic,
435 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
437 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
439 case IOCTL_KEYBOARD_SET_INDICATORS
:
440 DPRINT("IOCTL_KEYBOARD_SET_INDICATORS\n");
441 if (Stk
->Parameters
.DeviceIoControl
.InputBufferLength
<
442 sizeof(KEYBOARD_INDICATOR_PARAMETERS
)) {
443 DPRINT("Keyboard IOCTL_KEYBOARD_SET_INDICTATORS: "
444 "invalid buffer size\n");
445 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
449 /*RtlCopyMemory(&DevExt->KeyboardIndicators,
450 Irp->AssociatedIrp.SystemBuffer,
451 sizeof(KEYBOARD_INDICATOR_PARAMETERS));*/
453 //DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags);
455 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
457 case IOCTL_KEYBOARD_SET_TYPEMATIC
:
458 DPRINT("IOCTL_KEYBOARD_SET_TYPEMATIC\n");
459 if (Stk
->Parameters
.DeviceIoControl
.InputBufferLength
<
460 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS
)) {
461 DPRINT("Keyboard IOCTL_KEYBOARD_SET_TYPEMATIC "
462 "invalid buffer size\n");
463 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
467 /*RtlCopyMemory(&DevExt->KeyboardTypematic,
468 Irp->AssociatedIrp.SystemBuffer,
469 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
471 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
473 case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION
:
474 /* We should check the UnitID, but it's kind of pointless as
475 * all keyboards are supposed to have the same one
477 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
478 &IndicatorTranslation,
479 sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION));*/
481 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
483 case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD
:
484 /* Nothing to do here */
485 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
488 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
493 Status
= Irp
->IoStatus
.Status
;
497 if (DeviceObject
== MouseFdo
)
499 // it's mouse's IOCTL
500 PIO_STACK_LOCATION Stk
;
502 Irp
->IoStatus
.Information
= 0;
503 Stk
= IoGetCurrentIrpStackLocation(Irp
);
505 switch (Stk
->Parameters
.DeviceIoControl
.IoControlCode
)
507 case IOCTL_INTERNAL_MOUSE_CONNECT
:
508 usb_dbg_print(DBGLVL_MAXIMUM
, ("IOCTL_INTERNAL_MOUSE_CONNECT\n"));
509 if (Stk
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(CONNECT_DATA
)) {
510 usb_dbg_print(DBGLVL_MINIMUM
, ("IOCTL_INTERNAL_MOUSE_CONNECT: "
511 "invalid buffer size\n"));
512 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
513 goto intcontfailure2
;
516 RtlCopyMemory(&MouseClassInformation
,
517 Stk
->Parameters
.DeviceIoControl
.Type3InputBuffer
,
518 sizeof(CONNECT_DATA
));
520 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
524 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;//STATUS_INVALID_DEVICE_REQUEST;
528 Status
= Irp
->IoStatus
.Status
;
531 if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
533 usb_dbg_print(DBGLVL_MINIMUM
, ("Invalid internal device request!\n"));
536 if (Status
!= STATUS_PENDING
)
537 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
544 IN PCWSTR PortTypeName
,
545 IN PUNICODE_STRING DeviceName
,
546 IN PCWSTR RegistryPath
)
548 UNICODE_STRING PathU
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP");
549 OBJECT_ATTRIBUTES ObjectAttributes
;
550 HANDLE hDeviceMapKey
= (HANDLE
)-1;
551 HANDLE hPortKey
= (HANDLE
)-1;
552 UNICODE_STRING PortTypeNameU
;
555 InitializeObjectAttributes(&ObjectAttributes
, &PathU
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
556 Status
= ZwOpenKey(&hDeviceMapKey
, 0, &ObjectAttributes
);
557 if (!NT_SUCCESS(Status
))
559 usb_dbg_print(DBGLVL_MINIMUM
, ("ZwOpenKey() failed with status 0x%08lx\n", Status
));
563 RtlInitUnicodeString(&PortTypeNameU
, PortTypeName
);
564 InitializeObjectAttributes(&ObjectAttributes
, &PortTypeNameU
, OBJ_KERNEL_HANDLE
, hDeviceMapKey
, NULL
);
565 Status
= ZwCreateKey(&hPortKey
, KEY_SET_VALUE
, &ObjectAttributes
, 0, NULL
, REG_OPTION_VOLATILE
, NULL
);
566 if (!NT_SUCCESS(Status
))
568 usb_dbg_print(DBGLVL_MINIMUM
, ("ZwCreateKey() failed with status 0x%08lx\n", Status
));
572 Status
= ZwSetValueKey(hPortKey
, DeviceName
, 0, REG_SZ
, (PVOID
)RegistryPath
, (ULONG
)(wcslen(RegistryPath
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
)));
573 if (!NT_SUCCESS(Status
))
575 usb_dbg_print(DBGLVL_MINIMUM
, ("ZwSetValueKey() failed with status 0x%08lx\n", Status
));
579 Status
= STATUS_SUCCESS
;
582 if (hDeviceMapKey
!= (HANDLE
)-1)
583 ZwClose(hDeviceMapKey
);
584 if (hPortKey
!= (HANDLE
)-1)
590 MouseCreateDevice(IN PDRIVER_OBJECT DriverObject
)
592 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\PointerPortUSB");
593 PDEVEXT_HEADER DeviceExtension
;
597 Status
= AddRegistryEntry(L
"PointerPort", &DeviceName
, L
"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbdriver");
598 if (!NT_SUCCESS(Status
))
600 usb_dbg_print(DBGLVL_MINIMUM
, ("AddRegistryEntry() for usb mouse driver failed with status 0x%08lx\n", Status
));
604 Status
= IoCreateDevice(DriverObject
,
605 sizeof(DEVEXT_HEADER
),
608 FILE_DEVICE_SECURE_OPEN
,
612 if (!NT_SUCCESS(Status
))
614 usb_dbg_print(DBGLVL_MINIMUM
, ("IoCreateDevice() for usb mouse driver failed with status 0x%08lx\n", Status
));
617 DeviceExtension
= (PDEVEXT_HEADER
)Fdo
->DeviceExtension
;
618 RtlZeroMemory(DeviceExtension
, sizeof(DEVEXT_HEADER
));
620 DeviceExtension
->dispatch
= MouseDispatch
;
623 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
624 usb_dbg_print(DBGLVL_MEDIUM
, ("Created mouse Fdo: %p\n", Fdo
));
626 return STATUS_SUCCESS
;