July 21st, 2005

Deciphering an HRESULT

Heath Stewart
Principal Software Engineer

Aaron Stebner recently blogged about ways to find out the cause of 1935 Windows Installer errors and I wanted to provide a little more background on what an HRESULT defines.

An HRESULT in the 32-bit world and beyond is defined as a long, or a signed 32-bit integer. It is defined in, among other places, winerror.h in the Platform SDK. It defines the severity of an error, whether the error is from user code, a facility that defines where the error came from, and the actual error code. As defined in winerror.h:

//  Values are 32 bit values layed out as follows:
//
//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//  +---+-+-+-----------------------+-------------------------------+
//  |Sev|C|R|     Facility          |               Code            |
//  +---+-+-+-----------------------+-------------------------------+
//
//  where
//
//      Sev - is the severity code
//
//          00 - Success
//          01 - Informational
//          10 - Warning
//          11 - Error
//
//      C - is the Customer code flag
//
//      R - is a reserved bit
//
//      Facility - is the facility code
//
//      Code - is the facility's status code

Return codes like S_OK and S_FALSE have the values 0 and 1, respectively. S_FALSE is not treated as an error because the severity bits are 0. Return codes like E_FAIL have the error bit set to 1 (the high-order bit). The macro HRESULT_SEVERITY can help determine if the return code represents an error or not by performing a bitwise AND on the high-order bit.

A facility helps identify from where the error came. Was it a security error or an error from the Common Language Runtime (CLR)? The macro HRESULT_FACILTY can help you determine that as well. winerror.h defines the following facilities (sorted by value):

#define FACILITY_NULL                    0
#define FACILITY_RPC                     1
#define FACILITY_DISPATCH                2
#define FACILITY_STORAGE                 3
#define FACILITY_ITF                     4
#define FACILITY_WIN32                   7
#define FACILITY_WINDOWS                 8
#define FACILITY_SSPI                    9
#define FACILITY_SECURITY                9
#define FACILITY_CONTROL                 10
#define FACILITY_CERT                    11
#define FACILITY_INTERNET                12
#define FACILITY_MEDIASERVER             13
#define FACILITY_MSMQ                    14
#define FACILITY_SETUPAPI                15
#define FACILITY_SCARD                   16
#define FACILITY_COMPLUS                 17
#define FACILITY_AAF                     18
#define FACILITY_URT                     19
#define FACILITY_ACS                     20
#define FACILITY_DPLAY                   21
#define FACILITY_UMI                     22
#define FACILITY_SXS                     23
#define FACILITY_WINDOWS_CE              24
#define FACILITY_HTTP                    25
#define FACILITY_BACKGROUNDCOPY          32
#define FACILITY_CONFIGURATION           33

All facilities except for FACILITY_ITF are defined by Microsoft. FACILITY_ITF is designated for user-defined error codes returned from interface methods. Microsoft recommends that when using FACILITY_ITF you use errors in the range of 0x0200 to 0xffff.

One might be asking if the 2 high-order bits define the severity and having both set is an error, why – in hexadecimal – does the error code number start with 8 instead of C? In the days of 16-bit computing, an HRESULT was only a 16-bit signed integer while an SCODE was a 32-bit signed integer. Only the highest-order bit designated the severity. The facility was also only 4 bits instead of 11. Error codes such as E_FAIL defined as 0x80004005 are legacy SCODEs and the values have not changed. Newer error codes may set both severity bits like ERROR_AUDITING_DISABLED defined as 0xC0090001.

Hopefully this helps you to decipher error codes and at least get some idea from where the error came.

Edit: Thanks to bgrainger for pointing out the correct recommended range.

Author

Heath Stewart
Principal Software Engineer

Heath is an application architect and developer, looking to help educate others to learn professional development. Besides designing and developing applications he enjoys writing about intermediate and advanced topics. Heath also consults for deployment packages and scenarios within Microsoft and for external customers.

0 comments

Discussion are closed.