https://git.reactos.org/?p=reactos.git;a=commitdiff;h=310a24da6ecd65c2bee0d84f73f7fc13175cdf92

commit 310a24da6ecd65c2bee0d84f73f7fc13175cdf92
Author:     Dmitry Borisov <[email protected]>
AuthorDate: Sun Sep 13 17:42:48 2020 +0600
Commit:     Stanislav Motylkov <[email protected]>
CommitDate: Sat Oct 10 16:46:16 2020 +0300

    [INPORT] Add driver for bus mouse devices (#3173)
    
    It adds basic input support for:
    - Standard Bus Mouse
    - Standard InPort Mouse
    - Logitech Bus Mouse
    - Microsoft Bus Mouse
    - Microsoft InPort Mouse
    - NEC PC-98 Bus Mouse
    
    Untested on PC/AT, but should work.
---
 boot/bootdata/txtsetup.sif          |   4 +
 drivers/input/CMakeLists.txt        |   1 +
 drivers/input/inport/CMakeLists.txt |  15 ++
 drivers/input/inport/hardware.c     | 433 ++++++++++++++++++++++++++++++++++++
 drivers/input/inport/inport.c       | 238 ++++++++++++++++++++
 drivers/input/inport/inport.h       | 158 +++++++++++++
 drivers/input/inport/inport.rc      |   5 +
 drivers/input/inport/ioctl.c        |  83 +++++++
 drivers/input/inport/pnp.c          | 283 +++++++++++++++++++++++
 drivers/input/inport/wmi.c          | 202 +++++++++++++++++
 media/inf/msmouse.inf               | 141 ++++++++++++
 11 files changed, 1563 insertions(+)

diff --git a/boot/bootdata/txtsetup.sif b/boot/bootdata/txtsetup.sif
index 5e2f0376e97..2b7b04002e2 100644
--- a/boot/bootdata/txtsetup.sif
+++ b/boot/bootdata/txtsetup.sif
@@ -174,6 +174,7 @@ GenDisk = disk
 USB\Class_03 = hidusb
 GENERIC_HID_DEVICE = hidusb
 *PNP0303 = i8042prt,{4D36E96B-E325-11CE-BFC1-08002BE10318}
+*nEC1F00 = inport,{4D36E96F-E325-11CE-BFC1-08002BE10318}
 ROOT\SWENUM = swenum
 
 [BootBusExtenders.Load]
@@ -203,6 +204,9 @@ buslogic = buslogic.sys
 storahci = storahci.sys
 disk = disk.sys
 
+[MouseDrivers.Load]
+inport = inport.sys
+
 [Cabinets]
 Cabinet=reactos.cab
 
diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt
index 0c70af1c8e1..ea103ab1d63 100644
--- a/drivers/input/CMakeLists.txt
+++ b/drivers/input/CMakeLists.txt
@@ -1,5 +1,6 @@
 
 add_subdirectory(i8042prt)
+add_subdirectory(inport)
 add_subdirectory(kbdclass)
 add_subdirectory(mouclass)
 add_subdirectory(sermouse)
diff --git a/drivers/input/inport/CMakeLists.txt 
b/drivers/input/inport/CMakeLists.txt
new file mode 100644
index 00000000000..1935d6dcf12
--- /dev/null
+++ b/drivers/input/inport/CMakeLists.txt
@@ -0,0 +1,15 @@
+
+list(APPEND SOURCE
+    hardware.c
+    inport.c
+    inport.h
+    ioctl.c
+    pnp.c
+    wmi.c)
+
+add_library(inport MODULE ${SOURCE} inport.rc)
+
+set_module_type(inport kernelmodedriver)
+add_pch(inport inport.h SOURCE)
+add_importlibs(inport ntoskrnl hal wmilib)
+add_cd_file(TARGET inport DESTINATION reactos/system32/drivers FOR all)
diff --git a/drivers/input/inport/hardware.c b/drivers/input/inport/hardware.c
new file mode 100644
index 00000000000..6cc1583c860
--- /dev/null
+++ b/drivers/input/inport/hardware.c
@@ -0,0 +1,433 @@
+/*
+ * PROJECT:     ReactOS InPort (Bus) Mouse Driver
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Hardware support code
+ * COPYRIGHT:   Copyright 2020 Dmitry Borisov ([email protected])
+ */
+
+/* Note: Some code was taken from Linux */
+
+/* INCLUDES 
*******************************************************************/
+
+#include "inport.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS 
********************************************************************/
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, InPortInitializeMouse)
+#endif
+
+#define READ_MOUSE(DeviceExtension, Port) \
+    READ_PORT_UCHAR((DeviceExtension)->IoBase + (Port))
+
+#define WRITE_MOUSE(DeviceExtension, Port, Data) \
+    WRITE_PORT_UCHAR((DeviceExtension)->IoBase + (Port), (Data))
+
+/*
+ * NEC
+ */
+#define NEC_BM_DATA          0x00
+
+#define NEC_BM_CONTROL       0x04
+    #define NEC_INT_ENABLE       0x00
+    #define NEC_INT_DISABLE      0x10
+
+    #define NEC_READ_X_LOW       0x00
+    #define NEC_READ_X_HIGH      0x20
+    #define NEC_READ_Y_LOW       0x40
+    #define NEC_READ_Y_HIGH      0x60
+
+    #define NEC_INPUT_CAPTURE    0x00
+    #define NEC_INPUT_HOLD       0x80
+
+#define NEC_BM_CONFIG        0x06
+    #define NEC_PPI_INT_ENABLE   0x08
+    #define NEC_PPI_INT_DISABLE  0x09
+    #define NEC_PPI_HC_NO_CLEAR  0x0E
+    #define NEC_PPI_HC_CLEAR     0x0F
+    #define NEC_PPI_DEFAULT_MODE 0x93
+
+#define NEC_BM_INT_RATE      0x4002
+    #define NEC_RATE_120_HZ      0x00
+    #define NEC_RATE_60_HZ       0x01
+    #define NEC_RATE_30_HZ       0x02
+    #define NEC_RATE_15_HZ       0x03
+
+#define NEC_BM_HIRESO_BASE   (PUCHAR)0x61
+
+#define NEC_BUTTON_RIGHT    0x20
+#define NEC_BUTTON_LEFT     0x80
+
+/*
+ * Microsoft InPort
+ */
+#define MS_INPORT_CONTROL    0x00
+    #define INPORT_REG_BTNS    0x00
+    #define INPORT_REG_X       0x01
+    #define INPORT_REG_Y       0x02
+    #define INPORT_REG_MODE    0x07
+    #define INPORT_RESET       0x80
+
+#define MS_INPORT_DATA       0x01
+    #define INPORT_MODE_IRQ    0x01
+    #define INPORT_MODE_BASE   0x10
+    #define INPORT_MODE_HOLD   0x20
+
+#define MS_INPORT_SIGNATURE  0x02
+
+#define MS_BUTTON_MIDDLE   0x01
+#define MS_BUTTON_LEFT     0x02
+#define MS_BUTTON_RIGHT    0x04
+
+/*
+ * Logitech
+ */
+#define LOG_BM_DATA          0x00
+
+#define LOG_BM_SIGNATURE     0x01
+    #define LOG_SIGNATURE_BYTE 0xA5
+
+#define LOG_BM_CONTROL       0x02
+    #define LOG_ENABLE_IRQ     0x00
+    #define LOG_DISABLE_IRQ    0x10
+
+    #define LOG_READ_X_LOW     0x80
+    #define LOG_READ_X_HIGH    0xA0
+    #define LOG_READ_Y_LOW     0xC0
+    #define LOG_READ_Y_HIGH    0xE0
+
+#define LOG_BM_CONFIG        0x03
+    #define LOG_DEFAULT_MODE   0x90
+    #define LOG_CONFIG_BYTE    0x91
+
+#define LOG_BUTTON_RIGHT     0x20
+#define LOG_BUTTON_MIDDLE    0x40
+#define LOG_BUTTON_LEFT      0x80
+
+/* FUNCTIONS 
******************************************************************/
+
+VOID
+NTAPI
+InPortDpcForIsr(
+    _In_ PKDPC Dpc,
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp,
+    _In_opt_ PVOID Context)
+{
+    PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    KIRQL OldIrql;
+    ULONG DummyInputDataConsumed;
+    INPORT_RAW_DATA RawData;
+
+    UNREFERENCED_PARAMETER(Dpc);
+    UNREFERENCED_PARAMETER(Irp);
+    UNREFERENCED_PARAMETER(Context);
+
+    /* Copy raw data */
+    OldIrql = KeAcquireInterruptSpinLock(DeviceExtension->InterruptObject);
+    RawData = DeviceExtension->RawData;
+    KeReleaseInterruptSpinLock(DeviceExtension->InterruptObject, OldIrql);
+
+    /* Fill out fields */
+    DeviceExtension->MouseInputData.LastX = RawData.DeltaX;
+    DeviceExtension->MouseInputData.LastY = RawData.DeltaY;
+    DeviceExtension->MouseInputData.ButtonFlags = 0;
+    if (RawData.ButtonDiff != 0)
+    {
+        switch (DeviceExtension->MouseType)
+        {
+            case NecBusMouse:
+            {
+                if (RawData.ButtonDiff & NEC_BUTTON_LEFT)
+                {
+                    if (RawData.Buttons & NEC_BUTTON_LEFT)
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_LEFT_BUTTON_UP;
+                    else
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_LEFT_BUTTON_DOWN;
+                }
+                if (RawData.ButtonDiff & NEC_BUTTON_RIGHT)
+                {
+                    if (RawData.Buttons & NEC_BUTTON_RIGHT)
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_RIGHT_BUTTON_UP;
+                    else
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_RIGHT_BUTTON_DOWN;
+                }
+
+                break;
+            }
+
+            case MsInPortMouse:
+            {
+                /* Button flags have to be inverted */
+                if (RawData.ButtonDiff & MS_BUTTON_LEFT)
+                {
+                    if (RawData.Buttons & MS_BUTTON_LEFT)
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_LEFT_BUTTON_DOWN;
+                    else
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_LEFT_BUTTON_UP;
+                }
+                if (RawData.ButtonDiff & MS_BUTTON_RIGHT)
+                {
+                    if (RawData.Buttons & MS_BUTTON_RIGHT)
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_RIGHT_BUTTON_DOWN;
+                    else
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_RIGHT_BUTTON_UP;
+                }
+                if (RawData.ButtonDiff & MS_BUTTON_MIDDLE)
+                {
+                    if (RawData.Buttons & MS_BUTTON_MIDDLE)
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_MIDDLE_BUTTON_DOWN;
+                    else
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_MIDDLE_BUTTON_UP;
+                }
+
+                break;
+            }
+
+            case LogitechBusMouse:
+            {
+                if (RawData.ButtonDiff & LOG_BUTTON_LEFT)
+                {
+                    if (RawData.Buttons & LOG_BUTTON_LEFT)
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_LEFT_BUTTON_UP;
+                    else
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_LEFT_BUTTON_DOWN;
+                }
+                if (RawData.ButtonDiff & LOG_BUTTON_RIGHT)
+                {
+                    if (RawData.Buttons & LOG_BUTTON_RIGHT)
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_RIGHT_BUTTON_UP;
+                    else
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_RIGHT_BUTTON_DOWN;
+                }
+                if (RawData.ButtonDiff & LOG_BUTTON_MIDDLE)
+                {
+                    if (RawData.Buttons & LOG_BUTTON_MIDDLE)
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_MIDDLE_BUTTON_UP;
+                    else
+                        DeviceExtension->MouseInputData.ButtonFlags |= 
MOUSE_MIDDLE_BUTTON_DOWN;
+                }
+
+                break;
+            }
+        }
+    }
+
+    /* Send mouse packet */
+    (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassService)(
+        DeviceExtension->ClassDeviceObject,
+        &DeviceExtension->MouseInputData,
+        &DeviceExtension->MouseInputData + 1,
+        &DummyInputDataConsumed);
+}
+
+BOOLEAN
+NTAPI
+InPortIsr(
+    _In_ PKINTERRUPT Interrupt,
+    _In_ PVOID Context)
+{
+    UCHAR Buttons;
+    ULONG ButtonDiff;
+    CHAR DeltaX, DeltaY;
+    PINPORT_DEVICE_EXTENSION DeviceExtension = Context;
+
+    UNREFERENCED_PARAMETER(Interrupt);
+
+    switch (DeviceExtension->MouseType)
+    {
+        case NecBusMouse:
+        {
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONTROL,
+                        NEC_INPUT_CAPTURE | NEC_INT_DISABLE);
+
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONTROL,
+                        NEC_INPUT_HOLD | NEC_INT_DISABLE | NEC_READ_X_LOW);
+            DeltaX = READ_MOUSE(DeviceExtension, NEC_BM_DATA) & 0x0F;
+
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONTROL,
+                        NEC_INPUT_HOLD | NEC_INT_DISABLE | NEC_READ_X_HIGH);
+            DeltaX |= READ_MOUSE(DeviceExtension, NEC_BM_DATA) << 4;
+
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONTROL,
+                        NEC_INPUT_HOLD | NEC_INT_DISABLE | NEC_READ_Y_LOW);
+            DeltaY = READ_MOUSE(DeviceExtension, NEC_BM_DATA) & 0x0F;
+
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONTROL,
+                        NEC_INPUT_HOLD | NEC_INT_DISABLE | NEC_READ_Y_HIGH);
+            Buttons = READ_MOUSE(DeviceExtension, NEC_BM_DATA);
+            DeltaY |= Buttons << 4;
+            Buttons &= (NEC_BUTTON_LEFT | NEC_BUTTON_RIGHT);
+
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONTROL,
+                        NEC_INPUT_HOLD | NEC_INT_ENABLE);
+
+            break;
+        }
+
+        case MsInPortMouse:
+        {
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_CONTROL, INPORT_REG_MODE);
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_DATA,
+                        INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE);
+
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_CONTROL, INPORT_REG_X);
+            DeltaX = READ_MOUSE(DeviceExtension, MS_INPORT_DATA);
+
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_CONTROL, INPORT_REG_Y);
+            DeltaY = READ_MOUSE(DeviceExtension, MS_INPORT_DATA);
+
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_CONTROL, INPORT_REG_BTNS);
+            Buttons = READ_MOUSE(DeviceExtension, MS_INPORT_DATA);
+            Buttons &= (MS_BUTTON_MIDDLE | MS_BUTTON_LEFT | MS_BUTTON_RIGHT);
+
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_CONTROL, INPORT_REG_MODE);
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_DATA,
+                        INPORT_MODE_IRQ | INPORT_MODE_BASE);
+
+            break;
+        }
+
+        case LogitechBusMouse:
+        {
+            WRITE_MOUSE(DeviceExtension, LOG_BM_CONTROL, LOG_READ_X_LOW);
+            DeltaX = READ_MOUSE(DeviceExtension, LOG_BM_DATA) & 0x0F;
+
+            WRITE_MOUSE(DeviceExtension, LOG_BM_CONTROL, LOG_READ_X_HIGH);
+            DeltaX |= READ_MOUSE(DeviceExtension, LOG_BM_DATA) << 4;
+
+            WRITE_MOUSE(DeviceExtension, LOG_BM_CONTROL, LOG_READ_Y_LOW);
+            DeltaY = READ_MOUSE(DeviceExtension, LOG_BM_DATA) & 0x0F;
+
+            WRITE_MOUSE(DeviceExtension, LOG_BM_CONTROL, LOG_READ_Y_HIGH);
+            Buttons = READ_MOUSE(DeviceExtension, LOG_BM_DATA);
+            DeltaY |= Buttons << 4;
+            Buttons &= (LOG_BUTTON_RIGHT | LOG_BUTTON_MIDDLE | 
LOG_BUTTON_LEFT);
+
+            WRITE_MOUSE(DeviceExtension, LOG_BM_CONTROL, LOG_ENABLE_IRQ);
+
+            break;
+        }
+    }
+
+    ButtonDiff = DeviceExtension->MouseButtonState ^ Buttons;
+    DeviceExtension->MouseButtonState = Buttons;
+
+    /*
+     * Bus mouse devices don't have a status register to check
+     * whether this interrupt is indeed for us.
+     */
+    if ((DeltaX == 0) && (DeltaY == 0) && (ButtonDiff == 0))
+    {
+        /* We just pretend that the interrupt is not ours */
+        return FALSE;
+    }
+    else
+    {
+        DeviceExtension->RawData.DeltaX = DeltaX;
+        DeviceExtension->RawData.DeltaY = DeltaY;
+        DeviceExtension->RawData.Buttons = Buttons;
+        DeviceExtension->RawData.ButtonDiff = ButtonDiff;
+
+        IoRequestDpc(DeviceExtension->Self, NULL, NULL);
+
+        return TRUE;
+    }
+}
+
+VOID
+NTAPI
+InPortInitializeMouse(
+    _In_ PINPORT_DEVICE_EXTENSION DeviceExtension)
+{
+    PAGED_CODE();
+
+    /* Initialize mouse and disable interrupts */
+    switch (DeviceExtension->MouseType)
+    {
+        case NecBusMouse:
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONFIG, NEC_PPI_DEFAULT_MODE);
+
+            /* Setup interrupt rate (unavailable on hireso machines) */
+            if (DeviceExtension->IoBase != NEC_BM_HIRESO_BASE)
+                WRITE_MOUSE(DeviceExtension, NEC_BM_INT_RATE, NEC_RATE_60_HZ);
+
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONFIG, NEC_PPI_INT_DISABLE);
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONFIG, NEC_PPI_HC_NO_CLEAR);
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONFIG, NEC_PPI_HC_CLEAR);
+            break;
+
+        case MsInPortMouse:
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_CONTROL, INPORT_RESET);
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_CONTROL, INPORT_REG_MODE);
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_DATA, INPORT_MODE_BASE);
+            break;
+
+        case LogitechBusMouse:
+            WRITE_MOUSE(DeviceExtension, LOG_BM_CONFIG, LOG_DEFAULT_MODE);
+            WRITE_MOUSE(DeviceExtension, LOG_BM_CONTROL, LOG_DISABLE_IRQ);
+            break;
+    }
+}
+
+BOOLEAN
+NTAPI
+InPortStartMouse(
+    _In_ PVOID SynchronizeContext)
+{
+    PINPORT_DEVICE_EXTENSION DeviceExtension = SynchronizeContext;
+
+    /* Enable interrupts */
+    switch (DeviceExtension->MouseType)
+    {
+        case NecBusMouse:
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONFIG, NEC_PPI_INT_ENABLE);
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONFIG, NEC_PPI_HC_NO_CLEAR);
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONFIG, NEC_PPI_HC_CLEAR);
+            break;
+
+        case MsInPortMouse:
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_CONTROL, INPORT_REG_MODE);
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_DATA,
+                        INPORT_MODE_IRQ | INPORT_MODE_BASE);
+            break;
+
+        case LogitechBusMouse:
+            WRITE_MOUSE(DeviceExtension, LOG_BM_CONTROL, LOG_ENABLE_IRQ);
+            break;
+    }
+
+    return TRUE;
+}
+
+BOOLEAN
+NTAPI
+InPortStopMouse(
+    _In_ PVOID SynchronizeContext)
+{
+    PINPORT_DEVICE_EXTENSION DeviceExtension = SynchronizeContext;
+
+    /* Disable interrupts */
+    switch (DeviceExtension->MouseType)
+    {
+        case NecBusMouse:
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONFIG, NEC_PPI_INT_DISABLE);
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONFIG, NEC_PPI_HC_NO_CLEAR);
+            WRITE_MOUSE(DeviceExtension, NEC_BM_CONFIG, NEC_PPI_HC_CLEAR);
+            break;
+
+        case MsInPortMouse:
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_CONTROL, INPORT_REG_MODE);
+            WRITE_MOUSE(DeviceExtension, MS_INPORT_DATA, INPORT_MODE_BASE);
+            break;
+
+        case LogitechBusMouse:
+            WRITE_MOUSE(DeviceExtension, LOG_BM_CONTROL, LOG_DISABLE_IRQ);
+            break;
+    }
+
+    return TRUE;
+}
diff --git a/drivers/input/inport/inport.c b/drivers/input/inport/inport.c
new file mode 100644
index 00000000000..6ed5c71162a
--- /dev/null
+++ b/drivers/input/inport/inport.c
@@ -0,0 +1,238 @@
+/*
+ * PROJECT:     ReactOS InPort (Bus) Mouse Driver
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Driver entrypoint
+ * COPYRIGHT:   Copyright 2020 Dmitry Borisov ([email protected])
+ */
+
+/* INCLUDES 
*******************************************************************/
+
+#include "inport.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS 
********************************************************************/
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(PAGE, InPortCreateClose)
+#pragma alloc_text(PAGE, InPortAddDevice)
+#pragma alloc_text(PAGE, InPortUnload)
+#endif
+
+UNICODE_STRING DriverRegistryPath;
+
+/* FUNCTIONS 
******************************************************************/
+
+NTSTATUS
+NTAPI
+InPortCreateClose(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp)
+{
+    PAGED_CODE();
+
+    DPRINT("%s(%p, %p) %X\n", __FUNCTION__, DeviceObject,
+           Irp, IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+InPortAddDevice(
+    _In_ PDRIVER_OBJECT DriverObject,
+    _In_ PDEVICE_OBJECT PhysicalDeviceObject)
+{
+    NTSTATUS Status;
+    PDEVICE_OBJECT Fdo;
+    PINPORT_DEVICE_EXTENSION FdoExtension = NULL;
+    WCHAR HardwareIdBuffer[32];
+    UNICODE_STRING HardwareId;
+    ULONG DummyResultLength;
+    UNICODE_STRING HardwareId1 = RTL_CONSTANT_STRING(L"*nEC1F00");
+    UNICODE_STRING HardwareId2 = RTL_CONSTANT_STRING(L"*PNP0F00");
+    UNICODE_STRING HardwareId3 = RTL_CONSTANT_STRING(L"*PNP0F02");
+    UNICODE_STRING HardwareId4 = RTL_CONSTANT_STRING(L"*PNP0F0D");
+    UNICODE_STRING HardwareId5 = RTL_CONSTANT_STRING(L"*PNP0F11");
+    UNICODE_STRING HardwareId6 = RTL_CONSTANT_STRING(L"*PNP0F15");
+
+    PAGED_CODE();
+
+    DPRINT("%s(%p, %p)\n", __FUNCTION__, DriverObject, PhysicalDeviceObject);
+
+    Status = IoCreateDevice(DriverObject,
+                            sizeof(INPORT_DEVICE_EXTENSION),
+                            NULL,
+                            FILE_DEVICE_INPORT_PORT,
+                            FILE_DEVICE_SECURE_OPEN,
+                            FALSE,
+                            &Fdo);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to create FDO 0x%X\n", Status);
+        goto Failure;
+    }
+
+    FdoExtension = Fdo->DeviceExtension;
+
+    RtlZeroMemory(FdoExtension, sizeof(INPORT_DEVICE_EXTENSION));
+    FdoExtension->State = dsStopped;
+    FdoExtension->Self = Fdo;
+    FdoExtension->Pdo = PhysicalDeviceObject;
+    FdoExtension->Ldo = IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject);
+    if (!FdoExtension->Ldo)
+    {
+        DPRINT1("Failed to attach FDO\n");
+        Status = STATUS_NO_SUCH_DEVICE;
+        goto Failure;
+    }
+
+    IoInitializeRemoveLock(&FdoExtension->RemoveLock, INPORT_TAG, 0, 0);
+    IoInitializeDpcRequest(Fdo, InPortDpcForIsr);
+
+    Status = IoGetDeviceProperty(PhysicalDeviceObject,
+                                 DevicePropertyHardwareID,
+                                 sizeof(HardwareIdBuffer),
+                                 HardwareIdBuffer,
+                                 &DummyResultLength);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to query the hardware ID string 0x%X\n", Status);
+        goto Failure;
+    }
+    RtlInitUnicodeString(&HardwareId, HardwareIdBuffer);
+
+    if (RtlEqualUnicodeString(&HardwareId, &HardwareId1, FALSE))
+    {
+        FdoExtension->MouseType = NecBusMouse;
+        FdoExtension->MouseAttributes.SampleRate = 60;
+        FdoExtension->MouseAttributes.NumberOfButtons = 2;
+    }
+    else if (RtlEqualUnicodeString(&HardwareId, &HardwareId3, FALSE) ||
+             RtlEqualUnicodeString(&HardwareId, &HardwareId4, FALSE))
+    {
+        FdoExtension->MouseType = MsInPortMouse;
+        FdoExtension->MouseAttributes.SampleRate = 100;
+        FdoExtension->MouseAttributes.NumberOfButtons = 3;
+    }
+    else if (RtlEqualUnicodeString(&HardwareId, &HardwareId2, FALSE) ||
+             RtlEqualUnicodeString(&HardwareId, &HardwareId5, FALSE) ||
+             RtlEqualUnicodeString(&HardwareId, &HardwareId6, FALSE))
+    {
+        FdoExtension->MouseType = LogitechBusMouse;
+        FdoExtension->MouseAttributes.SampleRate = 100;
+        FdoExtension->MouseAttributes.NumberOfButtons = 3;
+    }
+    else
+    {
+        DPRINT1("Unrecognized hardware '%wZ'\n", &HardwareId);
+        Status = STATUS_DEVICE_REMOVED;
+        goto Failure;
+    }
+    FdoExtension->MouseAttributes.MouseIdentifier = MOUSE_INPORT_HARDWARE;
+    /* 1 packet */
+    FdoExtension->MouseAttributes.InputDataQueueLength = 
sizeof(MOUSE_INPUT_DATA);
+
+    Fdo->Flags |= DO_BUFFERED_IO;
+    if (FdoExtension->Ldo->Flags & DO_POWER_PAGABLE)
+        Fdo->Flags |= DO_POWER_PAGABLE;
+    Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+    return STATUS_SUCCESS;
+
+Failure:
+    if (FdoExtension)
+    {
+        if (FdoExtension->Ldo)
+            IoDetachDevice(FdoExtension->Ldo);
+    }
+
+    if (Fdo)
+    {
+        IoDeleteDevice(Fdo);
+    }
+
+    return Status;
+}
+
+VOID
+NTAPI
+InPortUnload(
+    _In_ PDRIVER_OBJECT DriverObject)
+{
+    PAGED_CODE();
+
+    DPRINT("%s(%p)\n", __FUNCTION__, DriverObject);
+
+    RtlFreeUnicodeString(&DriverRegistryPath);
+}
+
+NTSTATUS
+NTAPI
+InPortPower(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp)
+{
+    NTSTATUS Status;
+    PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+
+    DPRINT("%s(%p, %p) %X\n", __FUNCTION__, DeviceObject, Irp,
+           IoGetCurrentIrpStackLocation(Irp)->MinorFunction);
+
+    Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
+    if (!NT_SUCCESS(Status))
+    {
+        Irp->IoStatus.Status = Status;
+        PoStartNextPowerIrp(Irp);
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+        return Status;
+    }
+
+    PoStartNextPowerIrp(Irp);
+    IoSkipCurrentIrpStackLocation(Irp);
+    Status = PoCallDriver(DeviceExtension->Ldo, Irp);
+
+    IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+DriverEntry(
+    _In_ PDRIVER_OBJECT DriverObject,
+    _In_ PUNICODE_STRING RegistryPath)
+{
+    DPRINT("%s(%p, %wZ)\n", __FUNCTION__, DriverObject, RegistryPath);
+
+    DriverRegistryPath.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+                                                      RegistryPath->Length +
+                                                      sizeof(UNICODE_NULL),
+                                                      INPORT_TAG);
+    if (!DriverRegistryPath.Buffer)
+    {
+        DPRINT1("Failed to allocate the registry string buffer\n");
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+    DriverRegistryPath.MaximumLength = RegistryPath->Length + 
sizeof(UNICODE_NULL);
+    RtlCopyUnicodeString(&DriverRegistryPath, RegistryPath);
+    DriverRegistryPath.Buffer[RegistryPath->Length / sizeof(WCHAR)] = 
UNICODE_NULL;
+
+    DriverObject->MajorFunction[IRP_MJ_CREATE] =
+    DriverObject->MajorFunction[IRP_MJ_CLOSE] = InPortCreateClose;
+    DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = 
InPortInternalDeviceControl;
+    DriverObject->MajorFunction[IRP_MJ_POWER] = InPortPower;
+    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = InPortWmi;
+    DriverObject->MajorFunction[IRP_MJ_PNP] = InPortPnp;
+    DriverObject->DriverExtension->AddDevice = InPortAddDevice;
+    DriverObject->DriverUnload = InPortUnload;
+
+    return STATUS_SUCCESS;
+}
diff --git a/drivers/input/inport/inport.h b/drivers/input/inport/inport.h
new file mode 100644
index 00000000000..2cae1cd6115
--- /dev/null
+++ b/drivers/input/inport/inport.h
@@ -0,0 +1,158 @@
+/*
+ * PROJECT:     ReactOS InPort (Bus) Mouse Driver
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Main header file
+ * COPYRIGHT:   Copyright 2020 Dmitry Borisov ([email protected])
+ */
+
+#ifndef _INPORT_H_
+#define _INPORT_H_
+
+#include <wdm.h>
+#include <wmilib.h>
+#include <wmistr.h>
+#include <kbdmou.h>
+
+#define INPORT_TAG 'tPnI'
+
+typedef enum
+{
+    dsStopped,
+    dsStarted,
+    dsRemoved
+} INPORT_DEVICE_STATE;
+
+typedef enum
+{
+    NecBusMouse,
+    MsInPortMouse,
+    LogitechBusMouse
+} INPORT_MOUSE_TYPE;
+
+typedef struct _INPORT_RAW_DATA
+{
+    CHAR DeltaX;
+    CHAR DeltaY;
+    UCHAR Buttons;
+    ULONG ButtonDiff;
+} INPORT_RAW_DATA, *PINPORT_RAW_DATA;
+
+typedef struct _INPORT_DEVICE_EXTENSION
+{
+    PDEVICE_OBJECT Self;
+    PDEVICE_OBJECT Pdo;
+    PDEVICE_OBJECT Ldo;
+    INPORT_DEVICE_STATE State;
+    IO_REMOVE_LOCK RemoveLock;
+    WMILIB_CONTEXT WmiLibInfo;
+    PUCHAR IoBase;
+    INPORT_MOUSE_TYPE MouseType;
+
+    /* Interrupt */
+    PKINTERRUPT InterruptObject;
+    ULONG InterruptVector;
+    KIRQL InterruptLevel;
+    KINTERRUPT_MODE InterruptMode;
+    BOOLEAN InterruptShared;
+    KAFFINITY InterruptAffinity;
+
+    /* Movement data and state of the mouse buttons */
+    INPORT_RAW_DATA RawData;
+
+    /* Mouclass */
+    CONNECT_DATA ConnectData;
+    PDEVICE_OBJECT ClassDeviceObject;
+    PVOID ClassService;
+
+    /* Mouse packet */
+    MOUSE_INPUT_DATA MouseInputData;
+
+    /* Previous state */
+    ULONG MouseButtonState;
+
+    /* Mouse device attributes */
+    MOUSE_ATTRIBUTES MouseAttributes;
+} INPORT_DEVICE_EXTENSION, *PINPORT_DEVICE_EXTENSION;
+
+DRIVER_INITIALIZE DriverEntry;
+
+DRIVER_UNLOAD InPortUnload;
+
+DRIVER_ADD_DEVICE InPortAddDevice;
+
+_Dispatch_type_(IRP_MJ_CREATE)
+_Dispatch_type_(IRP_MJ_CLOSE)
+DRIVER_DISPATCH_PAGED InPortCreateClose;
+
+_Dispatch_type_(IRP_MJ_INTERNAL_DEVICE_CONTROL)
+DRIVER_DISPATCH_RAISED InPortInternalDeviceControl;
+
+_Dispatch_type_(IRP_MJ_POWER)
+DRIVER_DISPATCH_RAISED InPortPower;
+
+_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
+DRIVER_DISPATCH_PAGED InPortWmi;
+
+_Dispatch_type_(IRP_MJ_PNP)
+DRIVER_DISPATCH_PAGED InPortPnp;
+
+KSERVICE_ROUTINE InPortIsr;
+
+IO_DPC_ROUTINE InPortDpcForIsr;
+
+KSYNCHRONIZE_ROUTINE InPortStartMouse;
+
+KSYNCHRONIZE_ROUTINE InPortStopMouse;
+
+NTSTATUS
+NTAPI
+InPortStartDevice(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp);
+
+NTSTATUS
+NTAPI
+InPortRemoveDevice(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp);
+
+VOID
+NTAPI
+InPortInitializeMouse(
+    _In_ PINPORT_DEVICE_EXTENSION DeviceExtension);
+
+NTSTATUS
+NTAPI
+InPortWmiRegistration(
+    _Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension);
+
+NTSTATUS
+NTAPI
+InPortWmiDeRegistration(
+    _Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension);
+
+NTSTATUS
+NTAPI
+InPortQueryWmiRegInfo(
+    _Inout_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PULONG RegFlags,
+    _Inout_ PUNICODE_STRING InstanceName,
+    _Out_opt_ PUNICODE_STRING *RegistryPath,
+    _Inout_ PUNICODE_STRING MofResourceName,
+    _Out_opt_ PDEVICE_OBJECT *Pdo);
+
+NTSTATUS
+NTAPI
+InPortQueryWmiDataBlock(
+    _Inout_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp,
+    _In_ ULONG GuidIndex,
+    _In_ ULONG InstanceIndex,
+    _In_ ULONG InstanceCount,
+    _Out_opt_ PULONG InstanceLengthArray,
+    _In_ ULONG BufferAvail,
+    _Out_opt_ PUCHAR Buffer);
+
+extern UNICODE_STRING DriverRegistryPath;
+
+#endif /* _INPORT_H_ */
diff --git a/drivers/input/inport/inport.rc b/drivers/input/inport/inport.rc
new file mode 100644
index 00000000000..27c12292c06
--- /dev/null
+++ b/drivers/input/inport/inport.rc
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION  "InPort (Bus) Mouse Device Driver"
+#define REACTOS_STR_INTERNAL_NAME     "inport"
+#define REACTOS_STR_ORIGINAL_FILENAME "inport.sys"
+#include <reactos/version.rc>
diff --git a/drivers/input/inport/ioctl.c b/drivers/input/inport/ioctl.c
new file mode 100644
index 00000000000..47d909eb438
--- /dev/null
+++ b/drivers/input/inport/ioctl.c
@@ -0,0 +1,83 @@
+/*
+ * PROJECT:     ReactOS InPort (Bus) Mouse Driver
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     I/O control handling
+ * COPYRIGHT:   Copyright 2020 Dmitry Borisov ([email protected])
+ */
+
+/* INCLUDES 
*******************************************************************/
+
+#include "inport.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS 
******************************************************************/
+
+NTSTATUS
+NTAPI
+InPortInternalDeviceControl(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp)
+{
+    NTSTATUS Status;
+    PCONNECT_DATA ConnectData;
+    PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("%s(%p, %p) 0x%X\n", __FUNCTION__, DeviceObject, Irp,
+           IrpSp->Parameters.DeviceIoControl.IoControlCode);
+
+    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
+    {
+        case IOCTL_INTERNAL_MOUSE_CONNECT:
+            if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < 
sizeof(CONNECT_DATA))
+            {
+                Status = STATUS_INVALID_PARAMETER;
+                break;
+            }
+
+            /* Already connected */
+            if (DeviceExtension->ClassService)
+            {
+                Status = STATUS_SHARING_VIOLATION;
+                break;
+            }
+
+            ConnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+
+            DeviceExtension->ClassDeviceObject = 
ConnectData->ClassDeviceObject;
+            DeviceExtension->ClassService = ConnectData->ClassService;
+
+            Status = STATUS_SUCCESS;
+            break;
+
+        case IOCTL_INTERNAL_MOUSE_DISCONNECT:
+            DeviceExtension->ClassService = NULL;
+
+            Status = STATUS_SUCCESS;
+            break;
+
+        case IOCTL_MOUSE_QUERY_ATTRIBUTES:
+            if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 
sizeof(MOUSE_ATTRIBUTES))
+            {
+                Status = STATUS_BUFFER_TOO_SMALL;
+                break;
+            }
+
+            *(PMOUSE_ATTRIBUTES)Irp->AssociatedIrp.SystemBuffer = 
DeviceExtension->MouseAttributes;
+            Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
+
+            Status = STATUS_SUCCESS;
+            break;
+
+        default:
+            Status = STATUS_INVALID_DEVICE_REQUEST;
+            break;
+    }
+
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return Status;
+}
diff --git a/drivers/input/inport/pnp.c b/drivers/input/inport/pnp.c
new file mode 100644
index 00000000000..82d0cd5b2c4
--- /dev/null
+++ b/drivers/input/inport/pnp.c
@@ -0,0 +1,283 @@
+/*
+ * PROJECT:     ReactOS InPort (Bus) Mouse Driver
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Plug and Play requests handling
+ * COPYRIGHT:   Copyright 2020 Dmitry Borisov ([email protected])
+ */
+
+/* INCLUDES 
*******************************************************************/
+
+#include "inport.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS 
********************************************************************/
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, InPortPnp)
+#pragma alloc_text(PAGE, InPortStartDevice)
+#pragma alloc_text(PAGE, InPortRemoveDevice)
+#endif
+
+/* FUNCTIONS 
******************************************************************/
+
+NTSTATUS
+NTAPI
+InPortStartDevice(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp)
+{
+    NTSTATUS Status;
+    PCM_RESOURCE_LIST AllocatedResources, AllocatedResourcesTranslated;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, DescriptorTranslated;
+    ULONG i;
+    ULONG RawVector;
+    BOOLEAN FoundBasePort = FALSE, FoundIrq = FALSE;
+    PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+    PAGED_CODE();
+
+    ASSERT(DeviceExtension->State == dsStopped);
+
+    if (!IoForwardIrpSynchronously(DeviceExtension->Ldo, Irp))
+    {
+        Status = STATUS_UNSUCCESSFUL;
+        goto Complete;
+    }
+    Status = Irp->IoStatus.Status;
+    if (!NT_SUCCESS(Status))
+    {
+       DPRINT1("LDO failed to start 0x%X\n", Status);
+       goto Complete;
+    }
+
+    AllocatedResources = IrpSp->Parameters.StartDevice.AllocatedResources;
+    AllocatedResourcesTranslated = 
IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated;
+    if (!AllocatedResources || !AllocatedResourcesTranslated)
+    {
+        DPRINT1("No allocated resources\n");
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto Complete;
+    }
+
+    if (AllocatedResources->Count != 1)
+        DPRINT1("Expected FullList count is 1, got %d\n", 
AllocatedResources->Count);
+
+    for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i++)
+    {
+        Descriptor = 
&AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i];
+        DescriptorTranslated = 
&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[i];
+
+        switch (Descriptor->Type)
+        {
+            case CmResourceTypePort:
+            {
+                DPRINT("[%p:%X:%X] I/O ports at [%p-%p]\n",
+                       Descriptor,
+                       Descriptor->ShareDisposition,
+                       Descriptor->Flags,
+                       Descriptor->u.Port.Start.LowPart,
+                       Descriptor->u.Port.Start.LowPart + 
(Descriptor->u.Port.Length - 1));
+
+                if (!FoundBasePort)
+                {
+                    DeviceExtension->IoBase = 
ULongToPtr(Descriptor->u.Port.Start.u.LowPart);
+
+                    FoundBasePort = TRUE;
+                }
+
+                break;
+            }
+
+            case CmResourceTypeInterrupt:
+            {
+                DPRINT("[%p:%X:%X] INT Vec %d Lev %d Aff %IX\n",
+                       Descriptor,
+                       Descriptor->ShareDisposition,
+                       Descriptor->Flags,
+                       Descriptor->u.Interrupt.Vector,
+                       Descriptor->u.Interrupt.Level,
+                       Descriptor->u.Interrupt.Affinity);
+
+                if (!FoundIrq)
+                {
+                    DeviceExtension->InterruptVector = 
DescriptorTranslated->u.Interrupt.Vector;
+                    DeviceExtension->InterruptLevel = 
(KIRQL)DescriptorTranslated->u.Interrupt.Level;
+                    if (DescriptorTranslated->Flags & 
CM_RESOURCE_INTERRUPT_LATCHED)
+                        DeviceExtension->InterruptMode = Latched;
+                    else
+                        DeviceExtension->InterruptMode = LevelSensitive;
+                    DeviceExtension->InterruptShared = 
(DescriptorTranslated->ShareDisposition == CmResourceShareShared);
+                    DeviceExtension->InterruptAffinity = 
DescriptorTranslated->u.Interrupt.Affinity;
+                    RawVector = Descriptor->u.Interrupt.Vector;
+
+                    FoundIrq = TRUE;
+                }
+
+                break;
+            }
+
+            default:
+                DPRINT("[%p:%X:%X] Unrecognized resource type %X\n",
+                       Descriptor,
+                       Descriptor->ShareDisposition,
+                       Descriptor->Flags,
+                       Descriptor->Type);
+                break;
+        }
+    }
+
+    if (!FoundBasePort || !FoundIrq)
+    {
+        DPRINT1("The device resources were not found\n");
+        Status = STATUS_DEVICE_CONFIGURATION_ERROR;
+        goto Complete;
+    }
+
+    DPRINT("I/O base at %p\n", DeviceExtension->IoBase);
+    DPRINT("IRQ %d\n", RawVector);
+
+    Status = InPortWmiRegistration(DeviceExtension);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("WMI registration failed 0x%X\n", Status);
+        goto Complete;
+    }
+
+    InPortInitializeMouse(DeviceExtension);
+
+    Status = IoConnectInterrupt(&DeviceExtension->InterruptObject,
+                                InPortIsr,
+                                DeviceExtension,
+                                NULL,
+                                DeviceExtension->InterruptVector,
+                                DeviceExtension->InterruptLevel,
+                                DeviceExtension->InterruptLevel,
+                                DeviceExtension->InterruptMode,
+                                DeviceExtension->InterruptShared,
+                                DeviceExtension->InterruptAffinity,
+                                FALSE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Could not connect to interrupt %d\n", 
DeviceExtension->InterruptVector);
+        goto Complete;
+    }
+
+    KeSynchronizeExecution(DeviceExtension->InterruptObject,
+                           InPortStartMouse,
+                           DeviceExtension);
+
+    DeviceExtension->State = dsStarted;
+
+Complete:
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+InPortRemoveDevice(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp)
+{
+    NTSTATUS Status;
+    BOOLEAN IsStarted;
+    PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+
+    PAGED_CODE();
+
+    InPortWmiDeRegistration(DeviceExtension);
+
+    IsStarted = (DeviceExtension->State == dsStarted);
+
+    DeviceExtension->State = dsRemoved;
+
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoSkipCurrentIrpStackLocation(Irp);
+    Status = IoCallDriver(DeviceExtension->Ldo, Irp);
+
+    IoReleaseRemoveLockAndWait(&DeviceExtension->RemoveLock, Irp);
+
+    /* Device is active */
+    if (IsStarted)
+    {
+        KeSynchronizeExecution(DeviceExtension->InterruptObject,
+                               InPortStopMouse,
+                               DeviceExtension);
+
+        IoDisconnectInterrupt(DeviceExtension->InterruptObject);
+
+        /* Flush DPC for ISR */
+        KeFlushQueuedDpcs();
+    }
+
+    IoDetachDevice(DeviceExtension->Ldo);
+    IoDeleteDevice(DeviceObject);
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+InPortPnp(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp)
+{
+    NTSTATUS Status;
+    PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+    PAGED_CODE();
+
+    DPRINT("%s(%p, %p) %X\n",
+           __FUNCTION__, DeviceObject, Irp, IrpSp->MinorFunction);
+
+    Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
+    if (!NT_SUCCESS(Status))
+    {
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+        return Status;
+    }
+
+    switch (IrpSp->MinorFunction)
+    {
+        case IRP_MN_START_DEVICE:
+            Status = InPortStartDevice(DeviceObject, Irp);
+            break;
+
+        case IRP_MN_REMOVE_DEVICE:
+            return InPortRemoveDevice(DeviceObject, Irp);
+
+        case IRP_MN_QUERY_STOP_DEVICE:
+            /* Device cannot work with other resources */
+            Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            break;
+
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        case IRP_MN_CANCEL_REMOVE_DEVICE:
+        case IRP_MN_STOP_DEVICE:
+        case IRP_MN_CANCEL_STOP_DEVICE:
+        case IRP_MN_SURPRISE_REMOVAL:
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            IoSkipCurrentIrpStackLocation(Irp);
+            Status = IoCallDriver(DeviceExtension->Ldo, Irp);
+            break;
+
+        default:
+            IoSkipCurrentIrpStackLocation(Irp);
+            Status = IoCallDriver(DeviceExtension->Ldo, Irp);
+            break;
+    }
+
+    IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
+
+    return Status;
+}
diff --git a/drivers/input/inport/wmi.c b/drivers/input/inport/wmi.c
new file mode 100644
index 00000000000..957fb14db53
--- /dev/null
+++ b/drivers/input/inport/wmi.c
@@ -0,0 +1,202 @@
+/*
+ * PROJECT:     ReactOS InPort (Bus) Mouse Driver
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     WMI support
+ * COPYRIGHT:   Copyright 2020 Dmitry Borisov ([email protected])
+ */
+
+/* INCLUDES 
*******************************************************************/
+
+#include "inport.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS 
********************************************************************/
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, InPortWmi)
+#pragma alloc_text(PAGE, InPortWmiRegistration)
+#pragma alloc_text(PAGE, InPortWmiDeRegistration)
+#pragma alloc_text(PAGE, InPortQueryWmiRegInfo)
+#pragma alloc_text(PAGE, InPortQueryWmiDataBlock)
+#endif
+
+GUID GuidWmiPortData = POINTER_PORT_WMI_STD_DATA_GUID;
+
+WMIGUIDREGINFO InPortWmiGuidList[] =
+{
+    {&GuidWmiPortData, 1, 0}
+};
+
+/* FUNCTIONS 
******************************************************************/
+
+NTSTATUS
+NTAPI
+InPortQueryWmiRegInfo(
+    _Inout_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PULONG RegFlags,
+    _Inout_ PUNICODE_STRING InstanceName,
+    _Out_opt_ PUNICODE_STRING *RegistryPath,
+    _Inout_ PUNICODE_STRING MofResourceName,
+    _Out_opt_ PDEVICE_OBJECT *Pdo)
+{
+    PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+
+    UNREFERENCED_PARAMETER(InstanceName);
+    UNREFERENCED_PARAMETER(MofResourceName);
+
+    PAGED_CODE();
+
+    DPRINT("%s()\n", __FUNCTION__);
+
+    *RegFlags = WMIREG_FLAG_INSTANCE_PDO;
+    *RegistryPath = &DriverRegistryPath;
+    *Pdo = DeviceExtension->Pdo;
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+InPortQueryWmiDataBlock(
+    _Inout_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp,
+    _In_ ULONG GuidIndex,
+    _In_ ULONG InstanceIndex,
+    _In_ ULONG InstanceCount,
+    _Out_opt_ PULONG InstanceLengthArray,
+    _In_ ULONG BufferAvail,
+    _Out_opt_ PUCHAR Buffer)
+{
+    NTSTATUS Status;
+    PPOINTER_PORT_WMI_STD_DATA InPortData;
+    PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+
+    PAGED_CODE();
+
+    DPRINT("%s()\n", __FUNCTION__);
+
+    if (GuidIndex > RTL_NUMBER_OF(InPortWmiGuidList))
+    {
+        Status = STATUS_WMI_GUID_NOT_FOUND;
+        goto Complete;
+    }
+
+    /* Only register 1 instance per GUID */
+    if (InstanceIndex != 0 || InstanceCount != 1)
+    {
+        Status = STATUS_WMI_INSTANCE_NOT_FOUND;
+        goto Complete;
+    }
+
+    if (!InstanceLengthArray || BufferAvail < 
sizeof(POINTER_PORT_WMI_STD_DATA))
+    {
+        Status = STATUS_BUFFER_TOO_SMALL;
+        goto Complete;
+    }
+
+    InPortData = (PPOINTER_PORT_WMI_STD_DATA)Buffer;
+
+    /* Bus mouse connector isn't defined in the DDK, so set type to something 
generic */
+    InPortData->ConnectorType = POINTER_PORT_WMI_STD_I8042;
+    /* 1 packet */
+    InPortData->DataQueueSize = 1;
+    /* Not supported by device */
+    InPortData->ErrorCount = 0;
+
+    InPortData->Buttons = DeviceExtension->MouseAttributes.NumberOfButtons;
+    InPortData->HardwareType = POINTER_PORT_WMI_STD_MOUSE;
+    *InstanceLengthArray = sizeof(POINTER_PORT_WMI_STD_DATA);
+
+    Status = STATUS_SUCCESS;
+
+Complete:
+    return WmiCompleteRequest(DeviceObject,
+                              Irp,
+                              Status,
+                              sizeof(POINTER_PORT_WMI_STD_DATA),
+                              IO_NO_INCREMENT);
+}
+
+NTSTATUS
+NTAPI
+InPortWmiRegistration(
+    _Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension)
+{
+    PAGED_CODE();
+
+    DeviceExtension->WmiLibInfo.GuidCount = RTL_NUMBER_OF(InPortWmiGuidList);
+    DeviceExtension->WmiLibInfo.GuidList = InPortWmiGuidList;
+
+    DeviceExtension->WmiLibInfo.QueryWmiRegInfo = InPortQueryWmiRegInfo;
+    DeviceExtension->WmiLibInfo.QueryWmiDataBlock = InPortQueryWmiDataBlock;
+    DeviceExtension->WmiLibInfo.SetWmiDataBlock = NULL;
+    DeviceExtension->WmiLibInfo.SetWmiDataItem = NULL;
+    DeviceExtension->WmiLibInfo.ExecuteWmiMethod = NULL;
+    DeviceExtension->WmiLibInfo.WmiFunctionControl = NULL;
+
+    return IoWMIRegistrationControl(DeviceExtension->Self,
+                                    WMIREG_ACTION_REGISTER);
+}
+
+NTSTATUS
+NTAPI
+InPortWmiDeRegistration(
+    _Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension)
+{
+    PAGED_CODE();
+
+    return IoWMIRegistrationControl(DeviceExtension->Self,
+                                    WMIREG_ACTION_DEREGISTER);
+}
+
+NTSTATUS
+NTAPI
+InPortWmi(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp)
+{
+    NTSTATUS Status;
+    SYSCTL_IRP_DISPOSITION Disposition;
+    PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+
+    PAGED_CODE();
+
+    DPRINT("%s(%p, %p) %X\n", __FUNCTION__, DeviceObject, Irp,
+           IoGetCurrentIrpStackLocation(Irp)->MinorFunction);
+
+    Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
+    if (!NT_SUCCESS(Status))
+    {
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+        return Status;
+    }
+
+    Status = WmiSystemControl(&DeviceExtension->WmiLibInfo,
+                              DeviceObject,
+                              Irp,
+                              &Disposition);
+    switch (Disposition)
+    {
+        case IrpProcessed:
+            break;
+
+        case IrpNotCompleted:
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            break;
+
+        case IrpForward:
+        case IrpNotWmi:
+            IoSkipCurrentIrpStackLocation(Irp);
+            Status = IoCallDriver(DeviceExtension->Ldo, Irp);
+            break;
+    }
+
+    IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
+
+    return Status;
+}
diff --git a/media/inf/msmouse.inf b/media/inf/msmouse.inf
index fdace56f06b..e6353789417 100644
--- a/media/inf/msmouse.inf
+++ b/media/inf/msmouse.inf
@@ -29,11 +29,14 @@ HKR, , UpperFilters,   0x00010000, "mouclass"
 %IbmMfg% = IbmMfg
 %LogMfg% = LogMfg
 %MSMfg%  = MSMfg
+%NecMfg% = NecMfg
 
 [StdMfg]
 %SERIAL_MOUSE.DeviceDesc% = 
Serial_Inst,*PNP0F0C,SERENUM\PNP0F0C,*PNP0F17,SERENUM\PNP0F17,SERIAL_MOUSE
 %PS2_MOUSE.DeviceDesc% = PS2_Inst,*PNP0F0E,*PNP0F19,PS2_MOUSE
 %HID_MOUSE.DeviceDesc% = HID_Inst,HID_DEVICE_SYSTEM_MOUSE
+%*PNP0F0D.DeviceDesc% = Inp_Inst,*PNP0F0D
+%*PNP0F11.DeviceDesc% = Inp_Inst,*PNP0F11
 %*PNP0F13.DeviceDesc% = PS2_Inst,*PNP0F13
 
 [IbmMfg]
@@ -42,12 +45,18 @@ HKR, , UpperFilters,   0x00010000, "mouclass"
 [LogMfg]
 %*PNP0F08.DeviceDesc% = Serial_Inst,*PNP0F08,SERENUM\PNP0F08
 %*PNP0F12.DeviceDesc% = PS2_Inst,*PNP0F12
+%*PNP0F15.DeviceDesc% = Inp_Inst,*PNP0F15
 
 [MSMfg]
+%*PNP0F00.DeviceDesc% = Inp_Inst,*PNP0F00
 %*PNP0F01.DeviceDesc% = Serial_Inst,*PNP0F01,SERENUM\PNP0F01
+%*PNP0F02.DeviceDesc% = Inp_Inst,*PNP0F02
 %*PNP0F03.DeviceDesc% = PS2_Inst,*PNP0F03
 %HID\Vid_045E&Pid_0047.DeviceDesc%=HID_Inst,, HID\Vid_045E&Pid_0047
 
+[NecMfg]
+%*nEC1F00.DeviceDesc% = Inp_Inst,*nEC1F00
+
 ; Generic Mouse
 %HID.MouseDevice%=HID_Inst,,HID_DEVICE_SYSTEM_MOUSE
 
@@ -109,6 +118,25 @@ 
HKLM,"SYSTEM\CurrentControlSet\Services\i8042prt\Parameters","MouseResolution",0
 HKR, , EnumPropPages32, 0, "syssetup.dll,PS2MousePropPageProvider"
 HKR, , LocationInformationOverride, 0, %LocationOverride%
 
+;----------------------------- INPORT DRIVER ----------------------------
+
+[Inp_Inst]
+CopyFiles = Inp_CopyFiles.NT, Mouclass_CopyFiles.NT
+
+[Inp_CopyFiles.NT]
+inport.sys
+
+[Inp_Inst.Services]
+AddService = inport, 0x00000002, Inp_Service_Inst
+AddService = mouclass, , mouclass_Service_Inst
+
+[Inp_Service_Inst]
+ServiceType   = 1
+StartType     = 1
+ErrorControl  = 1
+ServiceBinary = %12%\inport.sys
+LoadOrderGroup = Pointer Port
+
 ;---------------------------- HID MOUSE DRIVER --------------------------
 
 [HID_Inst.NT]
@@ -140,6 +168,8 @@ StdMfg = "(Standard mice)"
 SERIAL_MOUSE.DeviceDesc = "Standard Serial Mouse"
 PS2_MOUSE.DeviceDesc = "Standard PS/2 Mouse"
 HID_MOUSE.DeviceDesc = "HID Mouse"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "PS/2 port for PS/2-style mice"
 
 IbmMfg = "IBM"
@@ -148,11 +178,17 @@ IbmMfg = "IBM"
 LogMfg = "Logitech"
 *PNP0F08.DeviceDesc = "Logitech Serial Mouse"
 *PNP0F12.DeviceDesc = "Logitech PS/2-style Mouse"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
 MSMfg = "Microsoft"
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Microsoft Serial Mouse"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Microsoft PS/2-style Mouse"
 
+NecMfg = "NEC"
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0405]
 MouseClassName = "Myši a jiná polohovací zařízení"
 
@@ -160,16 +196,23 @@ StdMfg = "(Standardní myši)"
 SERIAL_MOUSE.DeviceDesc = "Standardní sériová myš"
 PS2_MOUSE.DeviceDesc = "Standardní PS/2 myš"
 HID_MOUSE.DeviceDesc = "HID myš"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "PS/2 port pro PS/2 myši"
 
 *IBM3780.DeviceDesc = "IBM PS/2 Trackpoint"
 
 *PNP0F08.DeviceDesc = "Logitech sériová myš"
 *PNP0F12.DeviceDesc = "Logitech PS/2 myš"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Microsoft sériová myš"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Microsoft PS/2 myš"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0407]
 MouseClassName = "Mäuse und andere Zeigegeräte"
 LocationOverride = "eingesteckt in PS/2-Mausanschluss"
@@ -178,14 +221,21 @@ StdMfg = "(Standard-Maus)"
 SERIAL_MOUSE.DeviceDesc = "Standard serielle Maus"
 PS2_MOUSE.DeviceDesc = "Standard PS/2 Maus"
 HID_MOUSE.DeviceDesc = "HID Maus"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "PS/2 Anschluss für PS/2-Maus"
 
 *PNP0F08.DeviceDesc = "Logitech serielle Maus"
 *PNP0F12.DeviceDesc = "Logitech PS/2-Maus"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Microsoft serielle Maus"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Microsoft PS/2-Maus"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0408]
 MouseClassName = "Ποντίκια και άλλες συσκευές εισόδου"
 
