1 /*++ 2 3 Copyright (c) Microsoft. All rights reserved. 4 5 Module Name: 6 7 FxValidateFunctions.cpp 8 9 Abstract: 10 11 Functions which validate external WDF data structures 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 28 29 30 31 32 --*/ 33 34 #include "fxobjectpch.hpp" 35 36 // We use DoTraceMessage 37 extern "C" { 38 #if defined(EVENT_TRACING) 39 #include "FxValidateFunctions.tmh" 40 #endif 41 } 42 43 _Must_inspect_result_ 44 NTSTATUS 45 FxValidateObjectAttributes( 46 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 47 __in PWDF_OBJECT_ATTRIBUTES Attributes, 48 __in ULONG Flags 49 ) 50 { 51 if (Attributes == NULL) { 52 if (Flags & FX_VALIDATE_OPTION_ATTRIBUTES_REQUIRED) { 53 DoTraceLevelMessage( 54 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 55 "WDF_OBJECT_ATTRIBUTES required, %!STATUS!", 56 (ULONG) STATUS_WDF_PARENT_NOT_SPECIFIED); 57 58 return STATUS_WDF_PARENT_NOT_SPECIFIED; 59 } 60 else { 61 return STATUS_SUCCESS; 62 } 63 } 64 65 if (Attributes->Size != sizeof(WDF_OBJECT_ATTRIBUTES)) { 66 // 67 // Size is wrong, bail out 68 // 69 DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, 70 "Attributes %p Size incorrect, expected %d, got %d, %!STATUS!", 71 Attributes, sizeof(WDF_OBJECT_ATTRIBUTES), 72 Attributes->Size, STATUS_INFO_LENGTH_MISMATCH); 73 74 return STATUS_INFO_LENGTH_MISMATCH; 75 } 76 77 if (Attributes->ContextTypeInfo != NULL) { 78 #pragma prefast(suppress:__WARNING_REDUNDANTTEST, "different structs of the same size") 79 if (Attributes->ContextTypeInfo->Size != 80 sizeof(WDF_OBJECT_CONTEXT_TYPE_INFO) && 81 Attributes->ContextTypeInfo->Size != 82 sizeof(WDF_OBJECT_CONTEXT_TYPE_INFO_V1_0)) { 83 DoTraceLevelMessage( 84 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, 85 "Attributes %p ContextTypeInfo %p Size %d incorrect, expected %d, %!STATUS!", 86 Attributes, Attributes->ContextTypeInfo, 87 Attributes->ContextTypeInfo->Size, 88 sizeof(WDF_OBJECT_CONTEXT_TYPE_INFO), STATUS_INFO_LENGTH_MISMATCH); 89 90 return STATUS_INFO_LENGTH_MISMATCH; 91 } 92 93 // 94 // A ContextName != NULL and a ContextSize of 0 is allowed 95 // 96 if (Attributes->ContextTypeInfo->ContextSize > 0 && 97 Attributes->ContextTypeInfo->ContextName == NULL) { 98 99 DoTraceLevelMessage( 100 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, 101 "Attributes %p ContextTypeInfo %p ContextSize %I64d is not zero, " 102 "but ContextName is NULL, %!STATUS!", 103 Attributes, Attributes->ContextTypeInfo, 104 Attributes->ContextTypeInfo->ContextSize, 105 STATUS_WDF_OBJECT_ATTRIBUTES_INVALID); 106 107 return STATUS_WDF_OBJECT_ATTRIBUTES_INVALID; 108 } 109 } 110 111 if (Attributes->ContextSizeOverride > 0) { 112 if (Attributes->ContextTypeInfo == NULL) { 113 // 114 // Can't specify additional size without a type 115 // 116 DoTraceLevelMessage( 117 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, 118 "Attributes %p ContextSizeOverride of %I64d specified, but no type " 119 "information, %!STATUS!", 120 Attributes, Attributes->ContextSizeOverride, 121 STATUS_WDF_OBJECT_ATTRIBUTES_INVALID); 122 123 return STATUS_WDF_OBJECT_ATTRIBUTES_INVALID; 124 } 125 else if (Attributes->ContextSizeOverride < 126 Attributes->ContextTypeInfo->ContextSize) { 127 DoTraceLevelMessage( 128 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, 129 "Attributes %p ContextSizeOverride %I64d < " 130 "ContextTypeInfo->ContextSize %I64d, %!STATUS!", 131 Attributes, Attributes->ContextSizeOverride, 132 Attributes->ContextTypeInfo->ContextSize, 133 STATUS_WDF_OBJECT_ATTRIBUTES_INVALID); 134 135 return STATUS_WDF_OBJECT_ATTRIBUTES_INVALID; 136 } 137 } 138 139 if (Flags & FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED) { 140 if (Attributes->ParentObject != NULL) { 141 DoTraceLevelMessage( 142 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, 143 "Attributes %p does not allow a parent object to be set, set to " 144 "%p, %!STATUS!", Attributes, Attributes->ParentObject, 145 STATUS_WDF_PARENT_ASSIGNMENT_NOT_ALLOWED); 146 147 return STATUS_WDF_PARENT_ASSIGNMENT_NOT_ALLOWED; 148 } 149 } 150 else if ((Flags & FX_VALIDATE_OPTION_PARENT_REQUIRED_FLAG) && 151 Attributes->ParentObject == NULL) { 152 DoTraceLevelMessage( 153 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 154 "ParentObject required in WDF_OBJECT_ATTRIBUTES %p, %!STATUS!", 155 Attributes, STATUS_WDF_PARENT_NOT_SPECIFIED); 156 157 return STATUS_WDF_PARENT_NOT_SPECIFIED; 158 } 159 160 // Enum range checks 161 if ((Attributes->ExecutionLevel == WdfExecutionLevelInvalid) || 162 (Attributes->ExecutionLevel > WdfExecutionLevelDispatch)) { 163 DoTraceLevelMessage( 164 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, 165 "Attributes %p execution level set to %d, out of range, %!STATUS!", 166 Attributes, Attributes->ExecutionLevel, 167 STATUS_WDF_OBJECT_ATTRIBUTES_INVALID); 168 return STATUS_WDF_OBJECT_ATTRIBUTES_INVALID; 169 } 170 171 if ((Attributes->SynchronizationScope == WdfSynchronizationScopeInvalid) || 172 (Attributes->SynchronizationScope > WdfSynchronizationScopeNone)) { 173 DoTraceLevelMessage( 174 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, 175 "Attributes %p synchronization scope set to %d, out of range, %!STATUS!", 176 Attributes, Attributes->SynchronizationScope, 177 STATUS_WDF_OBJECT_ATTRIBUTES_INVALID); 178 return STATUS_WDF_OBJECT_ATTRIBUTES_INVALID; 179 } 180 181 if ((Flags & FX_VALIDATE_OPTION_SYNCHRONIZATION_SCOPE_ALLOWED) == 0) { 182 183 // 184 // If synchronization is not allowed for this object, 185 // check the requested level to ensure none was specified. 186 // 187 if ((Attributes->SynchronizationScope != WdfSynchronizationScopeInheritFromParent) && 188 (Attributes->SynchronizationScope != WdfSynchronizationScopeNone)) { 189 190 DoTraceLevelMessage( 191 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, 192 "Attributes %p does not allow synchronization scope too be set, " 193 "but was set to %!WDF_SYNCHRONIZATION_SCOPE!, %!STATUS!", 194 Attributes, Attributes->SynchronizationScope, 195 STATUS_WDF_SYNCHRONIZATION_SCOPE_INVALID); 196 197 return STATUS_WDF_SYNCHRONIZATION_SCOPE_INVALID; 198 } 199 } 200 201 if ((Flags & FX_VALIDATE_OPTION_EXECUTION_LEVEL_ALLOWED) == 0) { 202 203 // 204 // If execution level restrictions are not allowed for this object, 205 // check the requested level to ensure none was specified. 206 // 207 if (Attributes->ExecutionLevel != WdfExecutionLevelInheritFromParent) { 208 DoTraceLevelMessage( 209 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR, 210 "Attributes %p does not allow execution level to be set, but was" 211 " set to %!WDF_EXECUTION_LEVEL!, %!STATUS!", 212 Attributes, Attributes->ExecutionLevel, 213 STATUS_WDF_EXECUTION_LEVEL_INVALID); 214 215 return STATUS_WDF_EXECUTION_LEVEL_INVALID; 216 } 217 } 218 219 return STATUS_SUCCESS; 220 } 221