1 /* 2 * PROJECT: ReactOS InPort (Bus) Mouse Driver 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Driver entrypoint 5 * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com) 6 */ 7 8 /* INCLUDES *******************************************************************/ 9 10 #include "inport.h" 11 12 #define NDEBUG 13 #include <debug.h> 14 15 /* GLOBALS ********************************************************************/ 16 17 UNICODE_STRING DriverRegistryPath; 18 19 /* FUNCTIONS ******************************************************************/ 20 21 CODE_SEG("PAGE") 22 NTSTATUS 23 NTAPI 24 InPortCreateClose( 25 _In_ PDEVICE_OBJECT DeviceObject, 26 _Inout_ PIRP Irp) 27 { 28 PAGED_CODE(); 29 30 DPRINT("%s(%p, %p) %X\n", __FUNCTION__, DeviceObject, 31 Irp, IoGetCurrentIrpStackLocation(Irp)->MajorFunction); 32 33 Irp->IoStatus.Information = 0; 34 Irp->IoStatus.Status = STATUS_SUCCESS; 35 IoCompleteRequest(Irp, IO_NO_INCREMENT); 36 37 return STATUS_SUCCESS; 38 } 39 40 CODE_SEG("PAGE") 41 NTSTATUS 42 NTAPI 43 InPortAddDevice( 44 _In_ PDRIVER_OBJECT DriverObject, 45 _In_ PDEVICE_OBJECT PhysicalDeviceObject) 46 { 47 NTSTATUS Status; 48 PDEVICE_OBJECT Fdo; 49 PINPORT_DEVICE_EXTENSION FdoExtension = NULL; 50 WCHAR HardwareIdBuffer[32]; 51 UNICODE_STRING HardwareId; 52 ULONG DummyResultLength; 53 UNICODE_STRING HardwareId1 = RTL_CONSTANT_STRING(L"*nEC1F00"); 54 UNICODE_STRING HardwareId2 = RTL_CONSTANT_STRING(L"*PNP0F00"); 55 UNICODE_STRING HardwareId3 = RTL_CONSTANT_STRING(L"*PNP0F02"); 56 UNICODE_STRING HardwareId4 = RTL_CONSTANT_STRING(L"*PNP0F0D"); 57 UNICODE_STRING HardwareId5 = RTL_CONSTANT_STRING(L"*PNP0F11"); 58 UNICODE_STRING HardwareId6 = RTL_CONSTANT_STRING(L"*PNP0F15"); 59 60 PAGED_CODE(); 61 62 DPRINT("%s(%p, %p)\n", __FUNCTION__, DriverObject, PhysicalDeviceObject); 63 64 Status = IoCreateDevice(DriverObject, 65 sizeof(INPORT_DEVICE_EXTENSION), 66 NULL, 67 FILE_DEVICE_INPORT_PORT, 68 FILE_DEVICE_SECURE_OPEN, 69 FALSE, 70 &Fdo); 71 if (!NT_SUCCESS(Status)) 72 { 73 DPRINT1("Failed to create FDO 0x%X\n", Status); 74 goto Failure; 75 } 76 77 FdoExtension = Fdo->DeviceExtension; 78 79 RtlZeroMemory(FdoExtension, sizeof(INPORT_DEVICE_EXTENSION)); 80 FdoExtension->State = dsStopped; 81 FdoExtension->Self = Fdo; 82 FdoExtension->Pdo = PhysicalDeviceObject; 83 FdoExtension->Ldo = IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject); 84 if (!FdoExtension->Ldo) 85 { 86 DPRINT1("Failed to attach FDO\n"); 87 Status = STATUS_NO_SUCH_DEVICE; 88 goto Failure; 89 } 90 91 IoInitializeRemoveLock(&FdoExtension->RemoveLock, INPORT_TAG, 0, 0); 92 IoInitializeDpcRequest(Fdo, InPortDpcForIsr); 93 94 Status = IoGetDeviceProperty(PhysicalDeviceObject, 95 DevicePropertyHardwareID, 96 sizeof(HardwareIdBuffer), 97 HardwareIdBuffer, 98 &DummyResultLength); 99 if (!NT_SUCCESS(Status)) 100 { 101 DPRINT1("Failed to query the hardware ID string 0x%X\n", Status); 102 goto Failure; 103 } 104 RtlInitUnicodeString(&HardwareId, HardwareIdBuffer); 105 106 if (RtlEqualUnicodeString(&HardwareId, &HardwareId1, FALSE)) 107 { 108 FdoExtension->MouseType = NecBusMouse; 109 FdoExtension->MouseAttributes.SampleRate = 60; 110 FdoExtension->MouseAttributes.NumberOfButtons = 2; 111 } 112 else if (RtlEqualUnicodeString(&HardwareId, &HardwareId3, FALSE) || 113 RtlEqualUnicodeString(&HardwareId, &HardwareId4, FALSE)) 114 { 115 FdoExtension->MouseType = MsInPortMouse; 116 FdoExtension->MouseAttributes.SampleRate = 100; 117 FdoExtension->MouseAttributes.NumberOfButtons = 3; 118 } 119 else if (RtlEqualUnicodeString(&HardwareId, &HardwareId2, FALSE) || 120 RtlEqualUnicodeString(&HardwareId, &HardwareId5, FALSE) || 121 RtlEqualUnicodeString(&HardwareId, &HardwareId6, FALSE)) 122 { 123 FdoExtension->MouseType = LogitechBusMouse; 124 FdoExtension->MouseAttributes.SampleRate = 100; 125 FdoExtension->MouseAttributes.NumberOfButtons = 3; 126 } 127 else 128 { 129 DPRINT1("Unrecognized hardware '%wZ'\n", &HardwareId); 130 Status = STATUS_DEVICE_REMOVED; 131 goto Failure; 132 } 133 FdoExtension->MouseAttributes.MouseIdentifier = MOUSE_INPORT_HARDWARE; 134 /* 1 packet */ 135 FdoExtension->MouseAttributes.InputDataQueueLength = sizeof(MOUSE_INPUT_DATA); 136 137 Fdo->Flags |= DO_BUFFERED_IO; 138 if (FdoExtension->Ldo->Flags & DO_POWER_PAGABLE) 139 Fdo->Flags |= DO_POWER_PAGABLE; 140 Fdo->Flags &= ~DO_DEVICE_INITIALIZING; 141 142 return STATUS_SUCCESS; 143 144 Failure: 145 if (FdoExtension) 146 { 147 if (FdoExtension->Ldo) 148 IoDetachDevice(FdoExtension->Ldo); 149 } 150 151 if (Fdo) 152 { 153 IoDeleteDevice(Fdo); 154 } 155 156 return Status; 157 } 158 159 CODE_SEG("PAGE") 160 VOID 161 NTAPI 162 InPortUnload( 163 _In_ PDRIVER_OBJECT DriverObject) 164 { 165 PAGED_CODE(); 166 167 DPRINT("%s(%p)\n", __FUNCTION__, DriverObject); 168 169 RtlFreeUnicodeString(&DriverRegistryPath); 170 } 171 172 NTSTATUS 173 NTAPI 174 InPortPower( 175 _In_ PDEVICE_OBJECT DeviceObject, 176 _Inout_ PIRP Irp) 177 { 178 NTSTATUS Status; 179 PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 180 181 DPRINT("%s(%p, %p) %X\n", __FUNCTION__, DeviceObject, Irp, 182 IoGetCurrentIrpStackLocation(Irp)->MinorFunction); 183 184 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp); 185 if (!NT_SUCCESS(Status)) 186 { 187 Irp->IoStatus.Status = Status; 188 PoStartNextPowerIrp(Irp); 189 IoCompleteRequest(Irp, IO_NO_INCREMENT); 190 191 return Status; 192 } 193 194 PoStartNextPowerIrp(Irp); 195 IoSkipCurrentIrpStackLocation(Irp); 196 Status = PoCallDriver(DeviceExtension->Ldo, Irp); 197 198 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp); 199 200 return Status; 201 } 202 203 CODE_SEG("INIT") 204 NTSTATUS 205 NTAPI 206 DriverEntry( 207 _In_ PDRIVER_OBJECT DriverObject, 208 _In_ PUNICODE_STRING RegistryPath) 209 { 210 DPRINT("%s(%p, %wZ)\n", __FUNCTION__, DriverObject, RegistryPath); 211 212 DriverRegistryPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, 213 RegistryPath->Length + 214 sizeof(UNICODE_NULL), 215 INPORT_TAG); 216 if (!DriverRegistryPath.Buffer) 217 { 218 DPRINT1("Failed to allocate the registry string buffer\n"); 219 return STATUS_INSUFFICIENT_RESOURCES; 220 } 221 DriverRegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); 222 RtlCopyUnicodeString(&DriverRegistryPath, RegistryPath); 223 DriverRegistryPath.Buffer[RegistryPath->Length / sizeof(WCHAR)] = UNICODE_NULL; 224 225 DriverObject->MajorFunction[IRP_MJ_CREATE] = 226 DriverObject->MajorFunction[IRP_MJ_CLOSE] = InPortCreateClose; 227 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = InPortInternalDeviceControl; 228 DriverObject->MajorFunction[IRP_MJ_POWER] = InPortPower; 229 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = InPortWmi; 230 DriverObject->MajorFunction[IRP_MJ_PNP] = InPortPnp; 231 DriverObject->DriverExtension->AddDevice = InPortAddDevice; 232 DriverObject->DriverUnload = InPortUnload; 233 234 return STATUS_SUCCESS; 235 } 236