@@ -193,16 +243,23 @@ StdMfg = "(Πρότυπα ποντίκια)"
 SERIAL_MOUSE.DeviceDesc = "Πρότυπο Σειριακό Ποντίκι"
 PS2_MOUSE.DeviceDesc = "Πρότυπο PS/2 Ποντίκι"
 HID_MOUSE.DeviceDesc = "Ποντίκι HID"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "PS/2 θύρα για PS/2 ποντίκια"
 
 *IBM3780.DeviceDesc = "IBM PS/2 Trackpoint"
 
 *PNP0F08.DeviceDesc = "Logitech Σειριακό Ποντίκι"
 *PNP0F12.DeviceDesc = "Logitech PS/2 Ποντίκι"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Microsoft Σειριακό Ποντίκι"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Microsoft PS/2 Ποντίκι"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0a]
 ReactOS = "Equipo de ReactOS"
 MouseClassName = "Ratones y otros dispositivos señaladores"
@@ -212,16 +269,23 @@ StdMfg = "(Ratón estándar)"
 SERIAL_MOUSE.DeviceDesc = "Ratón serie estándar"
 PS2_MOUSE.DeviceDesc = "Ratón PS/2 estándar"
 HID_MOUSE.DeviceDesc = "Ratón oculto"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "Puerto PS/2 para ratón PS/2"
 
 *IBM3780.DeviceDesc = "Trackpoint PS/2 de IBM"
 
 *PNP0F08.DeviceDesc = "Ratón serie de Logitech"
 *PNP0F12.DeviceDesc = "Ratón PS/2 de Logitech"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Ratón serie de Microsoft"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Ratón PS/2 de Microsoft"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.040C]
 MouseClassName = "Souris et autres périphériques de pointage"
 LocationOverride = "Branché sur le port PS/2"
