ReactOS 0.4.16-dev-112-g52265ae
fxwmiprovider.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxWmiProvider.cpp
8
9Abstract:
10
11 This module implements the FxWmiProvider object
12
13Author:
14
15
16
17Revision History:
18
19
20--*/
21
22#include "fxwmipch.hpp"
23
24extern "C" {
25// #include "FxWmiProvider.tmh"
26}
27
29 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
32 ) :
35 FxDriverGlobals),
36 m_FunctionControl(FxDriverGlobals)
37{
41
42 m_Parent = Device->m_PkgWmi;
43
47
49
50 m_Flags = Config->Flags;
51 m_MinInstanceBufferSize = Config->MinInstanceBufferSize;
52 RtlCopyMemory(&m_Guid, &Config->Guid, sizeof(GUID));
53
54 if (Config->EvtWmiProviderFunctionControl != NULL) {
55 m_FunctionControl.m_Method = Config->EvtWmiProviderFunctionControl;
56 }
57
58 //
59 // Driver cannot call WdfObjectDelete on this handle
60 //
62
64}
65
67{
69}
70
73 VOID
74 )
75{
76 //
77 // Object is being deleted, remove this object from the irp handler's list
78 // of providers. If we don't do this, the irp handler will have a list
79 // which contains entries which have been freed.
80 //
82
83 return FxNonPagedObject::Dispose(); // __super call
84}
85
89 __in PFX_DRIVER_GLOBALS CallersGlobals,
90 __in WDFDEVICE Device,
93 __out WDFWMIPROVIDER* WmiProvider,
95 )
96{
102 GUID zeroGuid;
103 BOOLEAN update;
104
105 FxObjectHandleGetPtrAndGlobals(CallersGlobals,
106 Device,
108 (PVOID*) &pDevice,
110
111 *Provider = NULL;
112 update = FALSE;
113
114 *WmiProvider = NULL;
115
119 if (!NT_SUCCESS(status)) {
120 return status;
121 }
122
123 if (WmiProviderConfig->Size != sizeof(WDF_WMI_PROVIDER_CONFIG)) {
125
128 "WmiProviderConfig Size 0x%x, expected size 0x%x, %!STATUS!",
130 status);
131
132 return status;
133 }
134
135 if ((WmiProviderConfig->Flags & ~WdfWmiProviderValidFlags) != 0) {
139 "Invalid flag(s) set, Flags 0x%x, valid mask 0x%x, %!STATUS!",
141 status);
142 return status;
143 }
144
148
151 "WdfWmiProviderTracing must be the only flag set, %!STATUS!",
152 status);
153
154 return status;
155 }
156
157 //
158 // Function control makes sense if it is expensive. Otherwise you will
159 // not be called back on it.
160 //
161 // The opposite, marking yourself as expensive but providing no callback is
162 // OK b/c the provider marks the enabled state and the driver can retrieve
163 // it at runtime.
164 //
165 // Function control also applies to tracing GUIDs since the tracing subsystem
166 // will call enable/disable events to start/stop tracing.
167 //
168 if (WmiProviderConfig->EvtWmiProviderFunctionControl != NULL &&
171
174 "EvtWmiProviderFunctionControl can only be set if Flags 0x%x has "
175 "WdfWmiProviderTracing (%d) or WdfWmiProviderExpensive (%d) bit "
176 "values set, %!STATUS!",
179
180 return status;
181 }
182
183 RtlZeroMemory(&zeroGuid, sizeof(zeroGuid));
184
186 &zeroGuid,
187 sizeof(GUID)) == sizeof(GUID)) {
189
192 "WmiProvider Guid filed is all zeros, %!STATUS!",
193 status);
194
195 return status;
196 }
197
198 pProvider = NULL;
199
202
203 if (pProvider == NULL) {
205
208 "Could not allocate memory for a WDFWMIPROVIDER, %!STATUS!",
209 status);
210
211 return status;
212 }
213
215
216 if (NT_SUCCESS(status)) {
218
219 if (!NT_SUCCESS(status)) {
221 }
222 else {
223 //
224 // NT_SUCCES(status) case
225 //
226 *WmiProvider = (WDFWMIPROVIDER) hProvider;
227 }
228 }
229
230 if (NT_SUCCESS(status)) {
232
233 if (update) {
235 }
236 }
237 else {
238 //
239 // AddProvider incremented update count on success however since we
240 // are not going to update registration due to this failure, decrement
241 // the count.
242 //
243 if (update) {
245 }
246
248 }
249
250 return status;
251}
252
257 __in BOOLEAN NoErrorIfPresent,
260 )
261{
263
264 *Update = FALSE;
265
266 if (!IsListEmpty(&Instance->m_ListEntry)) {
267 if (NoErrorIfPresent) {
268 return STATUS_SUCCESS;
269 }
270 else {
271 //
272 // Entry is already on a list, bad caller!
273 //
275
278 "WDFWMIINSTANCE %p already added, %!STATUS!",
279 Instance->GetHandle(), status);
280
281 return status;
282 }
283 }
284
285 //
286 // Check to see if we are in the process of
287 //
288 switch (m_Parent->m_RegisteredState) {
290 //
291 // The GUID will be reported when we do the initial registration
292 //
293 break;
294
296 //
297 // Either the GUID will be reported when we do the re-registration or
298 // we will clean it up when we goto the cleanup state.
299 //
300 break;
301
303 //
304 // Since we already registered we need to tell WMI the change in the
305 // number of instances on this provider.
306 //
307 *Update = TRUE;
308 break;
309
311 //
312 // Device is going away, registration is not allowed for the device
313 // anymore.
314 //
316
319 "WMI is being cleanedup, WDFWMIINSTANCE %p add failing, %!STATUS!",
320 Instance->GetHandle(), status);
321
322 return status;
323
324 default:
325 ASSERT(FALSE);
326 break;
327 }
328
329 if (Action == AddInstanceToTail) {
331 }
332 else {
334 }
335
336 //
337 // Since the count is increasing to at least one, we are not going to
338 // need to report this GUID as missing. We could check the
339 // m_Parent->m_RegisteredState and only set it when we are registered, but
340 // it does us no harm to always clear this value regardless of state.
341 //
343
346
347 return status;
348}
349
354 __in BOOLEAN NoErrorIfPresent
355 )
356{
358 KIRQL irql;
359 BOOLEAN update;
360
363
366 "WDFWMIINSTANCE %p cannot be added to tracing WDFWMIPROVIDER %p, "
367 "%!STATUS!", Instance->GetHandle(), GetHandle(), status);
368
369 return status;
370 }
371
372 m_Parent->Lock(&irql);
373 status = AddInstanceLocked(Instance, NoErrorIfPresent, &update);
374
375 if (update) {
377 }
379
380 if (update) {
382 }
383
384 return status;
385}
386
387VOID
390 )
391{
392 KIRQL irql;
393 BOOLEAN update;
394
395 update = FALSE;
396
397 m_Parent->Lock(&irql);
398
399 if (!IsListEmpty(&Instance->m_ListEntry)) {
400 //
401 // Instance is in the list of instances on this provider. Remove it.
402 //
403 RemoveEntryList(&Instance->m_ListEntry);
404 InitializeListHead(&Instance->m_ListEntry);
406
408 update = TRUE;
409
410 //
411 // When the count goes to zero, inform WMI that the GUID should be
412 // removed when we get requeried. We only need to do this once we have
413 // been registered. In all other states, we ignore this value.
414 //
415 if (m_NumInstances == 0 &&
418 }
419 }
420 }
421 else {
422 //
423 // The instance was explicitly removed and now the instance is trying
424 // to remove itself during dispose. Nothing to do.
425 //
426 DO_NOTHING();
427 }
428
429 if (update) {
431 }
432
434
435 if (update) {
437 }
438}
439
440ULONG
443 )
444{
446 ULONG index;
447 KIRQL irql;
448
449 m_Parent->Lock(&irql);
450 for (index = 0, ple = m_InstanceListHead.Flink;
452 index++, ple = ple->Flink) {
454 break;
455 }
456 }
458
459 return index;
460}
461
467 )
468{
470 KIRQL irql;
471
472 m_Parent->Lock(&irql);
475
476 return pInstance;
477}
478
484 )
485{
486 FxWmiInstance* pFound;
488 ULONG i;
489
490 pFound = NULL;
491
492 for (i = 0, ple = m_InstanceListHead.Flink;
494 ple = ple->Flink, i++) {
495
496 if (i == Index) {
498 pFound->ADDREF(Tag);
499 break;
500 }
501 }
502
503 return pFound;
504}
505
511 )
512{
514 GetHandle(),
515 Control,
516 Enable);
517}
518
519ULONG
521 VOID
522 )
523{
524 ULONG flags;
525
528
529 //
530 // Once tracing GUID is registered, we do not allow it to be unregistered
531 //
533 }
534 else {
536
539 }
540
543 }
544 }
545
546 if (m_RemoveGuid) {
547 //
548 // We have gone down to zero instances of this provider, report it as
549 // gone to WMI.
550 //
553
554 //
555 // Once reported as removed, we do not have not have to report ourselves
556 // as removed again.
557 //
559 }
560
561 return flags;
562}
563
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define index(s, c)
Definition: various.h:29
@ Update
Definition: registry.c:565
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
FxWmiIrpHandler * m_PkgWmi
Definition: fxdevice.hpp:672
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
VOID MarkNoDeleteDDI(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1118
virtual BOOLEAN Dispose(VOID)
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
__inline CfxDevice * GetDevice(VOID)
Definition: fxpackage.hpp:46
BOOLEAN DeferUpdateLocked(__in KIRQL OldIrql)
VOID RemoveProvider(__in FxWmiProvider *Provider)
_Must_inspect_result_ NTSTATUS AddProvider(__in FxWmiProvider *Provider, __out_opt PBOOLEAN Update=NULL)
WmiRegisteredState m_RegisteredState
VOID UpdateGuids(VOID)
LIST_ENTRY m_InstanceListHead
FxWmiIrpHandler * m_Parent
ULONGLONG m_TracingHandle
ULONG m_MinInstanceBufferSize
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS CallersGlobals, __in WDFDEVICE Device, __in_opt PWDF_OBJECT_ATTRIBUTES ProviderAttributes, __in PWDF_WMI_PROVIDER_CONFIG WmiProviderConfig, __out WDFWMIPROVIDER *WmiProvider, __out FxWmiProvider **Provider)
BOOLEAN m_EventControlEnabled
FxWmiProvider(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_WMI_PROVIDER_CONFIG Config, __in CfxDevice *Device)
LIST_ENTRY m_ListEntry
_Must_inspect_result_ FxWmiInstance * GetInstanceReferencedLocked(__in ULONG Index, __in PVOID Tag)
BOOLEAN m_RemoveGuid
FxWmiProviderFunctionControlCallback m_FunctionControl
ULONG GetInstanceIndex(__in FxWmiInstance *Instance)
_Must_inspect_result_ NTSTATUS FunctionControl(__in WDF_WMI_PROVIDER_CONTROL Control, __in BOOLEAN Enable)
BOOLEAN m_DataBlockControlEnabled
virtual BOOLEAN Dispose(VOID)
_Must_inspect_result_ NTSTATUS AddInstanceLocked(__in FxWmiInstance *Instance, __in BOOLEAN NoErrorIfPresent, __out PBOOLEAN Update, __in AddInstanceAction Action=AddInstanceToTail)
VOID RemoveInstance(__in FxWmiInstance *Instance)
ULONG GetRegistrationFlagsLocked(VOID)
_Must_inspect_result_ NTSTATUS AddInstance(__in FxWmiInstance *Instance, __in BOOLEAN NoErrorIfPresent=FALSE)
_Must_inspect_result_ FxWmiInstance * GetInstanceReferenced(__in ULONG Index, __in PVOID Tag)
#define __in
Definition: dbghelp.h:35
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGPNP
Definition: dbgtrace.h:67
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
KIRQL irql
Definition: wave.h:1
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
FxDevice * pDevice
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Device, FX_TYPE_DEVICE,(PVOID *)&pDevice, &pFxDriverGlobals)
PFX_DRIVER_GLOBALS pFxDriverGlobals
PSINGLE_LIST_ENTRY ple
@ ObjectDoNotLock
Definition: fxobject.hpp:128
@ FX_TYPE_WMI_PROVIDER
Definition: fxtypes.h:49
@ FX_TYPE_DEVICE
Definition: fxtypes.h:47
@ FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED
_Must_inspect_result_ NTSTATUS FxValidateObjectAttributes(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG Flags=FX_VALIDATE_OPTION_NONE_SPECIFIED)
FxWmiProvider * pProvider
Definition: fxwmiapi.cpp:54
FxWmiInstanceExternal * pInstance
Definition: fxwmiapi.cpp:113
WDFWMIPROVIDER hProvider
Definition: fxwmiapi.cpp:165
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define DO_NOTHING()
Definition: mxgeneral.h:32
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
PFN_WDF_WMI_PROVIDER_FUNCTION_CONTROL m_Method
_Must_inspect_result_ NTSTATUS Invoke(__in WDFDEVICE Device, __in WDFWMIPROVIDER WmiProvider, __in WDF_WMI_PROVIDER_CONTROL Control, __in BOOLEAN Enable)
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: ps.c:97
#define GetHandle(h)
Definition: treelist.c:116
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
@ WdfWmiProviderValidFlags
Definition: wdfwmi.h:72
@ WdfWmiProviderExpensive
Definition: wdfwmi.h:70
@ WdfWmiProviderTracing
Definition: wdfwmi.h:71
@ WdfWmiProviderEventOnly
Definition: wdfwmi.h:69
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_INSTANCE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_opt_ WDFWMIINSTANCE * Instance
Definition: wdfwmi.h:481
WDF_EXTERN_C_START enum _WDF_WMI_PROVIDER_CONTROL WDF_WMI_PROVIDER_CONTROL
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_PROVIDER_CONFIG WmiProviderConfig
Definition: wdfwmi.h:358
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_PROVIDER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWMIPROVIDER * WmiProvider
Definition: wdfwmi.h:363
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_PROVIDER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES ProviderAttributes
Definition: wdfwmi.h:360
#define WMIREG_FLAG_INSTANCE_PDO
Definition: wmistr.h:69
#define WMIREG_FLAG_TRACE_CONTROL_GUID
Definition: wmistr.h:74
#define WMIREG_FLAG_REMOVE_GUID
Definition: wmistr.h:70
#define WMIREG_FLAG_EVENT_ONLY_GUID
Definition: wmistr.h:75
#define WMIREG_FLAG_EXPENSIVE
Definition: wmistr.h:66
#define WMIREG_FLAG_TRACED_GUID
Definition: wmistr.h:73
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList