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