xref: /reactos/drivers/input/inport/wmi.c (revision 3adf4508)
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