简体   繁体   中英

How to correctly use On Error Goto for different HRESULT values

I am trying to read a file. The call is from VB to CPP dll.

Here is my sample code snippet

VB CALL

  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

My CPP function:

HRESULT ReadFile(...)
{

hr= actualread(...)
if(FAILED(hr)
{
return E_FAIL // 
}

If I change E_FAIL to ERROR_FILE_NOT_FOUND VB is not logging the error message.

The E_FAIL message description is Unspecified error. Which does not help the user much.

It logs E_POINTER,E_HANDLE etc anything that starts with E_ not with ERROR_

COM specifies which values in a HRESULT are treated as errors, and which aren't. To quote from 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.

The E_ constants are designed to be used this way, and have appropriate values to ensure they get treated as errors. The ERROR_ constants are not, they are meant for a different convention for reporting errors.

As WhozCraig pointed out in the comments, there is a HRESULT_FROM_WIN32 function you can use to convert a Win32 error code to a HRESULT .

Decoding Errors

-2147220978 style numbers are 32 bit signed integers, convert to hex with calculator.

Windows errors (smallish numbers) and COM HResults (typically, but with exceptions, start with an 8 as in 0x80040154) are defined in WinError.h, except 8007nnnn where you look up the Window error number that it contains.

As a general rule Windows errors are less than 65,535 (0xFFFF). Errors starting 0x80000001 are Component Object Model (COM) HResults. Errors starting 0xC0000001 are NTStatus results. Errors starting 0xD0000001 are also NTStatus values returned in a HResult.

  • WinError - Returned from Windows API Calls

  • HResult - Returned from COM calls

  • NTStatus - Returned from kernel and some API calls also return when encountering a kernel error.

NTStatus errors (typically but not always start with an C as in 0xC0000022) are defined in NTStatus.h.

.h files are the best source because it includes the symbolic name of the error which can give clues such as the source of the error. FormatMessage doesn't give the symbolic name only the description.

You get these files by downloading the Platform SDK (it's gigabytes)

http://www.microsoft.com/en-us/download/details.aspx%3Fid%3D8279&sa=U&ei=w2IrULDDLsHFmAWbmIHoBg&ved=0CBwQFjAA&usg=AFQjCNHZn9-4f2NnuN9o3UWUsOF3wL7HBQ

If you just want the two files I have them on my skydrive so I can reference them anywhere I go.

https://skydrive.live.com/redir?resid=E2F0CE17A268A4FA!121

Note internet errors (12,000 - 12,999) are windows errors but are specified in wininet.h also available above.

There are errors defined in other .h files. But 99% are in the three above.

Structure of HResults and NTStatus Codes

The most significant bit in HResults, and the two most significant bits in NTStatus are set on error. Hence Hresults start 8 on error and NTStatus starts C on Error. The next 14 or 15 bits are reserved and some specify the facility - what area the error is in. This is the third and fourth number when reading hex. EG 0xnn07nnnn - An HResult facility code 7 is a normal Windows' error (returned from a COM program - hence it's returned as a HResult). Facility codes are defined in Winerror.h for HResults and NTStatus.h for NTStatus codes. They are different.

To Decode 0x8003nnnn Errors

HResults with facility code 3 means the HResult contains OLE Structured Storage errors (0x0 to 0xff). These are the same as Dos error codes. These don't seem to be in Windows' header files and the list of codes is at the end of this post.

To Decode 0x8004nnnn Errors

HResults with facility code 4 means the HResult contains OLE errors (0x0 to 0x1ff) while the rest of the range (0x200 onwards) is component specific errors so 20e from one component will have a different meaning to 20e from another component.

This is why the source of the error is extra important for errors above 0x80040200.

To Decode 0x8007nnnn Errors

HResults with facility code 7 means the HResult contains a Windows' error code. You have to look up the Windows' error code not the HResult.

To decode 0x80070002. The 0x means it's a hexadecimal number, the 8 means error, the first 7 means it a windows error, and the rest of the number, 2, is the actual Windows error.

To look up the error we need it in decimal format. Start Calculator (Start - All Programs - Accessories - Calculator) and choose View menu - Scientific, then View menu - Hex. Enter 2. Then View menu - Decimal. It will say 2.

Start a Command Prompt (Start - All Programs - Accessories - Command Prompt) and type

net helpmsg 2

and it will say

The system cannot find the file specified.

or look it up in winerror.h

//
// MessageId: ERROR_FILE_NOT_FOUND
//
// MessageText:
//
// The system cannot find the file specified.
//
#define ERROR_FILE_NOT_FOUND             2L

To Decode 0x8019nnnn Errors

HResults with facility 0x19 are HTTP errors. Codes under 16,384 (0x4000) are the same as HTTP errors, eg HTTP status 404: The requested URL does not exist on the server is 0x80190194 (0x194 = 404). Codes 16,384 and higher are BITS specific.

To Decode 0xDnnnnnnn Errors

HResults starting 0xD are an HResult with a NTStatus value in it. Just cange the lead D to a C and treat as an NTStatus (Hresult = NTStatus OR 10000000).

Dos Error Codes (for 0x8003nnnn errors) Code Message

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) 

Facility Codes

NTStatus Facilities HResults Facilities

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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM