Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
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, RtlGetLastNtStatus)
#pragma alloc_text(PAGE, RtlGetLastWin32Error)
#pragma alloc_text(PAGE, RtlNtStatusToDosError)
#pragma alloc_text(PAGE, RtlRestoreLastWin32Error)
#pragma alloc_text(PAGE, RtlSetLastWin32Error)
#pragma alloc_text(PAGE, RtlSetLastWin32ErrorAndNtStatusFromNtStatus)
#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) { try { Teb->LastStatusValue = Status; } except (EXCEPTION_EXECUTE_HANDLER) { } }
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
DbgBreakPoint(); #endif // DBG
#endif // NTOS_KERNEL_RUNTIME
return ERROR_MR_MID_NOT_FOUND; }
NTSTATUS NTAPI RtlGetLastNtStatus( VOID ) { return NtCurrentTeb()->LastStatusValue; }
LONG NTAPI RtlGetLastWin32Error( VOID ) { return NtCurrentTeb()->LastErrorValue; }
VOID NTAPI RtlSetLastWin32ErrorAndNtStatusFromNtStatus( NTSTATUS Status ) { //
// RtlNtStatusToDosError stores into NtCurrentTeb()->LastStatusValue.
//
RtlSetLastWin32Error(RtlNtStatusToDosError(Status)); }
VOID NTAPI RtlSetLastWin32Error( LONG Win32Error ) { //
// Arguably this should clear or reset the last nt status, but it does not
// touch it.
//
NtCurrentTeb()->LastErrorValue = Win32Error; }
VOID NTAPI RtlRestoreLastWin32Error( LONG Win32Error ) { #if DBG
if ((LONG)NtCurrentTeb()->LastErrorValue != Win32Error) #endif
NtCurrentTeb()->LastErrorValue = Win32Error; }
|