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; }
No comments:
Post a Comment