【问题标题】:What is the difference between HRESULT error codes that start with 0x8 and with 0xC?以 0x8 和 0xC 开头的 HRESULT 错误代码有什么区别?
【发布时间】:2019-01-04 07:46:15
【问题描述】:

这更像是一种好奇心。我一直在查看许多 Win32 API 和 Windows 组件返回以表示错误的 HRESULT 错误代码。

如果我正确理解its structure,最高有效位 31 是错误位。如果已设置,则 HRESULT 包含错误。

例如,0x80004002E_NOINTERFACE

不支持此类接口。

但是当它的两个最高有效位设置为0xC0262588 时会发生什么?是什么让它与众不同?

上面的那个值似乎也转化为一个错误,即ERROR_GRAPHICS_MCA_INTERNAL_ERROR

发生内部监视器配置 API 错误。

编辑:documentation declares 这样的值是无效的,但随后会列出多个据称无效的值。

【问题讨论】:

  • 由于HRESULT 的类型定义为long,因此第一个错误位是一种使用通用if (value < 0) 检查结果的方法。
  • @DavidHeffernan:是的,我可以看到。但是有四分之一的this page 充满了以0xC 开头的HRESULT 代码。这就是我想要理解的。 MS 明显违反了这条规则。
  • @DavidHeffernan:我以为我在原始帖子中链接到了那个页面。
  • 该问题应明确说明文档声明此类值无效,然后继续列出多个据称无效的值。就目前而言,您是否知道文档声明此类值无效,这一点并不明显。你没有提到它对第 30 位的说法,而且据我们所知,你还没有阅读过文档的那部分内容。提出问题时,请向读者说明您的知识和研究范围。
  • 如果Using NTSTATUSNT_WARNING(Status)NT_ERROR(Status) (8 vs c) 之间存在显着差异,我们在代码中考虑了这一点(例如copy datacompletion。但在case HRESULT 我们可以简单地忽略 8xxxxxxx 和 cxxxxxxx 之间的不同

标签: c windows winapi hresult


【解决方案1】:

从 HRESULT 定义的结构中,0x8 和 0xC 在“R”位是不同的,如果设置了 N 位,则该位由 NTSTATUS 编号空间定义。在 NTSTATUS 定义中,0x8 表示 STATUS_SEVERITY_WARNING,0xC 表示 STATUS_SEVERITY_ERROR。

参考:“[MS-ERREF]: Windows Error Codes

【讨论】:

  • 问题是为什么在 shared/winerror.h、um/nserror.h、um/mferror.h 和 winrt/ 中有许多用两位严重性代码定义的 HRESULT 值dlnaerror.h。在许多情况下,只是通过在两个域中定义相同的设施代码并在两个 ntdll.dll 中为状态代码存储相同的消息,将相同的代码集作为NTSTATUS 和(不正确的)HRESULT 值提供.mui 和 kernelbase.dll.mui。但是其他仅 HRESULT 的设施也有这些严格不正确的严重性代码。有关示例,请参阅我的问题本身的 cmets。
  • 这个文档看起来很奇怪,因为它排除了 MSB 中的值 0xC0:如果 N 为零,R 必须为零。但是这些值已经存在,因为问题已经存在,一些 cmets 也表明了这一点。此外,位数行的顺序错误。 MSB 向左
  • @harper 是的,我同意你对这份文件的看法,我正在研究和确认内部。至于位序,有一句“Values are 32 bit, layouts below. 下图与字节序无关;即该图以主机字节顺序显示,仅显示编号空间的布局。 "它消除了你的困惑吗?
  • @eryksun 在我参考的文档中说可以将 NTSTATUS 值映射到等效的 HRESULT 值。我在 HRESULT 中搜索 oxC 代码,例如,AUDITING_DISABLED(指定的事件当前未被审计。)您将在 NTSTATUS 中看到类似的代码。但我不知道地图规则是什么。这可以解释您在头文件中找到的内容吗?
  • STATUS_AUDITING_DISABLEDERROR_AUDITING_DISABLED 在实践中是相关的,但代码彼此无关(即 0xC0000356 vs 0xC0090001)。前者位于NTSTATUS 系统设施(0x000) 中,后者位于HRESULT 安全设施(0x009) 中。如果返回为HRESULT,我们可以用 NT 设施位(即0xC0000356 | 0x10000000 == 0xD0000356)标记前者。用户应清除 NT 位并在 ntdll.dll 中查找 0xC0000356 的消息。 OTOH,0xC0090001 是 HRESULT,而不是 NTSTATUS 代码,它的消息在 kernelbase.dll,而不是 ntdll.dll。
猜你喜欢
  • 1970-01-01
  • 2019-09-11
  • 1970-01-01
  • 1970-01-01
  • 2011-06-29
  • 2013-11-26
  • 2014-03-21
  • 2015-05-30
  • 1970-01-01
相关资源
最近更新 更多