In Windows, is there any way to convert an errno into an HRESULT?
Asked Answered
P

2

6

I know the HRESULT_FROM_WIN32 macro to convert a Win32 error code into an HRESULT, is there any way to do the conversion starting from an errno error?

Perjured answered 10/9, 2012 at 13:38 Comment(1)
Possible duplicate of Convert errno.h error values to Win32 GetLastError() equivalentsPrimateship
N
5

In short, no.

As of http://msdn.microsoft.com/en-us/library/5814770t%28v=vs.100%29.aspx

The errno values are constants assigned to errno in the event of various error conditions.

ERRNO.H contains the definitions of the errno values. However, not all the definitions given in ERRNO.H are used in 32-bit Windows operating systems. Some of the values in ERRNO.H are present to maintain compatibility with the UNIX family of operating systems.

The errno values in a 32-bit Windows operating system are a subset of the values for errno in XENIX systems. Thus, the errno value is not necessarily the same as the actual error code returned by a system call from the Windows operating systems. To access the actual operating system error code, use the _doserrno variable, which contains this value.

Of course you can write your own function with switch-cases which will "translate" error codes.

You can see that there are about 80 errno values defined on windows.

Nubilous answered 10/9, 2012 at 13:45 Comment(2)
So, at least for the values that Windows will emit, you can get the system error code by just checking _doserrno, and you could get an HRESULT using HRESULT_FROM_WIN32(_doserrno)? Excellent.Ambidextrous
That is not actually correct. Generally errno has the CRT error and _doserrno has the win32 error, so technically HRESULT_FROM_WIN32(_doserrno) should be work. You are correct that not all errno values are used in Windows, like ENODEV is not used in Windows.Vigilant
V
2

The Windows CRT should always set both _doserrno and errno. _doserrno will have the Win32 error, and errno will have the UNIX errno value.

The Windows CRT will not set all of the errno values, like ENODEV is the first one not used.

To go from Win32 error to errno, _get_errno_from_oserr will map it. There isn't one to go the other way because the mapping is lossy.

_dosmaperr is normally used to set CRT errors and sets both globals. Sometimes the CRT sets the error manually though.

Instead of using the globals, it is considered better to use the get/set version, eg. _get_doserrno(), but the globals should work in a normal flow.

// this should work in a realistic flow like:
if (_snwprintf(buf, ARRAYSIZE(buf), L"%i", i) == -1) {
    hr = HRESULT_FROM_WIN32(_doserrno);
}

// or, this is a little more robust
unsigned long err = 0;
NTASSERT(!_get_doserrno(&err));
HRESULT hr = HRESULT_FROM_WIN32(err);
Vigilant answered 28/2, 2019 at 1:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.