From 310a24da6ecd65c2bee0d84f73f7fc13175cdf92 Mon Sep 17 00:00:00 2001 From: Dmitry Borisov Date: Sun, 13 Sep 2020 17:42:48 +0600 Subject: [PATCH] [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(+) create mode 100644 drivers/input/inport/CMakeLists.txt create mode 100644 drivers/input/inport/hardware.c create mode 100644 drivers/input/inport/inport.c create mode 100644 drivers/input/inport/inport.h create mode 100644 drivers/input/inport/inport.rc create mode 100644 drivers/input/inport/ioctl.c create mode 100644 drivers/input/inport/pnp.c create mode 100644 drivers/input/inport/wmi.c 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 (di.sean@protonmail.com) + */ + +/* Note: Some code was taken from Linux */ + +/* INCLUDES *******************************************************************/ + +#include "inport.h" + +#define NDEBUG +#include + +/* 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 (di.sean@protonmail.com) + */ + +/* INCLUDES *******************************************************************/ + +#include "inport.h" + +#define NDEBUG +#include + +/* 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 (di.sean@protonmail.com) + */ + +#ifndef _INPORT_H_ +#define _INPORT_H_ + +#include +#include +#include +#include + +#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 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 (di.sean@protonmail.com) + */ + +/* INCLUDES *******************************************************************/ + +#include "inport.h" + +#define NDEBUG +#include + +/* 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 (di.sean@protonmail.com) + */ + +/* INCLUDES *******************************************************************/ + +#include "inport.h" + +#define NDEBUG +#include + +/* 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 (di.sean@protonmail.com) + */ + +/* INCLUDES *******************************************************************/ + +#include "inport.h" + +#define NDEBUG +#include + +/* 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"