1 /*++
2
3 Copyright (c) Microsoft Corporation
4
5 Module Name:
6
7 FxWmiInstance.cpp
8
9 Abstract:
10
11 This module implements the FxWmiInstance object and its derivations
12
13 Author:
14
15
16
17 Revision History:
18
19
20 --*/
21
22 #include "fxwmipch.hpp"
23
24 extern "C" {
25 // #include "FxWmiInstance.tmh"
26 }
27
FxWmiInstance(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in USHORT ObjectSize,__in FxWmiProvider * Provider)28 FxWmiInstance::FxWmiInstance(
29 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
30 __in USHORT ObjectSize,
31 __in FxWmiProvider* Provider
32 ) :
33 FxNonPagedObject(FX_TYPE_WMI_INSTANCE, ObjectSize, FxDriverGlobals)
34 {
35 InitializeListHead(&m_ListEntry);
36 m_Provider = Provider;
37 m_Provider->ADDREF(this);
38 MarkDisposeOverride(ObjectDoNotLock);
39 }
40
~FxWmiInstance()41 FxWmiInstance::~FxWmiInstance()
42 {
43 ASSERT(IsListEmpty(&m_ListEntry));
44 }
45
46 BOOLEAN
Dispose(VOID)47 FxWmiInstance::Dispose(
48 VOID
49 )
50 {
51 m_Provider->RemoveInstance(this);
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
62 _Must_inspect_result_
63 NTSTATUS
FireEvent(__in_bcount_opt (EventBufferSize)PVOID EventBuffer,__inout ULONG EventBufferSize)64 FxWmiInstance::FireEvent(
65 __in_bcount_opt(EventBufferSize) PVOID EventBuffer,
66 __inout ULONG EventBufferSize
67 )
68 {
69 ULONG sizeNeeded;
70 PWNODE_SINGLE_INSTANCE pNode;
71 NTSTATUS status;
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 //
83 pNode = (PWNODE_SINGLE_INSTANCE)
84 ExAllocatePoolWithTag(NonPagedPool, sizeNeeded, GetDriverGlobals()->Tag);
85
86 if (pNode != NULL) {
87 RtlCopyMemory(&pNode->WnodeHeader.Guid,
88 m_Provider->GetGUID(),
89 sizeof(GUID));
90
91 pNode->WnodeHeader.ProviderId = IoWMIDeviceObjectToProviderId(
92 GetDevice()->GetDeviceObject());
93 pNode->WnodeHeader.BufferSize = sizeNeeded;
94 pNode->WnodeHeader.Flags = WNODE_FLAG_SINGLE_INSTANCE |
95 WNODE_FLAG_EVENT_ITEM |
96 WNODE_FLAG_STATIC_INSTANCE_NAMES;
97 KeQuerySystemTime(&pNode->WnodeHeader.TimeStamp);
98
99 pNode->InstanceIndex = m_Provider->GetInstanceIndex(this);
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 {
117 status = STATUS_INSUFFICIENT_RESOURCES;
118
119 DoTraceLevelMessage(
120 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDEVICE,
121 "WDFWMIINSTANCE %p insufficient resources to fire event,%!STATUS!",
122 GetHandle(), status);
123 }
124
125 return status;
126 }
127
FxWmiInstanceExternal(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in PWDF_WMI_INSTANCE_CONFIG Config,__in FxWmiProvider * Provider)128 FxWmiInstanceExternal::FxWmiInstanceExternal(
129 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
130 __in PWDF_WMI_INSTANCE_CONFIG Config,
131 __in FxWmiProvider* Provider
132 ) :
133 FxWmiInstance(FxDriverGlobals, sizeof(FxWmiInstanceExternal), Provider),
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
142 if (m_UseContextForQuery == FALSE) {
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
151 _Must_inspect_result_
152 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)153 FxWmiInstanceExternal::_Create(
154 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
155 __in FxWmiProvider* Provider,
156 __in PWDF_WMI_INSTANCE_CONFIG WmiInstanceConfig,
157 __in_opt PWDF_OBJECT_ATTRIBUTES InstanceAttributes,
158 __out WDFWMIINSTANCE* WmiInstance,
159 __out FxWmiInstanceExternal** Instance
160 )
161 {
162 FxWmiInstanceExternal* pInstance;
163 WDFWMIINSTANCE hInstance;
164 NTSTATUS status;
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
183 status = STATUS_INVALID_PARAMETER;
184
185 DoTraceLevelMessage(
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,
200 InstanceAttributes,
201 FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED);
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) {
213 status = STATUS_INVALID_PARAMETER;
214
215 DoTraceLevelMessage(
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) {
231 status = STATUS_INVALID_PARAMETER;
232
233 DoTraceLevelMessage(
234 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
235 "UseContextForQuery set, but InstanceAttributes %p is null or "
236 "there is no associated type, %!STATUS!",
237 InstanceAttributes, 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)) {
249 DoTraceLevelMessage(
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 //
265 status = STATUS_INTEGER_OVERFLOW;
266
267 DoTraceLevelMessage(
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()) {
279 status = STATUS_BUFFER_TOO_SMALL;
280
281 DoTraceLevelMessage(
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) {
296 status = STATUS_INSUFFICIENT_RESOURCES;
297
298 DoTraceLevelMessage(
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) {
307 pInstance->SetContextForQueryLength((ULONG) contextSize);
308 }
309
310 if (NT_SUCCESS(status)) {
311 status = pInstance->Commit(
312 InstanceAttributes, (PWDFOBJECT) &hInstance, Provider);
313
314 if (NT_SUCCESS(status)) {
315 //
316 // Assign the handle back to the caller.
317 //
318 *WmiInstance = hInstance;
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)) {
331 *Instance = pInstance;
332 }
333 else {
334 pInstance->DeleteFromFailedCreate();
335 }
336
337 return status;
338 }
339
340 BOOLEAN
IsQueryInstanceSupported(VOID)341 FxWmiInstanceExternal::IsQueryInstanceSupported(
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 ||
355 m_QueryInstanceCallback.m_Method != NULL ||
356 m_ExecuteMethodCallback.m_Method != NULL) ? TRUE
357 : FALSE;
358 }
359
360 _Must_inspect_result_
361 __drv_sameIRQL
__drv_maxIRQL(PASSIVE_LEVEL)362 __drv_maxIRQL(PASSIVE_LEVEL)
363 NTSTATUS
364 FxWmiInstanceExternal::QueryInstance(
365 __inout ULONG OutBufferSize,
366 __out_bcount(OutBufferSize) PVOID OutBuffer,
367 __out PULONG BufferUsed
368 )
369 {
370 NTSTATUS status;
371
372 if (m_UseContextForQuery) {
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 //
378 *BufferUsed = m_ContextLength;
379
380 if (OutBufferSize < m_ContextLength) {
381 status = STATUS_BUFFER_TOO_SMALL;
382
383 DoTraceLevelMessage(
384 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDEVICE,
385 "WDFWMIINSTANCE %p query instance using context for query, "
386 "query buffer length %d, context length %d, %!STATUS!",
387 GetHandle(), OutBufferSize, m_ContextLength, status);
388 }
389 else {
390 status = STATUS_SUCCESS;
391
392 RtlCopyMemory(OutBuffer,
393 &GetContextHeader()->Context[0],
394 m_ContextLength);
395 }
396 }
397 else if (m_QueryInstanceCallback.m_Method != NULL) {
398 BYTE dummy;
399
400 if (OutBufferSize == 0) {
401 ASSERT(m_Provider->GetMinInstanceBufferSize() == 0);
402 OutBuffer = (PVOID) &dummy;
403 OutBufferSize = sizeof(dummy);
404 }
405
406 status = m_QueryInstanceCallback.Invoke(
407 GetDevice()->GetHandle(),
408 GetHandle(),
409 OutBufferSize,
410 OutBuffer,
411 BufferUsed
412 );
413
414 if (status == STATUS_PENDING) {
415 DoTraceLevelMessage(
416 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
417 "WDFWMIINSTANCE %p was queried and returned %!STATUS!, which is "
418 "not an allowed return value", GetHandle(), status);
419
420 FxVerifierDbgBreakPoint(GetDriverGlobals());
421
422 status = STATUS_UNSUCCESSFUL;
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 //
431 DoTraceLevelMessage(
432 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
433 "WDFWMIINSTANCE %p was queried with buffer size %d, "
434 " but returned %d bytes and %!STATUS!, should return "
435 "!NT_SUCCESS in this case",
436 GetHandle(), OutBufferSize, *BufferUsed, status);
437
438 FxVerifierDbgBreakPoint(GetDriverGlobals());
439
440 status = STATUS_UNSUCCESSFUL;
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 //
448 status = STATUS_BUFFER_TOO_SMALL;
449 }
450 }
451 else if (status == STATUS_BUFFER_TOO_SMALL) {
452 if (m_Provider->GetMinInstanceBufferSize()) {
453 DoTraceLevelMessage(
454 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
455 "WDFWMIINSTANCE %p returned %!STATUS!, but it specified "
456 "a minimum instance size %d in its WDFWMIPROVIDER %p",
457 GetHandle(), status, m_Provider->GetMinInstanceBufferSize(),
458 m_Provider->GetHandle());
459 DoTraceLevelMessage(
460 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
461 "This is a break in the contract. Minimum instance size "
462 "should only be used for fixed sized instances");
463
464 FxVerifierDbgBreakPoint(GetDriverGlobals());
465 }
466 }
467 }
468 else {
469 ASSERT(m_ExecuteMethodCallback.m_Method != NULL);
470
471 DoTraceLevelMessage(
472 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
473 "WDFWMIINSTANCE %p was queried with no query callback and supports "
474 "execute method (%p), zero bytes returned", GetHandle(),
475 m_ExecuteMethodCallback.m_Method);
476
477 status = STATUS_SUCCESS;
478 *BufferUsed = 0;
479 }
480
481 return status;
482 }
483
484 BOOLEAN
IsSetInstanceSupported(VOID)485 FxWmiInstanceExternal::IsSetInstanceSupported(
486 VOID
487 )
488 {
489 return m_SetInstanceCallback.m_Method != NULL ? TRUE : FALSE;
490 }
491
492 _Must_inspect_result_
493 __drv_sameIRQL
__drv_maxIRQL(PASSIVE_LEVEL)494 __drv_maxIRQL(PASSIVE_LEVEL)
495 NTSTATUS
496 FxWmiInstanceExternal::SetInstance(
497 __in ULONG InBufferSize,
498 __in_bcount(InBufferSize) PVOID InBuffer
499 )
500 {
501 return m_SetInstanceCallback.Invoke(
502 GetDevice()->GetHandle(),
503 GetHandle(),
504 InBufferSize,
505 InBuffer
506 );
507 }
508
509 BOOLEAN
IsSetItemSupported(VOID)510 FxWmiInstanceExternal::IsSetItemSupported(
511 VOID
512 )
513 {
514 return m_SetItemCallback.m_Method != NULL ? TRUE : FALSE;
515 }
516
517 _Must_inspect_result_
518 __drv_sameIRQL
__drv_maxIRQL(PASSIVE_LEVEL)519 __drv_maxIRQL(PASSIVE_LEVEL)
520 NTSTATUS
521 FxWmiInstanceExternal::SetItem(
522 __in ULONG DataItemId,
523 __in ULONG InBufferSize,
524 __in_bcount(InBufferSize) PVOID InBuffer
525 )
526 {
527 return m_SetItemCallback.Invoke(
528 GetDevice()->GetHandle(),
529 GetHandle(),
530 DataItemId,
531 InBufferSize,
532 InBuffer
533 );
534 }
535
536 BOOLEAN
IsExecuteMethodSupported(VOID)537 FxWmiInstanceExternal::IsExecuteMethodSupported(
538 VOID
539 )
540 {
541 return m_ExecuteMethodCallback.m_Method != NULL ? TRUE : FALSE;
542 }
543
544 _Must_inspect_result_
545 __drv_sameIRQL
__drv_maxIRQL(PASSIVE_LEVEL)546 __drv_maxIRQL(PASSIVE_LEVEL)
547 NTSTATUS
548 FxWmiInstanceExternal::ExecuteMethod(
549 __in ULONG MethodId,
550 __in ULONG InBufferSize,
551 __inout ULONG OutBufferSize,
552 __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize))
553 __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize))
554 PVOID Buffer,
555 __out PULONG BufferUsed
556 )
557 {
558 return m_ExecuteMethodCallback.Invoke(
559 GetDevice()->GetHandle(),
560 GetHandle(),
561 MethodId,
562 InBufferSize,
563 OutBufferSize,
564 Buffer,
565 BufferUsed
566 );
567 }
568
FxWmiInstanceInternal(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in FxWmiInstanceInternalCallbacks * Callbacks,__in FxWmiProvider * Provider)569 FxWmiInstanceInternal::FxWmiInstanceInternal(
570 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
571 __in FxWmiInstanceInternalCallbacks* Callbacks,
572 __in FxWmiProvider* Provider
573 ) : FxWmiInstance(FxDriverGlobals, sizeof(FxWmiInstanceInternal), Provider)
574 {
575 m_QueryInstance = Callbacks->QueryInstance;
576 m_SetInstance = Callbacks->SetInstance;
577 m_SetItem = Callbacks->SetItem;
578 m_ExecuteMethod = Callbacks->ExecuteMethod;
579 }
580
581 BOOLEAN
IsQueryInstanceSupported(VOID)582 FxWmiInstanceInternal::IsQueryInstanceSupported(
583 VOID
584 )
585 {
586 return m_QueryInstance != NULL ? TRUE : FALSE;
587 }
588
589 _Must_inspect_result_
590 __drv_sameIRQL
__drv_maxIRQL(PASSIVE_LEVEL)591 __drv_maxIRQL(PASSIVE_LEVEL)
592 NTSTATUS
593 FxWmiInstanceInternal::QueryInstance(
594 __inout ULONG OutBufferSize,
595 __out_bcount(OutBufferSize) PVOID OutBuffer,
596 __out PULONG BufferUsed
597 )
598 {
599 return m_QueryInstance(GetDevice(),
600 this,
601 OutBufferSize,
602 OutBuffer,
603 BufferUsed);
604 }
605
606 BOOLEAN
IsSetInstanceSupported(VOID)607 FxWmiInstanceInternal::IsSetInstanceSupported(
608 VOID
609 )
610 {
611 return m_SetInstance != NULL ? TRUE : FALSE;
612 }
613
614 _Must_inspect_result_
615 __drv_sameIRQL
__drv_maxIRQL(PASSIVE_LEVEL)616 __drv_maxIRQL(PASSIVE_LEVEL)
617 NTSTATUS
618 FxWmiInstanceInternal::SetInstance(
619 __in ULONG InBufferSize,
620 __in_bcount(InBufferSize) PVOID InBuffer
621 )
622 {
623 return m_SetInstance(GetDevice(),
624 this,
625 InBufferSize,
626 InBuffer);
627 }
628
629 BOOLEAN
IsSetItemSupported(VOID)630 FxWmiInstanceInternal::IsSetItemSupported(
631 VOID
632 )
633 {
634 return m_SetItem != NULL ? TRUE : FALSE;
635 }
636
637 _Must_inspect_result_
638 __drv_sameIRQL
__drv_maxIRQL(PASSIVE_LEVEL)639 __drv_maxIRQL(PASSIVE_LEVEL)
640 NTSTATUS
641 FxWmiInstanceInternal::SetItem(
642 __in ULONG DataItemId,
643 __in ULONG InBufferSize,
644 __in_bcount(InBufferSize) PVOID InBuffer
645 )
646 {
647 return m_SetItem(GetDevice(),
648 this,
649 DataItemId,
650 InBufferSize,
651 InBuffer);
652 }
653
654 BOOLEAN
IsExecuteMethodSupported(VOID)655 FxWmiInstanceInternal::IsExecuteMethodSupported(
656 VOID
657 )
658
659 {
660 return m_ExecuteMethod != NULL ? TRUE : FALSE;
661 }
662
663 _Must_inspect_result_
664 __drv_sameIRQL
__drv_maxIRQL(PASSIVE_LEVEL)665 __drv_maxIRQL(PASSIVE_LEVEL)
666 NTSTATUS
667 FxWmiInstanceInternal::ExecuteMethod(
668 __in ULONG MethodId,
669 __in ULONG InBufferSize,
670 __inout ULONG OutBufferSize,
671 __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize))
672 __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize))
673 PVOID Buffer,
674 __out PULONG BufferUsed
675 )
676 {
677 return m_ExecuteMethod(GetDevice(),
678 this,
679 MethodId,
680 InBufferSize,
681 OutBufferSize,
682 Buffer,
683 BufferUsed);
684 }
685