HRESULT

The key type involved in COM error reporting is HRESULT.12. In addition, the COM Library provides a few functions and macros to help applications of any kind deal with error information. An HRESULT is a simple 32-bit value:


   typedef LONG HRESULT;

An HRESULT is divided up into an internal structure that has four fields with the following format (numbers indicate bit positions):

Field

Use

S:

(1 bit) Severity field:

0

Success. The function was successful; it behaved according to its proscribed semantics.

1

Error. The function failed due to an error condition.

R:

(2 bits) Reserved for future use; must be set to zero by present programs generating HRESULTs; present code should not take action that relies on any particular bits being set or cleared this field.

Facility:

(13 bits) Indicates which group of status codes this belongs to. New facilities must be allocated by a central coordinating body since they need to be universally unique.13. However, the need for new facility codes is very small. Most cases can and should use FACILITY_ITF. See the section "Use of FACILITY_ITF" below.

Code:

(16 bits) Describes what actually took place, error or otherwise.


COM presently defines the following facility codes:

Facility Name

Facility Value

Description

FACILITY_NULL

0

Used for broadly applicable common status codes that have no specific grouping. S_OK belongs to this facility, for example.

FACILITY_ITF

4

Used for by far the majority of result codes that are returned from an interface member function. Use of this facility indicates that the meaning of the error code is defined solely by the definition of the particular interface in question; an HRESULT with exactly the same 32-bit value returned from another interface might have a different meaning

FACILITY_RPC

1

Used for errors that result from an underlying remote procedure call implementation. In general, this specification does not explicitly document the RPC errors that can be returned from functions, though they nevertheless can be returned in situations where the interface being used is in fact remoted

FACILITY_DISPATCH

2

Used for IDispatch-interface-related status codes.

FACILITY_STORAGE

3

Used for persistent-storage-related status codes. Status codes whose code (lower 16 bits) value is in the range of DOS error codes (less than 256) have the same meaning as the corresponding DOS error.

FACILITY_WIN32

7

Used to provide a means of mapping an error code from a function in the Win32 API into an HRESULT. The semantically significant part of a Win32 error is 16 bits large.

FACILITY_WINDOWS

8

Used for additional error codes from Microsoft-defined interfaces.

FACILITY_CONTROL

10

Used for OLE Controls-related error values.


A particular HRESULT value by convention uses the following naming structure:


   <Facility>_<Sev>_<Reason>

where <Facility> is either the facility name or some other distinguishing identifier, <Sev> is a single letter, one of the set { S, E } indicating the severity (success or error), and <Reason> is a short identifier that describes the meaning of the code. Status codes from FACILITY_NULL omit the <Facility>_ prefix. For example, the status code E_NOMEMORY is the general out-of memory error. All codes have either S_ or E_ in them allowing quick visual determination if the code means success or failure.

The general "success" HRESULT is named S_OK, meaning "everything worked" as per the function specification. The value of this HRESULT is zero. In addition, as it is useful to have functions that can succeed but return Boolean results, the code S_FALSE is defined are success codes intended to mean "function worked and the result is false."


#define   S_OK      0
#define   S_FALSE      1

A list of presently-defined standard error codes and their semantics can be found in Appendix A.

From a general interface design perspective, success status codes should be used for circumstances where the consequence of "what happened" in a method invocation is most naturally understood and dealt with by client code by looking at the out-values returned from the interface function: NULL pointers, and so forth. Error status codes should in contrast be used in situations where the function has performed in a manner that would naturally require "out-of-band" processing in the client code, logic that is written to deal with situations in which the interface implementation truly did not behave in a manner under which normal client code can make normal forward progress. The distinction is an imprecise and subtle one, and indeed many existing interface definitions do not for historical reasons abide by this reasoning. However, with this approach, it becomes feasible to implement automated COM development tools that appropriately turn the error codes into exceptions as was mentioned above.

Interface functions in general take the form:


   HRESULT ISomeInteface::SomeFunction(ARG1_T arg1, ... , ARGN_T argn, RET_T * pret);

Stylistically, what would otherwise be the return value is passed as an out-value through the last argument of the function. COM development tools which map error returns into exceptions might also consider mapping the last argument of such a function containing only one out-parameter into what the programmer sees as the "return value" of the method invocation.

The COM remoting infrastructure only supports reporting of RPC-induced errors (such as communication failures) through interface member functions that return HRESULTs. For interface member functions of other return types, such as void, such errors are silently discarded. To do otherwise would, to say the least, significantly complicate local / remote transparency.