From 8d0ef952e247e16ff9bbb60e18fc24855b0a789d Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Mon, 5 Nov 2018 20:21:27 +0100 Subject: [PATCH] msvcp140: Add _Winerror_map implementation. Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- dlls/msvcp140/msvcp140.spec | 2 +- dlls/msvcp140/tests/msvcp140.c | 58 ++++++++++++++++++++++++++++++ dlls/msvcp90/misc.c | 65 ++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 1 deletion(-) diff --git a/dlls/msvcp140/msvcp140.spec b/dlls/msvcp140/msvcp140.spec index 296d06c059b..7c54f809a52 100644 --- a/dlls/msvcp140/msvcp140.spec +++ b/dlls/msvcp140/msvcp140.spec @@ -1669,7 +1669,7 @@ @ stub -arch=arm ?_W_Gettnames@_Locinfo@std@@QBA?AV_Timevec@2@XZ @ stub -arch=i386 ?_W_Gettnames@_Locinfo@std@@QBE?AV_Timevec@2@XZ @ stub -arch=win64 ?_W_Gettnames@_Locinfo@std@@QEBA?AV_Timevec@2@XZ -@ stub ?_Winerror_map@std@@YAHH@Z +@ cdecl ?_Winerror_map@std@@YAHH@Z(long) _Winerror_map @ cdecl -arch=win32 ?_Winerror_message@std@@YAKKPADK@Z(long ptr long) _Winerror_message @ cdecl -arch=win64 ?_Winerror_message@std@@YAKKPEADK@Z(long ptr long) _Winerror_message @ stub ?_XGetLastError@std@@YAXXZ diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c index 870573edd80..5705882c88a 100644 --- a/dlls/msvcp140/tests/msvcp140.c +++ b/dlls/msvcp140/tests/msvcp140.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #include "windef.h" @@ -192,6 +193,7 @@ static int (__cdecl *p_To_byte)(const WCHAR *src, char *dst); static int (__cdecl *p_To_wide)(const char *src, WCHAR *dst); static int (__cdecl *p_Unlink)(WCHAR const*); static ULONG (__cdecl *p__Winerror_message)(ULONG, char*, ULONG); +static int (__cdecl *p__Winerror_map)(int); static BOOLEAN (WINAPI *pCreateSymbolicLinkW)(const WCHAR *, const WCHAR *, DWORD); @@ -212,6 +214,7 @@ static BOOL init(void) SET(p__Thrd_id, "_Thrd_id"); SET(p__Task_impl_base__IsNonBlockingThread, "?_IsNonBlockingThread@_Task_impl_base@details@Concurrency@@SA_NXZ"); SET(p__ContextCallback__IsCurrentOriginSTA, "?_IsCurrentOriginSTA@_ContextCallback@details@Concurrency@@CA_NXZ"); + SET(p__Winerror_map, "?_Winerror_map@std@@YAHH@Z"); if(sizeof(void*) == 8) { /* 64-bit initialization */ SET(p_task_continuation_context_ctor, "??0task_continuation_context@Concurrency@@AEAA@XZ"); @@ -1303,6 +1306,60 @@ static void test__Winerror_message(void) ok(buf[0] == 'a', "buf = %s\n", buf); } +static void test__Winerror_map(void) +{ + static struct { + int winerr, doserr; + BOOL broken; + } tests[] = { + {ERROR_INVALID_FUNCTION, ENOSYS}, {ERROR_FILE_NOT_FOUND, ENOENT}, + {ERROR_PATH_NOT_FOUND, ENOENT}, {ERROR_TOO_MANY_OPEN_FILES, EMFILE}, + {ERROR_ACCESS_DENIED, EACCES}, {ERROR_INVALID_HANDLE, EINVAL}, + {ERROR_NOT_ENOUGH_MEMORY, ENOMEM}, {ERROR_INVALID_ACCESS, EACCES}, + {ERROR_OUTOFMEMORY, ENOMEM}, {ERROR_INVALID_DRIVE, ENODEV}, + {ERROR_CURRENT_DIRECTORY, EACCES}, {ERROR_NOT_SAME_DEVICE, EXDEV}, + {ERROR_WRITE_PROTECT, EACCES}, {ERROR_BAD_UNIT, ENODEV}, + {ERROR_NOT_READY, EAGAIN}, {ERROR_SEEK, EIO}, {ERROR_WRITE_FAULT, EIO}, + {ERROR_READ_FAULT, EIO}, {ERROR_SHARING_VIOLATION, EACCES}, + {ERROR_LOCK_VIOLATION, ENOLCK}, {ERROR_HANDLE_DISK_FULL, ENOSPC}, + {ERROR_NOT_SUPPORTED, ENOTSUP, TRUE}, {ERROR_DEV_NOT_EXIST, ENODEV}, + {ERROR_FILE_EXISTS, EEXIST}, {ERROR_CANNOT_MAKE, EACCES}, + {ERROR_INVALID_PARAMETER, EINVAL, TRUE}, {ERROR_OPEN_FAILED, EIO}, + {ERROR_BUFFER_OVERFLOW, ENAMETOOLONG}, {ERROR_DISK_FULL, ENOSPC}, + {ERROR_INVALID_NAME, EINVAL}, {ERROR_NEGATIVE_SEEK, EINVAL}, + {ERROR_BUSY_DRIVE, EBUSY}, {ERROR_DIR_NOT_EMPTY, ENOTEMPTY}, + {ERROR_BUSY, EBUSY}, {ERROR_ALREADY_EXISTS, EEXIST}, + {ERROR_LOCKED, ENOLCK}, {ERROR_DIRECTORY, EINVAL}, + {ERROR_OPERATION_ABORTED, ECANCELED}, {ERROR_NOACCESS, EACCES}, + {ERROR_CANTOPEN, EIO}, {ERROR_CANTREAD, EIO}, {ERROR_CANTWRITE, EIO}, + {ERROR_RETRY, EAGAIN}, {ERROR_OPEN_FILES, EBUSY}, + {ERROR_DEVICE_IN_USE, EBUSY}, {ERROR_REPARSE_TAG_INVALID, EINVAL, TRUE}, + {WSAEINTR, EINTR}, {WSAEBADF, EBADF}, {WSAEACCES, EACCES}, + {WSAEFAULT, EFAULT}, {WSAEINVAL, EINVAL}, {WSAEMFILE, EMFILE}, + {WSAEWOULDBLOCK, EWOULDBLOCK}, {WSAEINPROGRESS, EINPROGRESS}, + {WSAEALREADY, EALREADY}, {WSAENOTSOCK, ENOTSOCK}, + {WSAEDESTADDRREQ, EDESTADDRREQ}, {WSAEMSGSIZE, EMSGSIZE}, + {WSAEPROTOTYPE, EPROTOTYPE}, {WSAENOPROTOOPT, ENOPROTOOPT}, + {WSAEPROTONOSUPPORT, EPROTONOSUPPORT}, {WSAEOPNOTSUPP, EOPNOTSUPP}, + {WSAEAFNOSUPPORT, EAFNOSUPPORT}, {WSAEADDRINUSE, EADDRINUSE}, + {WSAEADDRNOTAVAIL, EADDRNOTAVAIL}, {WSAENETDOWN, ENETDOWN}, + {WSAENETUNREACH, ENETUNREACH}, {WSAENETRESET, ENETRESET}, + {WSAECONNABORTED, ECONNABORTED}, {WSAECONNRESET, ECONNRESET}, + {WSAENOBUFS, ENOBUFS}, {WSAEISCONN, EISCONN}, {WSAENOTCONN, ENOTCONN}, + {WSAETIMEDOUT, ETIMEDOUT}, {WSAECONNREFUSED, ECONNREFUSED}, + {WSAENAMETOOLONG, ENAMETOOLONG}, {WSAEHOSTUNREACH, EHOSTUNREACH} + }; + int i, ret; + + for(i=0; i= 140 +static struct { + int winerr; + int doserr; +} winerror_map[] = +{ + {ERROR_INVALID_FUNCTION, ENOSYS}, {ERROR_FILE_NOT_FOUND, ENOENT}, + {ERROR_PATH_NOT_FOUND, ENOENT}, {ERROR_TOO_MANY_OPEN_FILES, EMFILE}, + {ERROR_ACCESS_DENIED, EACCES}, {ERROR_INVALID_HANDLE, EINVAL}, + {ERROR_NOT_ENOUGH_MEMORY, ENOMEM}, {ERROR_INVALID_ACCESS, EACCES}, + {ERROR_OUTOFMEMORY, ENOMEM}, {ERROR_INVALID_DRIVE, ENODEV}, + {ERROR_CURRENT_DIRECTORY, EACCES}, {ERROR_NOT_SAME_DEVICE, EXDEV}, + {ERROR_WRITE_PROTECT, EACCES}, {ERROR_BAD_UNIT, ENODEV}, + {ERROR_NOT_READY, EAGAIN}, {ERROR_SEEK, EIO}, {ERROR_WRITE_FAULT, EIO}, + {ERROR_READ_FAULT, EIO}, {ERROR_SHARING_VIOLATION, EACCES}, + {ERROR_LOCK_VIOLATION, ENOLCK}, {ERROR_HANDLE_DISK_FULL, ENOSPC}, + {ERROR_NOT_SUPPORTED, ENOTSUP}, {ERROR_DEV_NOT_EXIST, ENODEV}, + {ERROR_FILE_EXISTS, EEXIST}, {ERROR_CANNOT_MAKE, EACCES}, + {ERROR_INVALID_PARAMETER, EINVAL}, {ERROR_OPEN_FAILED, EIO}, + {ERROR_BUFFER_OVERFLOW, ENAMETOOLONG}, {ERROR_DISK_FULL, ENOSPC}, + {ERROR_INVALID_NAME, EINVAL}, {ERROR_NEGATIVE_SEEK, EINVAL}, + {ERROR_BUSY_DRIVE, EBUSY}, {ERROR_DIR_NOT_EMPTY, ENOTEMPTY}, + {ERROR_BUSY, EBUSY}, {ERROR_ALREADY_EXISTS, EEXIST}, + {ERROR_LOCKED, ENOLCK}, {ERROR_DIRECTORY, EINVAL}, + {ERROR_OPERATION_ABORTED, ECANCELED}, {ERROR_NOACCESS, EACCES}, + {ERROR_CANTOPEN, EIO}, {ERROR_CANTREAD, EIO}, {ERROR_CANTWRITE, EIO}, + {ERROR_RETRY, EAGAIN}, {ERROR_OPEN_FILES, EBUSY}, + {ERROR_DEVICE_IN_USE, EBUSY}, {ERROR_REPARSE_TAG_INVALID, EINVAL}, + {WSAEINTR, EINTR}, {WSAEBADF, EBADF}, {WSAEACCES, EACCES}, + {WSAEFAULT, EFAULT}, {WSAEINVAL, EINVAL}, {WSAEMFILE, EMFILE}, + {WSAEWOULDBLOCK, EWOULDBLOCK}, {WSAEINPROGRESS, EINPROGRESS}, + {WSAEALREADY, EALREADY}, {WSAENOTSOCK, ENOTSOCK}, + {WSAEDESTADDRREQ, EDESTADDRREQ}, {WSAEMSGSIZE, EMSGSIZE}, + {WSAEPROTOTYPE, EPROTOTYPE}, {WSAENOPROTOOPT, ENOPROTOOPT}, + {WSAEPROTONOSUPPORT, EPROTONOSUPPORT}, {WSAEOPNOTSUPP, EOPNOTSUPP}, + {WSAEAFNOSUPPORT, EAFNOSUPPORT}, {WSAEADDRINUSE, EADDRINUSE}, + {WSAEADDRNOTAVAIL, EADDRNOTAVAIL}, {WSAENETDOWN, ENETDOWN}, + {WSAENETUNREACH, ENETUNREACH}, {WSAENETRESET, ENETRESET}, + {WSAECONNABORTED, ECONNABORTED}, {WSAECONNRESET, ECONNRESET}, + {WSAENOBUFS, ENOBUFS}, {WSAEISCONN, EISCONN}, {WSAENOTCONN, ENOTCONN}, + {WSAETIMEDOUT, ETIMEDOUT}, {WSAECONNREFUSED, ECONNREFUSED}, + {WSAENAMETOOLONG, ENAMETOOLONG}, {WSAEHOSTUNREACH, EHOSTUNREACH} +}; +#endif + struct __Container_proxy; typedef struct { @@ -2809,4 +2854,24 @@ ULONG __cdecl _Winerror_message(ULONG err, char *buf, ULONG size) return FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, buf, size, NULL); } + +/* ?_Winerror_map@std@@YAHH@Z */ +int __cdecl _Winerror_map(int err) +{ + int low = 0, high = ARRAY_SIZE(winerror_map) - 1, mid; + + while(low <= high) + { + mid = (low + high) / 2; + + if(err == winerror_map[mid].winerr) + return winerror_map[mid].doserr; + if(err > winerror_map[mid].winerr) + low = mid + 1; + else + high = mid - 1; + } + + return 0; +} #endif