121 lines
4.8 KiB
C
121 lines
4.8 KiB
C
/*****************************************************************************\
|
|
* *
|
|
* 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 <errno.h>
|
|
#include <stdio.h>
|
|
/* MsvcLibX library extensions */
|
|
#include "msvcDebugm.h"
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
/*---------------------------------------------------------------------------*\
|
|
* *
|
|
| 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
|
|
/* 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 */
|
|
|