1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxRequestApiUm.cpp
8 
9 Abstract:
10 
11     This module implements FxRequest object
12 
13 Author:
14 
15 Environment:
16 
17     User mode only
18 
19 Revision History:
20 
21 
22 --*/
23 #include "coreprivshared.hpp"
24 
25 // Tracing support
26 extern "C" {
27 #include "FxRequestApiUm.tmh"
28 
29 _Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)30 _IRQL_requires_max_(PASSIVE_LEVEL)
31 WDFAPI
32 NTSTATUS
33 WDFEXPORT(WdfRequestImpersonate)(
34     _In_
35     PWDF_DRIVER_GLOBALS DriverGlobals,
36     _In_
37     WDFREQUEST Request,
38     _In_
39     SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
40     _In_
41     PFN_WDF_REQUEST_IMPERSONATE EvtRequestImpersonate,
42     _In_opt_
43     PVOID Context
44     )
45 
46 /*++
47 
48 Routine Description:
49 
50     The WdfRequestImpersonate method registers the event that the framework
51     should call for impersonation.
52 
53 Arguments:
54 
55     Request : Request object
56 
57     ImpersonationLevel : A SECURITY_IMPERSONATION_LEVEL-typed value that identifies
58         the level of impersonation.
59 
60     EvtRequestImpersonate : A pointer to the IImpersonateCallback interface whose
61         method the framework calls for impersonation.
62 
63 Returns:
64 
65     Impersonate returns STATUS_SUCCESS if the operation succeeds. Otherwise,
66     this method returns one of the error codes that are defined in ntstatus.h.
67 
68 --*/
69 
70 {
71     PFX_DRIVER_GLOBALS pFxDriverGlobals;
72     NTSTATUS status;
73     FxRequest *pRequest;
74 
75     //
76     // Validate the request handle, and get the FxRequest*
77     //
78     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
79                                    Request,
80                                    FX_TYPE_REQUEST,
81                                    (PVOID*)&pRequest,
82                                    &pFxDriverGlobals);
83 
84     if (VALID_IMPERSONATION_LEVEL(ImpersonationLevel) == FALSE) {
85         status = STATUS_INVALID_PARAMETER;
86         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
87                             "ImpersonationLevel is not a valid level, %!STATUS!",
88                             status);
89         FxVerifierDbgBreakPoint(pFxDriverGlobals);
90         return status;
91     }
92 
93     if (EvtRequestImpersonate == NULL) {
94         status = STATUS_INVALID_PARAMETER;
95         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
96                             "EvtRequestImpersonate must not be NULL, %!STATUS!",
97                             status);
98         FxVerifierDbgBreakPoint(pFxDriverGlobals);
99         return status;
100     }
101 
102 
103 #if FX_VERBOSE_TRACE
104     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST,
105                         "Enter: WDFREQUEST 0x%p", Request);
106 #endif // FX_VERBOSE_TRACE
107 
108     status = pRequest->Impersonate(ImpersonationLevel,
109                                    EvtRequestImpersonate,
110                                    Context);
111 
112     return status;
113 }
114 
_IRQL_requires_max_(PASSIVE_LEVEL)115 _IRQL_requires_max_(PASSIVE_LEVEL)
116 WDFAPI
117 ULONG
118 WDFEXPORT(WdfRequestGetRequestorProcessId)(
119     _In_
120     PWDF_DRIVER_GLOBALS DriverGlobals,
121     _In_
122     WDFREQUEST Request
123     )
124 /*++
125 
126 Routine Description:
127 
128     This routine returns the identifier of the process that sent the I/O request.
129 
130     The WDM IRP is invalid once WdfRequestComplete is called, regardless
131     of any reference counts on the WDFREQUEST object.
132 
133 Arguments:
134 
135     Request - Handle to the Request object
136 
137 Returns:
138 
139     Process ID
140 
141 --*/
142 {
143     PFX_DRIVER_GLOBALS pFxDriverGlobals;
144     NTSTATUS status;
145     FxRequest *pRequest;
146     MdIrp irp;
147 
148     //
149     // Validate the request handle, and get the FxRequest*
150     //
151     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
152                                    Request,
153                                    FX_TYPE_REQUEST,
154                                    (PVOID*)&pRequest,
155                                    &pFxDriverGlobals);
156 
157 #if FX_VERBOSE_TRACE
158     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST,
159                         "Enter: WDFREQUEST 0x%p", Request);
160 #endif // FX_VERBOSE_TRACE
161 
162     status = pRequest->GetIrp(&irp);
163 
164     if (!NT_SUCCESS(status)) {
165         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
166                             "WDFREQUEST is already completed 0x%p, %!STATUS!",
167                             Request, status);
168         FxVerifierDbgBreakPoint(pFxDriverGlobals);
169         return 0;
170     }
171 
172     return irp->GetRequestorProcessId();
173 }
174 
_IRQL_requires_max_(PASSIVE_LEVEL)175 _IRQL_requires_max_(PASSIVE_LEVEL)
176 WDFAPI
177 BOOLEAN
178 WDFEXPORT(WdfRequestIsFromUserModeDriver)(
179     _In_
180     PWDF_DRIVER_GLOBALS DriverGlobals,
181     _In_
182     WDFREQUEST Request
183     )
184 {
185     PFX_DRIVER_GLOBALS pFxDriverGlobals;
186     NTSTATUS status;
187     FxRequest *pRequest;
188     MdIrp irp;
189 
190     //
191     // Validate the request handle, and get the FxRequest*
192     //
193     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
194                                    Request,
195                                    FX_TYPE_REQUEST,
196                                    (PVOID*)&pRequest,
197                                    &pFxDriverGlobals);
198 
199 #if FX_VERBOSE_TRACE
200     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST,
201                         "Enter: WDFREQUEST 0x%p", Request);
202 #endif // FX_VERBOSE_TRACE
203 
204     status = pRequest->GetIrp(&irp);
205 
206     if (!NT_SUCCESS(status)) {
207         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
208                             "WDFREQUEST is already completed 0x%p, %!STATUS!",
209                             Request, status);
210         FxVerifierDbgBreakPoint(pFxDriverGlobals);
211         return FALSE;
212     }
213 
214     return (pRequest->GetFxIrp()->GetIoIrp()->IsDriverCreated() ? TRUE : FALSE);
215 }
216 
_IRQL_requires_max_(PASSIVE_LEVEL)217 _IRQL_requires_max_(PASSIVE_LEVEL)
218 WDFAPI
219 VOID
220 WDFEXPORT(WdfRequestSetUserModeDriverInitiatedIo)(
221     _In_
222     PWDF_DRIVER_GLOBALS DriverGlobals,
223     _In_
224     WDFREQUEST Request,
225     _In_
226     BOOLEAN IsUserModeDriverInitiated
227     )
228 {
229     PFX_DRIVER_GLOBALS pFxDriverGlobals;
230     NTSTATUS status;
231     FxRequest *pRequest;
232     MdIrp irp;
233 
234     //
235     // Validate the request handle, and get the FxRequest*
236     //
237     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
238                                    Request,
239                                    FX_TYPE_REQUEST,
240                                    (PVOID*)&pRequest,
241                                    &pFxDriverGlobals);
242 
243 #if FX_VERBOSE_TRACE
244     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST,
245                         "Enter: WDFREQUEST 0x%p", Request);
246 #endif // FX_VERBOSE_TRACE
247 
248     status = pRequest->GetIrp(&irp);
249 
250     if (!NT_SUCCESS(status)) {
251         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
252                             "WDFREQUEST is already completed 0x%p, %!STATUS!",
253                             Request, status);
254         FxVerifierDbgBreakPoint(pFxDriverGlobals);
255         return;
256     }
257 
258     pRequest->GetFxIrp()->GetIoIrp()->SetUserModeDriverInitiatedIo(
259                                             IsUserModeDriverInitiated
260                                             );
261 }
262 
_IRQL_requires_max_(PASSIVE_LEVEL)263 _IRQL_requires_max_(PASSIVE_LEVEL)
264 WDFAPI
265 BOOLEAN
266 WDFEXPORT(WdfRequestGetUserModeDriverInitiatedIo)(
267     _In_
268     PWDF_DRIVER_GLOBALS DriverGlobals,
269     _In_
270     WDFREQUEST Request
271     )
272 {
273     PFX_DRIVER_GLOBALS pFxDriverGlobals;
274     NTSTATUS status;
275     FxRequest *pRequest;
276     MdIrp irp;
277 
278     //
279     // Validate the request handle, and get the FxRequest*
280     //
281     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
282                                    Request,
283                                    FX_TYPE_REQUEST,
284                                    (PVOID*)&pRequest,
285                                    &pFxDriverGlobals);
286 
287 #if FX_VERBOSE_TRACE
288     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST,
289                         "Enter: WDFREQUEST 0x%p", Request);
290 #endif // FX_VERBOSE_TRACE
291 
292     status = pRequest->GetIrp(&irp);
293 
294     if (!NT_SUCCESS(status)) {
295         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
296                             "WDFREQUEST is already completed 0x%p, %!STATUS!",
297                             Request, status);
298         FxVerifierDbgBreakPoint(pFxDriverGlobals);
299         return FALSE;
300     }
301 
302     return (pRequest->GetFxIrp()->GetIoIrp()->GetUserModeDriverInitiatedIo()
303         ? TRUE : FALSE);
304 }
305 
_IRQL_requires_max_(PASSIVE_LEVEL)306 _IRQL_requires_max_(PASSIVE_LEVEL)
307 WDFAPI
308 VOID
309 WDFEXPORT(WdfRequestSetActivityId)(
310     _In_
311     PWDF_DRIVER_GLOBALS DriverGlobals,
312     _In_
313     WDFREQUEST Request,
314     _In_
315     LPGUID ActivityId
316     )
317 {
318     PFX_DRIVER_GLOBALS pFxDriverGlobals;
319     NTSTATUS status;
320     FxRequest *pRequest;
321     MdIrp irp;
322 
323     //
324     // Validate the request handle, and get the FxRequest*
325     //
326     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
327                                    Request,
328                                    FX_TYPE_REQUEST,
329                                    (PVOID*)&pRequest,
330                                    &pFxDriverGlobals);
331 
332 #if FX_VERBOSE_TRACE
333     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST,
334                         "Enter: WDFREQUEST 0x%p", Request);
335 #endif // FX_VERBOSE_TRACE
336 
337     status = pRequest->GetIrp(&irp);
338 
339     if (!NT_SUCCESS(status)) {
340         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
341                             "WDFREQUEST is already completed 0x%p, %!STATUS!",
342                             Request, status);
343         FxVerifierDbgBreakPoint(pFxDriverGlobals);
344         return;
345     }
346 
347     pRequest->GetFxIrp()->GetIoIrp()->SetActivityId(ActivityId);
348 }
349 
_IRQL_requires_max_(PASSIVE_LEVEL)350 _IRQL_requires_max_(PASSIVE_LEVEL)
351 WDFAPI
352 NTSTATUS
353 WDFEXPORT(WdfRequestRetrieveActivityId)(
354     _In_
355     PWDF_DRIVER_GLOBALS DriverGlobals,
356     _In_
357     WDFREQUEST Request,
358     _Out_
359     LPGUID ActivityId
360     )
361 {
362     PFX_DRIVER_GLOBALS pFxDriverGlobals;
363     NTSTATUS status;
364     FxRequest *pRequest;
365     MdIrp irp;
366 
367     //
368     // Validate the request handle, and get the FxRequest*
369     //
370     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
371                                    Request,
372                                    FX_TYPE_REQUEST,
373                                    (PVOID*)&pRequest,
374                                    &pFxDriverGlobals);
375 
376     FxPointerNotNull(pFxDriverGlobals, ActivityId);
377 
378 #if FX_VERBOSE_TRACE
379     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST,
380                         "Enter: WDFREQUEST 0x%p", Request);
381 #endif // FX_VERBOSE_TRACE
382 
383     status = pRequest->GetIrp(&irp);
384 
385     if (!NT_SUCCESS(status)) {
386         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
387                             "WDFREQUEST is already completed 0x%p, %!STATUS!",
388                             Request, status);
389         FxVerifierDbgBreakPoint(pFxDriverGlobals);
390         return status;
391     }
392 
393     if (pRequest->GetFxIrp()->GetIoIrp()->IsActivityIdSet() == FALSE) {
394         status = STATUS_INVALID_DEVICE_REQUEST;
395         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
396                             "WDFREQUEST 0x%p Activity ID is not set for the "
397                             "request, %!STATUS!", Request, status);
398         return status;
399     }
400 
401     *ActivityId = *(pRequest->GetFxIrp()->GetIoIrp()->GetActivityId());
402     status = STATUS_SUCCESS;
403 
404     return status;
405 }
406 
_IRQL_requires_max_(PASSIVE_LEVEL)407 _IRQL_requires_max_(PASSIVE_LEVEL)
408 WDFAPI
409 WDF_DEVICE_IO_TYPE
410 WDFEXPORT(WdfRequestGetEffectiveIoType)(
411     _In_
412     PWDF_DRIVER_GLOBALS DriverGlobals,
413     _In_
414     WDFREQUEST Request
415     )
416 {
417     PFX_DRIVER_GLOBALS pFxDriverGlobals;
418     NTSTATUS status;
419     FxRequest *pRequest;
420     MdIrp irp;
421 
422     //
423     // Validate the request handle, and get the FxRequest*
424     //
425     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
426                                    Request,
427                                    FX_TYPE_REQUEST,
428                                    (PVOID*)&pRequest,
429                                    &pFxDriverGlobals);
430 
431 #if FX_VERBOSE_TRACE
432     DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGREQUEST,
433                         "Enter: WDFREQUEST 0x%p", Request);
434 #endif // FX_VERBOSE_TRACE
435 
436     status = pRequest->GetIrp(&irp);
437 
438     if (!NT_SUCCESS(status)) {
439         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
440                             "WDFREQUEST is already completed 0x%p, %!STATUS!",
441                             Request, status);
442         FxVerifierDbgBreakPoint(pFxDriverGlobals);
443         return WdfDeviceIoUndefined;
444     }
445 
446     return (WDF_DEVICE_IO_TYPE)(pRequest->GetFxIrp()->GetIoIrp()->GetTransferMode());
447 }
448 
449 } // extern "C" the whole file
450