Include fixed snprintf for Windows in platform.c

Use _WIN32 to detect it rather that _MSC_VER as it turns out MSYS2 uses the
broken MS version by default too.
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 9fb870a..2445031 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -39,6 +39,10 @@
 #error "mbed TLS requires a platform with 8-bit chars"
 #endif
 
+#if defined(_WIN32) && !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_C is required on Windows"
+#endif
+
 #if defined(MBEDTLS_DEPRECATED_WARNING) && \
     !defined(__GNUC__) && !defined(__clang__)
 #error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang"
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 1fe730c..33b20c0 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -142,10 +142,7 @@
  *
  * All these define require MBEDTLS_PLATFORM_C to be defined!
  *
- * WARNING: MBEDTLS_PLATFORM_SNPRINTF_ALT is not available on Windows
- * for compatibility reasons.
- *
- * WARNING: MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as
+ * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as
  * MBEDTLS_PLATFORM_XXX_MACRO!
  *
  * Uncomment a macro to enable alternate implementation of specific base
@@ -2004,12 +2001,15 @@
  * \def MBEDTLS_PLATFORM_C
  *
  * Enable the platform abstraction layer that allows you to re-assign
- * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit()
+ * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
  *
  * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
  * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
  * above to be specified at runtime or compile time respectively.
  *
+ * \note This abstraction layer must be enabled on Windows (including MSYS2)
+ * as other module rely on it for a fixed snprintf implementation.
+ *
  * Module:  library/platform.c
  * Caller:  Most other .c files
  *
@@ -2379,6 +2379,7 @@
 //#define MBEDTLS_PLATFORM_STD_EXIT            exit /**< Default exit to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_FPRINTF      fprintf /**< Default fprintf to use, can be undefined */
 //#define MBEDTLS_PLATFORM_STD_PRINTF        printf /**< Default printf to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
 //#define MBEDTLS_PLATFORM_STD_SNPRINTF    snprintf /**< Default snprintf to use, can be undefined */
 
 /* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
@@ -2388,6 +2389,7 @@
 //#define MBEDTLS_PLATFORM_EXIT_MACRO            exit /**< Default exit macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_FPRINTF_MACRO      fprintf /**< Default fprintf macro to use, can be undefined */
 //#define MBEDTLS_PLATFORM_PRINTF_MACRO        printf /**< Default printf macro to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
 //#define MBEDTLS_PLATFORM_SNPRINTF_MACRO    snprintf /**< Default snprintf macro to use, can be undefined */
 
 /* SSL Cache options */
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index b71a09c..5dab974 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -46,8 +46,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
+#if defined(_WIN32)
+#define MBEDTLS_PLATFORM_STD_SNPRINTF   mbedtls_platform_win32_snprintf /**< Default snprintf to use  */
+#else
 #define MBEDTLS_PLATFORM_STD_SNPRINTF   snprintf /**< Default snprintf to use  */
 #endif
+#endif
 #if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
 #define MBEDTLS_PLATFORM_STD_PRINTF   printf /**< Default printf to use  */
 #endif
@@ -150,7 +154,18 @@
 
 /*
  * The function pointers for snprintf
+ *
+ * The snprintf implementation should conform to C99:
+ * - it *must* always correctly zero-terminate the buffer
+ *   (except when n == 0, then it must leave the buffer untouched)
+ * - however it is acceptable to return -1 instead of the required length when
+ *   the destination buffer is too short.
  */
+#if defined(_WIN32)
+/* For Windows (inc. MSYS2), we provide our own fixed implementation */
+int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
+#endif
+
 #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
 extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
 
diff --git a/library/platform.c b/library/platform.c
index 123267a..23dba94 100644
--- a/library/platform.c
+++ b/library/platform.c
@@ -63,6 +63,21 @@
 }
 #endif /* MBEDTLS_PLATFORM_MEMORY */
 
+#if defined(_WIN32)
+#include <stdarg.h>
+int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... )
+{
+    int ret;
+    va_list argp;
+
+    va_start( argp, fmt );
+    ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp );
+    va_end( argp );
+
+    return( ret );
+}
+#endif
+
 #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
 #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
 /*