diff --git a/src/fdlib.c b/src/fdlib.c
index 748d805cd2166449c2533040c25c03dfcd783b44..13625aa2db3c0335c0f0ce18d161f839b4d03fb8 100644
--- a/src/fdlib.c
+++ b/src/fdlib.c
@@ -99,8 +99,86 @@ static inline void libc_free(void *ptr);
 #define libc_free(PTR)	free(PTR)
 #endif
 
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
 /* _dosmaperr is internal but still exported in the dll interface. */
 __declspec(dllimport) void __cdecl _dosmaperr(unsigned long);
+#else
+/* msvcr100.dll seems to not implement _dosmaperr()... */
+#undef _dosmaperr
+#define _dosmaperr	pike_dosmaperr
+
+/* Mapping of Windows error codes to POSIX error codes. */
+static const unsigned long pike_doserrtab[][2] = {
+  {  ERROR_INVALID_FUNCTION,		EINVAL,		}, /* 1 */
+  {  ERROR_FILE_NOT_FOUND,		ENOENT,		}, /* 2 */
+  {  ERROR_PATH_NOT_FOUND,		ENOENT,		}, /* 3 */
+  {  ERROR_TOO_MANY_OPEN_FILES,		EMFILE,		}, /* 4 */
+  {  ERROR_ACCESS_DENIED,		EACCES,		}, /* 5 */
+  {  ERROR_INVALID_HANDLE,		EBADF,		}, /* 6 */
+  {  ERROR_ARENA_TRASHED,		ENOMEM,		}, /* 7 */
+  {  ERROR_NOT_ENOUGH_MEMORY,		ENOMEM,		}, /* 8 */
+  {  ERROR_INVALID_BLOCK,		ENOMEM,		}, /* 9 */
+  {  ERROR_BAD_ENVIRONMENT,		E2BIG,		}, /* 10 */
+  {  ERROR_BAD_FORMAT,			ENOEXEC,	}, /* 11 */
+  {  ERROR_INVALID_ACCESS,		EINVAL,		}, /* 12 */
+  {  ERROR_INVALID_DATA,		EINVAL,		}, /* 13 */
+  {  ERROR_INVALID_DRIVE,		ENOENT,		}, /* 15 */
+  {  ERROR_CURRENT_DIRECTORY,		EACCES,		}, /* 16 */
+  {  ERROR_NOT_SAME_DEVICE,		EXDEV,		}, /* 17 */
+  {  ERROR_NO_MORE_FILES,		ENOENT,		}, /* 18 */
+  {  ERROR_LOCK_VIOLATION,		EACCES,		}, /* 33 */
+  {  ERROR_BAD_NETPATH,			ENOENT,		}, /* 53 */
+  {  ERROR_NETWORK_ACCESS_DENIED,	EACCES,		}, /* 65 */
+  {  ERROR_BAD_NET_NAME,		ENOENT,		}, /* 67 */
+  {  ERROR_FILE_EXISTS,			EEXIST,		}, /* 80 */
+  {  ERROR_CANNOT_MAKE,			EACCES,		}, /* 82 */
+  {  ERROR_FAIL_I24,			EACCES,		}, /* 83 */
+  {  ERROR_INVALID_PARAMETER,		EINVAL,		}, /* 87 */
+  {  ERROR_NO_PROC_SLOTS,		EAGAIN,		}, /* 89 */
+  {  ERROR_DRIVE_LOCKED,		EACCES,		}, /* 108 */
+  {  ERROR_BROKEN_PIPE,			EPIPE,		}, /* 109 */
+  {  ERROR_DISK_FULL,			ENOSPC,		}, /* 112 */
+  {  ERROR_INVALID_TARGET_HANDLE,	EBADF,		}, /* 114 */
+  {  ERROR_INVALID_HANDLE,		EINVAL,		}, /* 124 */
+  {  ERROR_WAIT_NO_CHILDREN,		ECHILD,		}, /* 128 */
+  {  ERROR_CHILD_NOT_COMPLETE,		ECHILD,		}, /* 129 */
+  {  ERROR_DIRECT_ACCESS_HANDLE,	EBADF,		}, /* 130 */
+  {  ERROR_NEGATIVE_SEEK,		EINVAL,		}, /* 131 */
+  {  ERROR_SEEK_ON_DEVICE,		EACCES,		}, /* 132 */
+  {  ERROR_DIR_NOT_EMPTY,		ENOTEMPTY,	}, /* 145 */
+  {  ERROR_NOT_LOCKED,			EACCES,		}, /* 158 */
+  {  ERROR_BAD_PATHNAME,		ENOENT,		}, /* 161 */
+  {  ERROR_MAX_THRDS_REACHED,		EAGAIN,		}, /* 164 */
+  {  ERROR_LOCK_FAILED,			EACCES,		}, /* 167 */
+  {  ERROR_ALREADY_EXISTS,		EEXIST,		}, /* 183 */
+  {  ERROR_FILENAME_EXCED_RANGE,	ENOENT,		}, /* 206 */
+  {  ERROR_NESTING_NOT_ALLOWED,		EAGAIN,		}, /* 215 */
+  {  ERROR_NOT_ENOUGH_QUOTA,		ENOMEM,		}, /* 1816 */
+};
+
+static inline void _dosmaperr(unsigned long err)
+{
+  int l = 0, h = NELEM(pike_doserrtab);
+  int m;
+  while (l < h) {
+    int m = (l+h)>>1;
+    int e = pike_doserrtab[m][0];
+
+    if (e == err) {
+      errno = pike_doserrtab[m][1];
+      return;
+    }
+
+    if (e < err) {
+      l = m+1;
+    } else {
+      h = m;
+    }
+  }
+  errno = EINVAL;
+}
+
+#endif
 
 PMOD_EXPORT void set_errno_from_win32_error (unsigned long err)
 {