@@ -230,14 +294,21 @@ StdMfg = "(Souris standards)"
 SERIAL_MOUSE.DeviceDesc = "Souris série standard"
 PS2_MOUSE.DeviceDesc = "Souris PS/2 standard"
 HID_MOUSE.DeviceDesc = "Souris HID"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "Port PS/2 pour souris type PS/2"
 
 *PNP0F08.DeviceDesc = "Souris série Logitech"
 *PNP0F12.DeviceDesc = "Souris PS/2 Logitech"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Souris série Microsoft"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Souris PS/2 Microsoft"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0411]
 MouseClassName = "マウスとその他のポインティング デバイス"
 
@@ -245,16 +316,23 @@ StdMfg = "(スタンダード マウス)"
 SERIAL_MOUSE.DeviceDesc = "スタンダード シリアル マウス"
 PS2_MOUSE.DeviceDesc = "スタンダード PS/2 マウス"
 HID_MOUSE.DeviceDesc = "HID マウス"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "PS/2接続マウス用のPS/2 ポート"
 
 *IBM3780.DeviceDesc = "IBM PS/2 トラックポイント"
 
 *PNP0F08.DeviceDesc = "Logitech シリアル マウス"
 *PNP0F12.DeviceDesc = "Logitech PS/2接続マウス"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Microsoft シリアル マウス"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Microsoft PS/2接続マウス"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0415]
 ReactOS = "Zespół ReactOS"
 MouseClassName = "Mysz i inne urządzenia wskazujące"
@@ -264,16 +342,23 @@ StdMfg = "(Standardowa mysz)"
 SERIAL_MOUSE.DeviceDesc = "Standardowa mysz szeregowa"
 PS2_MOUSE.DeviceDesc = "Standardowa mysz PS/2"
 HID_MOUSE.DeviceDesc = "Mysz zgodna z HID"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "Port PS/2 dla myszy"
 
 *IBM3780.DeviceDesc = "Trackpoint PS/2 IBM"
 
 *PNP0F08.DeviceDesc = "Mysz szeregowa Logitech"
 *PNP0F12.DeviceDesc = "Mysz PS/2 Logitech"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Mysz szeregowa Microsoft"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Mysz PS/2 Microsoft"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0416]
 MouseClassName = "Mouse e outros dispositivos apontadores"
 
@@ -281,16 +366,23 @@ StdMfg = "(Mouse padrão)"
 SERIAL_MOUSE.DeviceDesc = "Mouse serial padrão"
 PS2_MOUSE.DeviceDesc = "Mouse PS/2 padrão"
 HID_MOUSE.DeviceDesc = "Mouse interno"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "Porta PS/2 para mouse PS/2"
 
 *IBM3780.DeviceDesc = "Trackpoint PS/2 IBM"
 
 *PNP0F08.DeviceDesc = "Mouse serial Logitech"
 *PNP0F12.DeviceDesc = "Mouse PS/2 Logitech"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Mouse serial Microsoft"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Mouse PS/2 Microsoft"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0418]
 ReactOS = "Echipa ReactOS"
 MouseClassName = "Șoricel și alte dispozitive de indicare"
