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