diff -urN a/configure.in b/configure.in
--- a/configure.in	2012-06-30 13:55:03.293615455 +0100
+++ b/configure.in	2012-06-30 13:55:21.634756095 +0100
@@ -522,6 +522,27 @@
 fi
 AC_MSG_RESULT($MACHDEP)
 
+# Windows uses ; to separate paths, everything else uses :
+AC_MSG_CHECKING(DELIM)
+DELIM=:
+if test "$MACHDEP" = "win"
+then
+	DELIM=\;
+fi
+AC_MSG_RESULT([$DELIM])
+AC_SUBST(DELIM)
+
+# MSYS make uses a 'virtual' VPATH, but getpath.c uses
+# GetModuleFileNameW (replacing \ with /). This allows the user to
+# define the 'actual 'real' value. Note, it should contain / not \,
+# which is what is returned by "pwd -W".
+AC_ARG_VAR(MSYSVPATH,
+           For MSYS, allows specifying the real VPATH. Use / not \)
+if test -z "$MSYSVPATH"; then
+    MSYSVPATH=$srcdir
+fi
+AC_SUBST(MSYSVPATH)
+
 AC_MSG_CHECKING([for init system calls])
 AC_SUBST(INITSYS)
 case $host in
@@ -2965,7 +2986,7 @@
 AC_MSG_CHECKING(MACHDEP_OBJS)
 case $host in
   *-*-mingw*)
-    extra_machdep_objs="PC/dl_nt.o PC/getpathp.o PC/import_nt.o"
+    extra_machdep_objs="PC/dl_nt.o Modules/getpath.o PC/import_nt.o"
     ;;
 esac
 if test -z "$MACHDEP_OBJS"
@@ -4170,6 +4191,28 @@
 # check for endianness
 AC_C_BIGENDIAN
 
+# REPARSE_DATA_BUFFER is in winnt.h on mingw32 and (unusably) ddk/ntifs.h on mingw64.
+case $host in
+  *-*-mingw*)
+AC_CACHE_CHECK([if struct REPARSE_DATA_BUFFER is in winnt.h],
+[ac_cv_struct_reparse_data_buffer_in_winnt_h],
+  [AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM(
+      [#include <windows.h>
+       #include <winnt.h>],
+      [REPARSE_DATA_BUFFER rdb],
+    )],
+    [ac_cv_struct_reparse_data_buffer_in_winnt_h=yes],
+    [ac_cv_struct_reparse_data_buffer_in_winnt_h=no]
+  )
+])
+if test "x${ac_cv_struct_reparse_data_buffer_in_winnt_h}" = xyes; then
+  AC_DEFINE([REPARSE_DATA_BUFFER_IN_WINNT], [], [REPARSE_DATA_BUFFER in winnt.h])
+  AC_SUBST(REPARSE_DATA_BUFFER_IN_WINNT)
+fi
+  ;;
+esac
+
 # Check whether right shifting a negative integer extends the sign bit
 # or fills with zeros (like the Cray J90, according to Tim Peters).
 AC_MSG_CHECKING(whether right shift extends the sign bit)
@@ -4706,7 +4749,8 @@
     # FIXME: why windows builds don't use PC/frozen_dllmain.o ?
     PYTHON_OBJS_FROZENMAIN=""
     # default sys.path calculations for windows platforms
-    MODULE_GETPATH=PC/getpathp.o
+    # MODULE_GETPATH=PC/getpathp.o
+    MODULE_GETPATH=Modules/getpath.o
     ;;
 esac
 
diff -urN a/Include/osdefs.h b/Include/osdefs.h
--- a/Include/osdefs.h	2012-04-10 00:07:29.000000000 +0100
+++ b/Include/osdefs.h	2012-06-30 13:55:21.636756112 +0100
@@ -10,7 +10,7 @@
 /* Mod by chrish: QNX has WATCOM, but isn't DOS */
 #if !defined(__QNX__)
 #if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2)
