diff --git a/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c b/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c
index d978d6a402e..6ca86d1ba4a 100644
--- a/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c
+++ b/reactos/drivers/usb/nt4compat/usbdriver/compdrv.c
@@ -370,7 +370,7 @@ compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
TRAP();
}
- // let's scan the interfacs for those we recognize
+ // let's scan the interfaces for those we recognize
pconfig_desc = (PUSB_CONFIGURATION_DESC) buf;
if (pconfig_desc->wTotalLength > 512)
{
@@ -387,6 +387,9 @@ compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
return;
}
+ usb_dbg_print(DBGLVL_MAXIMUM, ("compdev_select_driver(): got %d interfaces\n",
+ (LONG)pconfig_desc->bNumInterfaces));
+
for(i = 0; i < (LONG) pconfig_desc->bNumInterfaces; i++)
{
for(j = 0, credit = 0, pcand = NULL; j < DEVMGR_MAX_DRIVERS; j++)
@@ -407,6 +410,7 @@ compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
param.dev_mgr = dev_mgr;
param.pdriver = pcand;
param.dev_handle = 0;
+ param.if_desc = pif_desc;
pcand->disp_tbl.dev_connect(¶m, usb_make_handle(dev_id, i, 0));
}
}
diff --git a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c
index 3e33097417c..d99dbddfe30 100644
--- a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c
+++ b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c
@@ -158,6 +158,12 @@ dev_mgr_driver_entry_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr)
pdrvr[GEN_IF_DRIVER_IDX].driver_init = gendrv_if_driver_init;
pdrvr[GEN_IF_DRIVER_IDX].driver_destroy = gendrv_if_driver_destroy;
+
+ pdrvr[MOUSE_DRIVER_IDX].driver_init = mouse_driver_init;
+ pdrvr[MOUSE_DRIVER_IDX].driver_destroy = mouse_driver_destroy;
+
+ //pdrvr[KEYBOARD_DRIVER_IDX].driver_init = gendrv_if_driver_init;
+ //pdrvr[KEYBOARD_DRIVER_IDX].driver_destroy = gendrv_if_driver_destroy;
}
BOOLEAN
diff --git a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h
index 625cb587c4b..91b4c1d4273 100644
--- a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h
+++ b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h
@@ -6,6 +6,7 @@ typedef struct _CONNECT_DATA
DEV_HANDLE dev_handle;
struct _USB_DRIVER *pdriver;
struct _USB_DEV_MANAGER *dev_mgr;
+ PUSB_INTERFACE_DESC if_desc;
} CONNECT_DATA, *PCONNECT_DATA;
@@ -49,13 +50,15 @@ typedef struct _USB_DRIVER_DESCRIPTION
} USB_DRIVER_DESCRIPTION,*PUSB_DRIVER_DESCRIPTION;
-#define DEVMGR_MAX_DRIVERS 6
+#define DEVMGR_MAX_DRIVERS 7//8
#define RH_DRIVER_IDX 0
#define HUB_DRIVER_IDX 1
#define UMSS_DRIVER_IDX 2
#define COMP_DRIVER_IDX 3
#define GEN_DRIVER_IDX 4
#define GEN_IF_DRIVER_IDX 5
+#define MOUSE_DRIVER_IDX 6
+#define KEYBOARD_DRIVER_IDX 7//temp disabled
typedef struct _USB_DRIVER
{
diff --git a/reactos/drivers/usb/nt4compat/usbdriver/mouse.c b/reactos/drivers/usb/nt4compat/usbdriver/mouse.c
new file mode 100644
index 00000000000..6e79298c6d4
--- /dev/null
+++ b/reactos/drivers/usb/nt4compat/usbdriver/mouse.c
@@ -0,0 +1,365 @@
+/*
+ * PROJECT: ReactOS USB Drivers
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: mouse.c
+ * PURPOSE: Generic USB mouse driver
+ * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
+ */
+
+#include "usbdriver.h"
+#include "ntddmou.h"
+
+BOOLEAN mouse_connect(PCONNECT_DATA dev_mgr, DEV_HANDLE dev_handle);
+BOOLEAN mouse_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
+BOOLEAN mouse_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
+
+VOID mouse_irq(PURB purb, PVOID pcontext);
+VOID mouse_set_cfg_completion(PURB purb, PVOID pcontext);
+
+
+BOOLEAN
+mouse_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
+{
+ PMOUSE_DRVR_EXTENSION pdrvr_ext;
+
+ if (dev_mgr == NULL || pdriver == NULL)
+ return FALSE;
+
+ //init driver structure, no PNP table functions
+ pdriver->driver_desc.flags = USB_DRIVER_FLAG_IF_CAPABLE;
+ pdriver->driver_desc.vendor_id = 0xffff; // USB Vendor ID
+ pdriver->driver_desc.product_id = 0xffff; // USB Product ID.
+ pdriver->driver_desc.release_num = 0x100; // Release Number of Device
+
+ pdriver->driver_desc.config_val = 1; // Configuration Value
+ pdriver->driver_desc.if_num = 1; // Interface Number
+ pdriver->driver_desc.if_class = USB_CLASS_HID; // Interface Class
+ pdriver->driver_desc.if_sub_class = 1; // Interface SubClass
+ pdriver->driver_desc.if_protocol = 2; // Interface Protocol
+
+ pdriver->driver_desc.driver_name = "USB Mouse driver"; // Driver name for Name Registry
+ pdriver->driver_desc.dev_class = USB_CLASS_HID;
+ pdriver->driver_desc.dev_sub_class = 1; // Device Subclass
+ pdriver->driver_desc.dev_protocol = 2; // Protocol Info.
+
+ pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(MOUSE_DRVR_EXTENSION));
+ pdriver->driver_ext_size = sizeof(MOUSE_DRVR_EXTENSION);
+
+ RtlZeroMemory(pdriver->driver_ext, sizeof(MOUSE_DRVR_EXTENSION));
+ pdrvr_ext = (PMOUSE_DRVR_EXTENSION) pdriver->driver_ext;
+ pdrvr_ext->dev_mgr = dev_mgr;
+
+ pdriver->disp_tbl.version = 1;
+ pdriver->disp_tbl.dev_connect = mouse_connect;
+ pdriver->disp_tbl.dev_disconnect = mouse_disconnect;
+ pdriver->disp_tbl.dev_stop = mouse_stop;
+ pdriver->disp_tbl.dev_reserved = NULL;
+
+ usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_driver_init(): mouse driver is initialized\n"));
+ return TRUE;
+}
+
+BOOLEAN
+mouse_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
+{
+ //PMOUSE_DRVR_EXTENSION pdrvr_ext;
+ if (dev_mgr == NULL || pdriver == NULL)
+ return FALSE;
+
+ //pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdriver->driver_ext;
+ //umss_delete_port_device(pdrvr_ext->port_dev_obj);
+ //pdrvr_ext->port_dev_obj = NULL;
+
+ //ASSERT(IsListEmpty(&pdrvr_ext->dev_list) == TRUE);
+ usb_free_mem(pdriver->driver_ext);
+ pdriver->driver_ext = NULL;
+ pdriver->driver_ext_size = 0;
+ usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_driver_destroy(): mouse driver is destroyed\n"));
+ return TRUE;
+}
+
+BOOLEAN
+mouse_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle)
+{
+ PURB purb;
+ NTSTATUS status;
+ PUSB_DEV_MANAGER dev_mgr;
+ PUSB_DRIVER pdrvr;
+ PUSB_DEV pdev;
+ PMOUSE_DRVR_EXTENSION pdev_ext;
+// LONG i;
+ PUSB_ENDPOINT_DESC pendp_desc = NULL;
+ ULONG MaxPacketSize;
+
+ usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_connect(): entering...\n"));
+
+ dev_mgr = param->dev_mgr;
+ pdrvr = param->pdriver;
+ pdev_ext = (PMOUSE_DRVR_EXTENSION)pdrvr->driver_ext;
+
+ // Lock USB Device
+ status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
+ if (status != STATUS_SUCCESS)
+ {
+ //usb_free_mem(desc_buf);
+ usb_dbg_print(DBGLVL_MEDIUM, ("mouse_connect(): unable to query&lock device, status=0x%x\n", status));
+ return FALSE;
+ }
+
+ // Endpoint-finding code
+ if (param->if_desc)
+ {
+ // Get a pointer to the config packet from compdev
+ PUCHAR Buffer = (PUCHAR)param->if_desc;
+ ULONG Offset = 0;
+ BOOLEAN FoundEndpoint = FALSE;
+
+ // Find our the only needed endpoint descriptor
+ while (Offset < 512)
+ {
+ pendp_desc = (PUSB_ENDPOINT_DESC)&Buffer[Offset];
+ usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_connect(): DescType=0x%x, Attrs=0x%x, Len=%d\n",
+ pendp_desc->bDescriptorType, pendp_desc->bmAttributes, pendp_desc->bLength));
+
+ if (pendp_desc->bDescriptorType == USB_DT_ENDPOINT &&
+ pendp_desc->bLength == sizeof(USB_ENDPOINT_DESC))
+ {
+ // Found it
+ FoundEndpoint = TRUE;
+ break;
+ }
+
+ Offset += pendp_desc->bLength;
+ }
+
+ if (!FoundEndpoint)
+ return FALSE;
+
+ // FIXME: Check if it's INT endpoint
+ // (pendp_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
+
+ // endpoint must be IN
+ if ((pendp_desc->bEndpointAddress & USB_DIR_IN) == 0)
+ return FALSE;
+ }
+
+
+ // Endpoint descriptor substitution code
+ {
+ ULONG if_idx, endp_idx;
+ PUSB_ENDPOINT pendp;
+
+ //FoundEndpoint = FALSE;
+ for(if_idx = 0; if_idx < MAX_INTERFACES_PER_CONFIG /*pdev->usb_config->if_count*/; if_idx++)
+ {
+ for(endp_idx = 0; endp_idx < MAX_ENDPS_PER_IF /*pdev->usb_config->interf[if_idx].endp_count*/; endp_idx++)
+ {
+ pendp = &pdev->usb_config->interf[if_idx].endp[endp_idx];
+
+ if (pendp->pusb_endp_desc != NULL)
+ {
+ //HACKHACK: for some reason this usb driver chooses different and completely wrong
+ // endpoint. Since I don't have time to research this, I just find the
+ // endpoint descriptor myself and copy it
+ memcpy(pendp->pusb_endp_desc, pendp_desc, pendp_desc->bLength);
+
+ usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_connect(): [%i][%i] DescType=0x%x, Attrs=0x%x, Len=%d\n",if_idx, endp_idx,
+ pendp->pusb_endp_desc->bDescriptorType, pendp->pusb_endp_desc->bmAttributes, pendp->pusb_endp_desc->bLength));
+ }
+ }
+ }
+ }
+
+ // Unlock USB Device
+ usb_unlock_dev(pdev);
+
+ // Send URB
+ purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
+ if (purb == NULL)
+ return FALSE;
+ RtlZeroMemory(purb, sizeof(URB));
+
+ MaxPacketSize = pendp_desc->wMaxPacketSize;
+ if (MaxPacketSize > 8)
+ MaxPacketSize = 8;
+
+ // Build a URB for our interrupt transfer
+ UsbBuildInterruptOrBulkTransferRequest(purb,
+ usb_make_handle((dev_handle >> 16), 0, 0),
+ (PUCHAR)&pdev_ext->mouse_data,
+ MaxPacketSize, //use max packet size
+ mouse_irq,
+ pdev_ext,
+ 0);
+
+ // Call USB driver stack
+ status = usb_submit_urb(pdev_ext->dev_mgr, purb);
+ if (status != STATUS_PENDING)
+ {
+ usb_free_mem(purb);
+ purb = NULL;
+ }
+
+ return TRUE;
+}
+
+// pcontext == device extension
+VOID
+mouse_set_cfg_completion(PURB purb, PVOID pcontext)
+{
+ PMOUSE_DRVR_EXTENSION pdev_ext = (PMOUSE_DRVR_EXTENSION)pcontext;
+ DEV_HANDLE endp_handle;
+ NTSTATUS status;
+
+ if (purb->status != STATUS_SUCCESS)
+ {
+ usb_free_mem(purb);
+ return;
+ }
+
+ endp_handle = purb->endp_handle;
+
+ //usb_free_mem(purb);
+ //purb = NULL;
+
+ usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_set_cfg_completion() endpoint handle=0x%x\n", endp_handle));
+
+ // Build a URB for our interrupt transfer
+ UsbBuildInterruptOrBulkTransferRequest(purb,
+ endp_handle,
+ /*usb_make_handle((pdev_ext->dev_handle >> 16), pdev_ext->if_idx,
+ pdev_ext->int_endp_idx),*/
+ (PUCHAR)&pdev_ext->mouse_data,
+ 4, // FIXME: use max packet size!
+ mouse_irq,
+ pdev_ext,
+ 0);
+
+ // Call USB driver stack
+ status = usb_submit_urb(pdev_ext->dev_mgr, purb);
+ if (status != STATUS_PENDING)
+ {
+ usb_free_mem(purb);
+ purb = NULL;
+ }
+}
+
+
+VOID
+mouse_irq(PURB purb, PVOID pcontext)
+{
+ MOUSE_INPUT_DATA MouseInputData;
+ //ULONG InputDataConsumed;
+ NTSTATUS status;
+ PMOUSE_DRVR_EXTENSION pdev_ext = (PMOUSE_DRVR_EXTENSION)pcontext;
+ signed char *data = pdev_ext->mouse_data;
+ usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_irq(): called\n"));
+
+ ASSERT(purb);
+
+ if (purb->status != STATUS_SUCCESS)
+ {
+ usb_dbg_print(DBGLVL_MAXIMUM, ("mouse_irq(): purb->status 0x%08X\n", purb->status));
+ //return;
+ }
+
+ 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]));
+
+ // Fill mouse input data structure
+ MouseInputData.Flags = MOUSE_MOVE_RELATIVE;
+ MouseInputData.LastX = data[1];
+ MouseInputData.LastY = data[2];
+
+ MouseInputData.ButtonFlags = 0;
+ MouseInputData.ButtonData = 0;
+
+ if ((data[0] & 0x01) && ((pdev_ext->btn_old & 0x01) != (data[0] & 0x01)))
+ MouseInputData.ButtonFlags |= MOUSE_LEFT_BUTTON_DOWN;
+ else if (!(data[0] & 0x01) && ((pdev_ext->btn_old & 0x01) != (data[0] & 0x01)))
+ MouseInputData.ButtonFlags |= MOUSE_LEFT_BUTTON_UP;
+
+ if ((data[0] & 0x02) && ((pdev_ext->btn_old & 0x02) != (data[0] & 0x02)))
+ MouseInputData.ButtonFlags |= MOUSE_RIGHT_BUTTON_DOWN;
+ else if (!(data[0] & 0x02) && ((pdev_ext->btn_old & 0x02) != (data[0] & 0x02)))
+ MouseInputData.ButtonFlags |= MOUSE_RIGHT_BUTTON_UP;
+
+ if ((data[0] & 0x04) && ((pdev_ext->btn_old & 0x04) != (data[0] & 0x04)))
+ MouseInputData.ButtonFlags |= MOUSE_MIDDLE_BUTTON_DOWN;
+ else if (!(data[0] & 0x04) && ((pdev_ext->btn_old & 0x04) != (data[0] & 0x04)))
+ MouseInputData.ButtonFlags |= MOUSE_MIDDLE_BUTTON_UP;
+
+ if ((data[0] & 0x08) && ((pdev_ext->btn_old & 0x08) != (data[0] & 0x08)))
+ MouseInputData.ButtonFlags |= MOUSE_BUTTON_4_DOWN;
+ else if (!(data[0] & 0x08) && ((pdev_ext->btn_old & 0x08) != (data[0] & 0x08)))
+ MouseInputData.ButtonFlags |= MOUSE_BUTTON_4_UP;
+
+ if ((data[0] & 0x10) && ((pdev_ext->btn_old & 0x10) != (data[0] & 0x10)))
+ MouseInputData.ButtonFlags |= MOUSE_BUTTON_5_DOWN;
+ else if (!(data[0] & 0x10) && ((pdev_ext->btn_old & 0x10) != (data[0] & 0x10)))
+ MouseInputData.ButtonFlags |= MOUSE_BUTTON_5_UP;
+
+ if (data[3])
+ {
+ MouseInputData.ButtonFlags |= MOUSE_WHEEL;
+ MouseInputData.ButtonData = data[3];
+ }
+
+ // Commit the input data somewhere...
+ /*if (UsbPortInterface.MouseConnectData->ClassService)
+ {
+ KIRQL OldIrql;
+
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+ (*(PSERVICE_CALLBACK_ROUTINE)UsbPortInterface.MouseConnectData->ClassService)(
+ UsbPortInterface.MouseConnectData->ClassDeviceObject,
+ &MouseInputData,
+ (&MouseInputData)+1,
+ &InputDataConsumed);
+ KeLowerIrql(OldIrql);
+ }*/
+
+ // Save old button data
+ pdev_ext->btn_old = data[0];
+
+ // resubmit the urb
+ status = usb_submit_urb(pdev_ext->dev_mgr, purb);
+}
+
+BOOLEAN
+mouse_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
+{
+ UNREFERENCED_PARAMETER(dev_handle);
+ UNREFERENCED_PARAMETER(dev_mgr);
+ return TRUE;
+}
+
+BOOLEAN
+mouse_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
+{
+ PDEVICE_OBJECT dev_obj;
+ NTSTATUS status;
+ PUSB_DEV pdev;
+ PUSB_DRIVER pdrvr;
+
+ if (dev_mgr == NULL || dev_handle == 0)
+ return FALSE;
+
+ pdev = NULL;
+ //special use of the lock dev, simply use this routine to get the dev
+ status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
+ if (pdev == NULL)
+ {
+ return FALSE;
+ }
+ if (status == STATUS_SUCCESS)
+ {
+ // must be a bug
+ TRAP();
+ usb_unlock_dev(pdev);
+ }
+ pdrvr = pdev->dev_driver;
+ dev_obj = pdev->dev_obj;
+ pdev = NULL;
+
+ return TRUE;//umss_delete_device(dev_mgr, pdrvr, dev_obj, FALSE);
+}
diff --git a/reactos/drivers/usb/nt4compat/usbdriver/mouse.h b/reactos/drivers/usb/nt4compat/usbdriver/mouse.h
new file mode 100644
index 00000000000..6162b9b8b8f
--- /dev/null
+++ b/reactos/drivers/usb/nt4compat/usbdriver/mouse.h
@@ -0,0 +1,23 @@
+#ifndef __MOUSE_H__
+#define __MOUSE_H__
+
+typedef struct _MOUSE_DRVR_EXTENSION
+{
+ //INTERRUPT_DATA_BLOCK idb;
+ PUSB_INTERFACE_DESC pif_desc;
+ UCHAR if_idx, out_endp_idx, in_endp_idx, int_endp_idx;
+ PUSB_ENDPOINT_DESC pout_endp_desc, pin_endp_desc, pint_endp_desc;
+
+ PUSB_DEV_MANAGER dev_mgr;
+ signed char mouse_data[8];
+ UCHAR btn_old;
+} MOUSE_DRVR_EXTENSION, *PMOUSE_DRVR_EXTENSION;
+
+
+BOOLEAN
+mouse_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver);
+
+BOOLEAN
+mouse_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver);
+
+#endif
diff --git a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c
index bf9a559c849..f54c61fac9b 100644
--- a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c
+++ b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c
@@ -1241,6 +1241,8 @@ uhci_process_pending_endp(PUHCI_DEV uhci)
}
// if can_submit is STATUS_SUCCESS, the purb is inserted into the schedule
+ uhci_dbg_print(DBGLVL_MAXIMUM, ("uhci_process_pending_endp(): endp_type=0x%x\n",
+ endp_type(pendp)));
switch (endp_type(pendp))
{
case USB_ENDPOINT_XFER_BULK:
diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usb.c b/reactos/drivers/usb/nt4compat/usbdriver/usb.c
index e7eb2edb599..73859497e65 100644
--- a/reactos/drivers/usb/nt4compat/usbdriver/usb.c
+++ b/reactos/drivers/usb/nt4compat/usbdriver/usb.c
@@ -781,7 +781,6 @@ LBL_OUT:
return status;
}
-
void
usb_config_dev_completion(PURB purb, PVOID context)
{
diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usb.h b/reactos/drivers/usb/nt4compat/usbdriver/usb.h
index 8a622ca3d3a..aaa9a76b750 100644
--- a/reactos/drivers/usb/nt4compat/usbdriver/usb.h
+++ b/reactos/drivers/usb/nt4compat/usbdriver/usb.h
@@ -955,6 +955,15 @@ ULONG endp_ref,
PURB purb
);
+void usb_fill_int_urb(PURB urb,
+ struct _USB_DEV *dev,
+ ULONG pipe,
+ PVOID transfer_buffer,
+ LONG buffer_length,
+ PURBCOMPLETION complete,
+ PVOID context,
+ int interval);
+
LONG
usb_calc_bus_time(
LONG low_speed,
diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h
index a6c26a36927..29c6d6b144b 100644
--- a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h
+++ b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.h
@@ -26,4 +26,5 @@
#include "devmgr.h"
#include "hub.h"
#include "umss.h"
+#include "mouse.h"
#include "uhciver.h"
diff --git a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild
index 04796ba9a89..f15c7bcf89c 100644
--- a/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild
+++ b/reactos/drivers/usb/nt4compat/usbdriver/usbdriver.rbuild
@@ -18,6 +18,7 @@
compdrv.c
etd.c
gendrv.c
+ mouse.c
usbdriver.rc
usbdriver.h