如何为不同的 HRESULT 值正确使用 On Error Goto
How to correctly use On Error Goto for different HRESULT values
我正在尝试读取文件。调用是从 VB 到 CPP dll。
这是我的示例代码片段
VB 通话
Private Sub ReadFile(...)
On Error GoTo Problem
Dim errorString As String
Sample.ReadFile basepath, filename, register, errorString
GoTo Completed
Problem:
WriteToLogFile basepath + filename + errorString //error string contains the formatted hresult message from cpp dll
我的 CPP 功能:
HRESULT ReadFile(...)
{
hr= actualread(...)
if(FAILED(hr)
{
return E_FAIL //
}
如果我将 E_FAIL
更改为 ERROR_FILE_NOT_FOUND
VB 则不会记录错误消息。
E_FAIL
消息描述是 未指定的错误。 这对用户帮助不大。
它记录 E_POINTER、E_HANDLE 等任何以 E_ 开头而不是以 ERROR_
开头的内容
COM 指定 HRESULT
中的哪些值被视为错误,哪些不是。引用自Structure of COM Error Codes:
The high-order bit in the HRESULT or SCODE indicates whether the return value represents success or failure. If set to 0, SEVERITY_SUCCESS, the value indicates success. If set to 1, SEVERITY_ERROR, it indicates failure.
E_
常量旨在以这种方式使用,并具有适当的值以确保它们被视为错误。 ERROR_
常量不是,它们用于报告错误的不同约定。
正如 WhozCraig 在评论中指出的那样,有一个 HRESULT_FROM_WIN32
函数可用于将 Win32 错误代码转换为 HRESULT
。
解码错误
-2147220978 样式数字为32位有符号整数,用计算器转换为十六进制。
Windows 错误(较小的数字)和 COM HResults(通常,但有例外,以 0x80040154 中的 8 开头)在 WinError.h 中定义,但 8007nnnn 除外,您可以在其中查找 Window 它包含的错误编号。
作为一般规则 Windows 错误少于 65,535 (0xFFFF)。以 0x80000001 开头的错误是组件对象模型 (COM) HResults。以 0xC0000001 开头的错误是 NTStatus 结果。以 0xD0000001 开头的错误也是 NTStatus 值 return 在 HResult 中编辑。
WinError - 从 Windows API 调用
返回
HResult - 从 COM 调用返回
NTStatus - 从内核返回,一些 API 调用也 return 当
遇到内核错误。
NTStatus 错误(通常但不总是以 C 开头,如 0xC0000022)在 NTStatus.h 中定义。
.h 文件是最好的来源,因为它包含错误的符号名称,可以提供错误来源等线索。 FormatMessage 不给出符号名称,只给出描述。
您可以通过下载 Platform SDK(它是千兆字节)来获取这些文件
如果你只想要这两个文件,我把它们放在我的 skydrive 上,这样我就可以随时随地参考它们。
https://skydrive.live.com/redir?resid=E2F0CE17A268A4FA!121
请注意互联网错误 (12,000 - 12,999) 是 windows 错误,但在 wininet.h 中指定也可在上面找到。
其他 .h 文件中定义了错误。但是99%都在上面这三个。
HResult 和 NTStatus 代码的结构
HResults 中的最高位和 NTStatus 中的两个最高位设置为错误。因此,Hresults 在出错时启动 8,而 NTStatus 在出错时启动 C。接下来的 14 或 15 位是保留位,其中一些指定了设施 - 错误所在的区域。这是读取十六进制时的第三和第四个数字。 EG 0xnn07nnnn - HResult 设施代码 7 是一个正常的 Windows' 错误(return 来自 COM 程序 - 因此它被 returned 作为 HResult)。设施代码在 Winerror.h 中为 HResults 定义,在 NTStatus.h 中为 NTStatus 代码定义。他们是不同的。
解码 0x8003nnnn 错误
设施代码为 3 的 HResults 表示 HResult 包含 OLE 结构化存储错误(0x0 到 0xff)。这些与 Dos 错误代码相同。这些似乎不在 Windows' 头文件中,代码列表在 post.
的末尾
解码 0x8004nnnn 错误
设施代码为 4 的 HResults 表示 HResult 包含 OLE 错误(0x0 到 0x1ff),而范围的其余部分(0x200 起)是特定于组件的错误,因此来自一个组件的 20e 与来自另一个组件的 20e 具有不同的含义.
这就是为什么错误来源对于 0x80040200 以上的错误格外重要。
解码 0x8007nnnn 错误
设施代码为 7 的 HResults 表示 HResult 包含 Windows' 错误代码。您必须查找 Windows' 错误代码而不是 HResult。
解码0x80070002。 0x 表示它是一个十六进制数,8 表示错误,前 7 表示它是一个 windows 错误,其余数字 2 是实际的 Windows 错误。
要查找错误,我们需要十进制格式的错误。启动计算器(开始 - 所有程序 - 附件 - 计算器)并选择查看菜单 - 科学,然后选择查看菜单 - 十六进制。输入 2。然后查看菜单 - 十进制。它会说 2.
启动命令提示符(开始 - 所有程序 - 附件 - 命令提示符)并输入
net helpmsg 2
它会说
The system cannot find the file specified.
或在winerror.h
中查找
//
// MessageId: ERROR_FILE_NOT_FOUND
//
// MessageText:
//
// The system cannot find the file specified.
//
#define ERROR_FILE_NOT_FOUND 2L
解码 0x8019nnnn 错误
设备为 0x19 的 HResults 是 HTTP 错误。 16,384 (0x4000) 以下的代码与 HTTP 错误相同,例如 HTTP 状态 404:服务器上不存在请求的 URL 是 0x80190194 (0x194 = 404)。代码 16,384 及更高版本是特定于 BITS 的。
解码 0xDnnnnnnn 错误
从 0xD 开始的 HResult 是一个带有 NTStatus 值的 HResult。只需将引导 D 更改为 C 并将其视为 NTStatus (Hresult = NTStatus OR 10000000)。
Dos 错误代码(0x8003nnnn 错误)
代码消息
01 Invalid function number
02 File not found
03 Path not found
04 Too many open files (no handles left)
05 Access denied
06 Invalid handle
07 Memory control blocks destroyed
08 Insufficient memory
09 Invalid memory block address
0A Invalid environment
0B Invalid format
0C Invalid access mode (open mode is invalid)
0D Invalid data
0E Reserved
0F Invalid drive specified
10 Attempt to remove current directory
11 Not same device
12 No more files
13 Attempt to write on a write-protected diskette
14 Unknown unit
15 Drive not ready
16 Unknown command
17 CRC error
18 Bad request structure length
19 Seek error
1A Unknown media type
1B Sector not found
1C Printer out of paper
1D Write fault
1E Read fault
1F General failure
20 Sharing violation
21 Lock violation
22 Invalid disk change
23 FCB unavailable
24 Sharing buffer overflow
25 Reserved
26 Unable to complete file operation (DOS 4.x)
27-31 Reserved
32 Network request not supported
33 Remote computer not listening
34 Duplicate name on network
35 Network name not found
36 Network busy
37 Network device no longer exists
38 NetBIOS command limit exceeded
39 Network adapter error
3A Incorrect network response
3B Unexpected network error
3C Incompatible remote adapter
3D Print queue full
3E No space for print file
3F Print file deleted
40 Network name deleted
41 Access denied
42 Network device type incorrect
43 Network name not found
44 Network name limit exceeded
45 NetBIOS session limit exceeded
46 Temporarily paused
47 Network request not accepted
48 Print or disk redirection is paused
49-4F Reserved
50 File already exists
51 Reserved
52 Cannot make directory entry
53 Fail on INT 24
54 Too many redirections
55 Duplicate redirection
56 Invalid password
57 Invalid parameter
58 Network device fault
59 Function not supported by network (DOS 4.x)
5A Required system component not installed (DOS 4.x)
设施代码
NTStatus 设施 HResults 设施
Common status values
0x0 Null 0x0
Debugger 0x1 Rpc 0x1
Rpc_runtime 0x2 Dispatch 0x2
Rpc_stubs 0x3 Storage 0x3
Io_error_code 0x4 Itf 0x4
Various drivers 0x5-0xf Win32 0x7
Ntwin32 0x7 Windows 0x8
Ntsspi 0x9 Sspi 0x9
Terminal_server 0xa Security 0x9
Faciltiy_mui_error_code 0xb Control 0xa
Usb_error_code 0x10 Cert 0xb
Hid_error_code 0x11 Internet 0xc
Firewire_error_code 0x12 Mediaserver 0xd
Cluster_error_code 0x13 Msmq 0xe
Acpi_error_code 0x14 Setupapi 0xf
Sxs_error_code 0x15 Scard 0x10
Transaction 0x19 Complus 0x11
Commonlog 0x1a Aaf 0x12
Video 0x1b Urt 0x13
Filter_manager 0x1c Acs 0x14
Monitor 0x1d Dplay 0x15
Graphics_kernel 0x1e Umi 0x16
Driver_framework 0x20 Sxs 0x17
Fve_error_code 0x21 Windows_ce 0x18
Fwp_error_code 0x22 Http 0x19
Ndis_error_code 0x23 Usermode_commonlog 0x1a
Hypervisor 0x35 Usermode_filter_manager 0x1f
Ipsec 0x36 Backgroundcopy 0x20
Maximum_value 0x37 Configuration 0x21
State_management 0x22
Metadirectory 0x23
Windowsupdate 0x24
Directoryservice 0x25
Graphics 0x26
Shell 0x27
Tpm_services 0x28
Tpm_software 0x29
Pla 0x30
Fve 0x31
Fwp 0x32
Winrm 0x33
Ndis 0x34
Usermode_hypervisor 0x35
Cmi 0x36
Windows_defender 0x50
我正在尝试读取文件。调用是从 VB 到 CPP dll。
这是我的示例代码片段
VB 通话
Private Sub ReadFile(...)
On Error GoTo Problem
Dim errorString As String
Sample.ReadFile basepath, filename, register, errorString
GoTo Completed
Problem:
WriteToLogFile basepath + filename + errorString //error string contains the formatted hresult message from cpp dll
我的 CPP 功能:
HRESULT ReadFile(...)
{
hr= actualread(...)
if(FAILED(hr)
{
return E_FAIL //
}
如果我将 E_FAIL
更改为 ERROR_FILE_NOT_FOUND
VB 则不会记录错误消息。
E_FAIL
消息描述是 未指定的错误。 这对用户帮助不大。
它记录 E_POINTER、E_HANDLE 等任何以 E_ 开头而不是以 ERROR_
开头的内容COM 指定 HRESULT
中的哪些值被视为错误,哪些不是。引用自Structure of COM Error Codes:
The high-order bit in the HRESULT or SCODE indicates whether the return value represents success or failure. If set to 0, SEVERITY_SUCCESS, the value indicates success. If set to 1, SEVERITY_ERROR, it indicates failure.
E_
常量旨在以这种方式使用,并具有适当的值以确保它们被视为错误。 ERROR_
常量不是,它们用于报告错误的不同约定。
正如 WhozCraig 在评论中指出的那样,有一个 HRESULT_FROM_WIN32
函数可用于将 Win32 错误代码转换为 HRESULT
。
解码错误
-2147220978 样式数字为32位有符号整数,用计算器转换为十六进制。
Windows 错误(较小的数字)和 COM HResults(通常,但有例外,以 0x80040154 中的 8 开头)在 WinError.h 中定义,但 8007nnnn 除外,您可以在其中查找 Window 它包含的错误编号。
作为一般规则 Windows 错误少于 65,535 (0xFFFF)。以 0x80000001 开头的错误是组件对象模型 (COM) HResults。以 0xC0000001 开头的错误是 NTStatus 结果。以 0xD0000001 开头的错误也是 NTStatus 值 return 在 HResult 中编辑。
WinError - 从 Windows API 调用
返回
HResult - 从 COM 调用返回
NTStatus - 从内核返回,一些 API 调用也 return 当 遇到内核错误。
NTStatus 错误(通常但不总是以 C 开头,如 0xC0000022)在 NTStatus.h 中定义。
.h 文件是最好的来源,因为它包含错误的符号名称,可以提供错误来源等线索。 FormatMessage 不给出符号名称,只给出描述。
您可以通过下载 Platform SDK(它是千兆字节)来获取这些文件
如果你只想要这两个文件,我把它们放在我的 skydrive 上,这样我就可以随时随地参考它们。
https://skydrive.live.com/redir?resid=E2F0CE17A268A4FA!121
请注意互联网错误 (12,000 - 12,999) 是 windows 错误,但在 wininet.h 中指定也可在上面找到。
其他 .h 文件中定义了错误。但是99%都在上面这三个。
HResult 和 NTStatus 代码的结构
HResults 中的最高位和 NTStatus 中的两个最高位设置为错误。因此,Hresults 在出错时启动 8,而 NTStatus 在出错时启动 C。接下来的 14 或 15 位是保留位,其中一些指定了设施 - 错误所在的区域。这是读取十六进制时的第三和第四个数字。 EG 0xnn07nnnn - HResult 设施代码 7 是一个正常的 Windows' 错误(return 来自 COM 程序 - 因此它被 returned 作为 HResult)。设施代码在 Winerror.h 中为 HResults 定义,在 NTStatus.h 中为 NTStatus 代码定义。他们是不同的。
解码 0x8003nnnn 错误
设施代码为 3 的 HResults 表示 HResult 包含 OLE 结构化存储错误(0x0 到 0xff)。这些与 Dos 错误代码相同。这些似乎不在 Windows' 头文件中,代码列表在 post.
的末尾解码 0x8004nnnn 错误
设施代码为 4 的 HResults 表示 HResult 包含 OLE 错误(0x0 到 0x1ff),而范围的其余部分(0x200 起)是特定于组件的错误,因此来自一个组件的 20e 与来自另一个组件的 20e 具有不同的含义.
这就是为什么错误来源对于 0x80040200 以上的错误格外重要。
解码 0x8007nnnn 错误
设施代码为 7 的 HResults 表示 HResult 包含 Windows' 错误代码。您必须查找 Windows' 错误代码而不是 HResult。
解码0x80070002。 0x 表示它是一个十六进制数,8 表示错误,前 7 表示它是一个 windows 错误,其余数字 2 是实际的 Windows 错误。
要查找错误,我们需要十进制格式的错误。启动计算器(开始 - 所有程序 - 附件 - 计算器)并选择查看菜单 - 科学,然后选择查看菜单 - 十六进制。输入 2。然后查看菜单 - 十进制。它会说 2.
启动命令提示符(开始 - 所有程序 - 附件 - 命令提示符)并输入
net helpmsg 2
它会说
The system cannot find the file specified.
或在winerror.h
中查找//
// MessageId: ERROR_FILE_NOT_FOUND
//
// MessageText:
//
// The system cannot find the file specified.
//
#define ERROR_FILE_NOT_FOUND 2L
解码 0x8019nnnn 错误
设备为 0x19 的 HResults 是 HTTP 错误。 16,384 (0x4000) 以下的代码与 HTTP 错误相同,例如 HTTP 状态 404:服务器上不存在请求的 URL 是 0x80190194 (0x194 = 404)。代码 16,384 及更高版本是特定于 BITS 的。
解码 0xDnnnnnnn 错误
从 0xD 开始的 HResult 是一个带有 NTStatus 值的 HResult。只需将引导 D 更改为 C 并将其视为 NTStatus (Hresult = NTStatus OR 10000000)。
Dos 错误代码(0x8003nnnn 错误) 代码消息
01 Invalid function number
02 File not found
03 Path not found
04 Too many open files (no handles left)
05 Access denied
06 Invalid handle
07 Memory control blocks destroyed
08 Insufficient memory
09 Invalid memory block address
0A Invalid environment
0B Invalid format
0C Invalid access mode (open mode is invalid)
0D Invalid data
0E Reserved
0F Invalid drive specified
10 Attempt to remove current directory
11 Not same device
12 No more files
13 Attempt to write on a write-protected diskette
14 Unknown unit
15 Drive not ready
16 Unknown command
17 CRC error
18 Bad request structure length
19 Seek error
1A Unknown media type
1B Sector not found
1C Printer out of paper
1D Write fault
1E Read fault
1F General failure
20 Sharing violation
21 Lock violation
22 Invalid disk change
23 FCB unavailable
24 Sharing buffer overflow
25 Reserved
26 Unable to complete file operation (DOS 4.x)
27-31 Reserved
32 Network request not supported
33 Remote computer not listening
34 Duplicate name on network
35 Network name not found
36 Network busy
37 Network device no longer exists
38 NetBIOS command limit exceeded
39 Network adapter error
3A Incorrect network response
3B Unexpected network error
3C Incompatible remote adapter
3D Print queue full
3E No space for print file
3F Print file deleted
40 Network name deleted
41 Access denied
42 Network device type incorrect
43 Network name not found
44 Network name limit exceeded
45 NetBIOS session limit exceeded
46 Temporarily paused
47 Network request not accepted
48 Print or disk redirection is paused
49-4F Reserved
50 File already exists
51 Reserved
52 Cannot make directory entry
53 Fail on INT 24
54 Too many redirections
55 Duplicate redirection
56 Invalid password
57 Invalid parameter
58 Network device fault
59 Function not supported by network (DOS 4.x)
5A Required system component not installed (DOS 4.x)
设施代码
NTStatus 设施 HResults 设施
Common status values
0x0 Null 0x0
Debugger 0x1 Rpc 0x1
Rpc_runtime 0x2 Dispatch 0x2
Rpc_stubs 0x3 Storage 0x3
Io_error_code 0x4 Itf 0x4
Various drivers 0x5-0xf Win32 0x7
Ntwin32 0x7 Windows 0x8
Ntsspi 0x9 Sspi 0x9
Terminal_server 0xa Security 0x9
Faciltiy_mui_error_code 0xb Control 0xa
Usb_error_code 0x10 Cert 0xb
Hid_error_code 0x11 Internet 0xc
Firewire_error_code 0x12 Mediaserver 0xd
Cluster_error_code 0x13 Msmq 0xe
Acpi_error_code 0x14 Setupapi 0xf
Sxs_error_code 0x15 Scard 0x10
Transaction 0x19 Complus 0x11
Commonlog 0x1a Aaf 0x12
Video 0x1b Urt 0x13
Filter_manager 0x1c Acs 0x14
Monitor 0x1d Dplay 0x15
Graphics_kernel 0x1e Umi 0x16
Driver_framework 0x20 Sxs 0x17
Fve_error_code 0x21 Windows_ce 0x18
Fwp_error_code 0x22 Http 0x19
Ndis_error_code 0x23 Usermode_commonlog 0x1a
Hypervisor 0x35 Usermode_filter_manager 0x1f
Ipsec 0x36 Backgroundcopy 0x20
Maximum_value 0x37 Configuration 0x21
State_management 0x22
Metadirectory 0x23
Windowsupdate 0x24
Directoryservice 0x25
Graphics 0x26
Shell 0x27
Tpm_services 0x28
Tpm_software 0x29
Pla 0x30
Fve 0x31
Fwp 0x32
Winrm 0x33
Ndis 0x34
Usermode_hypervisor 0x35
Cmi 0x36
Windows_defender 0x50