@@ -299,16 +391,23 @@ StdMfg = "(șoricel standard)"
 SERIAL_MOUSE.DeviceDesc = "Șoricel serial standard"
 PS2_MOUSE.DeviceDesc = "Șoricel PS/2 standard"
 HID_MOUSE.DeviceDesc = "Șoricel HID"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "Port pentru șoricel PS/2"
 
 *IBM3780.DeviceDesc = "Rotulă IBM PS/2"
 
 *PNP0F08.DeviceDesc = "Șoricel serial Logitech"
 *PNP0F12.DeviceDesc = "Șoricel PS/2 Logitech"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Șoricel serial Microsoft"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Șoricel PS/2 Microsoft"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0419]
 ReactOS = "Команда ReactOS"
 MouseClassName = "Мыши и другие указывающие устройства"
@@ -318,14 +417,21 @@ StdMfg = "(Стандартная мышь)"
 SERIAL_MOUSE.DeviceDesc = "Стандартная последовательная мышь"
 PS2_MOUSE.DeviceDesc = "Стандартная мышь PS/2"
 HID_MOUSE.DeviceDesc = "HID-мышь"
+*PNP0F0D.DeviceDesc = "Стандартная мышь InPort"
+*PNP0F11.DeviceDesc = "Стандартная шинная мышь"
 *PNP0F13.DeviceDesc = "PS/2-порт на мыши PS/2-вида"
 
 *PNP0F08.DeviceDesc = "Последовательная мышь Logitech"
 *PNP0F12.DeviceDesc = "Мышь Logitech PS/2-вида"
