diff --git a/BUILD b/BUILD
index fa9a1209899b08aa8f09f0308cfc2b55c78c6a90..237322a5e10d3e2b80d0df7168e6ff7d069e4225 100644
--- a/BUILD
+++ b/BUILD
@@ -84,6 +84,7 @@ cc_library(
     "src/core/lib/support/stack_lockfree.c",
     "src/core/lib/support/string.c",
     "src/core/lib/support/string_posix.c",
+    "src/core/lib/support/string_util_win32.c",
     "src/core/lib/support/string_win32.c",
     "src/core/lib/support/subprocess_posix.c",
     "src/core/lib/support/subprocess_windows.c",
@@ -98,6 +99,7 @@ cc_library(
     "src/core/lib/support/time_precise.c",
     "src/core/lib/support/time_win32.c",
     "src/core/lib/support/tls_pthread.c",
+    "src/core/lib/support/tmpfile_msys.c",
     "src/core/lib/support/tmpfile_posix.c",
     "src/core/lib/support/tmpfile_win32.c",
     "src/core/lib/support/wrap_memcpy.c",
@@ -1211,6 +1213,7 @@ objc_library(
     "src/core/lib/support/stack_lockfree.c",
     "src/core/lib/support/string.c",
     "src/core/lib/support/string_posix.c",
+    "src/core/lib/support/string_util_win32.c",
     "src/core/lib/support/string_win32.c",
     "src/core/lib/support/subprocess_posix.c",
     "src/core/lib/support/subprocess_windows.c",
@@ -1225,6 +1228,7 @@ objc_library(
     "src/core/lib/support/time_precise.c",
     "src/core/lib/support/time_win32.c",
     "src/core/lib/support/tls_pthread.c",
+    "src/core/lib/support/tmpfile_msys.c",
     "src/core/lib/support/tmpfile_posix.c",
     "src/core/lib/support/tmpfile_win32.c",
     "src/core/lib/support/wrap_memcpy.c",
diff --git a/Makefile b/Makefile
index 488d6f4dcec2e150f32830fdb0d9191da5d76c88..fdc523907d3222204e5020cfc7be2b7010c7246c 100644
--- a/Makefile
+++ b/Makefile
@@ -2322,6 +2322,7 @@ LIBGPR_SRC = \
     src/core/lib/support/stack_lockfree.c \
     src/core/lib/support/string.c \
     src/core/lib/support/string_posix.c \
+    src/core/lib/support/string_util_win32.c \
     src/core/lib/support/string_win32.c \
     src/core/lib/support/subprocess_posix.c \
     src/core/lib/support/subprocess_windows.c \
@@ -2336,6 +2337,7 @@ LIBGPR_SRC = \
     src/core/lib/support/time_precise.c \
     src/core/lib/support/time_win32.c \
     src/core/lib/support/tls_pthread.c \
+    src/core/lib/support/tmpfile_msys.c \
     src/core/lib/support/tmpfile_posix.c \
     src/core/lib/support/tmpfile_win32.c \
     src/core/lib/support/wrap_memcpy.c \
diff --git a/binding.gyp b/binding.gyp
index 8efc8a2b8e6493b4d9533a640f95d1a825ca96a4..492b75f8fd4c8d5aa3d78695c81735addc8643fe 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -519,6 +519,7 @@
         'src/core/lib/support/stack_lockfree.c',
         'src/core/lib/support/string.c',
         'src/core/lib/support/string_posix.c',
+        'src/core/lib/support/string_util_win32.c',
         'src/core/lib/support/string_win32.c',
         'src/core/lib/support/subprocess_posix.c',
         'src/core/lib/support/subprocess_windows.c',
@@ -533,6 +534,7 @@
         'src/core/lib/support/time_precise.c',
         'src/core/lib/support/time_win32.c',
         'src/core/lib/support/tls_pthread.c',
+        'src/core/lib/support/tmpfile_msys.c',
         'src/core/lib/support/tmpfile_posix.c',
         'src/core/lib/support/tmpfile_win32.c',
         'src/core/lib/support/wrap_memcpy.c',
diff --git a/build.yaml b/build.yaml
index a6feea507465fca4bb18a5892b08f19b61c60951..4a0663452d86a8d7261f5375c147a2c37454ea4e 100644
--- a/build.yaml
+++ b/build.yaml
@@ -103,6 +103,7 @@ filegroups:
   - src/core/lib/support/stack_lockfree.c
   - src/core/lib/support/string.c
   - src/core/lib/support/string_posix.c
+  - src/core/lib/support/string_util_win32.c
   - src/core/lib/support/string_win32.c
   - src/core/lib/support/subprocess_posix.c
   - src/core/lib/support/subprocess_windows.c
@@ -117,6 +118,7 @@ filegroups:
   - src/core/lib/support/time_precise.c
   - src/core/lib/support/time_win32.c
   - src/core/lib/support/tls_pthread.c
+  - src/core/lib/support/tmpfile_msys.c
   - src/core/lib/support/tmpfile_posix.c
   - src/core/lib/support/tmpfile_win32.c
   - src/core/lib/support/wrap_memcpy.c
diff --git a/config.m4 b/config.m4
index 7d3d899a405366e2643b7b69e5b3ee7f4118c37c..acd798741fbdfdf2c2ceca83113f114fa83f7257 100644
--- a/config.m4
+++ b/config.m4
@@ -63,6 +63,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/support/stack_lockfree.c \
     src/core/lib/support/string.c \
     src/core/lib/support/string_posix.c \
+    src/core/lib/support/string_util_win32.c \
     src/core/lib/support/string_win32.c \
     src/core/lib/support/subprocess_posix.c \
     src/core/lib/support/subprocess_windows.c \
@@ -77,6 +78,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/support/time_precise.c \
     src/core/lib/support/time_win32.c \
     src/core/lib/support/tls_pthread.c \
+    src/core/lib/support/tmpfile_msys.c \
     src/core/lib/support/tmpfile_posix.c \
     src/core/lib/support/tmpfile_win32.c \
     src/core/lib/support/wrap_memcpy.c \
diff --git a/gRPC.podspec b/gRPC.podspec
index 82c5eaac411476b990e99a81fb563645b5886dea..b3122dd272e30a34181b36f045d809d3ea9718b4 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -144,6 +144,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/support/stack_lockfree.c',
                       'src/core/lib/support/string.c',
                       'src/core/lib/support/string_posix.c',
+                      'src/core/lib/support/string_util_win32.c',
                       'src/core/lib/support/string_win32.c',
                       'src/core/lib/support/subprocess_posix.c',
                       'src/core/lib/support/subprocess_windows.c',
@@ -158,6 +159,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/support/time_precise.c',
                       'src/core/lib/support/time_win32.c',
                       'src/core/lib/support/tls_pthread.c',
+                      'src/core/lib/support/tmpfile_msys.c',
                       'src/core/lib/support/tmpfile_posix.c',
                       'src/core/lib/support/tmpfile_win32.c',
                       'src/core/lib/support/wrap_memcpy.c',
diff --git a/grpc.gemspec b/grpc.gemspec
index b8cfc4e6c4e5213f3f87fa1fc7e33e56e749e482..3e0677ebdcb5164ecca46448b2a293faf50a3fb3 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -128,6 +128,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/support/stack_lockfree.c )
   s.files += %w( src/core/lib/support/string.c )
   s.files += %w( src/core/lib/support/string_posix.c )
+  s.files += %w( src/core/lib/support/string_util_win32.c )
   s.files += %w( src/core/lib/support/string_win32.c )
   s.files += %w( src/core/lib/support/subprocess_posix.c )
   s.files += %w( src/core/lib/support/subprocess_windows.c )
@@ -142,6 +143,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/support/time_precise.c )
   s.files += %w( src/core/lib/support/time_win32.c )
   s.files += %w( src/core/lib/support/tls_pthread.c )
+  s.files += %w( src/core/lib/support/tmpfile_msys.c )
   s.files += %w( src/core/lib/support/tmpfile_posix.c )
   s.files += %w( src/core/lib/support/tmpfile_win32.c )
   s.files += %w( src/core/lib/support/wrap_memcpy.c )
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index 3242f07599be6f1cda6752011fe5551e123d0fe1..bbcb4098e3a2538b5d052a0f0945d5a95a86f1a2 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -82,28 +82,31 @@
    things.  */
 
 #if !defined(GPR_NO_AUTODETECT_PLATFORM)
+#if defined(_WIN64) || defined(WIN64) || defined(_WIN32) || defined(WIN32)
 #if defined(_WIN64) || defined(WIN64)
-#define GPR_PLATFORM_STRING "windows"
-#define GPR_WIN32 1
 #define GPR_ARCH_64 1
-#define GPR_GETPID_IN_PROCESS_H 1
-#define GPR_WINSOCK_SOCKET 1
-#define GPR_WINDOWS_SUBPROCESS 1
-#ifdef __GNUC__
-#define GPR_GCC_ATOMIC 1
-#define GPR_GCC_TLS 1
 #else
-#define GPR_WIN32_ATOMIC 1
-#define GPR_MSVC_TLS 1
+#define GPR_ARCH_32 1
 #endif
-#define GPR_WINDOWS_CRASH_HANDLER 1
-#elif defined(_WIN32) || defined(WIN32)
 #define GPR_PLATFORM_STRING "windows"
-#define GPR_ARCH_32 1
 #define GPR_WIN32 1
-#define GPR_GETPID_IN_PROCESS_H 1
 #define GPR_WINSOCK_SOCKET 1
 #define GPR_WINDOWS_SUBPROCESS 1
+#define GPR_WIN32_ENV
+#ifdef __MSYS__
+#define GPR_GETPID_IN_UNISTD_H 1
+#define GPR_MSYS_TMPFILE
+#define GPR_POSIX_LOG
+#define GPR_POSIX_STRING
+#define GPR_POSIX_TIME
+#else
+#define GPR_GETPID_IN_PROCESS_H 1
+#define GPR_WIN32_TMPFILE
+#define GPR_WIN32_LOG
+#define GPR_WINDOWS_CRASH_HANDLER 1
+#define GPR_WIN32_STRING
+#define GPR_WIN32_TIME
+#endif
 #ifdef __GNUC__
 #define GPR_GCC_ATOMIC 1
 #define GPR_GCC_TLS 1
@@ -111,7 +114,6 @@
 #define GPR_WIN32_ATOMIC 1
 #define GPR_MSVC_TLS 1
 #endif
-#define GPR_WINDOWS_CRASH_HANDLER 1
 #elif defined(ANDROID) || defined(__ANDROID__)
 #define GPR_PLATFORM_STRING "android"
 #define GPR_ANDROID 1
@@ -126,7 +128,8 @@
 #define GPR_POSIX_SOCKETADDR 1
 #define GPR_POSIX_SOCKETUTILS 1
 #define GPR_POSIX_ENV 1
-#define GPR_POSIX_FILE 1
+#define GPR_POSIX_TMPFILE 1
+#define GPR_POSIX_LOG
 #define GPR_POSIX_STRING 1
 #define GPR_POSIX_SUBPROCESS 1
 #define GPR_POSIX_SYNC 1
@@ -153,6 +156,7 @@
 #define GPR_GCC_ATOMIC 1
 #define GPR_GCC_TLS 1
 #define GPR_LINUX 1
+#define GPR_LINUX_LOG
 #define GPR_LINUX_MULTIPOLL_WITH_EPOLL 1
 #define GPR_POSIX_WAKEUP_FD 1
 #define GPR_POSIX_SOCKET 1
@@ -175,7 +179,7 @@
 #ifndef GPR_LINUX_SOCKETUTILS
 #define GPR_POSIX_SOCKETUTILS
 #endif
-#define GPR_POSIX_FILE 1
+#define GPR_POSIX_TMPFILE 1
 #define GPR_POSIX_STRING 1
 #define GPR_POSIX_SUBPROCESS 1
 #define GPR_POSIX_SYNC 1
@@ -213,7 +217,7 @@
 #define GPR_POSIX_SOCKETADDR 1
 #define GPR_POSIX_SOCKETUTILS 1
 #define GPR_POSIX_ENV 1
-#define GPR_POSIX_FILE 1
+#define GPR_POSIX_TMPFILE 1
 #define GPR_POSIX_STRING 1
 #define GPR_POSIX_SUBPROCESS 1
 #define GPR_POSIX_SYNC 1
@@ -243,7 +247,7 @@
 #define GPR_POSIX_SOCKETADDR 1
 #define GPR_POSIX_SOCKETUTILS 1
 #define GPR_POSIX_ENV 1
-#define GPR_POSIX_FILE 1
+#define GPR_POSIX_TMPFILE 1
 #define GPR_POSIX_STRING 1
 #define GPR_POSIX_SUBPROCESS 1
 #define GPR_POSIX_SYNC 1
@@ -280,7 +284,7 @@
 #define GPR_POSIX_SOCKETADDR 1
 #define GPR_POSIX_SOCKETUTILS 1
 #define GPR_POSIX_ENV 1
-#define GPR_POSIX_FILE 1
+#define GPR_POSIX_TMPFILE 1
 #define GPR_POSIX_STRING 1
 #define GPR_POSIX_SUBPROCESS 1
 #define GPR_POSIX_SYNC 1
diff --git a/package.xml b/package.xml
index 2f4c6255394a25a71ed053d7829cfc293b370ea9..b21e974c8eff8566091785119d7572dcfd47f1b1 100644
--- a/package.xml
+++ b/package.xml
@@ -131,6 +131,7 @@
     <file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/string.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/string_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/string_util_win32.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/string_win32.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/subprocess_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/subprocess_windows.c" role="src" />
@@ -145,6 +146,7 @@
     <file baseinstalldir="/" name="src/core/lib/support/time_precise.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/time_win32.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/tls_pthread.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/tmpfile_msys.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/tmpfile_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/tmpfile_win32.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/wrap_memcpy.c" role="src" />
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index 6940dec7b02201d2cbf07dbe591fd05bee488321..53f58477a4a9b9c8b08fc7373b1c772ab013a952 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -510,30 +510,17 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
 
 unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s,
                                        unsigned port_index) {
-  grpc_tcp_listener *sp;
-  for (sp = s->head; sp && port_index != 0; sp = sp->next, --port_index)
-    ;
-  if (sp) {
-    return 1;
-  } else {
-    return 0;
-  }
+  (void)s;
+  (void)port_index;
+  abort();
 }
 
 int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index,
                             unsigned fd_index) {
-  grpc_tcp_listener *sp;
-  if (fd_index != 0) {
-    /* Windows implementation has only one fd per port_index. */
-    return -1;
-  }
-  for (sp = s->head; sp && port_index != 0; sp = sp->next, --port_index)
-    ;
-  if (sp) {
-    return _open_osfhandle((intptr_t)sp->socket->socket, 0);
-  } else {
-    return -1;
-  }
+  (void)s;
+  (void)port_index;
+  (void)fd_index;
+  abort();
 }
 
 void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index 7ee689a7e46ea395dfb1f34b20d9427d95169d93..39968239334b0988444787d2ceb36b786bcb983a 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -35,6 +35,8 @@
 
 #ifdef GPR_WINSOCK_SOCKET
 
