c++windowscomextract-error-message

How can I obtain the error message texts for (NetworkDirect) HRESULT Status Codes that Visual Studio is showing?


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:

enter image description here

How can I access these texts in my program at runtime?


Solution

  • 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:

    [MS-ERREF]: 2.1 HRESULT

    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.