/*****************************************************************************\ * * * Filename err2errno.c * * * * Description: Convert a WIN32 error to a Unix errno * * * * Notes: * * * * History: * * 2014-02-17 JFL Created this module. * * 2016-10-05 JFL Fixed compatibility with Visual Studio 2003 and older. * * Removed a few useless special cases, and added EZERO case.* * Make sure the global errno is _not_ changed by this funct.* * * * Copyright 2016 Hewlett Packard Enterprise Development LP * * Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * \*****************************************************************************/ /* Microsoft C libraries include files */ #include #include /* MsvcLibX library extensions */ #include "debugm.h" #ifdef _WIN32 #include /*---------------------------------------------------------------------------*\ * * | Function: Win32ErrorToErrno | | | | Description: Convert a Win32 system error code to a Posix errno | | | | Parameters: DWORD dwError The Win32 error code | | | | Returns: The corresponding Posix errno | | | | Notes: There's no 1-to-1 correspondance between Windows and | | Posix errors. This routine attempts to convert codes for | | the most likely errors for MsvcLibX. | | Please add those you encounter, that end up in the | | default category, and incorrectly return EIO by default. | | | | Does not change errno. (Contrary to _dosmaperr, etc) | | You must set errno thereafter if desired. | | | | History: | | 2014-02-05 JFL Created this routine | | 2014-03-05 JFL Added the default call to _get_errno_from_oserr(). | | 2015-12-07 JFL Use the new error conversion routine name in the UCRT. | * * \*---------------------------------------------------------------------------*/ #if defined(_UCRT) /* Visual Studio 14 and later */ #define _get_errno_from_oserr __acrt_errno_from_os_error /* The name changed in the UCRT */ #endif #if (_MSC_VER < 1400) /* Anything older than Visual Studio 8 (= VS 2003 and older) */ #pragma message("Defining our own _get_errno_from_oserr()") extern void __cdecl _dosmaperr(unsigned long); int _get_errno_from_oserr(unsigned long dwErr) { _dosmaperr(dwErr); /* Sets errno from WIN32 error */ return errno; } #else #pragma message("Using the default " MSVCLIBX_STRINGIZE(_get_errno_from_oserr) "()") /* Equivalent function in MSVC library. Does not know about symlink errors. */ extern int __cdecl _get_errno_from_oserr(unsigned long oserrno); #endif int Win32ErrorToErrno() { DWORD dwError = GetLastError(); DEBUG_CODE({ LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); DEBUG_PRINTF(("// Win32 error %d (0x%X): %s", dwError, dwError, lpMsgBuf ? lpMsgBuf : "Unknown\n")); LocalFree( lpMsgBuf ); }); switch (dwError) { case ERROR_SUCCESS: return 0; case ERROR_PRIVILEGE_NOT_HELD: /* Not running with the SE_CREATE_SYMBOLIC_LINK_NAME privilege */ case ERROR_REPARSE_ATTRIBUTE_CONFLICT: return EACCES; case ERROR_INSUFFICIENT_BUFFER: return E2BIG; case ERROR_FILE_EXISTS: case ERROR_ALREADY_EXISTS: return EEXIST; case ERROR_WRITE_PROTECT: return EROFS; case ERROR_HANDLE_DISK_FULL: return ENOSPC; case ERROR_NOT_A_REPARSE_POINT: case ERROR_REPARSE_TAG_MISMATCH: case ERROR_INVALID_FLAGS: case ERROR_INVALID_PARAMETER: return EINVAL; case ERROR_INVALID_REPARSE_DATA: case ERROR_REPARSE_TAG_INVALID: return EBADF; /* Not supposed to happen in Posix OSs, but may happen when experimenting with junction() IOCTLs. */ case ERROR_NO_UNICODE_TRANSLATION: return EILSEQ; default: { int errno0, errno1; errno0 = errno; /* Preserve the initial errno */ errno1 = _get_errno_from_oserr(dwError); /* Let MSVC library decide. May change errno. */ errno = errno0; /* Restore the initial errno */ return errno1; } } } #endif /* _WIN32 */