From c505e9341862140a47338320ec30046c349eff61 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 29 Dec 2005 18:28:05 +0000 Subject: [PATCH 1/1] - Formatting fixes - Add SEH to NtRaiseHardError. svn path=/trunk/; revision=20429 --- reactos/ntoskrnl/ex/error.c | 224 +++++++++++++++++++++++++++++++----- 1 file changed, 197 insertions(+), 27 deletions(-) diff --git a/reactos/ntoskrnl/ex/error.c b/reactos/ntoskrnl/ex/error.c index 83a6fd1ac8b..df152026e0f 100644 --- a/reactos/ntoskrnl/ex/error.c +++ b/reactos/ntoskrnl/ex/error.c @@ -1,10 +1,9 @@ /* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel + * PROJECT: ReactOS Kernel * FILE: ntoskrnl/ex/error.c * PURPOSE: Error Functions and Status/Exception Dispatching/Raising - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Created File + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) */ /* INCLUDES *****************************************************************/ @@ -13,6 +12,8 @@ #define NDEBUG #include +#define TAG_ERR TAG('E', 'r', 'r', ' ') + /* GLOBALS ****************************************************************/ BOOLEAN ExReadyForErrors = FALSE; @@ -21,11 +22,23 @@ PEPROCESS ExpDefaultErrorPortProcess = NULL; /* FUNCTIONS ****************************************************************/ +VOID +NTAPI +ExpRaiseHardError(IN NTSTATUS ErrorStatus, + IN ULONG NumberOfParameters, + IN ULONG UnicodeStringParameterMask, + IN PULONG_PTR Parameters, + IN ULONG ValidResponseOptions, + OUT PULONG Response) +{ + UNIMPLEMENTED; +} + /* * @implemented */ VOID -STDCALL +NTAPI ExRaiseAccessViolation(VOID) { /* Raise the Right Status */ @@ -36,7 +49,7 @@ ExRaiseAccessViolation(VOID) * @implemented */ VOID -STDCALL +NTAPI ExRaiseDatatypeMisalignment (VOID) { /* Raise the Right Status */ @@ -47,17 +60,18 @@ ExRaiseDatatypeMisalignment (VOID) * @implemented */ LONG -STDCALL +NTAPI ExSystemExceptionFilter(VOID) { - return KeGetPreviousMode() != KernelMode ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; + return KeGetPreviousMode() != KernelMode ? + EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; } /* * @unimplemented */ VOID -STDCALL +NTAPI ExRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, @@ -65,11 +79,19 @@ ExRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG ValidResponseOptions, OUT PULONG Response) { - UNIMPLEMENTED; + /* FIXME: Capture to user-mode! */ + + /* Now call the worker function */ + ExpRaiseHardError(ErrorStatus, + NumberOfParameters, + UnicodeStringParameterMask, + Parameters, + ValidResponseOptions, + Response); } NTSTATUS -STDCALL +NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, @@ -77,37 +99,184 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG ValidResponseOptions, OUT PULONG Response) { + NTSTATUS Status; + PULONG_PTR SafeParams = NULL; + ULONG SafeResponse; + UNICODE_STRING SafeString; + ULONG i; + ULONG ParamSize; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); DPRINT1("Hard error %x\n", ErrorStatus); - /* Call the Executive Function (WE SHOULD PUT SEH HERE/CAPTURE!) */ - ExRaiseHardError(ErrorStatus, - NumberOfParameters, - UnicodeStringParameterMask, - Parameters, - ValidResponseOptions, - Response); + /* Validate parameter count */ + if (NumberOfParameters > MAXIMUM_HARDERROR_PARAMETERS) + { + /* Fail */ + DPRINT1("Invalid parameters\n"); + return STATUS_INVALID_PARAMETER_2; + } + + /* Make sure we have some at least */ + if ((Parameters) && !(NumberOfParameters)) + { + /* Fail */ + DPRINT1("Invalid parameters\n"); + return STATUS_INVALID_PARAMETER_2; + } + + /* Check if we were called from user-mode */ + if (PreviousMode != KernelMode) + { + /* First validate the responses */ + switch (ValidResponseOptions) + { + /* Check all valid cases */ + case OptionAbortRetryIgnore: + case OptionOk: + case OptionOkCancel: + case OptionRetryCancel: + case OptionYesNo: + case OptionYesNoCancel: + case OptionShutdownSystem: + break; + + /* Anything else is invalid */ + default: + return STATUS_INVALID_PARAMETER_4; + } + + /* Enter SEH Block */ + _SEH_TRY + { + /* Validate the response pointer */ + ProbeForWriteUlong(Response); + + /* Check if we have parameters */ + if (Parameters) + { + /* Validate the parameter pointers */ + ParamSize = sizeof(ULONG_PTR) * NumberOfParameters; + ProbeForRead(Parameters, ParamSize, sizeof(ULONG_PTR)); + + /* Allocate a safe buffer */ + SafeParams = ExAllocatePoolWithTag(PagedPool, + ParamSize, + TAG_ERR); + + /* Copy them */ + RtlMoveMemory(SafeParams, Parameters, ParamSize); + + /* Nowo check if there's strings in it */ + if (UnicodeStringParameterMask) + { + /* Loop every string */ + for (i = 0; i < NumberOfParameters; i++) + { + /* Check if this parameter is a string */ + if (UnicodeStringParameterMask & (1 << i)) + { + /* Probe the structure */ + ProbeForRead((PVOID)SafeParams[i], + sizeof(UNICODE_STRING), + sizeof(ULONG_PTR)); - /* Return Success */ - return STATUS_SUCCESS; + /* Capture it */ + RtlMoveMemory(&SafeString, + (PVOID)SafeParams[i], + sizeof(UNICODE_STRING)); + + /* Probe the buffer */ + ProbeForRead(SafeString.Buffer, + SafeString.MaximumLength, + sizeof(UCHAR)); + } + } + } + } + } + _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) + { + /* Free captured buffer */ + if (SafeParams) ExFreePool(SafeParams); + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + /* If we failed to capture/probe, bail out */ + if (!NT_SUCCESS(Status)) return Status; + + /* Call the system function directly, because we probed */ + ExpRaiseHardError(ErrorStatus, + NumberOfParameters, + UnicodeStringParameterMask, + SafeParams, + ValidResponseOptions, + &SafeResponse); + } + else + { + /* Reuse variable */ + SafeParams = Parameters; + + /* + * Call the Executive Function. It will probe and copy pointers to + * user-mode + */ + ExRaiseHardError(ErrorStatus, + NumberOfParameters, + UnicodeStringParameterMask, + SafeParams, + ValidResponseOptions, + &SafeResponse); + } + + /* Check if we were called in user-mode */ + if (PreviousMode != KernelMode) + { + /* That means we have a buffer to free */ + if (SafeParams) ExFreePool(SafeParams); + + /* Enter SEH Block for return */ + _SEH_TRY + { + /* Return the response */ + *Response = SafeResponse; + } + _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + /* Return the response */ + *Response = SafeResponse; + } + + /* Return status */ + return Status; } NTSTATUS -STDCALL +NTAPI NtSetDefaultHardErrorPort(IN HANDLE PortHandle) { KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); NTSTATUS Status = STATUS_UNSUCCESSFUL; /* Check if we have the Privilege */ - if(!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) { - - DPRINT1("NtSetDefaultHardErrorPort: Caller requires the SeTcbPrivilege privilege!\n"); + if(!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) + { + DPRINT1("NtSetDefaultHardErrorPort: Caller requires " + "the SeTcbPrivilege privilege!\n"); return STATUS_PRIVILEGE_NOT_HELD; } /* Only called once during bootup, make sure we weren't called yet */ - if(!ExReadyForErrors) { - + if(!ExReadyForErrors) + { + /* Reference the port */ Status = ObReferenceObjectByHandle(PortHandle, 0, LpcPortObjectType, @@ -116,14 +285,15 @@ NtSetDefaultHardErrorPort(IN HANDLE PortHandle) NULL); /* Check for Success */ - if(NT_SUCCESS(Status)) { - + if(NT_SUCCESS(Status)) + { /* Save the data */ ExpDefaultErrorPortProcess = PsGetCurrentProcess(); ExReadyForErrors = TRUE; } } + /* Return status to caller */ return Status; } -- 2.17.1