-#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#if (defined(PYOS_OS2) && defined(PYCC_GCC)) || defined(__MINGW32__)
 #define MAXPATHLEN 260
 #define SEP '/'
 #define ALTSEP '\\'
diff -urN a/Lib/distutils/cygwinccompiler.py b/Lib/distutils/cygwinccompiler.py
--- a/Lib/distutils/cygwinccompiler.py	2012-06-30 13:55:03.298615492 +0100
+++ b/Lib/distutils/cygwinccompiler.py	2012-06-30 13:55:21.636756112 +0100
@@ -55,6 +55,7 @@
 from distutils.file_util import write_file
 from distutils.errors import DistutilsExecError, CompileError, UnknownFileError
 from distutils import log
+from subprocess import Popen, PIPE
 
 def get_msvcr():
     """Include the appropriate MSVC runtime library if Python was built
@@ -442,7 +443,13 @@
     from distutils.spawn import find_executable
     import re
 
-    gcc_exe = find_executable('gcc')
+    gcc_exe = os.environ.get('CC') or find_executable('gcc')
+    ld_exe = find_executable('ld')
+    out = Popen(gcc_exe+' --print-prog-name ld', shell=True, stdout=PIPE).stdout
+    try:
+        ld_exe = str(out.read()).strip()
+    finally:
+        out.close()
     if gcc_exe:
         out = os.popen(gcc_exe + ' -dumpversion','r')
         out_string = out.read()
@@ -454,7 +461,6 @@
             gcc_version = None
     else:
         gcc_version = None
-    ld_exe = find_executable('ld')
     if ld_exe:
         out = os.popen(ld_exe + ' -v','r')
         out_string = out.read()
@@ -466,7 +472,7 @@
             ld_version = None
     else:
         ld_version = None
-    dllwrap_exe = find_executable('dllwrap')
+    dllwrap_exe = os.environ.get('DLLWRAP') or find_executable('dllwrap')
     if dllwrap_exe:
         out = os.popen(dllwrap_exe + ' --version','r')
         out_string = out.read()
diff -urN a/Lib/plat-generic/regen b/Lib/plat-generic/regen
--- a/Lib/plat-generic/regen	2012-04-10 00:07:30.000000000 +0100
+++ b/Lib/plat-generic/regen	2012-06-30 13:55:21.636756112 +0100
@@ -1,3 +1,9 @@
 #! /bin/sh
 set -v
-python$EXE ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h
+if [ -n $1 ]; then
+    CCINSTALL=$($1 -print-search-dirs | head -1 | cut -d' ' -f2)
+    REGENHEADER=$CCINSTALL/include/stddef.h
+else
+    REGENHEADER=/usr/include/netinet/in.h
+fi
+python$EXE ../../Tools/scripts/h2py.py -i '(u_long)' $REGENHEADER
diff -urN a/Makefile.pre.in b/Makefile.pre.in
--- a/Makefile.pre.in	2012-06-30 13:55:03.303615532 +0100
+++ b/Makefile.pre.in	2012-06-30 14:02:09.315869117 +0100
@@ -27,6 +27,7 @@
 VERSION=	@VERSION@
 srcdir=		@srcdir@
 VPATH=		@srcdir@
+MSYSVPATH=	@MSYSVPATH@
 
 CC=		@CC@
 CXX=		@CXX@
@@ -78,7 +79,8 @@
 # C flags used for building the interpreter object files
 PY_CFLAGS=	$(CFLAGS) $(CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE
 
-
+# ; on Windows otherwise :
+DELIM=		@DELIM@
 # Machine-dependent subdirectories
 MACHDEP=	@MACHDEP@
 
@@ -541,7 +543,7 @@
 		-DPREFIX='"$(prefix)"' \
 		-DEXEC_PREFIX='"$(exec_prefix)"' \
 		-DVERSION='"$(VERSION)"' \
-		-DVPATH='"$(VPATH)"' \
+		-DVPATH='"$(MSYSVPATH)"' \
 		-o $@ $(srcdir)/Modules/getpath.c
 
 # default sys.path calculations for windows platforms
@@ -838,6 +840,7 @@
 	if test -f $(LDLIBRARY); then \
 		if test -n "$(DLLLIBRARY)" ; then \
 			$(INSTALL_SHARED) $(DLLLIBRARY) $(DESTDIR)$(BINDIR); \
+			mkdir -p $(DESTDIR)$(LIBPL); $(INSTALL_SHARED) $(LDLIBRARY)  $(DESTDIR)$(LIBPL); \
 		else \
 			$(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \
 			if test $(LDLIBRARY) != $(INSTSONAME); then \
@@ -982,7 +985,7 @@
 	export PYTHONPATH; PYTHONPATH="`pwd`/Lib"; \
 	export DYLD_FRAMEWORK_PATH; DYLD_FRAMEWORK_PATH="`pwd`"; \
 	export EXE; EXE="$(BUILDEXE)"; \
-	cd $(srcdir)/Lib/$(PLATDIR); $(RUNSHARED) ./regen
+	cd $(srcdir)/Lib/$(PLATDIR); $(RUNSHARED) ./regen $(CC)
 
 python-config: $(srcdir)/Misc/python-config.in
 	# Substitution happens here, as the completely-expanded BINDIR
diff -urN a/Modules/getpath.c b/Modules/getpath.c
--- a/Modules/getpath.c	2012-04-10 00:07:34.000000000 +0100
+++ b/Modules/getpath.c	2012-06-30 13:55:21.637756119 +0100
@@ -10,6 +10,10 @@
 #include <mach-o/dyld.h>
 #endif
 
+#ifdef MS_WINDOWS
+#include <windows.h>
+#endif
+
 /* Search in some common locations for the associated Python libraries.
  *
  * Two directories must be found, the platform independent directory
@@ -128,6 +132,10 @@
 static char prefix[MAXPATHLEN+1];
 static char exec_prefix[MAXPATHLEN+1];
 static char progpath[MAXPATHLEN+1];
+#ifdef MS_WINDOWS
+static char dllpath[MAXPATHLEN+1];
+extern HANDLE PyWin_DLLhModule;
+#endif
 static char *module_search_path = NULL;
 static char lib_python[] = "lib/python" VERSION;
 
@@ -137,7 +145,7 @@
     size_t i = strlen(dir);
     while (i > 0 && dir[i] != SEP)
         --i;
-    dir[i] = '\0';
+    dir[i] = 0;
 }
 
 
@@ -208,7 +216,11 @@
 joinpath(char *buffer, char *stuff)
 {
     size_t n, k;
+#ifdef MS_WINDOWS
+    if (stuff[0] == SEP || (stuff[0] != 0 && stuff[1] == L':'))
+#else
     if (stuff[0] == SEP)
+#endif
         n = 0;
     else {
         n = strlen(buffer);
@@ -229,7 +241,11 @@
 static void
 copy_absolute(char *path, char *p)
 {
+#ifdef MS_WINDOWS
+    if (p[0] == SEP || (p[0] != 0 && p[1] == ':'))
+#else
     if (p[0] == SEP)
+#endif
         strcpy(path, p);
     else {
         if (!getcwd(path, MAXPATHLEN)) {
@@ -249,7 +265,11 @@
 {
     char buffer[MAXPATHLEN + 1];
 
+#ifdef MS_WINDOWS
+    if (path[0] == SEP || (path[0] != 0 && path[1] == L':'))
+#else
     if (path[0] == SEP)
+#endif
         return;
     copy_absolute(buffer, path);
     strcpy(path, buffer);
@@ -367,6 +387,35 @@
 }
 
 
+#ifdef MS_WINDOWS
+/* Calculates dllpath and progpath, replacing \\ with / */
+int GetWindowsModulePaths()
+{
+    int result = 0;
+    wchar_t* seps;
+    result = GetModuleFileNameW(NULL, progpath, MAXPATHLEN);
+    seps = wcschr(progpath, L'\\');
+    while(seps) {
+        *seps = L'/';
+        seps = wcschr(seps, L'\\');
+    }
+    dllpath[0] = 0;
+#ifdef Py_ENABLE_SHARED
+    if (PyWin_DLLhModule) {
+        if((GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN) > 0)) {
+            result = 1;
+            seps = wcschr(dllpath, L'\\');
+            while(seps) {
+                *seps = L'/';
+                seps = wcschr(seps, L'\\');
+            }
+        }
+    }
+#endif
+    return result;
+}
+#endif /* MS_WINDOWS */
+
 static void
 calculate_path(void)
 {
@@ -418,6 +467,10 @@
      else if(0 == _NSGetExecutablePath(progpath, &nsexeclength) && progpath[0] == SEP)
        ;
 #endif /* __APPLE__ */
+#ifdef MS_WINDOWS
+    else if(GetWindowsModulePaths()) {
+    }
+#endif /* MS_WINDOWS */
         else if (path) {
                 while (1) {
                         char *delim = strchr(path, DELIM);
@@ -445,7 +498,11 @@
         }
         else
                 progpath[0] = '\0';
+#ifdef MS_WINDOWS
+        if (progpath[0] != '\0' && progpath[0] != SEP && progpath[1] != ':')
+#else
         if (progpath[0] != SEP && progpath[0] != '\0')
+#endif
                 absolutize(progpath);
         strncpy(argv0_path, progpath, MAXPATHLEN);
         argv0_path[MAXPATHLEN] = '\0';
@@ -691,8 +748,6 @@
     return progpath;
 }
 
-
 #ifdef __cplusplus
 }
 #endif
-
diff -urN a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c	2012-06-30 13:55:03.309615577 +0100
+++ b/Modules/posixmodule.c	2012-06-30 13:55:21.638756126 +0100
@@ -2180,7 +2180,7 @@
             Py_END_ALLOW_THREADS
             /* FindNextFile sets error to ERROR_NO_MORE_FILES if
                it got to the end of the directory. */
-            if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
+            if (!result && GetLastError() != 0 && GetLastError() != ERROR_NO_MORE_FILES) {
                 Py_DECREF(d);
                 win32_error_unicode("FindNextFileW", wnamebuf);
                 FindClose(hFindFile);
@@ -2248,7 +2248,7 @@
         Py_END_ALLOW_THREADS
         /* FindNextFile sets error to ERROR_NO_MORE_FILES if
            it got to the end of the directory. */
-        if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
+        if (!result && GetLastError() != 0 && GetLastError() != ERROR_NO_MORE_FILES) {
             Py_DECREF(d);
             win32_error("FindNextFile", namebuf);
             FindClose(hFindFile);
diff -urN a/Modules/Setup.config.in b/Modules/Setup.config.in
--- a/Modules/Setup.config.in	2012-06-30 13:55:03.310615585 +0100
+++ b/Modules/Setup.config.in	2012-06-30 13:55:21.639756133 +0100
@@ -18,6 +18,9 @@
 @BUILDIN_WIN32_MODULE@operator operator.c	# operator.add() and similar goodies
 @BUILDIN_WIN32_MODULE@_locale _localemodule.c	# -lintl
 @BUILDIN_WIN32_MODULE@_winreg ../PC/_winreg.c
+@BUILDIN_WIN32_MODULE@time timemodule.c
+@BUILDIN_WIN32_MODULE@_subprocess ../PC/_subprocess.c
+@BUILDIN_WIN32_MODULE@msvcrt ../PC/msvcrtmodule.c
 
 
 # The rest of the modules previously listed in this file are built
diff -urN a/Modules/Setup.dist b/Modules/Setup.dist
--- a/Modules/Setup.dist	2012-06-30 13:55:03.311615593 +0100
+++ b/Modules/Setup.dist	2012-06-30 13:55:21.639756133 +0100
@@ -84,14 +84,14 @@
 # Empty since this is now just the runtime prefix.
 DESTPATH=
 
-# Site specific path components -- should begin with : if non-empty
+# Site specific path components -- should begin with $(DELIM) if non-empty
 SITEPATH=
 
 # Standard path components for test modules
 TESTPATH=
 
 # Path components for machine- or system-dependent modules and shared libraries
-MACHDEPPATH=:plat-$(MACHDEP)
+MACHDEPPATH=$(DELIM)plat-$(MACHDEP)
 EXTRAMACHDEPPATH=
 
 # Path component for the Tkinter-related modules
diff -urN a/Modules/socketmodule.h b/Modules/socketmodule.h
--- a/Modules/socketmodule.h	2012-06-30 13:55:03.312615601 +0100
+++ b/Modules/socketmodule.h	2012-06-30 13:55:21.639756133 +0100
@@ -28,7 +28,7 @@
  * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK.
  */
 # ifdef SIO_GET_MULTICAST_FILTER
-#  include <MSTcpIP.h> /* for SIO_RCVALL */
+#  include <mstcpip.h> /* for SIO_RCVALL */
 #  define HAVE_ADDRINFO
 #  define HAVE_SOCKADDR_STORAGE
 #  define HAVE_GETADDRINFO
diff -urN a/Parser/metagrammar.c b/Parser/metagrammar.c
--- a/Parser/metagrammar.c	2012-04-10 00:07:35.000000000 +0100
+++ b/Parser/metagrammar.c	2012-06-30 13:55:21.639756133 +0100
@@ -139,7 +139,7 @@
     {7, 0},
     {8, 0},
 };
-static grammar _PyParser_Grammar = {
+static grammar _PyParser_MetaGrammar = {
     6,
     dfas,
     {19, labels},
@@ -149,7 +149,7 @@
 grammar *
 meta_grammar(void)
 {
-    return &_PyParser_Grammar;
+    return &_PyParser_MetaGrammar;
 }
 
 grammar *
diff -urN a/Python/pythonrun.c b/Python/pythonrun.c
--- a/Python/pythonrun.c	2012-04-10 00:07:35.000000000 +0100
+++ b/Python/pythonrun.c	2012-06-30 13:55:21.640756141 +0100
@@ -18,6 +18,9 @@
 #include "eval.h"
 #include "marshal.h"
 #include "abstract.h"
+#ifdef __MINGW32__
+#include "osdefs.h"
+#endif
 
 #ifdef HAVE_SIGNAL_H
 #include <signal.h>
@@ -666,6 +669,13 @@
 void
 Py_SetProgramName(char *pn)
 {
+#ifdef __MINGW32__
+    char* seps = strchr(pn, ALTSEP);
+    while(seps) {
+        *seps = SEP;
+        seps = strchr(seps, ALTSEP);
+    }
+#endif
     if (pn && *pn)
         progname = pn;
 }
diff -urN a/setup.py b/setup.py
--- a/setup.py	2012-06-30 13:55:03.315615622 +0100
+++ b/setup.py	2012-06-30 13:55:21.641756149 +0100
@@ -923,7 +923,8 @@
                 for p in ['msvcrtmodule.c']]) )
 
             exts.append( Extension('_msi', [os.path.join(pc_srcdir, p)
-                for p in ['_msi.c']]) )
+                for p in ['_msi.c']],
+                libraries=['msi','cabinet','rpcrt4']) ) # To link with lib(msi|cabinet|rpcrt4).a
 
             exts.append( Extension('_subprocess', [os.path.join(pc_srcdir, p)
                 for p in ['_subprocess.c']]) )