0

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?

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

7 Comments

But author the book is Jeffrey Richter, and this chapter (#1) is about the Win32 error codes...
@AndreyBushman: The book is misleading you. What David said is correct. Severities and Facilities only apply to COM HRESULT error codes, not to Win32 error codes. And GetLastError() only applies when a Win32 API function fails, unless documented otherwise. In the case of OpenMutex(), GetLastError() is only meaningful if OpenMutex() returns a NULL mutex handle, which your code is not checking for.
Actually, on second glance, that table is something similar to a COM error code, but not the same thing. But it's not a Win32 error code either.
I fixed my code: the if (NULL == hMutex) instead of the if (S_OK != errCode).
@DavidHeffernan: what the table describes is actually lower-level NT error codes, which are similar to COM HRESULT error codes with a slightly different layout for the Severity and Facility fields.
|
1

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.

1 Comment

Thank you for the clarification.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.