+#include <limits.h>
+
 #include "src/core/lib/iomgr/sockaddr_win32.h"
 
 #include <grpc/support/alloc.h>
@@ -51,12 +53,20 @@
 #include "src/core/lib/iomgr/tcp_client.h"
 #include "src/core/lib/iomgr/timer.h"
 
+#if defined(__MSYS__) && defined(GPR_ARCH_64)
+/* Nasty workaround for nasty bug when using the 64 bits msys compiler
+   in conjunction with Microsoft Windows headers. */
+#define GRPC_FIONBIO _IOW('f', 126, uint32_t)
+#else
+#define GRPC_FIONBIO FIONBIO
+#endif
+
 static int set_non_block(SOCKET sock) {
   int status;
-  unsigned long param = 1;
+  uint32_t param = 1;
   DWORD ret;
   status =
-      WSAIoctl(sock, FIONBIO, &param, sizeof(param), NULL, 0, &ret, NULL, NULL);
+      WSAIoctl(sock, GRPC_FIONBIO, &param, sizeof(param), NULL, 0, &ret, NULL, NULL);
   return status == 0;
 }
 
diff --git a/src/core/lib/support/env_win32.c b/src/core/lib/support/env_win32.c
index ef84c941df659196ea82f58b6311334d5128bc0a..e670e1e8d03f77a8d3c11bdb6950ee1df41c42be 100644
--- a/src/core/lib/support/env_win32.c
+++ b/src/core/lib/support/env_win32.c
@@ -33,41 +33,47 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WIN32_ENV
+
+#include <windows.h>
 
 #include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
