diff --git a/unix/main.c b/unix/main.c
index 3fd6113284ac54ceb7def82b20f3613ef59c2a9c..af818de087657b55334a4d996cedf7191038b574 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -394,11 +394,7 @@ int main(int argc, char **argv) {
                 return usage(argv);
             }
         } else {
-#ifdef __MINGW32__
-            char *basedir = _fullpath(NULL, argv[a], _MAX_PATH);
-#else
             char *basedir = realpath(argv[a], NULL);
-#endif
             if (basedir == NULL) {
                 fprintf(stderr, "%s: can't open file '%s': [Errno %d] ", argv[0], argv[1], errno);
                 perror("");
diff --git a/windows/Makefile b/windows/Makefile
index 2f5418886f82accaa8ca05a48192dacb5b4a28bc..351aad6f1af6ebad8a63041373df193895f418f2 100644
--- a/windows/Makefile
+++ b/windows/Makefile
@@ -30,6 +30,7 @@ endif
 SRC_C = \
 	unix/main.c \
 	unix/file.c \
+	realpath.c \
 
 OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
 
diff --git a/windows/mpconfigport.h b/windows/mpconfigport.h
index 80d8ac89b5954d73bec61da80c9d40f15041056f..d27c59cb3185a6d6f027cf6c9ac5a14678e35999 100644
--- a/windows/mpconfigport.h
+++ b/windows/mpconfigport.h
@@ -36,3 +36,5 @@ typedef const void *machine_const_ptr_t; // must be of pointer size
 extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
 #define MICROPY_EXTRA_BUILTINS \
     { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
+
+#include "realpath.h"
diff --git a/windows/realpath.c b/windows/realpath.c
new file mode 100644
index 0000000000000000000000000000000000000000..550298a7d5430cc2be103c0e3909cbc5f4be0816
--- /dev/null
+++ b/windows/realpath.c
@@ -0,0 +1,42 @@
+#include <stdlib.h>
+#include <errno.h>
+#include <io.h>
+
+#ifndef R_OK
+    #define R_OK 4
+#endif
+
+// Make sure a path only has forward slashes.
+char *to_unix_path(char *p) {
+    if (p != NULL) {
+        char *pp = p;
+        while (*pp != 0) {
+            if (*pp == '\\')
+                *pp = '/';
+            ++pp;
+        }
+    }
+    return p;
+}
+
+// Implement realpath() using _fullpath and make it use the same error codes as realpath() on unix.
+// Also have it return a path with forward slashes only as some code relies on this,
+// but _fullpath() returns backward slashes no matter what.
+char *realpath(const char *path, char *resolved_path) {
+    char *ret = NULL;
+    if (path == NULL) {
+        errno = EINVAL;
+    } else if (access(path, R_OK) == 0) {
+        ret = resolved_path;
+        if (ret == NULL)
+            ret = malloc(_MAX_PATH);
+        if (ret == NULL) {
+            errno = ENOMEM;
+        } else {
+            ret = _fullpath(ret, path, _MAX_PATH);
+            if (ret == NULL)
+                errno = EIO;
+        }
+    }
+    return to_unix_path(ret);
+}
diff --git a/windows/realpath.h b/windows/realpath.h
new file mode 100644
index 0000000000000000000000000000000000000000..77798acd57a077cfc3b0480667c66f5452283b91
--- /dev/null
+++ b/windows/realpath.h
@@ -0,0 +1,2 @@
+
+extern char *realpath(const char *path, char *resolved_path);