HRESULT is the highest fidelity error code of the three big ones (WINERROR, NTSTATUS and HRESULT). Both of the other error types can be converted, without any information loss, into an HRESULT via HRESULT_FROM_WIN32 and HRESULT_FROM_NT.

HRESULT was defined as the error type for COM functions to return.

HRESULT and NTSTATUS have a similar structure but very different sets of values.
1bit holds 2 severity levels, SUCCESS, ERROR.
1bit is used to allow HRESULT_FROM_NT to store a full NTSTATUS in an HRESULT. The define for this bit is FACILITY_NT_BIT.
There are 12bits set aside for Facilities, which are used to create feature-specific error codes. Within each facility is 16bits to define codes specific to that facility.
FACILITY_NULL contains generic codes like S_OK, E_FAIL and S_FALSE.
FACILITY_WIN32 contains all the WINERROR codes.

Checking HRESULT values must be done via the SUCCEEDED(hr) or FAILED(hr) macros.

HRESULT Usage


HRESULT ApiReturningHresult(HANDLE handle)
{
if (handle == INVALID_HANDLE_VALUE) {
return E_HANDLE;
}
return S_OK;
}

HRESULT hr = S_OK;
HANDLE handle = INVALID_HANDLE_VALUE;
hr = ApiReturningHresult(handle);
if (FAILED(hr))
{
printf("ApiReturningHresult returned %x", hr);
exit();
}

Conversions to HRESULT


NTSTATUS ntstatus = STATUS_SUCCESS;
HRESULT hr = HRESULT_FROM_NT(ntstatus);

DWORD winerror = ERROR_SUCCESS;
HRESULT hr = HRESULT_FROM_WIN32(winerror);

Conversions from HRESULT


HRESULT = S_OK;
NTSTATUS ntstatus = STATUS_SUCCESS;
if (hr & FACILITY_NT_BIT)
{
ntstatus = hr & ~FACILITY_NT_BIT;
} else if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
{
ntstatus = NTSTATUS_FROM_WIN32(HRESULT_CODE(hr));
} else if (SUCCEEDED(hr))
{
ntstatus = STATUS_SUCCESS;
} else
{
ntstatus = STATUS_UNSUCCESSFUL;
}

HRESULT hr = S_OK;
DWORD winerror = ERROR_SUCCESS;
if (SUCCEEDED(hr))
{
winerror = S_OK;
} else if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
{
winerror = HRESULT_CODE(hr);
} else
{
winerror = ERROR_UNIDENTIFIED_ERROR;
}