+*PNP0F15.DeviceDesc = "Шинная мышь Logitech"
 
+*PNP0F00.DeviceDesc = "Шинная мышь Microsoft"
 *PNP0F01.DeviceDesc = "Последовательная мышь Microsoft"
+*PNP0F02.DeviceDesc = "Мышь Microsoft InPort"
 *PNP0F03.DeviceDesc = "Мышь Microsoft PS/2-вида"
 
+*nEC1F00.DeviceDesc = "Шинная мышь для NEC PC-98"
+
 [Strings.041B]
 MouseClassName = "Myši a iné polohovacie zariadenia"
 
@@ -333,14 +439,21 @@ StdMfg = "(Štandardná myš)"
 SERIAL_MOUSE.DeviceDesc = "Štandardná sériová myš"
 PS2_MOUSE.DeviceDesc = "Štandardná PS/2 myš"
 HID_MOUSE.DeviceDesc = "HID myš"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "PS/2 port pre myši typu PS/2"
 
 *PNP0F08.DeviceDesc = "Logitech sériová myš"
 *PNP0F12.DeviceDesc = "Logitech PS/2 myš"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Microsoft sériová myš"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Microsoft PS/2 myš"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.041f]
 ReactOS = "ReactOS Takımı"
 MouseClassName = "Fâre ve Başka İmleme Aygıtları"
