1 /*++
2
3 Copyright (c) Microsoft Corporation
4
5 Module Name:
6
7 FxWmiApi.cpp
8
9 Abstract:
10
11 This module implements the C interface to the WMI package
12 for the driver frameworks.
13
14 Author:
15
16
17
18 Environment:
19
20 Kernel mode only
21
22 Revision History:
23
24
25
26 --*/
27
28 #include "fxwmipch.hpp"
29
30 //
31 // Extern "C" the tmh file and all external APIs
32 //
33 extern "C" {
34 #include "fxwmiapi.tmh"
35
36 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)37 __drv_maxIRQL(DISPATCH_LEVEL)
38 NTSTATUS
39 WDFEXPORT(WdfWmiProviderCreate)(
40 __in
41 PWDF_DRIVER_GLOBALS DriverGlobals,
42 __in
43 WDFDEVICE Device,
44 __in
45 PWDF_WMI_PROVIDER_CONFIG WmiProviderConfig,
46 __in_opt
47 PWDF_OBJECT_ATTRIBUTES ProviderAttributes,
48 __out
49 WDFWMIPROVIDER* WmiProvider
50 )
51 {
52 FxDevice* pDevice;
53 FxPowerPolicyOwnerSettings* ownerSettings;
54 FxWmiProvider* pProvider;
55
56 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
57 Device,
58 FX_TYPE_DEVICE,
59 (PVOID*) &pDevice);
60
61 FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), WmiProviderConfig);
62 FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), WmiProvider);
63
64 //
65 // If the Device is a power policy owner then do not allow client drivers
66 // to register for GUID_POWER_DEVICE_ENABLE or GUID_POWER_DEVICE_WAKE_ENABLE
67 // if the framework has already register a provider for those guids.
68 //
69 if (pDevice->m_PkgPnp->IsPowerPolicyOwner()) {
70 ownerSettings = pDevice->m_PkgPnp->m_PowerPolicyMachine.m_Owner;
71
72 if ((FxIsEqualGuid(&WmiProviderConfig->Guid,
73 &GUID_POWER_DEVICE_ENABLE) &&
74 ownerSettings->m_IdleSettings.WmiInstance != NULL) ||
75
76 (FxIsEqualGuid(&WmiProviderConfig->Guid,
77 &GUID_POWER_DEVICE_WAKE_ENABLE) &&
78 ownerSettings->m_WakeSettings.WmiInstance != NULL)) {
79
80 DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_ERROR,
81 TRACINGDEVICE, "WMI Guid already registered by "
82 "framework");
83 return STATUS_WMI_GUID_DISCONNECTED;
84 }
85 }
86
87 return FxWmiProvider::_Create(GetFxDriverGlobals(DriverGlobals),
88 Device,
89 ProviderAttributes,
90 WmiProviderConfig,
91 WmiProvider,
92 &pProvider);
93 }
94
95 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)96 __drv_maxIRQL(DISPATCH_LEVEL)
97 NTSTATUS
98 WDFEXPORT(WdfWmiInstanceCreate)(
99 __in
100 PWDF_DRIVER_GLOBALS DriverGlobals,
101 __in
102 WDFDEVICE Device,
103 __in
104 PWDF_WMI_INSTANCE_CONFIG InstanceConfig,
105 __in_opt
106 PWDF_OBJECT_ATTRIBUTES InstanceAttributes,
107 __out_opt
108 WDFWMIINSTANCE* Instance
109 )
110 {
111 PFX_DRIVER_GLOBALS pFxDriverGlobals;
112 FxWmiProvider* pProvider;
113 FxWmiInstanceExternal* pInstance;
114 WDFWMIINSTANCE hInstance;
115 NTSTATUS status;
116
117 pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
118 pInstance = NULL;
119
120 FxPointerNotNull(pFxDriverGlobals, InstanceConfig);
121
122 if (InstanceConfig->Size != sizeof(WDF_WMI_INSTANCE_CONFIG)) {
123 status = STATUS_INFO_LENGTH_MISMATCH;
124 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
125 "Expected InstanceConfig Size %d, got %d, %!STATUS!",
126 InstanceConfig->Size, sizeof(*InstanceConfig),
127 status);
128 return status;
129 }
130
131 if (InstanceConfig->Provider == NULL &&
132 InstanceConfig->ProviderConfig == NULL) {
133 status = STATUS_INVALID_PARAMETER;
134
135 DoTraceLevelMessage(
136 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
137 "InstanceConfig %p Provider and ProviderConfig are both NULL, only "
138 "one can be, %!STATUS!", InstanceConfig, status);
139
140 return status;
141 }
142 else if (InstanceConfig->Provider != NULL &&
143 InstanceConfig->ProviderConfig != NULL) {
144 status = STATUS_INVALID_PARAMETER;
145
146 DoTraceLevelMessage(
147 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
148 "InstanceConfig %p Provider %p and ProviderConfig %p are both not "
149 "NULL, only one can be, %!STATUS!", InstanceConfig,
150 InstanceConfig->Provider, InstanceConfig->ProviderConfig, status);
151
152 return status;
153 }
154
155 if (InstanceConfig->Provider != NULL) {
156 FxObjectHandleGetPtrAndGlobals(pFxDriverGlobals,
157 InstanceConfig->Provider,
158 FX_TYPE_WMI_PROVIDER,
159 (PVOID*) &pProvider,
160 &pFxDriverGlobals);
161 }
162 else {
163 FxDevice* pDevice;
164 FxPowerPolicyOwnerSettings* ownerSettings;
165 WDFWMIPROVIDER hProvider;
166
167 hProvider = NULL;
168 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
169 Device,
170 FX_TYPE_DEVICE,
171 (PVOID*) &pDevice);
172
173 //
174 // If the Device is a power policy owner then do not allow client drivers
175 // to register for GUID_POWER_DEVICE_ENABLE or GUID_POWER_DEVICE_WAKE_ENABLE
176 // if the framework has already register a provider for those guids.
177 //
178 if (pDevice->m_PkgPnp->IsPowerPolicyOwner()) {
179 ownerSettings = pDevice->m_PkgPnp->m_PowerPolicyMachine.m_Owner;
180
181 if ((FxIsEqualGuid(&InstanceConfig->ProviderConfig->Guid,
182 &GUID_POWER_DEVICE_ENABLE) &&
183 ownerSettings->m_IdleSettings.WmiInstance != NULL) ||
184
185 (FxIsEqualGuid(&InstanceConfig->ProviderConfig->Guid,
186 &GUID_POWER_DEVICE_WAKE_ENABLE) &&
187 ownerSettings->m_WakeSettings.WmiInstance != NULL)) {
188
189 status = STATUS_WMI_GUID_DISCONNECTED;
190 DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_ERROR,
191 TRACINGDEVICE, "WMI Guid already registered by "
192 "framework");
193 return status;
194 }
195 }
196
197 status = FxWmiProvider::_Create(pFxDriverGlobals,
198 Device,
199 NULL,
200 InstanceConfig->ProviderConfig,
201 &hProvider,
202 &pProvider);
203
204 if (!NT_SUCCESS(status)) {
205 return status;
206 }
207
208 //
209 // Use the object's globals and not the caller's
210 //
211 pFxDriverGlobals = pProvider->GetDriverGlobals();
212 }
213
214 status = FxWmiInstanceExternal::_Create(pFxDriverGlobals,
215 pProvider,
216 InstanceConfig,
217 InstanceAttributes,
218 &hInstance,
219 &pInstance);
220
221 if (NT_SUCCESS(status) && InstanceConfig->Register) {
222 status = pProvider->AddInstance(pInstance);
223 }
224
225 if (NT_SUCCESS(status)) {
226 if (Instance != NULL) {
227 *Instance = hInstance;
228 }
229 }
230 else {
231 //
232 // Something went wrong, cleanup
233 //
234 if (pInstance != NULL) {
235 //
236 // This will remove the instance from the provider's list as well.
237 //
238 pInstance->DeleteFromFailedCreate();
239 }
240
241 //
242 // Only remove the provider if we created it in this function
243 //
244 if (InstanceConfig->ProviderConfig != NULL) {
245 pProvider->DeleteFromFailedCreate();
246 }
247 }
248
249 return status;
250 }
251
252 WDFAPI
__drv_maxIRQL(DISPATCH_LEVEL)253 __drv_maxIRQL(DISPATCH_LEVEL)
254 WDFDEVICE
255 WDFEXPORT(WdfWmiProviderGetDevice)(
256 __in
257 PWDF_DRIVER_GLOBALS DriverGlobals,
258 __in
259 WDFWMIPROVIDER WmiProvider
260 )
261 {
262 FxWmiProvider *pProvider;
263
264 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
265 WmiProvider,
266 FX_TYPE_WMI_PROVIDER,
267 (PVOID*) &pProvider);
268
269 return pProvider->GetDevice()->GetHandle();
270 }
271
__drv_maxIRQL(DISPATCH_LEVEL)272 __drv_maxIRQL(DISPATCH_LEVEL)
273 BOOLEAN
274 WDFEXPORT(WdfWmiProviderIsEnabled)(
275 __in
276 PWDF_DRIVER_GLOBALS DriverGlobals,
277 __in
278 WDFWMIPROVIDER WmiProvider,
279 __in
280 WDF_WMI_PROVIDER_CONTROL ProviderControl
281 )
282 {
283 FxWmiProvider *pProvider;
284
285 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
286 WmiProvider,
287 FX_TYPE_WMI_PROVIDER,
288 (PVOID*) &pProvider);
289
290 return pProvider->IsEnabled(ProviderControl);
291 }
292
__drv_maxIRQL(DISPATCH_LEVEL)293 __drv_maxIRQL(DISPATCH_LEVEL)
294 ULONGLONG
295 WDFEXPORT(WdfWmiProviderGetTracingHandle)(
296 __in
297 PWDF_DRIVER_GLOBALS DriverGlobals,
298 __in
299 WDFWMIPROVIDER WmiProvider
300 )
301 {
302 FxWmiProvider *pProvider;
303
304 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
305 WmiProvider,
306 FX_TYPE_WMI_PROVIDER,
307 (PVOID*) &pProvider);
308
309 return pProvider->GetTracingHandle();
310 }
311
312 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)313 __drv_maxIRQL(DISPATCH_LEVEL)
314 NTSTATUS
315 WDFEXPORT(WdfWmiInstanceRegister)(
316 __in
317 PWDF_DRIVER_GLOBALS DriverGlobals,
318 __in
319 WDFWMIINSTANCE WmiInstance
320 )
321 {
322 FxWmiInstanceExternal* pInstance;
323 FxWmiProvider* pProvider;
324
325 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
326 WmiInstance,
327 FX_TYPE_WMI_INSTANCE,
328 (PVOID*) &pInstance);
329
330 pProvider = pInstance->GetProvider();
331
332 return pProvider->AddInstance(pInstance);
333 }
334
__drv_maxIRQL(DISPATCH_LEVEL)335 __drv_maxIRQL(DISPATCH_LEVEL)
336 VOID
337 WDFEXPORT(WdfWmiInstanceDeregister)(
338 __in
339 PWDF_DRIVER_GLOBALS DriverGlobals,
340 __in
341 WDFWMIINSTANCE WmiInstance
342 )
343 {
344 FxWmiInstanceExternal* pInstance;
345 FxWmiProvider* pProvider;
346
347 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
348 WmiInstance,
349 FX_TYPE_WMI_INSTANCE,
350 (PVOID*) &pInstance);
351
352 pProvider = pInstance->GetProvider();
353 pProvider->RemoveInstance(pInstance);
354 }
355
__drv_maxIRQL(DISPATCH_LEVEL)356 __drv_maxIRQL(DISPATCH_LEVEL)
357 WDFDEVICE
358 WDFEXPORT(WdfWmiInstanceGetDevice)(
359 __in
360 PWDF_DRIVER_GLOBALS DriverGlobals,
361 __in
362 WDFWMIINSTANCE WmiInstance
363 )
364 {
365 FxWmiInstanceExternal* pInstance;
366
367 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
368 WmiInstance,
369 FX_TYPE_WMI_INSTANCE,
370 (PVOID*) &pInstance);
371
372 return pInstance->GetDevice()->GetHandle();
373 }
374
__drv_maxIRQL(DISPATCH_LEVEL)375 __drv_maxIRQL(DISPATCH_LEVEL)
376 WDFWMIPROVIDER
377 WDFEXPORT(WdfWmiInstanceGetProvider)(
378 __in
379 PWDF_DRIVER_GLOBALS DriverGlobals,
380 __in
381 WDFWMIINSTANCE WmiInstance
382 )
383 {
384 FxWmiInstanceExternal *pInstance;
385
386 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
387 WmiInstance,
388 FX_TYPE_WMI_INSTANCE,
389 (PVOID*) &pInstance);
390
391 return pInstance->GetProvider()->GetHandle();
392 }
393
394
395 _Must_inspect_result_
__drv_maxIRQL(APC_LEVEL)396 __drv_maxIRQL(APC_LEVEL)
397 NTSTATUS
398 WDFEXPORT(WdfWmiInstanceFireEvent)(
399 __in
400 PWDF_DRIVER_GLOBALS DriverGlobals,
401 __in
402 WDFWMIINSTANCE WmiInstance,
403 __in_opt
404 ULONG EventDataSize,
405 __in_bcount_opt(EventDataSize)
406 PVOID EventData
407 )
408 /*++
409
410 Routine Description:
411 Fires an event based on the instance handle.
412
413 Arguments:
414 WmiInstance - instance which the event is associated with
415 EventDataSize - size of EventData in bytes
416 EventData - buffer associated with the event
417
418 Return Value:
419 NTSTATUS
420
421 --*/
422 {
423 FxWmiInstanceExternal* pInstance;
424 NTSTATUS status;
425
426 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
427 WmiInstance,
428 FX_TYPE_WMI_INSTANCE,
429 (PVOID*) &pInstance);
430
431 status = FxVerifierCheckIrqlLevel(pInstance->GetDriverGlobals(), APC_LEVEL);
432 if (!NT_SUCCESS(status)) {
433 return status;
434 }
435
436 return pInstance->FireEvent(EventData, EventDataSize);
437 }
438
439 } // extern "C"
440