HRESULT

HRESULT (a.k.a. SCODE) is one of data types you will see when playing with COM objects.

Although data type is called result handle, it is not handle to anything. While this may seem like nitpicking, there is one very important difference in case of 64-bit systems. This value is always 32 bits in length (UInt32) while true handle would be either 32 or 64 bits (IntPtr).

Another thing that may strike as unexpected is that result of successful operation is not necessarily 0 as you may expect from your Windows API experience. This value has total of seven sub-types but in reality only three are used.

Severity

If only check whether operation was successful is needed, you can just see state of first bit (31) (SEVERITY_SUCCESS or SEVERITY_ERROR). If that bit is cleared, you are fine. In case of trouble, that bit is set:

bool IsSuccess(uint error) {
return (error & 0x80000000) != 0x80000000;
}

If you have successful operation, you usually don't care about other two fields. They are usually only handy when error occurs.

Facility

Second field is facility code that occupies bits from 16 to 26, so some bit-magic is needed:

ushort GetFacilityCode(uint error) {
return (ushort)((error & 0x07FF0000) >> 16);
}

If you get facility with number less than or equal to 8, you are pretty sure that it originated from Windows. If you have SEVERITY_ERROR and facility value is 0 (FACILITY_NULL), developer was too lazy to assign facility code.

Error code

Third field is most useful one. Bits from 0 to 15 give you real error code:

ushort GetErrorCode(uint error) {
return (ushort)(error & 0x0000FFFF);
}

In case of errors that originated somewhere in Windows API (and that is a lot of them) this will give you System error code (e.g. ERROR_FILE_NOT_FOUND). Even if error originated from some custom source, you can be almost sure that they reused it for same purpose. From this code you can pretty much deduce where problem lies.

Leave a Reply

Your email address will not be published. Required fields are marked *