我知道NTSTATUS会在出现特定错误的情况下得到,但我得到的是结果,而不是pinvoke的ntstatus。那么如何将特定的NTSTATUS 值转换为Hresult。

我尝试没有成功:

class Program
{
    private const int FacilityNtBit = 0x10000000;

    //#define STATUS_DUPLICATE_OBJECTID        ((NTSTATUS)0xC000022AL)
    private const int STATUS_DUPLICATE_OBJECTID = unchecked((int) (0xC000022A));

    // HResult that is returned for the STATUS_DUPLICATE_OBJECTID
    private const int CorrectHrStatusDuplicateObjectid = -2147019886;

    static void Main(string[] args)
    {
        int res = HRESULT_FROM_NT(STATUS_DUPLICATE_OBJECTID);
        Debug.Assert(res == CorrectHrStatusDuplicateObjectid, "Must be the same");
    }

    private static int HRESULT_FROM_NT(int ntStatus)
    {
        //#define HRESULT_FROM_NT(x)      ((HRESULT) ((x) | FACILITY_NT_BIT))
        return ntStatus | FacilityNtBit;
    }
}

最佳答案

您拥有的NTSTATUS

  • 0xC000022A :STATUS_DUPLICATE_OBJECTID-尝试将ID插入索引中失败,因为该ID已在索引中。)
  • 严重性:1(1 = Failure)
  • 保留:1(1 = NTSTATUS)
  • 客户:0(0 =微软定义)
  • N:0(0 =不是NTSTATUS HRESULT)
  • 保留:0
  • 设施:0
  • 代码:554

  • 您想要的HRESULT
  • 0x80071392 :
  • 严重性:1(1 = Failure)
  • R保留:0
  • 客户:0(0 =微软定义)
  • N:0(0 =不是NTSTATUS HRESULT)
  • X保留:0
  • 设施:7(FACILITY_WIN32-保留此区域以将未修饰的错误代码映射到HRESULT中。)
  • 代码:5010(ERROR_OBJECT_ALREADY_EXISTS-该对象已存在。)

  • 表示同一错误的多种方法

    问题是同一错误有多种表示形式:
  • NTSTATUS :0xC000022A
  • Win32 :5010
  • HRESULT :0xD000022A(将NSTATUS转换为HRESULT)
  • HRESULT :0x80071392(将Win32错误转换为HRESULT)


  • 并非所有的NTSTATUS代码都可以转换为Win32。在这种情况下,尝试遍历RtlNtstatusToDosError会给您错误代码ERROR_MR_MID_NOT_FOUND:



    这就是为什么最好保留真实的错误消息。

    获取错误消息

    我认为遇到的真正问题是如何将NTSTATUS转换为可以显示给用户的错误消息。为此,您需要Microsoft知识库文章:

    10-04 13:47