Piotr Caban : msvcp140: Add _Winerror_map implementation.

Alexandre Julliard julliard at winehq.org
Sun Mar 3 13:21:29 CST 2019


Module: wine
Branch: oldstable
Commit: de1c2809f88aaa38ca098ec0fb4a737c4e4839fc
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=de1c2809f88aaa38ca098ec0fb4a737c4e4839fc

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Nov  5 20:21:27 2018 +0100

msvcp140: Add _Winerror_map implementation.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 8d0ef952e247e16ff9bbb60e18fc24855b0a789d)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 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 66c23e6..afd63f1 100644
--- a/dlls/msvcp140/msvcp140.spec
+++ b/dlls/msvcp140/msvcp140.spec
@@ -1669,7 +1669,7 @@
 @ stub -arch=arm ?_W_Gettnames at _Locinfo@std@@QBA?AV_Timevec at 2@XZ
 @ stub -arch=i386 ?_W_Gettnames at _Locinfo@std@@QBE?AV_Timevec at 2@XZ
 @ stub -arch=win64 ?_W_Gettnames at _Locinfo@std@@QEBA?AV_Timevec at 2@XZ
-@ stub ?_Winerror_map at std@@YAHH at Z
+@ cdecl ?_Winerror_map at std@@YAHH at Z(long) _Winerror_map
 @ cdecl -arch=win32 ?_Winerror_message at std@@YAKKPADK at Z(long ptr long) _Winerror_message
 @ cdecl -arch=win64 ?_Winerror_message at std@@YAKKPEADK at Z(long ptr long) _Winerror_message
 @ stub ?_XGetLastError at std@@YAXXZ
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c
index 606fb83..4be4d88 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 <errno.h>
 #include <stdio.h>
 
 #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 at _Task_impl_base@details at Concurrency@@SA_NXZ");
     SET(p__ContextCallback__IsCurrentOriginSTA, "?_IsCurrentOriginSTA at _ContextCallback@details at Concurrency@@CA_NXZ");
+    SET(p__Winerror_map, "?_Winerror_map at std@@YAHH at Z");
 
     if(sizeof(void*) == 8) { /* 64-bit initialization */
         SET(p_task_continuation_context_ctor, "??0task_continuation_context at Concurrency@@AEAA at XZ");
@@ -1304,6 +1307,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<ARRAY_SIZE(tests); i++)
+    {
+        ret = p__Winerror_map(tests[i].winerr);
+        ok(ret == tests[i].doserr || broken(tests[i].broken && !ret),
+                "_Winerror_map(%d) returned %d, expected %d\n",
+                tests[i].winerr, ret, tests[i].doserr);
+    }
+}
+
 START_TEST(msvcp140)
 {
     if(!init()) return;
@@ -1326,5 +1383,6 @@ START_TEST(msvcp140)
     test_Rename();
     test_Last_write_time();
     test__Winerror_message();
+    test__Winerror_map();
     FreeLibrary(msvcp);
 }
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index 89dfc45..2529224 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -197,6 +197,51 @@ static struct {
 };
 #endif
 
+#if _MSVCP_VER >= 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 {
@@ -2152,4 +2197,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 at std@@YAHH at 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




More information about the wine-cvs mailing list