I would like to convert Windows status constants to human-readable error messages, and I seem to be failing.
The following code is little helpful:
#include <Windows.h>
#include <comdef.h>
#include <iostream>
// from ndstatus.h
#define ND_ACCESS_VIOLATION ((HRESULT)0xC0000005L)
#define ND_INVALID_PARAMETER_3 ((HRESULT)0xC00000F1L)
int main() {
const HRESULT hr1 = E_FAIL;
std::cout << _com_error(hr1).ErrorMessage() << std::endl;
const HRESULT hr2 = STATUS_ACCESS_VIOLATION;
std::cout << _com_error(hr2).ErrorMessage() << std::endl;
const HRESULT hr3 = ND_ACCESS_VIOLATION;
std::cout << _com_error(hr3).ErrorMessage() << std::endl;
const HRESULT hr4 = ND_INVALID_PARAMETER_3;
std::cout << _com_error(hr4).ErrorMessage() << std::endl;
}
It prints
Unspecified error
Unknown error 0xC0000005
Unknown error 0xC0000005
Unknown error 0xC00000F1
While the first line is actually correct, the other three should work better, as I see these descriptions in the Visual Studio 2022 (v17.14.1) "Watch" window:
How can I access these texts in my program at runtime?
You can't use _com_error
for non-COM errors. E_FAIL
is a COM error, but the others are not.
Notice that E_FAIL
does not have the Reserved
bit set to 1, but the other values you showed do:
R (1 bit): Reserved. If the N bit is clear, this bit MUST be set to 0. If the N bit is set, this bit is defined by the NTSTATUS numbering space (as specified in section 2.3).
To resolve non-COM system error codes, try using std::system_error
instead, or just use FormatMessage()
directly.