1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxWmiIrpHandler.hpp
8 
9 Abstract:
10 
11     This module implements the wmi IRP handler for the driver frameworks.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19     Both kernel and user mode
20 
21 Revision History:
22 
23 
24 --*/
25 
26 #ifndef _FXWMIIRPHANDLER_H_
27 #define _FXWMIIRPHANDLER_H_
28 
29 typedef
30 _Must_inspect_result_
31 NTSTATUS
32 (*PFN_WMI_HANDLER_MINOR_DISPATCH)(
33     __in FxWmiIrpHandler* This,
34     __in PIRP Irp,
35     __in FxWmiProvider* Provider,
36     __in FxWmiInstance* Instance
37     );
38 
39 struct FxWmiMinorEntry {
40     __in PFN_WMI_HANDLER_MINOR_DISPATCH Handler;
41     __in BOOLEAN CheckInstance;
42 };
43 
44 class FxWmiIrpHandler : public FxPackage {
45     friend FxWmiProvider;
46 
47 public:
48 
49     FxWmiIrpHandler(
50         __in PFX_DRIVER_GLOBALS FxDriverGlobals,
51         __in CfxDevice *Device,
52         __in WDFTYPE Type = FX_TYPE_WMI_IRP_HANDLER
53         );
54 
55     ~FxWmiIrpHandler();
56 
57     _Must_inspect_result_
58     NTSTATUS
59     PostCreateDeviceInitialize(
60         VOID
61         );
62 
63     _Must_inspect_result_
64     NTSTATUS
65     HandleWmiTraceRequest(
66         __in PIRP Irp,
67         __in FxTraceInfo* Info
68         );
69 
70     virtual
71     _Must_inspect_result_
72     NTSTATUS
73     Dispatch(
74         __in PIRP Irp
75         );
76 
77     _Must_inspect_result_
78     NTSTATUS
79     Register(
80         VOID
81         );
82 
83     VOID
84     Deregister(
85         VOID
86         );
87 
88     VOID
89     Cleanup(
90         VOID
91         );
92 
93     VOID
94     ResetStateForPdoRestart(
95         VOID
96         );
97 
98     _Must_inspect_result_
99     NTSTATUS
100     AddProvider(
101         __in FxWmiProvider* Provider,
102         __out_opt PBOOLEAN Update = NULL
103         );
104 
105     _Must_inspect_result_
106     NTSTATUS
107     AddPowerPolicyProviderAndInstance(
108         __in    PWDF_WMI_PROVIDER_CONFIG ProviderConfig,
109         __in    FxWmiInstanceInternalCallbacks* Callbacks,
110         __inout FxWmiInstanceInternal** Instance
111         );
112 
113 protected:
114     static
115     VOID
116     CheckAssumptions(
117         VOID
118         );
119 
120     _Must_inspect_result_
121     NTSTATUS
122     AddProviderLocked(
123         __in FxWmiProvider* Provider,
124         __in KIRQL Irql,
125         __out_opt PBOOLEAN Update = NULL
126         );
127 
128     VOID
129     RemoveProvider(
130         __in FxWmiProvider* Provider
131         );
132 
133     VOID
134     RemoveProviderLocked(
135         __in FxWmiProvider* Provider
136         );
137 
138     _Must_inspect_result_
139     FxWmiProvider*
140     FindProviderLocked(
141         __in LPGUID Guid
142         );
143 
144     _Must_inspect_result_
145     FxWmiProvider*
146     FindProviderReferenced(
147         __in LPGUID Guid,
148         __in PVOID Tag
149         );
150 
151 private:
152     static
153     _Must_inspect_result_
154     NTSTATUS
155     _QueryAllData(
156         __in FxWmiIrpHandler* This,
157         __in PIRP Irp,
158         __in FxWmiProvider* Provider,
159         __in_opt FxWmiInstance* Instance
160         );
161 
162     static
163     _Must_inspect_result_
164     NTSTATUS
165     _QuerySingleInstance(
166         __in FxWmiIrpHandler* This,
167         __in PIRP Irp,
168         __in FxWmiProvider* Provider,
169         __in FxWmiInstance* Instance
170         );
171 
172     static
173     _Must_inspect_result_
174     NTSTATUS
175     _ChangeSingleInstance(
176         __in FxWmiIrpHandler* This,
177         __in PIRP Irp,
178         __in FxWmiProvider* Provider,
179         __in FxWmiInstance* Instance
180         );
181 
182     static
183     _Must_inspect_result_
184     NTSTATUS
185     _ChangeSingleItem(
186         __in FxWmiIrpHandler* This,
187         __in PIRP Irp,
188         __in FxWmiProvider* Provider,
189         __in FxWmiInstance* Instance
190         );
191 
192     static
193     _Must_inspect_result_
194     NTSTATUS
195     _EnableDisableEventsAndCollection(
196         __in FxWmiIrpHandler* This,
197         __in PIRP Irp,
198         __in FxWmiProvider* Provider,
199         __in FxWmiInstance* Instance
200         );
201 
202     static
203     _Must_inspect_result_
204     NTSTATUS
205     _RegInfo(
206         __in FxWmiIrpHandler* This,
207         __in PIRP Irp,
208         __in_opt FxWmiProvider* Provider,
209         __in_opt FxWmiInstance* Instance
210         );
211 
212     static
213     _Must_inspect_result_
214     NTSTATUS
215     _ExecuteMethod(
216         __in FxWmiIrpHandler* This,
217         __in PIRP Irp,
218         __in FxWmiProvider* Provider,
219         __in FxWmiInstance* Instance
220         );
221 
222     VOID
223     CompleteWmiQueryAllDataRequest(
224         __in PIRP Irp,
225         __in NTSTATUS Status,
226         __in ULONG BufferUsed
227         );
228 
229     VOID
230     CompleteWmiQuerySingleInstanceRequest(
231         __in PIRP Irp,
232         __in NTSTATUS Status,
233         __in ULONG BufferUsed
234         );
235 
236     VOID
237     CompleteWmiExecuteMethodRequest(
238         __in PIRP Irp,
239         __in NTSTATUS Status,
240         __in ULONG BufferUsed
241         );
242 
243     _Must_inspect_result_
244     NTSTATUS
245     CompleteWmiRequest(
246         __in PIRP Irp,
247         __in NTSTATUS Status,
248         __in ULONG BufferUsed
249         );
250 
251     BOOLEAN
252     DeferUpdateLocked(
253         __in KIRQL OldIrql
254         );
255 
256     static
257     MX_WORKITEM_ROUTINE _UpdateGuids;
258 
259     VOID
260     UpdateGuids(
261         VOID
262         );
263 
264     VOID
265     IncrementUpdateCount() {
266         LONG count;
267 
268         count = InterlockedIncrement(&m_UpdateCount);
269         ASSERT(count > 1);
270         UNREFERENCED_PARAMETER(count);
271     }
272 
273     VOID
274     DecrementUpdateCount() {
275         LONG count;
276 
277         count = InterlockedDecrement(&m_UpdateCount);
278         ASSERT(count >= 0);
279         if (count == 0) {
280             m_UpdateEvent.Set();
281         }
282     }
283 
284     VOID
285     DecrementUpdateCountAndWait() {
286 
287         DecrementUpdateCount();
288 
289         m_UpdateEvent.EnterCRAndWaitAndLeave();
290     }
291 
292 protected:
293     enum WmiRegisteredState {
294         WmiUnregistered = 0,
295         WmiRegistered,
296         WmiDeregistered,
297         WmiCleanedUp
298     };
299 
300 protected:
301     static const FxWmiMinorEntry m_WmiDispatchTable[];
302 
303     LIST_ENTRY m_ProvidersListHead;
304 
305     ULONG m_NumProviders;
306 
307     WmiRegisteredState m_RegisteredState;
308 
309     PIO_WORKITEM m_WorkItem;
310 
311     //
312     // count of references taken every time an update is needed
313     //
314     LONG m_UpdateCount;
315 
316     //
317     // WMI unregister waits on this event to ensure no upadtes are allowed
318     // after unregister.
319     //
320     FxCREvent m_UpdateEvent;
321 
322     PKEVENT m_WorkItemEvent;
323 
324     BOOLEAN m_WorkItemQueued;
325 
326 
327 };
328 
329 #endif // _FXWMIIRPHANDLER_H_
330