-
-#ifdef __MINGW32__
-errno_t getenv_s(size_t *size_needed, char *buffer, size_t size,
-                 const char *varname);
-#else
-#include <stdlib.h>
-#endif
+#include "src/core/lib/support/string_win32.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
 char *gpr_getenv(const char *name) {
-  size_t size;
   char *result = NULL;
-  errno_t err;
+  DWORD size;
+  LPTSTR tresult = NULL;
+  LPTSTR tname = gpr_char_to_tchar(name);
+  DWORD ret;
 
-  err = getenv_s(&size, NULL, 0, name);
-  if (err || (size == 0)) return NULL;
-  result = gpr_malloc(size);
-  err = getenv_s(&size, result, size, name);
-  if (err) {
-    gpr_free(result);
+  ret = GetEnvironmentVariable(tname, NULL, 0);
+  if (ret == 0) return NULL;
+  size = ret * (DWORD)sizeof(TCHAR);
+  tresult = gpr_malloc(size);
+  ret = GetEnvironmentVariable(tname, tresult, size);
+  gpr_free(tname);
+  if (ret == 0) {
+    gpr_free(tresult);
     return NULL;
   }
+  result = gpr_tchar_to_char(tresult);
+  gpr_free(tresult);
   return result;
 }
 
 void gpr_setenv(const char *name, const char *value) {
-  errno_t res = _putenv_s(name, value);
-  GPR_ASSERT(res == 0);
+  LPTSTR tname = gpr_char_to_tchar(name);
+  LPTSTR tvalue = gpr_char_to_tchar(value);
+  BOOL res = SetEnvironmentVariable(tname, tvalue);
+  gpr_free(tname);
+  gpr_free(tvalue);
+  GPR_ASSERT(res);
 }
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WIN32_ENV */
diff --git a/src/core/lib/support/log_linux.c b/src/core/lib/support/log_linux.c
index ff3febb38eb142a42d5e330374eb5e3913f5ee9a..ca04c022e3fd9b81aa0d880ddce2e415c5f0580f 100644
--- a/src/core/lib/support/log_linux.c
+++ b/src/core/lib/support/log_linux.c
@@ -41,7 +41,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_LINUX
+#ifdef GPR_LINUX_LOG
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
@@ -103,4 +103,4 @@ void gpr_default_log(gpr_log_func_args *args) {
   gpr_free(prefix);
 }
 
-#endif
+#endif /* GPR_LINUX_LOG */
diff --git a/src/core/lib/support/log_win32.c b/src/core/lib/support/log_win32.c
index ba78497a0a46884bca2be0e76a398988bac11fdd..29735bd18c77f182b9b98f015cb511b7b44d1d1e 100644
--- a/src/core/lib/support/log_win32.c
+++ b/src/core/lib/support/log_win32.c
@@ -33,7 +33,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WIN32_LOG
 
 #include <stdarg.h>
 #include <stdio.h>
@@ -109,18 +109,4 @@ void gpr_default_log(gpr_log_func_args *args) {
   fflush(stderr);
 }
 
-char *gpr_format_message(int messageid) {
-  LPTSTR tmessage;
-  char *message;
-  DWORD status = FormatMessage(
-      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
-          FORMAT_MESSAGE_IGNORE_INSERTS,
-      NULL, (DWORD)messageid, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-      (LPTSTR)(&tmessage), 0, NULL);
-  if (status == 0) return gpr_strdup("Unable to retrieve error string");
-  message = gpr_tchar_to_char(tmessage);
-  LocalFree(tmessage);
-  return message;
-}
-
-#endif /* GPR_WIN32 */
+#endif /* GPR_WIN32_LOG */
diff --git a/src/core/lib/support/string_util_win32.c b/src/core/lib/support/string_util_win32.c
new file mode 100644
index 0000000000000000000000000000000000000000..fd14ce54e43664e37d31840e9ad08eb049b5f113
--- /dev/null
+++ b/src/core/lib/support/string_util_win32.c
@@ -0,0 +1,91 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Posix code for gpr snprintf support. */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_WIN32
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+#include <strsafe.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/support/string.h"
+
+#if defined UNICODE || defined _UNICODE
+LPTSTR
+gpr_char_to_tchar(LPCSTR input) {
+  LPTSTR ret;
+  int needed = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0);
+  if (needed <= 0) return NULL;
+  ret = gpr_malloc((unsigned)needed * sizeof(TCHAR));
+  MultiByteToWideChar(CP_UTF8, 0, input, -1, ret, needed);
+  return ret;
+}
+
+LPSTR
+gpr_tchar_to_char(LPCTSTR input) {
+  LPSTR ret;
+  int needed = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL);
+  if (needed <= 0) return NULL;
+  ret = gpr_malloc((unsigned)needed);
+  WideCharToMultiByte(CP_UTF8, 0, input, -1, ret, needed, NULL, NULL);
+  return ret;
+}
+#else
+char *gpr_tchar_to_char(LPTSTR input) { return gpr_strdup(input); }
+
+char *gpr_char_to_tchar(LPTSTR input) { return gpr_strdup(input); }
+#endif
+
+char *gpr_format_message(int messageid) {
+  LPTSTR tmessage;
+  char *message;
+  DWORD status = FormatMessage(
+      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+          FORMAT_MESSAGE_IGNORE_INSERTS,
+      NULL, (DWORD)messageid, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+      (LPTSTR)(&tmessage), 0, NULL);
+  if (status == 0) return gpr_strdup("Unable to retrieve error string");
+  message = gpr_tchar_to_char(tmessage);
+  LocalFree(tmessage);
+  return message;
+}
+
+#endif /* GPR_WIN32 */
diff --git a/src/core/lib/support/string_win32.c b/src/core/lib/support/string_win32.c
index a2f9857356a3413ca25518ada04cf9671aef91c0..8382cde15a46a8016e2b4ed0f3afd00171c82a26 100644
--- a/src/core/lib/support/string_win32.c
+++ b/src/core/lib/support/string_win32.c
@@ -31,23 +31,28 @@
  *
  */
 
