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未被授予
如果我正在创建
HRESULTS
,我需要使用一些代码。如果用户可以调用将我的HRESULT
转换为字符串,那就太好了。(特别是因为我返回的HRESULT可以是我自己的代码,也可以是从Microsoft代码返回给我的HRESULT)。不要走这条路,只定义自己的
代码本身的重用是毫无意义的,因为拥有自己的代码只需要一个#define
重复使用错误字符串也不是一个好主意:
- 这些将被本地化。因此,如果您的(英文)应用程序在中文版Windows上运行,用户将看到这两种语言的混合
- 微软可能会随心所欲地更改文本,发布新版本的Windows或进行更新。例如,如果您使用
来指示HTTPS证书错误,而Microsoft决定修复他们模糊的消息,改为说“INVALIDIPSEC IKEcertificate TYPE”?(我根本不知道IKE是什么,对IPSEC只有一个模糊的概念,但你明白了。)ERROR\u IPSEC\u IKE\u INVALID\u CERT\u TYPE
- 您将无法自定义更清晰或更具体的错误消息
- 一旦API的用户开始使用
,您将永远与Microsoft提供的一组错误代码和消息联系在一起FormatMessage
如果你已经知道陈雷蒙会扇你耳光,你为什么还要考虑这个 当您定义自己的
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