Winapi 什么';劫持Windows错误代码以从我自己的代码返回的规则是什么?

Winapi 什么';劫持Windows错误代码以从我自己的代码返回的规则是什么?,winapi,Winapi,WinError.h中定义的错误代码是否可以被劫持并由我自己的代码返回 定义了一些通用的Win32错误代码: 错误\u文件\u未找到:“系统找不到指定的文件。” 当找不到文件时,我当然可以将其用于我自己的目的 然后仍然存在一些一般性错误: 错误\u访问被拒绝:“访问被拒绝。” 但一般认为,在尝试访问文件时会出现此错误。如果服务器返回401,我可能有一个HttpGet()函数返回ERROR\u ACCESS\u DENIED 但还有一些代码被定义为用于特定目的。假设我的HttpGet()函

WinError.h
中定义的错误代码是否可以被劫持并由我自己的代码返回

定义了一些通用的Win32错误代码:

  • 错误\u文件\u未找到
    :“系统找不到指定的文件。”
当找不到文件时,我当然可以将其用于我自己的目的

然后仍然存在一些一般性错误:

  • 错误\u访问被拒绝
    :“访问被拒绝。”
但一般认为,在尝试访问文件时会出现此错误。如果服务器返回
401
,我可能有一个
HttpGet()
函数返回
ERROR\u ACCESS\u DENIED

但还有一些代码被定义为用于特定目的。假设我的
HttpGet()
函数在
https
证书不是我们支持的类型时抛出错误:

  • 错误\u IPSEC\u IKE\u无效\u证书类型
    :“无效证书类型”
除了在
WinError.h
中明确定义代码属于IPSec之外:

///////////////////////////////////////////////////
//                                               //
//           Start of IPSec Error codes          //
//                                               //
//                 13000 to 13999                //
///////////////////////////////////////////////////

...

//
// MessageId: ERROR_IPSEC_IKE_INVALID_CERT_TYPE
//
// MessageText:
//
// Invalid certificate type
//
#define ERROR_IPSEC_IKE_INVALID_CERT_TYPE 13819L
但是错误文本正是我想要的

我们有一个财务系统,需要第二个用户批准交易;这意味着输入的凭据必须是与第一个人不同的用户:

  • MK_E_用户
    :“操作成功所需的用户输入”
或许:

  • 错误\u登录\u类型\u未被授予
    :“登录失败:用户未被授予此计算机上请求的登录类型。”
我感觉到,通过WinError探测,通过它们显示的字符串挑选错误代码,并重新指定它们的用途以指示它们不是为错误而设计的,这会给我一记耳光

Windows错误代码是免费提供的错误代码“池”吗?或者所有Windows错误代码都只能从Microsoft代码中返回


如果我正在创建
HRESULTS
,我需要使用一些代码。如果用户可以调用将我的
HRESULT
转换为字符串,那就太好了。(特别是因为我返回的HRESULT可以是我自己的代码,也可以是从Microsoft代码返回给我的HRESULT)。

不要走这条路,只定义自己的

代码本身的重用是毫无意义的,因为拥有自己的代码只需要一个
#define

重复使用错误字符串也不是一个好主意:

  • 这些将被本地化。因此,如果您的(英文)应用程序在中文版Windows上运行,用户将看到这两种语言的混合

  • 微软可能会随心所欲地更改文本,发布新版本的Windows或进行更新。例如,如果您使用
    ERROR\u IPSEC\u IKE\u INVALID\u CERT\u TYPE
    来指示HTTPS证书错误,而Microsoft决定修复他们模糊的消息,改为说“INVALIDIPSEC IKEcertificate TYPE”?(我根本不知道IKE是什么,对IPSEC只有一个模糊的概念,但你明白了。)

  • 您将无法自定义更清晰或更具体的错误消息

  • 一旦API的用户开始使用
    FormatMessage
    ,您将永远与Microsoft提供的一组错误代码和消息联系在一起


如果你已经知道陈雷蒙会扇你耳光,你为什么还要考虑这个

当您定义自己的
HRESULT
代码时,建议您使用并定义此应用程序定义代码范围内的代码。是的,应用程序之间的代码会重叠,但是如果您正在实现COM对象/接口,您还可以通过
SetErrorInfo
API提供额外的描述性消息,并通过实现
ISupportErrorInfo
来指示支持

COM+编程
一书中摘录的内容更详细地解释了这一点:(第67页)

更简单的是,您可以使用自定义的协作室代码,这在不同的模块中可能有所不同,因此您可以轻松地确定哪个模块是问题的根源

如果将
MESSAGETABLE
资源放入二进制文件中,
FormatMessage
API可以解析HRESULT并提取单个代码的描述文本,就像常规Windows错误代码一样(应用程序仍然需要为API函数提供模块句柄)

另见:


O.p.编辑:

来自微软的

2.1 HRESULT HRESULT编号空间可由供应商扩展。供应商可以为此字段提供自己的值,只要设置了C位(0x20000000),表示它是客户代码

C(1位):客户。此位指定值是客户定义的还是Microsoft定义的。该位为客户定义的值设置,为Microsoft定义的值清除

:Microsoft使用的所有值均清除了C

这意味着只要设置C位,我就可以生成我喜欢的任何HRESULT。实际上,这意味着我可以使用我喜欢的任何代码,例如:

E_LOGON_FAILURE = 0xA007052E;
当然,我不是随机得出这个数字的

首先,我将高位设置为1,以指示错误:

0x80000000
然后我“选择”一个错误代码,例如:

然后我需要选择一个设施。让我们选择,我不知道

最后,我设置,以指示它不是Microsoft定义的HRESULT:

0xA007052E
巧合的是,直到最后一步,一切都是微软宏的精髓:

将系统错误代码映射到HRESULT值

 HRESULT HRESULT_FROM_WIN32(DWORD x);

我想我可能已经找到了自己的答案,实际上:

系统错误代码非常广泛。。。因为这些代码是在WinEr中定义的
0xA007052E
 HRESULT HRESULT_FROM_WIN32(DWORD x);
E_HANDLE = 0x80070006;   //Invalid handle