Andrey Bushman
Andrey Bushman

Reputation: 12516

Why does the error code not have severity and facility code fields?

From the Windows via C/C++ book:

enter image description here

Ok, I try to get any system error code by Microsoft and to analize its fields:

HANDLE hMutex = OpenMutex(0, FALSE, _T("12345")); // some unexisting object 
if (NULL == hMutex) {
    DWORD errCode = GetLastError(); // I get 0x00000002 here
    PTSTR msg = NULL;
    LCID langId = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
    DWORD result = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, errCode, langId, (PTSTR)&msg, 0, NULL);
    wcerr << msg << endl;
    return 2;
}

My errCode value is 0x00000002, but I expected it will have the severinity field as 3 (error) and some value of the facility code field...

Why the gotten result has not the values in these fields?

Upvotes: 0

Views: 589

Answers (2)

Henri Socha
Henri Socha

Reputation: 291

If you go about 26,000 lines into winerror.h you will find the layout of the error code fields. It is different than the above table 1-2. EX: Facility is bits 26-16 and bit 26 separates Microsoft from other codes, 1024 facility codes each.

Near the layout are the definitions of SUCCEEDED(hr) and FAILED(hr). But more interestingly, just below them are definitions related to error codes sets.

HRESULT_FROM_WIN32(unsigned long x)
HRESULT_FROM_NT(x)

For example, CreateFile() might return the 16 bit error code.

#define ERROR_ACCESS_DENIED              5L

and you use HRESULT_FROM_WIN32(x) to turn it into the HRESULT

#define E_ACCESSDENIED                   _HRESULT_TYPEDEF_(0x80070005L)

Meanwhile, _open() might return its own 16 bit error code from the XENIX compatible error codes defined in errno.h.

#define EACCES          13

The basic issue/problem is that there are multiple error code sets. You can't just use HRESULT_FROM_WIN32 with every error returned. The sets overlap numerically and you need to know the API call that sourced the failure to know which error code map to use.

Finally, though COM errors are 32 bit Windows error codes, this error code format/layout did not originate with COM. They preceded COM. I would simply call them HRESULTS.

Upvotes: 1

David Heffernan
David Heffernan

Reputation: 613262

Your quoted text describes NTSTATUS error codes. These are kernel level error codes. Some documentation can be found here: Defining New NTSTATUS Values.

However, GetLastError returns Win32 error codes. These are, quite simply, different beasts from NTSTATUS codes. They do not have severity or facility codes.

MSDN says this about Win32 error codes:

Win32 error codes are 16-bit values extended to 32-bits with zero fill, and they can be returned by methods or in structures. In general, they are not vendor-extendable.

Your error code is ERROR_FILE_NOT_FOUND which clearly does not fit into the table in your answer because it has a severity of 0 meaning success.

Upvotes: 2

Related Questions