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
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)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
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)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
InPortWmiRegistration(_Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension)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
InPortWmiDeRegistration(_Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension)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
InPortWmi(_In_ PDEVICE_OBJECT DeviceObject,_Inout_ PIRP Irp)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