1 /*++
2 
3 Copyright (c) Microsoft. All rights reserved.
4 
5 Module Name:
6 
7     FxValidateFunctions.h
8 
9 Abstract:
10 
11     Split from FxValidateFunctions.hpp
12     (FxValidateFunctions.hpp has moved to shared\inc)
13 
14 Author:
15 
16 
17 
18 Environment:
19 
20     Both kernel and user mode
21 
22 Revision History:
23 
24 
25 --*/
26 #ifndef _FXREQUESTVALIDATEFUNCTIONS_HPP_
27 #define _FXREQUESTVALIDATEFUNCTIONS_HPP_
28 
29 #if defined(EVENT_TRACING)
30 extern "C" {
31 #include "FxRequestValidateFunctions.hpp.tmh"
32 }
33 #endif
34 
35 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
36 #define WDF_REQUEST_SEND_OPTIONS_VALID_FLAGS            \
37        (WDF_REQUEST_SEND_OPTION_TIMEOUT             |   \
38         WDF_REQUEST_SEND_OPTION_SYNCHRONOUS         |   \
39         WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE |   \
40         WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET)
41 
42 #else // (FX_CORE_MODE == FX_CORE_USER_MODE)
43 #define WDF_REQUEST_SEND_OPTIONS_VALID_FLAGS            \
44        (WDF_REQUEST_SEND_OPTION_TIMEOUT             |   \
45         WDF_REQUEST_SEND_OPTION_SYNCHRONOUS         |   \
46         WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE |   \
47         WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET     |   \
48         WDF_REQUEST_SEND_OPTION_IMPERSONATE_CLIENT  |   \
49         WDF_REQUEST_SEND_OPTION_IMPERSONATION_IGNORE_FAILURE)
50 #endif
51 
52 NTSTATUS
53 __inline
54 FxValidateRequestOptions(
55     _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
56     _In_ PWDF_REQUEST_SEND_OPTIONS Options,
57     _In_opt_ FxRequestBase* Request = NULL
58     )
59 {
60     if (Options == NULL) {
61         return STATUS_SUCCESS;
62     }
63 
64     if (Options->Size != sizeof(WDF_REQUEST_SEND_OPTIONS)) {
65         //
66         // Size is wrong, bale out
67         //
68         DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
69                             "Options %p Size incorrect, expected %d, got %d",
70                             Options, sizeof(WDF_REQUEST_SEND_OPTIONS),
71                             Options->Size);
72 
73         return STATUS_INFO_LENGTH_MISMATCH;
74     }
75 
76     if ((Options->Flags & ~WDF_REQUEST_SEND_OPTIONS_VALID_FLAGS) != 0) {
77         //
78         // Invalid flags
79         //
80         DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
81                             "Options %p Flags 0x%x invalid, valid mask is 0x%x",
82                             Options, Options->Flags,
83                             WDF_REQUEST_SEND_OPTIONS_VALID_FLAGS);
84 
85         return STATUS_INVALID_PARAMETER;
86     }
87 
88 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
89     UNREFERENCED_PARAMETER(Request);
90 
91     if ((Options->Flags & WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET) &&
92         (Options->Flags & ~WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET)) {
93         //
94         // If WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET is set, no other bits
95         // can be set.
96         //
97         DoTraceLevelMessage(
98             FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
99             "Options %p, if WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET (0x%x) is "
100             "set, no other Flags 0x%x can be set",
101             Options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET, Options->Flags);
102 
103         return STATUS_INVALID_PARAMETER;
104     }
105 
106 #else // FX_CORE_USER_MODE
107 
108     if ((Options->Flags & WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET) &&
109         (Options->Flags & ~(WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET |
110                             WDF_REQUEST_SEND_OPTION_IMPERSONATION_FLAGS))) {
111         //
112         // If WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET is set, no other bits
113         // can be set except impersonation flags.
114         //
115         DoTraceLevelMessage(
116             FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
117             "Options %p, if WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET (0x%x) is "
118             "set, no other Flags 0x%x can be set except impersonation flags "
119             "%!status!",
120             Options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET, Options->Flags,
121             STATUS_INVALID_PARAMETER);
122 
123         return STATUS_INVALID_PARAMETER;
124     }
125 
126     //
127     // Verify the send option flags.
128     //
129     if ((Options->Flags & WDF_REQUEST_SEND_OPTION_IMPERSONATION_FLAGS) != 0) {
130         //
131         // The request must be a create request (which also means it can never
132         // be a driver-created request).
133         //
134         if (Request == NULL ||
135             Request->IsAllocatedFromIo() == FALSE ||
136             Request->GetSubmitFxIrp()->GetMajorFunction() != IRP_MJ_CREATE) {
137             DoTraceLevelMessage(
138                 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
139                 "WDF_REQUEST_SEND_OPTION impersonation flags may only "
140                 "be set on Create requests. %!status!",
141                 STATUS_INVALID_PARAMETER);
142 
143             return STATUS_INVALID_PARAMETER;
144         }
145 
146         if ((Options->Flags & WDF_REQUEST_SEND_OPTION_IMPERSONATION_IGNORE_FAILURE) != 0 &&
147             (Options->Flags & WDF_REQUEST_SEND_OPTION_IMPERSONATE_CLIENT) == 0) {
148             DoTraceLevelMessage(
149                 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
150                 "Driver must set WDF_REQUEST_SEND_OPTION_IMPERSONATION_"
151                 "IGNORE_FAILURE with WDF_REQUEST_SEND_OPTION_IMPERSONATE_CLIENT."
152                 " %!status!", STATUS_INVALID_PARAMETER);
153 
154             return STATUS_INVALID_PARAMETER;
155         }
156     }
157 
158 #endif // FX_CORE_MODE
159 
160     return STATUS_SUCCESS;
161 }
162 
163 #endif // _FXREQUESTVALIDATEFUNCTIONS_HPP_
164