--- a/win32/win32.h
+++ b/win32/win32.h
@@ -347,14 +347,30 @@
 /* Note: PERLIO_FILE_ptr/base/cnt are not actually used for GCC or <VS2015
  * since FILE_ptr/base/cnt do the same thing anyway but it doesn't hurt to
  * define them all here for completeness. */
-#define PERLIO_FILE_flag_RD _IOREAD /* 0x001 */
-#define PERLIO_FILE_flag_WR _IOWRT  /* 0x002 */
-#define PERLIO_FILE_flag_RW _IORW   /* 0x080 */
-#define PERLIO_FILE_ptr(f)  ((f)->_ptr)
-#define PERLIO_FILE_base(f) ((f)->_base)
-#define PERLIO_FILE_cnt(f)  ((f)->_cnt)
-#define PERLIO_FILE_flag(f) ((f)->_flag)
-#define PERLIO_FILE_file(f) ((f)->_file)
+
+#ifndef _STUPID_INTERNAL_STDIO_HACK
+#define _STUPID_INTERNAL_STDIO_HACK
+typedef struct
+{
+  char* _ptr;
+  char* _base;
+  int _cnt;
+  long _flags;
+  long _file;
+  int _charbuf;
+  int _bufsiz;
+  char* _tmpfname;
+} __crt_stdio_stream_data;
+#endif /* _STUPID_INTERNAL_STDIO_HACK */
+
+#define PERLIO_FILE_flag_RD 0x0001 /* _IOREAD   */
+#define PERLIO_FILE_flag_WR 0x0002 /* _IOWRITE  */
+#define PERLIO_FILE_flag_RW 0x0004 /* _IOUPDATE */
+#define PERLIO_FILE_ptr(f) (((__crt_stdio_stream_data*)(f))->_ptr)
+#define PERLIO_FILE_base(f) (((__crt_stdio_stream_data*)(f))->_base)
+#define PERLIO_FILE_cnt(f) (((__crt_stdio_stream_data*)(f))->_cnt)
+#define PERLIO_FILE_flag(f) ((int)(((__crt_stdio_stream_data*)(f))->_flags))
+#define PERLIO_FILE_file(f) (*(int*)(&((__crt_stdio_stream_data*)(f))->_file))
 
 #endif
 
@@ -636,7 +652,7 @@
  * #if above).)
  */
 #if ! (_MSC_VER < 1400 || (_MSC_VER >= 1500 && _MSC_VER <= 1700) \
-  || defined(__MINGW32__))
+  || !defined(_UCRT))
 /* size of ioinfo struct is determined at runtime */
 #  define WIN32_DYN_IOINFO_SIZE
 #endif
@@ -645,32 +661,18 @@
 /*
  * Control structure for lowio file handles
  */
+
 typedef struct {
-    intptr_t osfhnd;/* underlying OS file HANDLE */
-    char osfile;    /* attributes of file (e.g., open in text mode?) */
-    char pipech;    /* one char buffer for handles opened on pipes */
-    int lockinitflag;
-    CRITICAL_SECTION lock;
-/* this struct definition breaks ABI compatibility with
- * not using, cl.exe's native VS version specitfic CRT. */
-#  if _MSC_VER >= 1400 && _MSC_VER < 1500
-#    error "This ioinfo struct is incomplete for Visual C 2005"
-#  endif
-/* VS2005 CRT has at least 3 different definitions of this struct based on the
- * CRT DLL's build number. */
-#  if _MSC_VER >= 1500
-#    ifndef _SAFECRT_IMPL
-    /* Not used in the safecrt downlevel. We do not define them, so we cannot
-     * use them accidentally */
-    char textmode : 7;/* __IOINFO_TM_ANSI or __IOINFO_TM_UTF8 or __IOINFO_TM_UTF16LE */
-    char unicode : 1; /* Was the file opened as unicode? */
-    char pipech2[2];  /* 2 more peak ahead chars for UNICODE mode */
-    __int64 startpos;      /* File position that matches buffer start */
-    BOOL utf8translations; /* Buffer contains translations other than CRLF*/
-    char dbcsBuffer;       /* Buffer for the lead byte of dbcs when converting from dbcs to unicode */
-    BOOL dbcsBufferUsed;   /* Bool for the lead byte buffer is used or not */
-#    endif
-#  endif
+  CRITICAL_SECTION lock;
+  intptr_t osfhnd;
+  __int64 startpos;
+  unsigned char osfile;
+  char textmode;
+  char _pipe_lookahead[3];
+  uint8_t unicode : 1;
+  uint8_t utf8translations : 1;
+  uint8_t dbcsBufferUsed : 1;
+  char mbBuffer[MB_LEN_MAX];
 } ioinfo;
 #else
 typedef intptr_t ioinfo;
