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: WMI support 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(PAGE, InPortWmi) 19 #pragma alloc_text(PAGE, InPortWmiRegistration) 20 #pragma alloc_text(PAGE, InPortWmiDeRegistration) 21 #pragma alloc_text(PAGE, InPortQueryWmiRegInfo) 22 #pragma alloc_text(PAGE, InPortQueryWmiDataBlock) 23 #endif 24 25 GUID GuidWmiPortData = POINTER_PORT_WMI_STD_DATA_GUID; 26 27 WMIGUIDREGINFO InPortWmiGuidList[] = 28 { 29 {&GuidWmiPortData, 1, 0} 30 }; 31 32 /* FUNCTIONS ******************************************************************/ 33 34 NTSTATUS 35 NTAPI 36 InPortQueryWmiRegInfo( 37 _Inout_ PDEVICE_OBJECT DeviceObject, 38 _Inout_ PULONG RegFlags, 39 _Inout_ PUNICODE_STRING InstanceName, 40 _Out_opt_ PUNICODE_STRING *RegistryPath, 41 _Inout_ PUNICODE_STRING MofResourceName, 42 _Out_opt_ PDEVICE_OBJECT *Pdo) 43 { 44 PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 45 46 UNREFERENCED_PARAMETER(InstanceName); 47 UNREFERENCED_PARAMETER(MofResourceName); 48 49 PAGED_CODE(); 50 51 DPRINT("%s()\n", __FUNCTION__); 52 53 *RegFlags = WMIREG_FLAG_INSTANCE_PDO; 54 *RegistryPath = &DriverRegistryPath; 55 *Pdo = DeviceExtension->Pdo; 56 57 return STATUS_SUCCESS; 58 } 59 60 NTSTATUS 61 NTAPI 62 InPortQueryWmiDataBlock( 63 _Inout_ PDEVICE_OBJECT DeviceObject, 64 _Inout_ PIRP Irp, 65 _In_ ULONG GuidIndex, 66 _In_ ULONG InstanceIndex, 67 _In_ ULONG InstanceCount, 68 _Out_opt_ PULONG InstanceLengthArray, 69 _In_ ULONG BufferAvail, 70 _Out_opt_ PUCHAR Buffer) 71 { 72 NTSTATUS Status; 73 PPOINTER_PORT_WMI_STD_DATA InPortData; 74 PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 75 76 PAGED_CODE(); 77 78 DPRINT("%s()\n", __FUNCTION__); 79 80 if (GuidIndex > RTL_NUMBER_OF(InPortWmiGuidList)) 81 { 82 Status = STATUS_WMI_GUID_NOT_FOUND; 83 goto Complete; 84 } 85 86 /* Only register 1 instance per GUID */ 87 if (InstanceIndex != 0 || InstanceCount != 1) 88 { 89 Status = STATUS_WMI_INSTANCE_NOT_FOUND; 90 goto Complete; 91 } 92 93 if (!InstanceLengthArray || BufferAvail < sizeof(POINTER_PORT_WMI_STD_DATA)) 94 { 95 Status = STATUS_BUFFER_TOO_SMALL; 96 goto Complete; 97 } 98 99 InPortData = (PPOINTER_PORT_WMI_STD_DATA)Buffer; 100 101 /* Bus mouse connector isn't defined in the DDK, so set type to something generic */ 102 InPortData->ConnectorType = POINTER_PORT_WMI_STD_I8042; 103 /* 1 packet */ 104 InPortData->DataQueueSize = 1; 105 /* Not supported by device */ 106 InPortData->ErrorCount = 0; 107 108 InPortData->Buttons = DeviceExtension->MouseAttributes.NumberOfButtons; 109 InPortData->HardwareType = POINTER_PORT_WMI_STD_MOUSE; 110 *InstanceLengthArray = sizeof(POINTER_PORT_WMI_STD_DATA); 111 112 Status = STATUS_SUCCESS; 113 114 Complete: 115 return WmiCompleteRequest(DeviceObject, 116 Irp, 117 Status, 118 sizeof(POINTER_PORT_WMI_STD_DATA), 119 IO_NO_INCREMENT); 120 } 121 122 NTSTATUS 123 NTAPI 124 InPortWmiRegistration( 125 _Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension) 126 { 127 PAGED_CODE(); 128 129 DeviceExtension->WmiLibInfo.GuidCount = RTL_NUMBER_OF(InPortWmiGuidList); 130 DeviceExtension->WmiLibInfo.GuidList = InPortWmiGuidList; 131 132 DeviceExtension->WmiLibInfo.QueryWmiRegInfo = InPortQueryWmiRegInfo; 133 DeviceExtension->WmiLibInfo.QueryWmiDataBlock = InPortQueryWmiDataBlock; 134 DeviceExtension->WmiLibInfo.SetWmiDataBlock = NULL; 135 DeviceExtension->WmiLibInfo.SetWmiDataItem = NULL; 136 DeviceExtension->WmiLibInfo.ExecuteWmiMethod = NULL; 137 DeviceExtension->WmiLibInfo.WmiFunctionControl = NULL; 138 139 return IoWMIRegistrationControl(DeviceExtension->Self, 140 WMIREG_ACTION_REGISTER); 141 } 142 143 NTSTATUS 144 NTAPI 145 InPortWmiDeRegistration( 146 _Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension) 147 { 148 PAGED_CODE(); 149 150 return IoWMIRegistrationControl(DeviceExtension->Self, 151 WMIREG_ACTION_DEREGISTER); 152 } 153 154 NTSTATUS 155 NTAPI 156 InPortWmi( 157 _In_ PDEVICE_OBJECT DeviceObject, 158 _Inout_ PIRP Irp) 159 { 160 NTSTATUS Status; 161 SYSCTL_IRP_DISPOSITION Disposition; 162 PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 163 164 PAGED_CODE(); 165 166 DPRINT("%s(%p, %p) %X\n", __FUNCTION__, DeviceObject, Irp, 167 IoGetCurrentIrpStackLocation(Irp)->MinorFunction); 168 169 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp); 170 if (!NT_SUCCESS(Status)) 171 { 172 Irp->IoStatus.Information = 0; 173 Irp->IoStatus.Status = Status; 174 IoCompleteRequest(Irp, IO_NO_INCREMENT); 175 176 return Status; 177 } 178 179 Status = WmiSystemControl(&DeviceExtension->WmiLibInfo, 180 DeviceObject, 181 Irp, 182 &Disposition); 183 switch (Disposition) 184 { 185 case IrpProcessed: 186 break; 187 188 case IrpNotCompleted: 189 IoCompleteRequest(Irp, IO_NO_INCREMENT); 190 break; 191 192 case IrpForward: 193 case IrpNotWmi: 194 IoSkipCurrentIrpStackLocation(Irp); 195 Status = IoCallDriver(DeviceExtension->Ldo, Irp); 196 break; 197 } 198 199 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp); 200 201 return Status; 202 } 203