-/* Posix code for gpr snprintf support. */
+/* Windows code for gpr snprintf support. */
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WIN32_STRING
 
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
+#include <wchar.h>
+#include <strsafe.h>
 
 #include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
 
 #include "src/core/lib/support/string.h"
 
 int gpr_asprintf(char **strp, const char *format, ...) {
   va_list args;
   int ret;
+
+  HRESULT success;
   size_t strp_buflen;
 
   /* Determine the length. */
@@ -68,9 +73,9 @@ int gpr_asprintf(char **strp, const char *format, ...) {
 
   /* Print to the buffer. */
   va_start(args, format);
-  ret = vsnprintf_s(*strp, strp_buflen, _TRUNCATE, format, args);
+  success = StringCbVPrintfA(*strp, strp_buflen, format, args);
   va_end(args);
-  if ((size_t)ret == strp_buflen - 1) {
+  if (success == S_OK) {
     return ret;
   }
 
@@ -80,30 +85,4 @@ int gpr_asprintf(char **strp, const char *format, ...) {
   return -1;
 }
 
-#if defined UNICODE || defined _UNICODE
-LPTSTR
-gpr_char_to_tchar(LPCSTR input) {
-  LPTSTR ret;
-  int needed = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0);
-  if (needed <= 0) return NULL;
-  ret = gpr_malloc((unsigned)needed * sizeof(TCHAR));
-  MultiByteToWideChar(CP_UTF8, 0, input, -1, ret, needed);
-  return ret;
-}
-
-LPSTR
-gpr_tchar_to_char(LPCTSTR input) {
-  LPSTR ret;
-  int needed = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL);
-  if (needed <= 0) return NULL;
-  ret = gpr_malloc((unsigned)needed);
-  WideCharToMultiByte(CP_UTF8, 0, input, -1, ret, needed, NULL, NULL);
-  return ret;
-}
-#else
-char *gpr_tchar_to_char(LPTSTR input) { return gpr_strdup(input); }
-
-char *gpr_char_to_tchar(LPTSTR input) { return gpr_strdup(input); }
-#endif
-
-#endif /* GPR_WIN32 */
+#endif /* GPR_WIN32_STRING */
diff --git a/src/core/lib/support/time_win32.c b/src/core/lib/support/time_win32.c
index f7acbd14a676b2935a1be201263a6597e3004e91..9e924ab3f4a38d137065dba8e9d9189c26bdc0d9 100644
--- a/src/core/lib/support/time_win32.c
+++ b/src/core/lib/support/time_win32.c
@@ -35,7 +35,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WIN32_TIME
 
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
@@ -107,4 +107,4 @@ void gpr_sleep_until(gpr_timespec until) {
   }
 }
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WIN32_TIME */
diff --git a/src/core/lib/support/tmpfile_msys.c b/src/core/lib/support/tmpfile_msys.c
new file mode 100644
index 0000000000000000000000000000000000000000..f0f803aa754df907dbb3edf7dffe4d28f06a8582
--- /dev/null
+++ b/src/core/lib/support/tmpfile_msys.c
@@ -0,0 +1,75 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_MSYS_TMPFILE
+
+#include <io.h>
+#include <stdio.h>
+#include <string.h>
+#include <tchar.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/support/string_win32.h"
+#include "src/core/lib/support/tmpfile.h"
+
+FILE *gpr_tmpfile(const char *prefix, char **tmp_filename_out) {
+  FILE *result = NULL;
+  char tmp_filename[MAX_PATH];
+  UINT success;
+
+  if (tmp_filename_out != NULL) *tmp_filename_out = NULL;
+
+  /* Generate a unique filename with our template + temporary path. */
+  success = GetTempFileNameA(".", prefix, 0, tmp_filename);
+  fprintf(stderr, "success = %d\n", success);
+  if (!success) goto end;
+
+  /* Open a file there. */
+  result = fopen(tmp_filename, "wb+");
+  fprintf(stderr, "result = %p\n", result);
+  if (result == NULL) goto end;
+
+end:
+  if (result && tmp_filename_out) {
+    *tmp_filename_out = gpr_strdup(tmp_filename);
+  }
+
+  return result;
+}
+
+#endif /* GPR_MSYS_TMPFILE */
diff --git a/src/core/lib/support/tmpfile_posix.c b/src/core/lib/support/tmpfile_posix.c
index 9e0e7ad80801d51ee6b28411cfae393c30d73994..0cd4bb6fc3cedcf2aad4548b10aa1c69627c65cd 100644
--- a/src/core/lib/support/tmpfile_posix.c
+++ b/src/core/lib/support/tmpfile_posix.c
@@ -33,7 +33,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_POSIX_FILE
+#ifdef GPR_POSIX_TMPFILE
 
 #include "src/core/lib/support/tmpfile.h"
 
