ReactOS 0.4.15-dev-7842-g558ab78
fxwmiinstance.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxWmiInstance.cpp
8
9Abstract:
10
11 This module implements the FxWmiInstance object and its derivations
12
13Author:
14
15
16
17Revision History:
18
19
20--*/
21
22#include "fxwmipch.hpp"
23
24extern "C" {
25// #include "FxWmiInstance.tmh"
26}
27
29 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
30 __in USHORT ObjectSize,
32 ) :
33 FxNonPagedObject(FX_TYPE_WMI_INSTANCE, ObjectSize, FxDriverGlobals)
34{
37 m_Provider->ADDREF(this);
39}
40
42{
44}
45
48 VOID
49 )
50{
52 m_Provider->RELEASE(this);
53
54 //
55 // Object is being deleted, remove this object from the provider's list
56 // of instances. If we don't do this, the provider will have a list which
57 // contains entries which have been freed.
58 //
59 return FxNonPagedObject::Dispose(); // __super call
60}
61
65 __in_bcount_opt(EventBufferSize) PVOID EventBuffer,
66 __inout ULONG EventBufferSize
67 )
68{
69 ULONG sizeNeeded;
72
73 if (EventBuffer == NULL) {
74 EventBufferSize = 0;
75 }
76
77 sizeNeeded = sizeof(WNODE_SINGLE_INSTANCE) + EventBufferSize;
78
79 //
80 // IoWMIWriteEvent will free the memory by calling ExFreePool. This means
81 // we cannot use a framework allocate function.
82 //
85
86 if (pNode != NULL) {
87 RtlCopyMemory(&pNode->WnodeHeader.Guid,
89 sizeof(GUID));
90
93 pNode->WnodeHeader.BufferSize = sizeNeeded;
97 KeQuerySystemTime(&pNode->WnodeHeader.TimeStamp);
98
100 pNode->SizeDataBlock = EventBufferSize;
101 pNode->DataBlockOffset = sizeof(WNODE_SINGLE_INSTANCE);
102
103 if (EventBuffer != NULL) {
104 RtlCopyMemory(&pNode->VariableData, EventBuffer, EventBufferSize);
105 }
106
107 //
108 // Upon success, IoWMIWriteEvent will free pNode.
109 //
110 status = IoWMIWriteEvent(pNode);
111
112 if (!NT_SUCCESS(status)) {
113 ExFreePool(pNode);
114 }
115 }
116 else {
118
121 "WDFWMIINSTANCE %p insufficient resources to fire event,%!STATUS!",
122 GetHandle(), status);
123 }
124
125 return status;
126}
127
129 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
132 ) :
134 m_QueryInstanceCallback(FxDriverGlobals),
135 m_SetInstanceCallback(FxDriverGlobals),
136 m_SetItemCallback(FxDriverGlobals),
137 m_ExecuteMethodCallback(FxDriverGlobals)
138{
139 m_ContextLength = 0;
140 m_UseContextForQuery = Config->UseContextForQuery;
141
143 m_QueryInstanceCallback.m_Method = Config->EvtWmiInstanceQueryInstance;
144 }
145 m_SetInstanceCallback.m_Method = Config->EvtWmiInstanceSetInstance;
146 m_SetItemCallback.m_Method = Config->EvtWmiInstanceSetItem;
147
148 m_ExecuteMethodCallback.m_Method = Config->EvtWmiInstanceExecuteMethod;
149}
150
154 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
156 __in PWDF_WMI_INSTANCE_CONFIG WmiInstanceConfig,
158 __out WDFWMIINSTANCE* WmiInstance,
160 )
161{
163 WDFWMIINSTANCE hInstance;
165 size_t contextSize;
166
167 contextSize = 0;
168 *Instance = 0;
169
170 *WmiInstance = NULL;
171
172 //
173 // For event only providers, you cannot specify any callbacks or context
174 // usage.
175 //
176 if (Provider->IsEventOnly() &&
177 (WmiInstanceConfig->UseContextForQuery ||
178 WmiInstanceConfig->EvtWmiInstanceQueryInstance != NULL ||
179 WmiInstanceConfig->EvtWmiInstanceSetInstance != NULL ||
180 WmiInstanceConfig->EvtWmiInstanceSetItem != NULL ||
181 WmiInstanceConfig->EvtWmiInstanceExecuteMethod != NULL)) {
182
184
186 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
187 "WDFWMIPROVIDER %p is event only and UseContextForQuery (%d) is TRUE,"
188 " or a callback (query instance %p, set instance %p, set item %p, "
189 "executue method %p) is not NULL, %!STATUS!",
190 Provider->GetHandle(), WmiInstanceConfig->UseContextForQuery,
191 WmiInstanceConfig->EvtWmiInstanceQueryInstance,
192 WmiInstanceConfig->EvtWmiInstanceSetInstance,
193 WmiInstanceConfig->EvtWmiInstanceSetItem,
194 WmiInstanceConfig->EvtWmiInstanceExecuteMethod, status);
195
196 return status;
197 }
198
199 status = FxValidateObjectAttributes(FxDriverGlobals,
202 if (!NT_SUCCESS(status)) {
203 return status;
204 }
205
206 if (WmiInstanceConfig->UseContextForQuery) {
207 //
208 // UseContextForQuery only supported for read only instances.
209 // ExecuteMethod has undefined side affects, so we allow it.
210 //
211 if (WmiInstanceConfig->EvtWmiInstanceSetInstance != NULL ||
212 WmiInstanceConfig->EvtWmiInstanceSetItem != NULL) {
214
216 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
217 "UseContextForQuery set, i.e. a read only instance, but "
218 "EvtWmiInstanceSetInstance %p or EvtWmiInstanceSetItem %p is "
219 "set, %!STATUS!",
220 WmiInstanceConfig->EvtWmiInstanceSetInstance,
221 WmiInstanceConfig->EvtWmiInstanceSetItem, status);
222
223 return status;
224 }
225
226 //
227 // We must have a context to use for the query
228 //
229 if (InstanceAttributes == NULL ||
230 InstanceAttributes->ContextTypeInfo == NULL) {
232
234 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
235 "UseContextForQuery set, but InstanceAttributes %p is null or "
236 "there is no associated type, %!STATUS!",
238
239 return status;
240 }
241
242 contextSize = InstanceAttributes->ContextTypeInfo->ContextSize;
243
244 if (InstanceAttributes->ContextSizeOverride != 0) {
245 status = RtlSizeTAdd(contextSize,
246 InstanceAttributes->ContextSizeOverride,
247 &contextSize);
248 if (!NT_SUCCESS(status)) {
250 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
251 "Overlfow adding contextSize %I64d with size override %I64d, "
252 "%!STATUS!", contextSize,
253 InstanceAttributes->ContextSizeOverride, status);
254
255 return status;
256 }
257 }
258
259 if (contextSize > ULONG_MAX) {
260 //
261 // Since we are casting to a ULONG below, detect loss of data here
262 // (only really applicable on 64 bit machines where sizeof(size_t) !=
263 // sizeof(ULONG)
264 //
266
268 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
269 "context size %I64d can be %d large, %!STATUS!",
270 contextSize, ULONG_MAX, status);
271
272 return status;
273 }
274
275 //
276 // Make sure the context is the minimum the buffer size.
277 //
278 if (contextSize < Provider->GetMinInstanceBufferSize()) {
280
282 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
283 "context size %I64d is less then the WDFWMIPROVIDER %p min size "
284 "of %d, %!STATUS!",
285 contextSize, Provider->GetHandle(),
286 Provider->GetMinInstanceBufferSize(), status);
287
288 return status;
289 }
290 }
291
292 pInstance = new(FxDriverGlobals, InstanceAttributes)
293 FxWmiInstanceExternal(FxDriverGlobals, WmiInstanceConfig, Provider);
294
295 if (pInstance == NULL) {
297
299 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
300 "could not allocate memory for WDFWMIINSTANCE, %!STATUS!",
301 status);
302
303 return status;
304 }
305
306 if (contextSize > 0) {
308 }
309
310 if (NT_SUCCESS(status)) {
313
314 if (NT_SUCCESS(status)) {
315 //
316 // Assign the handle back to the caller.
317 //
319 }
320 else {
321 //
322 // On failure, DeleteFromFailedCreate will delete the object and
323 // the Dispose callback will remove the instance from the provider's
324 // list.
325 //
326 DO_NOTHING();
327 }
328 }
329
330 if (NT_SUCCESS(status)) {
332 }
333 else {
335 }
336
337 return status;
338}
339
342 VOID
343 )
344{
345 //
346 // If we have a function pointer to call or we are using the context
347 // as the buffer, query instance is supported.
348 //
349 // Also, if neither of the first 2 are true, we need to support query
350 // instance if the device has an execute method callback b/c WMI will
351 // send a query instance to this instance which much succeed for the
352 // execute method irp to be sent.
353 //
354 return (m_UseContextForQuery ||
357 : FALSE;
358}
359
364FxWmiInstanceExternal::QueryInstance(
368 )
369{
371
373 //
374 // No matter what, we are reporting the length of the context. If the
375 // buffer is too small, it is used to report the desired buffer length.
376 // Otherwise, it is the amount of data we copied to the query buffer.
377 //
379
382
385 "WDFWMIINSTANCE %p query instance using context for query, "
386 "query buffer length %d, context length %d, %!STATUS!",
388 }
389 else {
391
395 }
396 }
398 BYTE dummy;
399
400 if (OutBufferSize == 0) {
402 OutBuffer = (PVOID) &dummy;
403 OutBufferSize = sizeof(dummy);
404 }
405
407 GetDevice()->GetHandle(),
408 GetHandle(),
410 OutBuffer,
412 );
413
414 if (status == STATUS_PENDING) {
417 "WDFWMIINSTANCE %p was queried and returned %!STATUS!, which is "
418 "not an allowed return value", GetHandle(), status);
419
421
423 *BufferUsed = 0;
424 }
425 else if (NT_SUCCESS(status)) {
426 if (*BufferUsed > OutBufferSize) {
427 //
428 // Caller error, they returned more bytes in *BufferUsed then
429 // was passed in via OutBufferSize, yet returned NT_SUCCESS
430 //
433 "WDFWMIINSTANCE %p was queried with buffer size %d, "
434 " but returned %d bytes and %!STATUS!, should return "
435 "!NT_SUCCESS in this case",
437
439
441 *BufferUsed = 0;
442 }
443 else if (OutBuffer == &dummy && *BufferUsed > 0) {
444 //
445 // Convert success back to an error where we can report the
446 // required size back to the caller.
447 //
449 }
450 }
451 else if (status == STATUS_BUFFER_TOO_SMALL) {
455 "WDFWMIINSTANCE %p returned %!STATUS!, but it specified "
456 "a minimum instance size %d in its WDFWMIPROVIDER %p",
461 "This is a break in the contract. Minimum instance size "
462 "should only be used for fixed sized instances");
463
465 }
466 }
467 }
468 else {
470
473 "WDFWMIINSTANCE %p was queried with no query callback and supports "
474 "execute method (%p), zero bytes returned", GetHandle(),
476
478 *BufferUsed = 0;
479 }
480
481 return status;
482}
483
486 VOID
487 )
488{
490}
491
496FxWmiInstanceExternal::SetInstance(
499 )
500{
501 return m_SetInstanceCallback.Invoke(
502 GetDevice()->GetHandle(),
503 GetHandle(),
505 InBuffer
506 );
507}
508
511 VOID
512 )
513{
515}
516
521FxWmiInstanceExternal::SetItem(
525 )
526{
527 return m_SetItemCallback.Invoke(
528 GetDevice()->GetHandle(),
529 GetHandle(),
532 InBuffer
533 );
534}
535
538 VOID
539 )
540{
542}
543
548FxWmiInstanceExternal::ExecuteMethod(
556 )
557{
558 return m_ExecuteMethodCallback.Invoke(
559 GetDevice()->GetHandle(),
560 GetHandle(),
561 MethodId,
564 Buffer,
566 );
567}
568
570 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
573 ) : FxWmiInstance(FxDriverGlobals, sizeof(FxWmiInstanceInternal), Provider)
574{
575 m_QueryInstance = Callbacks->QueryInstance;
576 m_SetInstance = Callbacks->SetInstance;
578 m_ExecuteMethod = Callbacks->ExecuteMethod;
579}
580
583 VOID
584 )
585{
586 return m_QueryInstance != NULL ? TRUE : FALSE;
587}
588
593FxWmiInstanceInternal::QueryInstance(
597 )
598{
599 return m_QueryInstance(GetDevice(),
600 this,
602 OutBuffer,
603 BufferUsed);
604}
605
608 VOID
609 )
610{
611 return m_SetInstance != NULL ? TRUE : FALSE;
612}
613
618FxWmiInstanceInternal::SetInstance(
621 )
622{
623 return m_SetInstance(GetDevice(),
624 this,
626 InBuffer);
627}
628
631 VOID
632 )
633{
634 return m_SetItem != NULL ? TRUE : FALSE;
635}
636
641FxWmiInstanceInternal::SetItem(
645 )
646{
647 return m_SetItem(GetDevice(),
648 this,
651 InBuffer);
652}
653
656 VOID
657 )
658
659{
660 return m_ExecuteMethod != NULL ? TRUE : FALSE;
661}
662
667FxWmiInstanceInternal::ExecuteMethod(
675 )
676{
677 return m_ExecuteMethod(GetDevice(),
678 this,
679 MethodId,
682 Buffer,
683 BufferUsed);
684}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
HINSTANCE hInstance
Definition: charmap.c:19
Definition: bufpool.h:45
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
virtual BOOLEAN Dispose(VOID)
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
__inline FxContextHeader * GetContextHeader(VOID)
Definition: fxobject.hpp:720
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
VOID SetContextForQueryLength(__in ULONG ContextSize)
virtual _Must_inspect_result_ __drv_sameIRQL __in ULONG __inout ULONG OutBufferSize
virtual BOOLEAN IsSetInstanceSupported(VOID)
virtual BOOLEAN IsQueryInstanceSupported(VOID)
FxWmiInstanceSetItemCallback m_SetItemCallback
FxWmiInstanceQueryInstanceCallback m_QueryInstanceCallback
FxWmiInstanceSetInstanceCallback m_SetInstanceCallback
virtual BOOLEAN IsSetItemSupported(VOID)
FxWmiInstanceExternal(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_WMI_INSTANCE_CONFIG Config, __in FxWmiProvider *Provider)
virtual _Must_inspect_result_ __drv_sameIRQL __out PULONG BufferUsed
virtual BOOLEAN IsExecuteMethodSupported(VOID)
FxWmiInstanceExecuteMethodCallback m_ExecuteMethodCallback
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxWmiProvider *Provider, __in PWDF_WMI_INSTANCE_CONFIG WmiInstanceConfig, __in_opt PWDF_OBJECT_ATTRIBUTES InstanceAttributes, __out WDFWMIINSTANCE *WmiInstance, __out FxWmiInstanceExternal **Instance)
virtual BOOLEAN IsSetInstanceSupported(VOID)
PFN_FX_WMI_INSTANCE_EXECUTE_METHOD m_ExecuteMethod
virtual BOOLEAN IsQueryInstanceSupported(VOID)
PFN_FX_WMI_INSTANCE_SET_ITEM m_SetItem
FxWmiInstanceInternal(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxWmiInstanceInternalCallbacks *Callbacks, __in FxWmiProvider *m_Provider)
virtual BOOLEAN IsSetItemSupported(VOID)
PFN_FX_WMI_INSTANCE_QUERY_INSTANCE m_QueryInstance
virtual BOOLEAN IsExecuteMethodSupported(VOID)
PFN_FX_WMI_INSTANCE_SET_INSTANCE m_SetInstance
virtual BOOLEAN Dispose(VOID)
LIST_ENTRY m_ListEntry
FxWmiProvider * m_Provider
_Must_inspect_result_ NTSTATUS FireEvent(__in_bcount_opt(EventBufferSize) PVOID EventBuffer, __inout ULONG EventBufferSize)
FxWmiInstance(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize, __in FxWmiProvider *Provider)
GUID * GetGUID(VOID)
ULONG GetInstanceIndex(__in FxWmiInstance *Instance)
WDFWMIPROVIDER GetHandle(VOID)
VOID RemoveInstance(__in FxWmiInstance *Instance)
ULONG GetMinInstanceBufferSize(VOID)
#define __inout_bcount(x)
Definition: dbghelp.h:56
#define __in
Definition: dbghelp.h:35
#define __out_bcount(x)
Definition: dbghelp.h:68
#define __in_bcount(x)
Definition: dbghelp.h:41
#define __inout
Definition: dbghelp.h:50
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define __in_bcount_opt(x)
Definition: dbghelp.h:44
#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:32
#define __drv_when(cond, annotes)
Definition: driverspecs.h:335
#define __drv_maxIRQL(irql)
Definition: driverspecs.h:291
#define __drv_sameIRQL
Definition: driverspecs.h:325
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
return pList GetDevice()
return pDevice GetDeviceObject()
FxVerifierDbgBreakPoint(pFxDriverGlobals)
@ ObjectDoNotLock
Definition: fxobject.hpp:128
@ FX_TYPE_WMI_INSTANCE
Definition: fxtypes.h:87
@ 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)
FxWmiInstanceExternal * pInstance
Definition: fxwmiapi.cpp:113
_Must_inspect_result_ __drv_sameIRQL __in FxWmiInstanceInternal * Instance
#define ULONG_MAX
Definition: limits.h:44
HRESULT SetItem(REFGUID guidKey, REFPROPVARIANT Value)
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define DO_NOTHING()
Definition: mxgeneral.h:32
NTSTATUS NTAPI IoWMIWriteEvent(_Inout_ PVOID WnodeEventItem)
Definition: wmi.c:109
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:385
unsigned short USHORT
Definition: pedump.c:61
_In_ UCHAR _In_ ULONG _Out_ PUCHAR _Outptr_result_bytebuffer_ OutBufferLength PVOID * OutBuffer
Definition: scsi.h:4071
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
PFN_WDF_WMI_INSTANCE_EXECUTE_METHOD m_Method
PFN_WDF_WMI_INSTANCE_QUERY_INSTANCE m_Method
PFN_WDF_WMI_INSTANCE_SET_INSTANCE m_Method
PFN_WDF_WMI_INSTANCE_SET_ITEM m_Method
Definition: ps.c:97
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:58
#define GetHandle(h)
Definition: treelist.c:116
uint32_t * PULONG
Definition: typedefs.h:59
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_In_ ULONG OutBufferSize
Definition: wdfwmi.h:87
_In_ ULONG _Out_ PULONG BufferUsed
Definition: wdfwmi.h:92
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_INSTANCE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES InstanceAttributes
Definition: wdfwmi.h:478
_Must_inspect_result_ _In_ WDFWMIINSTANCE WmiInstance
Definition: wdfwmi.h:514
_In_ ULONG InBufferSize
Definition: wdfwmi.h:106
_In_ ULONG MethodId
Definition: wdfwmi.h:142
_In_ ULONG DataItemId
Definition: wdfwmi.h:123
#define WNODE_FLAG_STATIC_INSTANCE_NAMES
Definition: wmistr.h:35
#define WNODE_FLAG_EVENT_ITEM
Definition: wmistr.h:31
struct tagWNODE_SINGLE_INSTANCE WNODE_SINGLE_INSTANCE
struct tagWNODE_SINGLE_INSTANCE * PWNODE_SINGLE_INSTANCE
#define WNODE_FLAG_SINGLE_INSTANCE
Definition: wmistr.h:29
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define IoWMIDeviceObjectToProviderId(DeviceObject)
unsigned char BYTE
Definition: xxhash.c:193