@@ -679,13 +681,13 @@
 /*
  * Array of arrays of control structures for lowio files.
  */
-EXTERN_C _CRTIMP ioinfo* __pioinfo[];
+EXTERN_C ioinfo* __pioinfo[128];
 
 /*
  * Definition of IOINFO_L2E, the log base 2 of the number of elements in each
  * array of ioinfo structs.
  */
-#define IOINFO_L2E	    5
+#define IOINFO_L2E	    6
 
 /*
  * Definition of IOINFO_ARRAY_ELTS, the number of elements in ioinfo array
--- a/win32/config.gc
+++ b/win32/config.gc
@@ -1073,11 +1073,11 @@
 startsh='#!/bin/sh'
 static_ext=' '
 stdchar='char'
-stdio_base='((fp)->_base)'
-stdio_bufsiz='((fp)->_cnt + (fp)->_ptr - (fp)->_base)'
-stdio_cnt='((fp)->_cnt)'
+stdio_base='(((__crt_stdio_stream_data*)(fp))->_base)'
+stdio_bufsiz='(((__crt_stdio_stream_data*)(fp))->_cnt + ((__crt_stdio_stream_data*)(fp))->_ptr - ((__crt_stdio_stream_data*)(fp))->_base)'
+stdio_cnt='(((__crt_stdio_stream_data*)(fp))->_cnt)'
 stdio_filbuf=''
-stdio_ptr='((fp)->_ptr)'
+stdio_ptr='(((__crt_stdio_stream_data*)(fp))->_ptr)'
 stdio_stream_array=''
 strerror_r_proto='0'
 strings='/usr/include/string.h'
--- a/win32/config_H.gc
+++ b/win32/config_H.gc
@@ -1066,11 +1066,27 @@
  *	This symbol is defined if using the FILE_ptr macro as an lvalue
  *	to increase the pointer by n leaves File_cnt(fp) unchanged.
  */
+
+#ifndef _STUPID_INTERNAL_STDIO_HACK
+#define _STUPID_INTERNAL_STDIO_HACK
+typedef struct
+{
+  char* _ptr;
+  char* _base;
+  int _cnt;
+  long _flags;
+  long _file;
+  int _charbuf;
+  int _bufsiz;
+  char* _tmpfname;
+} __crt_stdio_stream_data;
+#endif /* _STUPID_INTERNAL_STDIO_HACK */
+
 #define USE_STDIO_PTR 	/**/
 #ifdef USE_STDIO_PTR
-#define FILE_ptr(fp)	((fp)->_ptr)
+#define FILE_ptr(fp)	(((__crt_stdio_stream_data*)(fp))->_ptr)
 #define STDIO_PTR_LVALUE 		/**/
-#define FILE_cnt(fp)	((fp)->_cnt)
+#define FILE_cnt(fp)	(((__crt_stdio_stream_data*)(fp))->_cnt)
 #define STDIO_CNT_LVALUE 		/**/
 /*#define STDIO_PTR_LVAL_SETS_CNT	/ **/
 #define STDIO_PTR_LVAL_NOCHANGE_CNT	/**/
@@ -1098,8 +1114,8 @@
  */
 #define USE_STDIO_BASE 	/**/
 #ifdef USE_STDIO_BASE
-#define FILE_base(fp)	((fp)->_base)
-#define FILE_bufsiz(fp)	((fp)->_cnt + (fp)->_ptr - (fp)->_base)
+#define FILE_base(fp)	(((__crt_stdio_stream_data*)(fp))->_base)
+#define FILE_bufsiz(fp)	(((__crt_stdio_stream_data*)(fp))->_cnt + ((__crt_stdio_stream_data*)(fp))->_ptr - ((__crt_stdio_stream_data*)(fp))->_base)
 #endif
 
 /* DOUBLESIZE:
--- a/win32/win32sck.c
+++ b/win32/win32sck.c
@@ -60,6 +60,8 @@
 
 #ifdef WIN32_DYN_IOINFO_SIZE
 EXTERN_C Size_t w32_ioinfo_size;
+#else
+ioinfo* __pioinfo[128] = { 0 };
 #endif
 
 EXTERN_C void
--- a/dist/threads/threads.xs
+++ a/dist/threads/threads.xs
@@ -15,7 +15,7 @@
 #    define setjmp(x) _setjmp(x)
 #  endif
 #  if defined(__MINGW64__)
-#    define setjmp(x) _setjmpex((x), mingw_getsp())
+#    define setjmp(x) _setjmp((x), mingw_getsp())
 #  endif
 #endif
 #ifdef HAS_PPPORT_H