@@ -350,16 +463,23 @@ StdMfg = "(Ölçünlü Fâre)"
 SERIAL_MOUSE.DeviceDesc = "Ölçünlü Dizilik Fâre"
 PS2_MOUSE.DeviceDesc = "Ölçünlü PS/2 Fâre"
 HID_MOUSE.DeviceDesc = "HID Fâre"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "PS/2 Türünde Fâre İçin PS/2 Girişi"
 
 *IBM3780.DeviceDesc = "IBM PS/2 Trackpoint"
 
 *PNP0F08.DeviceDesc = "Logitech Dizilik Fâre"
 *PNP0F12.DeviceDesc = "Logitech PS/2 Türünde Fâre"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Microsoft Dizilik Fâre"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Microsoft PS/2 Türünde Fâre"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0422]
 ReactOS = "Команда ReactOS"
 MouseClassName = "Миші та інші вказівні пристрої"
@@ -369,16 +489,23 @@ StdMfg = "(Стандартні миші)"
 SERIAL_MOUSE.DeviceDesc = "Стандартна послідовна миша"
 PS2_MOUSE.DeviceDesc = "Стандартна миша PS/2"
 HID_MOUSE.DeviceDesc = "HID-миша"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "Порт PS/2 для миші PS/2-типу"
 
 *IBM3780.DeviceDesc = "Трекпойнт IBM PS/2"
 
 *PNP0F08.DeviceDesc = "Послідовна миша Logitech"
 *PNP0F12.DeviceDesc = "Миша Logitech PS/2-типу"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Послідовна миша Microsoft"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Миша Microsoft PS/2-типу"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0427]
 MouseClassName = "Pelės ir kiti manipuliatoriai"
 
@@ -386,25 +513,39 @@ StdMfg = "(Standartinė pelė)"
 SERIAL_MOUSE.DeviceDesc = "Standartinė nuoseklioji pelė"
 PS2_MOUSE.DeviceDesc = "Standartinė PS/2 pelė"
 HID_MOUSE.DeviceDesc = "HID pelė"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "PS/2 jungtis PS/2 tipo pelei"
 
 *IBM3780.DeviceDesc = "IBM PS/2 rutulinis manipuliatorius"
 
 *PNP0F08.DeviceDesc = "Logitech nuoseklioji pelė"
 *PNP0F12.DeviceDesc = "Logitech PS/2 tipo pelė"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Microsoft nuoseklioji pelė"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Microsoft PS/2 tipo pelė"
 
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"
+
 [Strings.0804]
 StdMfg = "(标准鼠标)"
 SERIAL_MOUSE.DeviceDesc = "标准串口鼠标"
 PS2_MOUSE.DeviceDesc = "标准 PS/2 鼠标"
 HID_MOUSE.DeviceDesc = "HID 鼠标"
+*PNP0F0D.DeviceDesc = "Standard InPort Mouse"
+*PNP0F11.DeviceDesc = "Standard Bus Mouse"
 *PNP0F13.DeviceDesc = "用于 PS/2 风格鼠标的 PS/2 端口"
 
 *PNP0F08.DeviceDesc = "Logitech 串口鼠标"
 *PNP0F12.DeviceDesc = "Logitech PS/2 风格鼠标"
+*PNP0F15.DeviceDesc = "Logitech Bus Mouse"
 
+*PNP0F00.DeviceDesc = "Microsoft Bus Mouse"
 *PNP0F01.DeviceDesc = "Microsoft 串口鼠标"
+*PNP0F02.DeviceDesc = "Microsoft InPort Mouse"
 *PNP0F03.DeviceDesc = "Microsoft PS/2 风格鼠标"
+
+*nEC1F00.DeviceDesc = "NEC PC-98 Bus Mouse"

Reply via email to