@@ -82,4 +82,4 @@ end:
   return result;
 }
 
-#endif /* GPR_POSIX_FILE */
+#endif /* GPR_POSIX_TMPFILE */
diff --git a/src/core/lib/support/tmpfile_win32.c b/src/core/lib/support/tmpfile_win32.c
index 0cb2904f8deccb799bfae1b7c3838bb414b80d22..9ac73128c39d16833820ff1ff25fc6fc3e94982d 100644
--- a/src/core/lib/support/tmpfile_win32.c
+++ b/src/core/lib/support/tmpfile_win32.c
@@ -33,7 +33,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WIN32_TMPFILE
 
 #include <io.h>
 #include <stdio.h>
@@ -81,4 +81,4 @@ end:
   return result;
 }
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WIN32_TMPFILE */
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 1f7f2a196be0e27701db97049f895e677d2bf8e4..e389782b47f7e6af8cc1cd8bda0e9d56892378ca 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -57,6 +57,7 @@ CORE_SOURCE_FILES = [
   'src/core/lib/support/stack_lockfree.c',
   'src/core/lib/support/string.c',
   'src/core/lib/support/string_posix.c',
+  'src/core/lib/support/string_util_win32.c',
   'src/core/lib/support/string_win32.c',
   'src/core/lib/support/subprocess_posix.c',
   'src/core/lib/support/subprocess_windows.c',
@@ -71,6 +72,7 @@ CORE_SOURCE_FILES = [
   'src/core/lib/support/time_precise.c',
   'src/core/lib/support/time_win32.c',
   'src/core/lib/support/tls_pthread.c',
+  'src/core/lib/support/tmpfile_msys.c',
   'src/core/lib/support/tmpfile_posix.c',
   'src/core/lib/support/tmpfile_win32.c',
   'src/core/lib/support/wrap_memcpy.c',
diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c
index 2b6d3dd223c8839c471a1f5f0137c67708e6e75d..154d607ec7c545c62ebcc2ecd4e3d20ac982d257 100644
--- a/test/core/util/port_windows.c
+++ b/test/core/util/port_windows.c
@@ -51,6 +51,11 @@
 #include "src/core/lib/support/env.h"
 #include "test/core/util/port_server_client.h"
 
+#if GPR_GETPID_IN_UNISTD_H
+#include <sys/unistd.h>
+static int _getpid() { return getpid(); }
+#endif
+
 #define NUM_RANDOM_PORTS_TO_PICK 100
 
 static int *chosen_ports = NULL;
@@ -114,7 +119,7 @@ static int is_port_available(int *port, int is_tcp) {
   /* Try binding to port */
   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = INADDR_ANY;
-  addr.sin_port = htons(*port);
+  addr.sin_port = htons((u_short)*port);
   if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
     gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno));
     closesocket(fd);
@@ -127,7 +132,7 @@ static int is_port_available(int *port, int is_tcp) {
     closesocket(fd);
     return 0;
   }
-  GPR_ASSERT(alen <= sizeof(addr));
+  GPR_ASSERT(alen <= (socklen_t)sizeof(addr));
   actual_port = ntohs(addr.sin_port);
   GPR_ASSERT(actual_port > 0);
   if (*port == 0) {
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 3155a4ece6aad2e7ff40ba67520f2837e5b51e05..62468a5a61a88357b1c4ca0db07c769f8efd8b1d 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -50,7 +50,7 @@ static unsigned seed(void) { return (unsigned)getpid(); }
 
 #if GPR_GETPID_IN_PROCESS_H
 #include <process.h>
-static unsigned seed(void) { return _getpid(); }
+static unsigned seed(void) { return (unsigned)_getpid(); }
 #endif
 
 #if GPR_WINDOWS_CRASH_HANDLER
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index b131a55b5922163e8ec58a3af651430dc40ce2cb..e0d971482815c7377d49544be1e37007c80d44b9 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1167,6 +1167,7 @@ src/core/lib/support/slice_buffer.c \
 src/core/lib/support/stack_lockfree.c \
 src/core/lib/support/string.c \
 src/core/lib/support/string_posix.c \
+src/core/lib/support/string_util_win32.c \
 src/core/lib/support/string_win32.c \
 src/core/lib/support/subprocess_posix.c \
 src/core/lib/support/subprocess_windows.c \
@@ -1181,6 +1182,7 @@ src/core/lib/support/time_posix.c \
 src/core/lib/support/time_precise.c \
 src/core/lib/support/time_win32.c \
 src/core/lib/support/tls_pthread.c \
+src/core/lib/support/tmpfile_msys.c \
 src/core/lib/support/tmpfile_posix.c \
 src/core/lib/support/tmpfile_win32.c \
 src/core/lib/support/wrap_memcpy.c
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 0b68315c82a8a2ebb524dd175e91d51263b444dd..b9a004423cb8aaa7d392d48fe03b5cbea1d0f5c5 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -5429,6 +5429,7 @@
       "src/core/lib/support/string.c", 
       "src/core/lib/support/string.h", 
       "src/core/lib/support/string_posix.c", 
+      "src/core/lib/support/string_util_win32.c", 
       "src/core/lib/support/string_win32.c", 
       "src/core/lib/support/string_win32.h", 
       "src/core/lib/support/subprocess_posix.c", 
@@ -5447,6 +5448,7 @@
       "src/core/lib/support/time_win32.c", 
       "src/core/lib/support/tls_pthread.c", 
       "src/core/lib/support/tmpfile.h", 
+      "src/core/lib/support/tmpfile_msys.c", 
       "src/core/lib/support/tmpfile_posix.c", 
       "src/core/lib/support/tmpfile_win32.c", 
       "src/core/lib/support/wrap_memcpy.c"
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj
index cdb128e48effa89f1b597e814a0cb580ff8aa9fc..26195bb54171553063ee237ff3ce6cc4adcd2ace 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj
@@ -259,6 +259,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_posix.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_util_win32.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_win32.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\subprocess_posix.c">
@@ -287,6 +289,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tls_pthread.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_msys.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_posix.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_win32.c">
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
index 8af6fdd44cb474aee5883074c2846620a5568135..be15391b0925ac226e9bbdd5b69d0ea50fb6a5ab 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
@@ -82,6 +82,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_posix.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_util_win32.c">
+      <Filter>src\core\lib\support</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_win32.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
@@ -124,6 +127,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tls_pthread.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_msys.c">
+      <Filter>src\core\lib\support</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_posix.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>