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