reactos/sdk/lib/drivers/wdf/shared/object/fxvalidatefunctions.cpp
Victor Perevertkin 8a978a179f
[WDF] Add Windows Driver Framework files
Takern from Microsoft GitHub repo:
d9c6040fe9

Licensed under MIT
2020-11-03 00:06:26 +03:00

221 lines
7.6 KiB
C++

/*++
Copyright (c) Microsoft. All rights reserved.
Module Name:
FxValidateFunctions.cpp
Abstract:
Functions which validate external WDF data structures
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#include "fxobjectpch.hpp"
// We use DoTraceMessage
extern "C" {
#if defined(EVENT_TRACING)
#include "FxValidateFunctions.tmh"
#endif
}
_Must_inspect_result_
NTSTATUS
FxValidateObjectAttributes(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in PWDF_OBJECT_ATTRIBUTES Attributes,
__in ULONG Flags
)
{
if (Attributes == NULL) {
if (Flags & FX_VALIDATE_OPTION_ATTRIBUTES_REQUIRED) {
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
"WDF_OBJECT_ATTRIBUTES required, %!STATUS!",
(ULONG) STATUS_WDF_PARENT_NOT_SPECIFIED);
return STATUS_WDF_PARENT_NOT_SPECIFIED;
}
else {
return STATUS_SUCCESS;
}
}
if (Attributes->Size != sizeof(WDF_OBJECT_ATTRIBUTES)) {
//
// Size is wrong, bail out
//
DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
"Attributes %p Size incorrect, expected %d, got %d, %!STATUS!",
Attributes, sizeof(WDF_OBJECT_ATTRIBUTES),
Attributes->Size, STATUS_INFO_LENGTH_MISMATCH);
return STATUS_INFO_LENGTH_MISMATCH;
}
if (Attributes->ContextTypeInfo != NULL) {
#pragma prefast(suppress:__WARNING_REDUNDANTTEST, "different structs of the same size")
if (Attributes->ContextTypeInfo->Size !=
sizeof(WDF_OBJECT_CONTEXT_TYPE_INFO) &&
Attributes->ContextTypeInfo->Size !=
sizeof(WDF_OBJECT_CONTEXT_TYPE_INFO_V1_0)) {
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
"Attributes %p ContextTypeInfo %p Size %d incorrect, expected %d, %!STATUS!",
Attributes, Attributes->ContextTypeInfo,
Attributes->ContextTypeInfo->Size,
sizeof(WDF_OBJECT_CONTEXT_TYPE_INFO), STATUS_INFO_LENGTH_MISMATCH);
return STATUS_INFO_LENGTH_MISMATCH;
}
//
// A ContextName != NULL and a ContextSize of 0 is allowed
//
if (Attributes->ContextTypeInfo->ContextSize > 0 &&
Attributes->ContextTypeInfo->ContextName == NULL) {
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
"Attributes %p ContextTypeInfo %p ContextSize %I64d is not zero, "
"but ContextName is NULL, %!STATUS!",
Attributes, Attributes->ContextTypeInfo,
Attributes->ContextTypeInfo->ContextSize,
STATUS_WDF_OBJECT_ATTRIBUTES_INVALID);
return STATUS_WDF_OBJECT_ATTRIBUTES_INVALID;
}
}
if (Attributes->ContextSizeOverride > 0) {
if (Attributes->ContextTypeInfo == NULL) {
//
// Can't specify additional size without a type
//
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
"Attributes %p ContextSizeOverride of %I64d specified, but no type "
"information, %!STATUS!",
Attributes, Attributes->ContextSizeOverride,
STATUS_WDF_OBJECT_ATTRIBUTES_INVALID);
return STATUS_WDF_OBJECT_ATTRIBUTES_INVALID;
}
else if (Attributes->ContextSizeOverride <
Attributes->ContextTypeInfo->ContextSize) {
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
"Attributes %p ContextSizeOverride %I64d < "
"ContextTypeInfo->ContextSize %I64d, %!STATUS!",
Attributes, Attributes->ContextSizeOverride,
Attributes->ContextTypeInfo->ContextSize,
STATUS_WDF_OBJECT_ATTRIBUTES_INVALID);
return STATUS_WDF_OBJECT_ATTRIBUTES_INVALID;
}
}
if (Flags & FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED) {
if (Attributes->ParentObject != NULL) {
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
"Attributes %p does not allow a parent object to be set, set to "
"%p, %!STATUS!", Attributes, Attributes->ParentObject,
STATUS_WDF_PARENT_ASSIGNMENT_NOT_ALLOWED);
return STATUS_WDF_PARENT_ASSIGNMENT_NOT_ALLOWED;
}
}
else if ((Flags & FX_VALIDATE_OPTION_PARENT_REQUIRED_FLAG) &&
Attributes->ParentObject == NULL) {
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
"ParentObject required in WDF_OBJECT_ATTRIBUTES %p, %!STATUS!",
Attributes, STATUS_WDF_PARENT_NOT_SPECIFIED);
return STATUS_WDF_PARENT_NOT_SPECIFIED;
}
// Enum range checks
if ((Attributes->ExecutionLevel == WdfExecutionLevelInvalid) ||
(Attributes->ExecutionLevel > WdfExecutionLevelDispatch)) {
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
"Attributes %p execution level set to %d, out of range, %!STATUS!",
Attributes, Attributes->ExecutionLevel,
STATUS_WDF_OBJECT_ATTRIBUTES_INVALID);
return STATUS_WDF_OBJECT_ATTRIBUTES_INVALID;
}
if ((Attributes->SynchronizationScope == WdfSynchronizationScopeInvalid) ||
(Attributes->SynchronizationScope > WdfSynchronizationScopeNone)) {
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
"Attributes %p synchronization scope set to %d, out of range, %!STATUS!",
Attributes, Attributes->SynchronizationScope,
STATUS_WDF_OBJECT_ATTRIBUTES_INVALID);
return STATUS_WDF_OBJECT_ATTRIBUTES_INVALID;
}
if ((Flags & FX_VALIDATE_OPTION_SYNCHRONIZATION_SCOPE_ALLOWED) == 0) {
//
// If synchronization is not allowed for this object,
// check the requested level to ensure none was specified.
//
if ((Attributes->SynchronizationScope != WdfSynchronizationScopeInheritFromParent) &&
(Attributes->SynchronizationScope != WdfSynchronizationScopeNone)) {
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
"Attributes %p does not allow synchronization scope too be set, "
"but was set to %!WDF_SYNCHRONIZATION_SCOPE!, %!STATUS!",
Attributes, Attributes->SynchronizationScope,
STATUS_WDF_SYNCHRONIZATION_SCOPE_INVALID);
return STATUS_WDF_SYNCHRONIZATION_SCOPE_INVALID;
}
}
if ((Flags & FX_VALIDATE_OPTION_EXECUTION_LEVEL_ALLOWED) == 0) {
//
// If execution level restrictions are not allowed for this object,
// check the requested level to ensure none was specified.
//
if (Attributes->ExecutionLevel != WdfExecutionLevelInheritFromParent) {
DoTraceLevelMessage(
FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGAPIERROR,
"Attributes %p does not allow execution level to be set, but was"
" set to %!WDF_EXECUTION_LEVEL!, %!STATUS!",
Attributes, Attributes->ExecutionLevel,
STATUS_WDF_EXECUTION_LEVEL_INVALID);
return STATUS_WDF_EXECUTION_LEVEL_INVALID;
}
}
return STATUS_SUCCESS;
}