diff --git a/reactos/ntoskrnl/include/internal/probe.h b/reactos/ntoskrnl/include/internal/probe.h new file mode 100644 index 00000000000..862f4320679 --- /dev/null +++ b/reactos/ntoskrnl/include/internal/probe.h @@ -0,0 +1,468 @@ +#ifndef __INCLUDE_INTERNAL_PROBE_H +#define __INCLUDE_INTERNAL_PROBE_H + +#include + +static +__inline +NTSTATUS +DefaultSetInfoBufferCheck(ULONG Class, + const INFORMATION_CLASS_INFO *ClassList, + ULONG ClassListEntries, + PVOID Buffer, + ULONG BufferLength, + KPROCESSOR_MODE PreviousMode) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (Class < ClassListEntries) + { + if (!(ClassList[Class].Flags & ICIF_SET)) + { + Status = STATUS_INVALID_INFO_CLASS; + } + else if (ClassList[Class].RequiredSizeSET > 0 && + BufferLength != ClassList[Class].RequiredSizeSET) + { + if (!(ClassList[Class].Flags & ICIF_SET_SIZE_VARIABLE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (NT_SUCCESS(Status)) + { + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + ProbeForRead(Buffer, + BufferLength, + ClassList[Class].AlignmentSET); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + } + } + else + Status = STATUS_INVALID_INFO_CLASS; + + return Status; +} + +static +__inline +NTSTATUS +DefaultQueryInfoBufferCheck(ULONG Class, + const INFORMATION_CLASS_INFO *ClassList, + ULONG ClassListEntries, + PVOID Buffer, + ULONG BufferLength, + PULONG ReturnLength, + KPROCESSOR_MODE PreviousMode) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (Class < ClassListEntries) + { + if (!(ClassList[Class].Flags & ICIF_QUERY)) + { + Status = STATUS_INVALID_INFO_CLASS; + } + else if (ClassList[Class].RequiredSizeQUERY > 0 && + BufferLength != ClassList[Class].RequiredSizeQUERY) + { + if (!(ClassList[Class].Flags & ICIF_QUERY_SIZE_VARIABLE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (NT_SUCCESS(Status)) + { + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + if (Buffer != NULL) + { + ProbeForWrite(Buffer, + BufferLength, + ClassList[Class].AlignmentQUERY); + } + + if (ReturnLength != NULL) + { + ProbeForWriteUlong(ReturnLength); + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + } + } + else + Status = STATUS_INVALID_INFO_CLASS; + + return Status; +} + +#endif +#ifndef __INCLUDE_INTERNAL_PROBE_H +#define __INCLUDE_INTERNAL_PROBE_H + +#include + +static +__inline +NTSTATUS +DefaultSetInfoBufferCheck(ULONG Class, + const INFORMATION_CLASS_INFO *ClassList, + ULONG ClassListEntries, + PVOID Buffer, + ULONG BufferLength, + KPROCESSOR_MODE PreviousMode) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (Class < ClassListEntries) + { + if (!(ClassList[Class].Flags & ICIF_SET)) + { + Status = STATUS_INVALID_INFO_CLASS; + } + else if (ClassList[Class].RequiredSizeSET > 0 && + BufferLength != ClassList[Class].RequiredSizeSET) + { + if (!(ClassList[Class].Flags & ICIF_SET_SIZE_VARIABLE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (NT_SUCCESS(Status)) + { + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + ProbeForRead(Buffer, + BufferLength, + ClassList[Class].AlignmentSET); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + } + } + else + Status = STATUS_INVALID_INFO_CLASS; + + return Status; +} + +static +__inline +NTSTATUS +DefaultQueryInfoBufferCheck(ULONG Class, + const INFORMATION_CLASS_INFO *ClassList, + ULONG ClassListEntries, + PVOID Buffer, + ULONG BufferLength, + PULONG ReturnLength, + KPROCESSOR_MODE PreviousMode) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (Class < ClassListEntries) + { + if (!(ClassList[Class].Flags & ICIF_QUERY)) + { + Status = STATUS_INVALID_INFO_CLASS; + } + else if (ClassList[Class].RequiredSizeQUERY > 0 && + BufferLength != ClassList[Class].RequiredSizeQUERY) + { + if (!(ClassList[Class].Flags & ICIF_QUERY_SIZE_VARIABLE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (NT_SUCCESS(Status)) + { + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + if (Buffer != NULL) + { + ProbeForWrite(Buffer, + BufferLength, + ClassList[Class].AlignmentQUERY); + } + + if (ReturnLength != NULL) + { + ProbeForWriteUlong(ReturnLength); + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + } + } + else + Status = STATUS_INVALID_INFO_CLASS; + + return Status; +} + +#endif +#ifndef __INCLUDE_INTERNAL_PROBE_H +#define __INCLUDE_INTERNAL_PROBE_H + +#include + +static +__inline +NTSTATUS +DefaultSetInfoBufferCheck(ULONG Class, + const INFORMATION_CLASS_INFO *ClassList, + ULONG ClassListEntries, + PVOID Buffer, + ULONG BufferLength, + KPROCESSOR_MODE PreviousMode) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (Class < ClassListEntries) + { + if (!(ClassList[Class].Flags & ICIF_SET)) + { + Status = STATUS_INVALID_INFO_CLASS; + } + else if (ClassList[Class].RequiredSizeSET > 0 && + BufferLength != ClassList[Class].RequiredSizeSET) + { + if (!(ClassList[Class].Flags & ICIF_SET_SIZE_VARIABLE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (NT_SUCCESS(Status)) + { + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + ProbeForRead(Buffer, + BufferLength, + ClassList[Class].AlignmentSET); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + } + } + else + Status = STATUS_INVALID_INFO_CLASS; + + return Status; +} + +static +__inline +NTSTATUS +DefaultQueryInfoBufferCheck(ULONG Class, + const INFORMATION_CLASS_INFO *ClassList, + ULONG ClassListEntries, + PVOID Buffer, + ULONG BufferLength, + PULONG ReturnLength, + KPROCESSOR_MODE PreviousMode) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (Class < ClassListEntries) + { + if (!(ClassList[Class].Flags & ICIF_QUERY)) + { + Status = STATUS_INVALID_INFO_CLASS; + } + else if (ClassList[Class].RequiredSizeQUERY > 0 && + BufferLength != ClassList[Class].RequiredSizeQUERY) + { + if (!(ClassList[Class].Flags & ICIF_QUERY_SIZE_VARIABLE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (NT_SUCCESS(Status)) + { + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + if (Buffer != NULL) + { + ProbeForWrite(Buffer, + BufferLength, + ClassList[Class].AlignmentQUERY); + } + + if (ReturnLength != NULL) + { + ProbeForWriteUlong(ReturnLength); + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + } + } + else + Status = STATUS_INVALID_INFO_CLASS; + + return Status; +} + +#endif +#ifndef __INCLUDE_INTERNAL_PROBE_H +#define __INCLUDE_INTERNAL_PROBE_H + +#include + +static +__inline +NTSTATUS +DefaultSetInfoBufferCheck(ULONG Class, + const INFORMATION_CLASS_INFO *ClassList, + ULONG ClassListEntries, + PVOID Buffer, + ULONG BufferLength, + KPROCESSOR_MODE PreviousMode) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (Class < ClassListEntries) + { + if (!(ClassList[Class].Flags & ICIF_SET)) + { + Status = STATUS_INVALID_INFO_CLASS; + } + else if (ClassList[Class].RequiredSizeSET > 0 && + BufferLength != ClassList[Class].RequiredSizeSET) + { + if (!(ClassList[Class].Flags & ICIF_SET_SIZE_VARIABLE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (NT_SUCCESS(Status)) + { + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + ProbeForRead(Buffer, + BufferLength, + ClassList[Class].AlignmentSET); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + } + } + else + Status = STATUS_INVALID_INFO_CLASS; + + return Status; +} + +static +__inline +NTSTATUS +DefaultQueryInfoBufferCheck(ULONG Class, + const INFORMATION_CLASS_INFO *ClassList, + ULONG ClassListEntries, + PVOID Buffer, + ULONG BufferLength, + PULONG ReturnLength, + KPROCESSOR_MODE PreviousMode) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (Class < ClassListEntries) + { + if (!(ClassList[Class].Flags & ICIF_QUERY)) + { + Status = STATUS_INVALID_INFO_CLASS; + } + else if (ClassList[Class].RequiredSizeQUERY > 0 && + BufferLength != ClassList[Class].RequiredSizeQUERY) + { + if (!(ClassList[Class].Flags & ICIF_QUERY_SIZE_VARIABLE)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (NT_SUCCESS(Status)) + { + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + if (Buffer != NULL) + { + ProbeForWrite(Buffer, + BufferLength, + ClassList[Class].AlignmentQUERY); + } + + if (ReturnLength != NULL) + { + ProbeForWriteUlong(ReturnLength); + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + } + } + else + Status = STATUS_INVALID_INFO_CLASS; + + return Status; +} + +#endif diff --git a/reactos/ntoskrnl/include/ntoskrnl.h b/reactos/ntoskrnl/include/ntoskrnl.h index f766ea6fe1b..71f4f655551 100644 --- a/reactos/ntoskrnl/include/ntoskrnl.h +++ b/reactos/ntoskrnl/include/ntoskrnl.h @@ -2,3 +2,4 @@ /* Headers that shouldn't be precompiled due to GCC bugs */ #include +#include "internal/probe.h"