1 //
2 // Copyright (C) Microsoft. All rights reserved.
3 //
4 #include "../pnppriv.hpp"
5
6 #include <initguid.h>
7 #include <wdmguid.h>
8
9 extern "C" {
10 #if defined(EVENT_TRACING)
11 #include "FxPkgPnpUM.tmh"
12 #endif
13 }
14
15 NTSTATUS
FilterResourceRequirements(__in IO_RESOURCE_REQUIREMENTS_LIST ** IoList)16 FxPkgPnp::FilterResourceRequirements(
17 __in IO_RESOURCE_REQUIREMENTS_LIST **IoList
18 )
19 {
20 UNREFERENCED_PARAMETER(IoList);
21 ASSERTMSG("Not implemented for UMDF\n", FALSE);
22
23 return STATUS_NOT_IMPLEMENTED;
24 }
25
26 _Must_inspect_result_
27 NTSTATUS
AllocateDmaEnablerList(VOID)28 FxPkgPnp::AllocateDmaEnablerList(
29 VOID
30 )
31 {
32 ASSERTMSG("Not implemented for UMDF\n", FALSE);
33
34 return STATUS_NOT_IMPLEMENTED;
35 }
36
37 VOID
AddDmaEnabler(__in FxDmaEnabler * Enabler)38 FxPkgPnp::AddDmaEnabler(
39 __in FxDmaEnabler* Enabler
40 )
41 {
42 UNREFERENCED_PARAMETER(Enabler);
43 ASSERTMSG("Not implemented for UMDF\n", FALSE);
44 }
45
46 VOID
RemoveDmaEnabler(__in FxDmaEnabler * Enabler)47 FxPkgPnp::RemoveDmaEnabler(
48 __in FxDmaEnabler* Enabler
49 )
50 {
51 UNREFERENCED_PARAMETER(Enabler);
52 ASSERTMSG("Not implemented for UMDF\n", FALSE);
53 }
54
55 NTSTATUS
UpdateWmiInstance(_In_ FxWmiInstanceAction Action,_In_ BOOLEAN ForS0Idle)56 FxPkgPnp::UpdateWmiInstance(
57 _In_ FxWmiInstanceAction Action,
58 _In_ BOOLEAN ForS0Idle
59 )
60 {
61 HRESULT hr;
62 NTSTATUS status;
63 IWudfDeviceStack* devStack;
64 WmiIdleWakeInstanceUpdate updateType;
65
66 devStack = m_Device->GetDeviceStack();
67
68 ASSERT(Action != InstanceActionInvalid);
69
70 if (Action == AddInstance) {
71 updateType = ForS0Idle ? AddS0IdleInstance : AddSxWakeInstance;
72 } else {
73 updateType = ForS0Idle ? RemoveS0IdleInstance : RemoveSxWakeInstance;
74 }
75
76 hr = devStack->UpdateIdleWakeWmiInstance(updateType);
77 if (S_OK == hr) {
78 status = STATUS_SUCCESS;
79 }
80 else {
81 PUMDF_VERSION_DATA driverVersion = devStack->GetMinDriverVersion();
82 BOOL preserveCompat =
83 devStack->ShouldPreserveIrpCompletionStatusCompatibility();
84
85 status = CHostFxUtil::NtStatusFromHr(hr,
86 driverVersion->MajorNumber,
87 driverVersion->MinorNumber,
88 preserveCompat);
89 }
90
91 if (!NT_SUCCESS(status)) {
92 DoTraceLevelMessage(GetDriverGlobals(),
93 TRACE_LEVEL_ERROR,
94 TRACINGPNP,
95 "failed to send ioctl to update %s WMI instance "
96 "%!STATUS!",
97 ForS0Idle ? "S0Idle" : "SxWake",
98 status);
99 }
100
101 return status;
102 }
103
104 NTSTATUS
ReadStateFromRegistry(_In_ PCUNICODE_STRING ValueName,_Out_ PULONG Value)105 FxPkgPnp::ReadStateFromRegistry(
106 _In_ PCUNICODE_STRING ValueName,
107 _Out_ PULONG Value
108 )
109 {
110 DWORD err;
111 NTSTATUS status;
112 DWORD data;
113 DWORD dataSize;
114 HKEY pwrPolKey = NULL;
115 IWudfDeviceStack* devStack;
116
117 ASSERT(NULL != Value);
118 ASSERT(ValueName != NULL &&
119 ValueName->Length != 0 &&
120 ValueName->Buffer != NULL);
121
122 *Value = 0;
123 devStack = m_Device->GetDeviceStack();
124
125 err = RegOpenKeyEx(devStack->GetDeviceRegistryKey(),
126 WUDF_POWER_POLICY_SETTINGS,
127 0,
128 KEY_READ,
129 &pwrPolKey);
130 if (ERROR_SUCCESS != err) {
131 DoTraceLevelMessage(GetDriverGlobals(),
132 TRACE_LEVEL_ERROR,
133 TRACINGPNP,
134 "RegOpenKeyEx returned error %d",
135 err);
136 goto Clean;
137 }
138
139 dataSize = sizeof(data);
140 err = RegQueryValueEx(pwrPolKey,
141 ValueName->Buffer,
142 NULL,
143 NULL,
144 (BYTE*) &data,
145 &dataSize);
146 if (ERROR_SUCCESS != err) {
147 DoTraceLevelMessage(GetDriverGlobals(),
148 TRACE_LEVEL_ERROR,
149 TRACINGPNP,
150 "failed to read registry, "
151 "RegQueryValueEx returned error %d",
152 err);
153 goto Clean;
154 }
155
156 *Value = data;
157 err = ERROR_SUCCESS;
158
159 Clean:
160 if (NULL != pwrPolKey) {
161 RegCloseKey(pwrPolKey);
162 }
163
164 if (ERROR_SUCCESS == err) {
165 status = STATUS_SUCCESS;
166 }
167 else {
168 PUMDF_VERSION_DATA driverVersion = devStack->GetMinDriverVersion();
169 BOOL preserveCompat =
170 devStack->ShouldPreserveIrpCompletionStatusCompatibility();
171
172 status = CHostFxUtil::NtStatusFromHr(HRESULT_FROM_WIN32(err),
173 driverVersion->MajorNumber,
174 driverVersion->MinorNumber,
175 preserveCompat);
176 }
177
178 return status;
179 }
180
181 VOID
WriteStateToRegistry(__in HANDLE RegKey,__in PUNICODE_STRING ValueName,__in ULONG Value)182 FxPkgPnp::WriteStateToRegistry(
183 __in HANDLE RegKey,
184 __in PUNICODE_STRING ValueName,
185 __in ULONG Value
186 )
187 {
188 DWORD err;
189 HRESULT hr;
190 HKEY hKey = NULL;
191 IWudfDeviceStack* devStack;
192 UMINT::WDF_PROPERTY_STORE_ROOT propertyStore;
193
194 UNREFERENCED_PARAMETER(RegKey);
195
196 ASSERT(ValueName != NULL &&
197 ValueName->Length != 0 &&
198 ValueName->Buffer != NULL);
199
200 devStack = m_Device->GetDeviceStack();
201
202 propertyStore.LengthCb = sizeof(UMINT::WDF_PROPERTY_STORE_ROOT);
203 propertyStore.RootClass = UMINT::WdfPropertyStoreRootClassHardwareKey;
204 propertyStore.Qualifier.HardwareKey.ServiceName = WUDF_POWER_POLICY_SETTINGS;
205
206 hr = devStack->CreateRegistryEntry(&propertyStore,
207 UMINT::WdfPropertyStoreCreateIfMissing,
208 KEY_QUERY_VALUE | KEY_SET_VALUE,
209 NULL,
210 &hKey,
211 NULL);
212 if (FAILED(hr)) {
213 goto Clean;
214 }
215
216 //
217 // Failure to save the user's idle/wake settings is not critical and we
218 // will continue on regardless. Hence we ignore the return value.
219 //
220 err = RegSetValueEx(hKey,
221 ValueName->Buffer,
222 0,
223 REG_DWORD,
224 (BYTE *) &Value,
225 sizeof(Value));
226 if (err != ERROR_SUCCESS) {
227 DoTraceLevelMessage(GetDriverGlobals(),
228 TRACE_LEVEL_ERROR,
229 TRACINGPNP,
230 "Failed to set Registry value "
231 "for S0Idle/SxWake error %d",
232 err);
233 goto Clean;
234 }
235
236 Clean:
237 if (NULL != hKey) {
238 RegCloseKey(hKey);
239 }
240 }
241
242 NTSTATUS
UpdateWmiInstanceForS0Idle(__in FxWmiInstanceAction Action)243 FxPkgPnp::UpdateWmiInstanceForS0Idle(
244 __in FxWmiInstanceAction Action
245 )
246 {
247 NTSTATUS status;
248
249 //
250 // Send an IOCTL to redirector
251 // to add/remove S0Idle WMI instance.
252 //
253 status = UpdateWmiInstance(Action, TRUE);
254
255 return status;
256 }
257
258 VOID
ReadRegistryS0Idle(__in PCUNICODE_STRING ValueName,__out BOOLEAN * Enabled)259 FxPkgPnp::ReadRegistryS0Idle(
260 __in PCUNICODE_STRING ValueName,
261 __out BOOLEAN *Enabled
262 )
263 {
264 NTSTATUS status;
265 ULONG value;
266
267 status = ReadStateFromRegistry(ValueName, &value);
268
269 //
270 // Modify value of Enabled only if success
271 //
272 if (NT_SUCCESS(status)) {
273 //
274 // Normalize the ULONG value into a BOOLEAN
275 //
276 *Enabled = (value == FALSE) ? FALSE : TRUE;
277 }
278 }
279
280 NTSTATUS
UpdateWmiInstanceForSxWake(__in FxWmiInstanceAction Action)281 FxPkgPnp::UpdateWmiInstanceForSxWake(
282 __in FxWmiInstanceAction Action
283 )
284 {
285 NTSTATUS status;
286
287 //
288 // Send an IOCTL to redirector
289 // to add/remove SxWake WMI instance.
290 //
291 status = UpdateWmiInstance(Action, FALSE);
292
293 return status;
294 }
295
296 VOID
ReadRegistrySxWake(__in PCUNICODE_STRING ValueName,__out BOOLEAN * Enabled)297 FxPkgPnp::ReadRegistrySxWake(
298 __in PCUNICODE_STRING ValueName,
299 __out BOOLEAN *Enabled
300 )
301 {
302 NTSTATUS status;
303 ULONG value;
304
305 status = ReadStateFromRegistry(ValueName, &value);
306
307 //
308 // Modify value of Enabled only if success
309 //
310 if (NT_SUCCESS(status)) {
311 //
312 // Normalize the ULONG value into a BOOLEAN
313 //
314 *Enabled = (value == FALSE) ? FALSE : TRUE;
315 }
316 }
317
318 VOID
PnpPassThroughQIWorker(__in MxDeviceObject * Device,__inout FxIrp * Irp,__inout FxIrp * ForwardIrp)319 PnpPassThroughQIWorker(
320 __in MxDeviceObject* Device,
321 __inout FxIrp* Irp,
322 __inout FxIrp* ForwardIrp
323 )
324 {
325 UNREFERENCED_PARAMETER(Device);
326 UNREFERENCED_PARAMETER(Irp);
327 UNREFERENCED_PARAMETER(ForwardIrp);
328 ASSERTMSG("Not implemented for UMDF\n", FALSE);
329 }
330
331
332 VOID
RevokeDmaEnablerResources(__in FxDmaEnabler *)333 FxPkgPnp::RevokeDmaEnablerResources(
334 __in FxDmaEnabler * /* DmaEnabler */
335 )
336 {
337 // Do nothing
338 }
339
340