1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxWmiInstance.hpp
8 
9 Abstract:
10 
11     This module implements the WMI instance object
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19     Both kernel and user mode
20 
21 Revision History:
22 
23 
24 
25 --*/
26 
27 #ifndef _FXWMIINSTANCE_H_
28 #define _FXWMIINSTANCE_H_
29 
30 
31 class FxWmiInstance : public FxNonPagedObject {
32 
33     friend FxWmiProvider;
34     friend FxWmiIrpHandler;
35 
36 public:
37     FxWmiInstance(
38         __in PFX_DRIVER_GLOBALS FxDriverGlobals,
39         __in USHORT ObjectSize,
40         __in FxWmiProvider* Provider
41         );
42 
43     ~FxWmiInstance();
44 
45     CfxDevice*
GetDevice(VOID)46     GetDevice(
47         VOID
48         )
49     {
50         return m_Provider->GetDevice();
51     }
52 
53     FxWmiProvider*
GetProvider(VOID)54     GetProvider(
55         VOID
56         )
57     {
58         return m_Provider;
59     }
60 
61     _Must_inspect_result_
62     NTSTATUS
63     FireEvent(
64         __in_bcount_opt(EventBufferSize) PVOID EventBuffer,
65         __inout ULONG EventBufferSize
66         );
67 
68     BOOLEAN
IsEnabled(__in WDF_WMI_PROVIDER_CONTROL Control)69     IsEnabled(
70         __in WDF_WMI_PROVIDER_CONTROL Control
71         )
72     {
73         return m_Provider->IsEnabled(Control);
74     }
75 
76     WDFWMIINSTANCE
GetHandle(VOID)77     GetHandle(
78         VOID
79         )
80     {
81         return (WDFWMIINSTANCE) GetObjectHandle();
82     }
83 
84     virtual
85     BOOLEAN
86     IsQueryInstanceSupported(
87         VOID
88         ) =0;
89 
90     virtual
91     _Must_inspect_result_
92     __drv_sameIRQL
93     __drv_maxIRQL(PASSIVE_LEVEL)
94     NTSTATUS
95     QueryInstance(
96         __in ULONG OutBufferSize,
97         __out_bcount_part(OutBufferSize, *BufferUsed) PVOID OutBuffer,
98         __out PULONG BufferUsed
99         ) =0;
100 
101     virtual
102     BOOLEAN
103     IsSetInstanceSupported(
104         VOID
105         ) =0;
106 
107     virtual
108     _Must_inspect_result_
109     __drv_sameIRQL
110     __drv_maxIRQL(PASSIVE_LEVEL)
111     NTSTATUS
112     SetInstance(
113         __in ULONG InBufferSize,
114         __in_bcount(InBufferSize) PVOID InBuffer
115         ) =0;
116 
117     virtual
118     BOOLEAN
119     IsSetItemSupported(
120         VOID
121         ) =0;
122 
123     virtual
124     _Must_inspect_result_
125     __drv_sameIRQL
126     __drv_maxIRQL(PASSIVE_LEVEL)
127     NTSTATUS
128     SetItem(
129         __in  ULONG DataItemId,
130         __in  ULONG InBufferSize,
131         __in_bcount(InBufferSize) PVOID InBuffer
132         ) =0;
133 
134     virtual
135     BOOLEAN
136     IsExecuteMethodSupported(
137         VOID
138         ) =0;
139 
140     virtual
141     _Must_inspect_result_
142     __drv_sameIRQL
143     __drv_maxIRQL(PASSIVE_LEVEL)
144     NTSTATUS
145     ExecuteMethod(
146         __in ULONG MethodId,
147         __in ULONG InBufferSize,
148         __inout ULONG OutBufferSize,
149         __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize))
150         __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize))
151             PVOID Buffer,
152         __out PULONG BufferUsed
153         ) =0;
154 
155     // begin FxObject overrides
156     virtual
157     BOOLEAN
158     Dispose(
159         VOID
160         );
161     // end FxObject overrides
162 
163 protected:
164     //
165     // List entry used by FxWmiProvider to hold the list of WMI instances
166     //
167     LIST_ENTRY m_ListEntry;
168 
169     //
170     // Pointer to the parent provider
171     //
172     FxWmiProvider* m_Provider;
173 };
174 
175 struct FxWmiInstanceQueryInstanceCallback : public FxCallback {
176 
177     PFN_WDF_WMI_INSTANCE_QUERY_INSTANCE m_Method;
178 
FxWmiInstanceQueryInstanceCallbackFxWmiInstanceQueryInstanceCallback179     FxWmiInstanceQueryInstanceCallback(
180         __in PFX_DRIVER_GLOBALS FxDriverGlobals
181         ) :
182         FxCallback(FxDriverGlobals),
183         m_Method(NULL)
184     {
185     }
186 
~FxWmiInstanceQueryInstanceCallbackFxWmiInstanceQueryInstanceCallback187     ~FxWmiInstanceQueryInstanceCallback()
188     {
189     }
190 
191     _Must_inspect_result_
192     __drv_sameIRQL
__drv_maxIRQLFxWmiInstanceQueryInstanceCallback193     __drv_maxIRQL(PASSIVE_LEVEL)
194     NTSTATUS
195     Invoke(
196         __in WDFDEVICE Device,
197         __in WDFWMIINSTANCE WmiInstance,
198         __inout ULONG OutBufferSize,
199         __out_bcount(OutBufferSize) PVOID OutBuffer,
200         __out PULONG BufferUsed
201         )
202     {
203         NTSTATUS status;
204 
205         UNREFERENCED_PARAMETER(Device);
206 
207         if (m_Method != NULL) {
208             CallbackStart();
209             status = m_Method(WmiInstance,
210                               OutBufferSize,
211                               OutBuffer,
212                               BufferUsed);
213             CallbackEnd();
214         }
215         else {
216             status = STATUS_UNSUCCESSFUL;
217         }
218 
219         return status;
220     }
221 };
222 
223 struct FxWmiInstanceSetInstanceCallback : public FxCallback {
224 
225     PFN_WDF_WMI_INSTANCE_SET_INSTANCE m_Method;
226 
FxWmiInstanceSetInstanceCallbackFxWmiInstanceSetInstanceCallback227     FxWmiInstanceSetInstanceCallback(
228         PFX_DRIVER_GLOBALS FxDriverGlobals
229         ) :
230         FxCallback(FxDriverGlobals),
231         m_Method(NULL)
232     {
233     }
234 
~FxWmiInstanceSetInstanceCallbackFxWmiInstanceSetInstanceCallback235     ~FxWmiInstanceSetInstanceCallback()
236     {
237     }
238 
239     _Must_inspect_result_
240     __drv_sameIRQL
__drv_maxIRQLFxWmiInstanceSetInstanceCallback241     __drv_maxIRQL(PASSIVE_LEVEL)
242     NTSTATUS
243     Invoke(
244         __in WDFDEVICE Device,
245         __in WDFWMIINSTANCE WmiInstance,
246         __in ULONG InBufferSize,
247         __in_bcount(InBufferSize) PVOID InBuffer
248         )
249     {
250         NTSTATUS status;
251 
252         UNREFERENCED_PARAMETER(Device);
253 
254         if (m_Method != NULL) {
255             CallbackStart();
256             status = m_Method(WmiInstance, InBufferSize, InBuffer);
257             CallbackEnd();
258         }
259         else {
260             status = STATUS_WMI_READ_ONLY;
261         }
262 
263         return status;
264     }
265 };
266 
267 struct FxWmiInstanceSetItemCallback : public FxCallback {
268 
269     PFN_WDF_WMI_INSTANCE_SET_ITEM  m_Method;
270 
FxWmiInstanceSetItemCallbackFxWmiInstanceSetItemCallback271     FxWmiInstanceSetItemCallback(
272         PFX_DRIVER_GLOBALS FxDriverGlobals
273         ) :
274         FxCallback(FxDriverGlobals),
275         m_Method(NULL)
276     {
277     }
278 
~FxWmiInstanceSetItemCallbackFxWmiInstanceSetItemCallback279     ~FxWmiInstanceSetItemCallback()
280     {
281     }
282 
283     _Must_inspect_result_
284     __drv_sameIRQL
__drv_maxIRQLFxWmiInstanceSetItemCallback285     __drv_maxIRQL(PASSIVE_LEVEL)
286     NTSTATUS
287     Invoke(
288         __in WDFDEVICE Device,
289         __in WDFWMIINSTANCE WmiInstance,
290         __in ULONG DataItemId,
291         __in ULONG InBufferSize,
292         __in_bcount(InBufferSize) PVOID InBuffer
293         )
294     {
295         NTSTATUS status;
296 
297         UNREFERENCED_PARAMETER(Device);
298 
299         if (m_Method != NULL) {
300             CallbackStart();
301             status = m_Method(WmiInstance,
302                               DataItemId,
303                               InBufferSize,
304                               InBuffer);
305             CallbackEnd();
306 
307         }
308         else {
309             status = STATUS_WMI_READ_ONLY;
310         }
311 
312         return status;
313     }
314 };
315 
316 struct FxWmiInstanceExecuteMethodCallback : public FxCallback {
317 
318     PFN_WDF_WMI_INSTANCE_EXECUTE_METHOD m_Method;
319 
FxWmiInstanceExecuteMethodCallbackFxWmiInstanceExecuteMethodCallback320     FxWmiInstanceExecuteMethodCallback(
321         PFX_DRIVER_GLOBALS FxDriverGlobals
322         ) :
323         FxCallback(FxDriverGlobals),
324         m_Method(NULL)
325     {
326     }
327 
~FxWmiInstanceExecuteMethodCallbackFxWmiInstanceExecuteMethodCallback328     ~FxWmiInstanceExecuteMethodCallback()
329     {
330     }
331 
332     _Must_inspect_result_
333     __drv_sameIRQL
__drv_maxIRQLFxWmiInstanceExecuteMethodCallback334     __drv_maxIRQL(PASSIVE_LEVEL)
335     NTSTATUS
336     Invoke(
337         __in WDFDEVICE Device,
338         __in WDFWMIINSTANCE WmiInstance,
339         __in ULONG MethodId,
340         __in ULONG InBufferSize,
341         __inout ULONG OutBufferSize,
342         __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize))
343         __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize))
344             PVOID Buffer,
345         __out PULONG BufferUsed
346         )
347     {
348         NTSTATUS status;
349 
350         UNREFERENCED_PARAMETER(Device);
351 
352         if (m_Method != NULL) {
353             CallbackStart();
354             status = m_Method(WmiInstance,
355                               MethodId,
356                               InBufferSize,
357                               OutBufferSize,
358                               Buffer,
359                               BufferUsed);
360             CallbackEnd();
361         }
362         else {
363             status = STATUS_WMI_GUID_NOT_FOUND;
364         }
365 
366         return status;
367     }
368 };
369 
370 class FxWmiInstanceExternal : public FxWmiInstance {
371 public:
372     FxWmiInstanceExternal(
373         __in PFX_DRIVER_GLOBALS FxDriverGlobals,
374         __in PWDF_WMI_INSTANCE_CONFIG Config,
375         __in FxWmiProvider* Provider
376         );
377 
378     VOID
SetContextForQueryLength(__in ULONG ContextSize)379     SetContextForQueryLength(
380         __in ULONG ContextSize
381         )
382     {
383         m_ContextLength = ContextSize;
384     }
385 
386     static
387     _Must_inspect_result_
388     NTSTATUS
389     _Create(
390         __in PFX_DRIVER_GLOBALS FxDriverGlobals,
391         __in FxWmiProvider* Provider,
392         __in PWDF_WMI_INSTANCE_CONFIG WmiInstanceConfig,
393         __in_opt PWDF_OBJECT_ATTRIBUTES InstanceAttributes,
394         __out WDFWMIINSTANCE* WmiInstance,
395         __out FxWmiInstanceExternal** Instance
396         );
397 
398 protected:
399     virtual
400     BOOLEAN
401     IsQueryInstanceSupported(
402         VOID
403         );
404 
405     virtual
406     _Must_inspect_result_
407     __drv_sameIRQL
408     __drv_maxIRQL(PASSIVE_LEVEL)
409     NTSTATUS
410     QueryInstance(
411         __inout ULONG OutBufferSize,
412         __out_xcount(OutBuffer->size) PVOID OutBuffer,
413         __out PULONG BufferUsed
414         );
415 
416     virtual
417     BOOLEAN
418     IsSetInstanceSupported(
419         VOID
420         );
421 
422     virtual
423     _Must_inspect_result_
424     __drv_sameIRQL
425     __drv_maxIRQL(PASSIVE_LEVEL)
426     NTSTATUS
427     SetInstance(
428         __in ULONG InBufferSize,
429         __in_bcount(InBufferSize) PVOID InBuffer
430         );
431 
432     virtual
433     BOOLEAN
434     IsSetItemSupported(
435         VOID
436         );
437 
438     virtual
439     _Must_inspect_result_
440     __drv_sameIRQL
441     __drv_maxIRQL(PASSIVE_LEVEL)
442     NTSTATUS
443     SetItem(
444         __in ULONG DataItemId,
445         __in ULONG InBufferSize,
446         __in_bcount(InBufferSize) PVOID InBuffer
447         );
448 
449     virtual
450     BOOLEAN
451     IsExecuteMethodSupported(
452         VOID
453         );
454 
455     virtual
456     _Must_inspect_result_
457     __drv_sameIRQL
458     __drv_maxIRQL(PASSIVE_LEVEL)
459     NTSTATUS
460     ExecuteMethod(
461         __in ULONG MethodId,
462         __in ULONG InBufferSize,
463         __inout ULONG OutBufferSize,
464         __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize))
465         __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize))
466             PVOID Buffer,
467         __out PULONG BufferUsed
468         );
469 
470 protected:
471     //
472     // Attributes associated with this instance
473     //
474     FxWmiInstanceQueryInstanceCallback m_QueryInstanceCallback;
475 
476     FxWmiInstanceSetInstanceCallback m_SetInstanceCallback;
477 
478     FxWmiInstanceSetItemCallback m_SetItemCallback;
479 
480     FxWmiInstanceExecuteMethodCallback m_ExecuteMethodCallback;
481 
482     ULONG m_ContextLength;
483 
484     BOOLEAN m_UseContextForQuery;
485 };
486 
487 typedef
488 _Must_inspect_result_
489 __drv_sameIRQL
490 __drv_maxIRQL(PASSIVE_LEVEL)
491 NTSTATUS
492 (*PFN_FX_WMI_INSTANCE_QUERY_INSTANCE)(
493     __in  CfxDevice* Device,
494     __in  FxWmiInstanceInternal* Instance,
495     __inout ULONG OutBufferSize,
496     __out_bcount(OutBufferSize) PVOID OutBuffer,
497     __out PULONG BufferUsed
498     );
499 
500 typedef
501 _Must_inspect_result_
502 __drv_sameIRQL
503 __drv_maxIRQL(PASSIVE_LEVEL)
504 NTSTATUS
505 (*PFN_FX_WMI_INSTANCE_SET_INSTANCE)(
506     __in CfxDevice* Device,
507     __in FxWmiInstanceInternal* Instance,
508     __in ULONG InBufferSize,
509     __in_bcount(InBufferSize) PVOID InBuffer
510     );
511 
512 typedef
513 _Must_inspect_result_
514 __drv_sameIRQL
515 __drv_maxIRQL(PASSIVE_LEVEL)
516 NTSTATUS
517 (*PFN_FX_WMI_INSTANCE_SET_ITEM)(
518     __in CfxDevice* Device,
519     __in FxWmiInstanceInternal* Instance,
520     __in ULONG DataItemId,
521     __in ULONG InBufferSize,
522     __in_bcount(InBufferSize) PVOID InBuffer
523     );
524 
525 typedef
526 _Must_inspect_result_
527 __drv_sameIRQL
528 __drv_maxIRQL(PASSIVE_LEVEL)
529 NTSTATUS
530 (*PFN_FX_WMI_INSTANCE_EXECUTE_METHOD)(
531     __in CfxDevice* Device,
532     __in FxWmiInstanceInternal* Instance,
533     __in ULONG MethodId,
534     __in ULONG InBufferSize,
535     __inout ULONG OutBufferSize,
536     __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize))
537     __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize))
538         PVOID Buffer,
539     __out PULONG BufferUsed
540     );
541 
542 struct FxWmiInstanceInternalCallbacks {
FxWmiInstanceInternalCallbacksFxWmiInstanceInternalCallbacks543     FxWmiInstanceInternalCallbacks(
544         VOID
545         )
546     {
547         RtlZeroMemory(this, sizeof(*this));
548     }
549 
550     //
551     // Callback when caller wants to query the entire data item's buffer.
552     //
553     PFN_FX_WMI_INSTANCE_QUERY_INSTANCE QueryInstance;
554 
555     //
556     // Callback when caller wants to set the entire data item's buffer.
557     //
558     PFN_FX_WMI_INSTANCE_SET_INSTANCE SetInstance;
559 
560     //
561     // Callback when caller wants to set a single field in the data item's buffer
562     //
563     PFN_FX_WMI_INSTANCE_SET_ITEM SetItem;
564 
565     //
566     // Callback when caller wants to execute a method on the data item.
567     //
568     PFN_FX_WMI_INSTANCE_EXECUTE_METHOD ExecuteMethod;
569 };
570 
571 class FxWmiInstanceInternal : public FxWmiInstance {
572 
573 public:
574     FxWmiInstanceInternal(
575         __in PFX_DRIVER_GLOBALS FxDriverGlobals,
576         __in FxWmiInstanceInternalCallbacks* Callbacks,
577         __in FxWmiProvider* m_Provider
578         );
579 
580 protected:
581     virtual
582     BOOLEAN
583     IsQueryInstanceSupported(
584         VOID
585         );
586 
587     virtual
588     _Must_inspect_result_
589     __drv_sameIRQL
590     __drv_maxIRQL(PASSIVE_LEVEL)
591     NTSTATUS
592     QueryInstance(
593         __inout ULONG OutBufferSize,
594         __out_bcount(OutBufferSize) PVOID OutBuffer,
595         __out PULONG BufferUsed
596         );
597 
598     virtual
599     BOOLEAN
600     IsSetInstanceSupported(
601         VOID
602         );
603 
604     virtual
605     _Must_inspect_result_
606     __drv_sameIRQL
607     __drv_maxIRQL(PASSIVE_LEVEL)
608     NTSTATUS
609     SetInstance(
610         __in ULONG InBufferSize,
611         __in_bcount(InBufferSize) PVOID InBuffer
612         );
613 
614     virtual
615     BOOLEAN
616     IsSetItemSupported(
617         VOID
618         );
619 
620     virtual
621     _Must_inspect_result_
622     __drv_sameIRQL
623     __drv_maxIRQL(PASSIVE_LEVEL)
624     NTSTATUS
625     SetItem(
626         __in ULONG DataItemId,
627         __in ULONG InBufferSize,
628         __in_bcount(InBufferSize) PVOID InBuffer
629         );
630 
631     virtual
632     BOOLEAN
633     IsExecuteMethodSupported(
634         VOID
635         );
636 
637     virtual
638     _Must_inspect_result_
639     __drv_sameIRQL
640     __drv_maxIRQL(PASSIVE_LEVEL)
641     NTSTATUS
642     ExecuteMethod(
643         __in ULONG MethodId,
644         __in ULONG InBufferSize,
645         __inout ULONG OutBufferSize,
646         __drv_when(InBufferSize >= OutBufferSize, __inout_bcount(InBufferSize))
647         __drv_when(InBufferSize < OutBufferSize, __inout_bcount(OutBufferSize))
648             PVOID Buffer,
649         __out PULONG BufferUsed
650         );
651 
652 protected:
653     PFN_FX_WMI_INSTANCE_QUERY_INSTANCE m_QueryInstance;
654     PFN_FX_WMI_INSTANCE_SET_INSTANCE m_SetInstance;
655     PFN_FX_WMI_INSTANCE_SET_ITEM m_SetItem;
656     PFN_FX_WMI_INSTANCE_EXECUTE_METHOD m_ExecuteMethod;
657 };
658 
659 #endif // _FXWMIINSTANCE_H_
660