diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/rtl/error.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/ntos/rtl/error.c')
-rw-r--r-- | private/ntos/rtl/error.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/private/ntos/rtl/error.c b/private/ntos/rtl/error.c new file mode 100644 index 000000000..fc727fbd0 --- /dev/null +++ b/private/ntos/rtl/error.c @@ -0,0 +1,189 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + error.c + +Abstract: + + This module contains a routine for converting NT status codes + to DOS/OS|2 error codes. + +Author: + + David Treadwell (davidtr) 04-Apr-1991 + +Revision History: + +--*/ + +#include <ntrtlp.h> +#include "winerror.h" +#include "error.h" + +#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME) +#pragma alloc_text(PAGE, RtlNtStatusToDosError) +#endif + +// +// Ensure that the Registry ERROR_SUCCESS error code and the +// NO_ERROR error code remain equal and zero. +// + +#if ERROR_SUCCESS != 0 || NO_ERROR != 0 +#error Invalid value for ERROR_SUCCESS. +#endif + +ULONG +RtlNtStatusToDosError ( + IN NTSTATUS Status + ) + +/*++ + +Routine Description: + + This routine converts an NT status code to its DOS/OS|2 equivalent. + Remembers the Status code value in the TEB. + +Arguments: + + Status - Supplies the status value to convert. + +Return Value: + + The matching DOS/OS|2 error code. + +--*/ + +{ + PTEB Teb; + + Teb = NtCurrentTeb(); + if ( Teb ) { + Teb->LastStatusValue = Status; + } + + return RtlNtStatusToDosErrorNoTeb( Status ); +} + +ULONG +RtlNtStatusToDosErrorNoTeb ( + IN NTSTATUS Status + ) + +/*++ + +Routine Description: + + This routine converts an NT status code to its DOS/OS 2 equivalent + and returns the translated value. + +Arguments: + + Status - Supplies the status value to convert. + +Return Value: + + The matching DOS/OS 2 error code. + +--*/ + +{ + + ULONG Offset; + ULONG Entry; + ULONG Index; + + // + // Convert any HRESULTs to their original form of a NTSTATUS or a + // WIN32 error + // + + + if (Status & 0x20000000) { + + // + // The customer bit is set so lets just pass the + // error code on thru + // + + return Status; + + } + else if ((Status & 0xffff0000) == 0x80070000) { + + // + // The status code was a win32 error already. + // + + return(Status & 0x0000ffff); + } + else if ((Status & 0xf0000000) == 0xd0000000) { + + // + // The status code is a HRESULT from NTSTATUS + // + + Status &= 0xcfffffff; + } + + // + // Scan the run length table and compute the entry in the translation + // table that maps the specified status code to a DOS error code. + // + + Entry = 0; + Index = 0; + do { + if ((ULONG)Status >= RtlpRunTable[Entry + 1].BaseCode) { + Index += (RtlpRunTable[Entry].RunLength * RtlpRunTable[Entry].CodeSize); + + } else { + Offset = (ULONG)Status - RtlpRunTable[Entry].BaseCode; + if (Offset >= RtlpRunTable[Entry].RunLength) { + break; + + } else { + Index += (Offset * (ULONG)RtlpRunTable[Entry].CodeSize); + if (RtlpRunTable[Entry].CodeSize == 1) { + return (ULONG)RtlpStatusTable[Index]; + + } else { + return (((ULONG)RtlpStatusTable[Index + 1] << 16) | + (ULONG)RtlpStatusTable[Index]); + } + } + } + + Entry += 1; + } while (Entry < (sizeof(RtlpRunTable) / sizeof(RUN_ENTRY))); + + // + // The translation to a DOS error code failed. + // + // The redirector maps unknown OS/2 error codes by ORing 0xC001 into + // the high 16 bits. Detect this and return the low 16 bits if true. + // + + if (((ULONG)Status >> 16) == 0xC001) { + return ((ULONG)Status & 0xFFFF); + } + +#ifndef NTOS_KERNEL_RUNTIME + DbgPrint("RTL: RtlNtStatusToDosError(0x%lx): No Valid Win32 Error Mapping\n",Status); + DbgPrint("RTL: Edit ntos\\rtl\\generr.c to correct the problem\n"); + DbgPrint("RTL: ERROR_MR_MID_NOT_FOUND is being returned\n"); + +#if DBG + if (NtCurrentPeb()->BeingDebugged) { + DbgBreakPoint(); + } + +#endif // DBG +#endif // NTOS_KERNEL_RUNTIME + + return ERROR_MR_MID_NOT_FOUND; +} |