diff --git a/include/share/compat.h b/include/share/compat.h
index 9c3d35e7..ee4c3e50 100644
--- a/include/share/compat.h
+++ b/include/share/compat.h
@@ -143,4 +143,14 @@
# endif
#endif /* defined _MSC_VER */
+
+/* FLAC needs to compile and work correctly on systems with a norrmal ISO C99
+ * snprintf as well as Microsoft Visual Studio which has an non-standards
+ * conformant snprint_s function.
+ *
+ * This function wraps the MS version to behave more like the the ISO version.
+ */
+
+int flac_snprintf(char *str, size_t size, const char *fmt, ...);
+
#endif /* FLAC__SHARE__COMPAT_H */
diff --git a/src/share/grabbag/Makefile.am b/src/share/grabbag/Makefile.am
index a7f2ee71..79d211ed 100644
--- a/src/share/grabbag/Makefile.am
+++ b/src/share/grabbag/Makefile.am
@@ -10,7 +10,8 @@ libgrabbag_la_SOURCES = \
file.c \
picture.c \
replaygain.c \
- seektable.c
+ seektable.c \
+ snprintf.c
EXTRA_DIST = \
Makefile.lite \
diff --git a/src/share/grabbag/grabbag_static.vcproj b/src/share/grabbag/grabbag_static.vcproj
index a950a99d..284bbb85 100644
--- a/src/share/grabbag/grabbag_static.vcproj
+++ b/src/share/grabbag/grabbag_static.vcproj
@@ -186,6 +186,10 @@
RelativePath=".\seektable.c"
>
+
+
+#endif
+
+#include
+#include
+
+#include "share/compat.h"
+
+/*
+ * FLAC needs to compile and work correctly on systems with a norrmal ISO C99
+ * snprintf as well as Microsoft Visual Studio which has an non-standards
+ * conformant snprint_s function.
+ *
+ * The important difference occurs when the resultant string (plus string
+ * terminator) would have been longer than the supplied size parameter. When
+ * this happens, ISO C's snprintf returns the length of resultant string, but
+ * does not over-write the end of the buffer. MS's snprintf_s in this case
+ * returns -1.
+ *
+ * The _MSC_VER code below attempts to modify the return code for snprintf_s
+ * to something that is more compatible with the behaviour of the ISO C version.
+ */
+
+int
+flac_snprintf(char *str, size_t size, const char *fmt, ...)
+{
+ va_list va;
+ int rc ;
+
+ va_start (va, fmt);
+
+#ifdef _MSC_VER
+ rc = vsnprintf_s (str, size, fmt, va);
+ rc = (rc > 0) ? rc : (size == 0 ? 1024 : size * 2);
+#else
+ rc = vsnprintf (str, size, fmt, va);
+#endif
+ va_end (va);
+
+ return rc;
+}