[CRT] Massively improve performance of rand_s
[reactos.git] / drivers / input / inport / wmi.c
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 }