UCRT's FILE struct and fd struct have different layouts, and their locks are different. Implementation in Wine does not match UCRT in Windows, causing ABI issues. see: https://bugs.winehq.org/show_bug.cgi?id=53960
-- v39: ucrtbase: Fix FILE _flag values. ucrtbase: Always use CRITICAL_SECTION for FILE locking. msvcrt: Don't use custom standard streams definition. ucrtbase: Add FILE structure tests. ucrtbase: Fix _iobuf struct layout. msvcp140: Use _get_stream_buffer_pointers() to access FILE internal buffers.
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcp90/ios.c | 16 +++++++++++++--- dlls/msvcp90/locale.c | 1 - dlls/msvcp90/msvcp90.h | 5 +++++ dlls/msvcp90/string.c | 1 - 4 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/dlls/msvcp90/ios.c b/dlls/msvcp90/ios.c index d81e6367878..1bf1a41cca4 100644 --- a/dlls/msvcp90/ios.c +++ b/dlls/msvcp90/ios.c @@ -17,7 +17,6 @@ */
#include <stdarg.h> -#include <stdio.h> #include <limits.h> #include <share.h>
@@ -3028,8 +3027,19 @@ void __thiscall basic_filebuf_char__Init(basic_filebuf_char *this, FILE *file, b
basic_streambuf_char__Init_empty(&this->base); if(file) - basic_streambuf_char__Init(&this->base, &file->_base, &file->_ptr, - &file->_cnt, &file->_base, &file->_ptr, &file->_cnt); + { + char **base, **ptr; + int *cnt; + +#if _MSVCP_VER >= 140 + _get_stream_buffer_pointers(file, &base, &ptr, &cnt); +#else + base = &file->_base; + ptr = &file->_ptr; + cnt = &file->_cnt; +#endif + basic_streambuf_char__Init(&this->base, base, ptr, cnt, base, ptr, cnt); + } }
/* ?_Initcvt@?$basic_filebuf@DU?$char_traits@D@std@@@std@@IAEXPAV?$codecvt@DDH@2@@Z */ diff --git a/dlls/msvcp90/locale.c b/dlls/msvcp90/locale.c index 4eaf679139c..28a0db9d3bd 100644 --- a/dlls/msvcp90/locale.c +++ b/dlls/msvcp90/locale.c @@ -24,7 +24,6 @@ #include "limits.h" #include "math.h" #include "mbctype.h" -#include "stdio.h" #include "wchar.h" #include "wctype.h" #include "uchar.h" diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h index 54c66952a60..23ce63947e5 100644 --- a/dlls/msvcp90/msvcp90.h +++ b/dlls/msvcp90/msvcp90.h @@ -17,6 +17,7 @@ */
#include "stdbool.h" +#include <stdio.h> #include "stdlib.h" #include "windef.h" #include "winbase.h" @@ -736,3 +737,7 @@ void __cdecl DECLSPEC_NORETURN _Xruntime_error(const char*); void DECLSPEC_NORETURN throw_exception(const char*); void DECLSPEC_NORETURN throw_failure(const char*); void DECLSPEC_NORETURN throw_range_error(const char*); + +#if _MSVCP_VER >= 140 +int CDECL _get_stream_buffer_pointers(FILE*,char***,char***,int**); +#endif diff --git a/dlls/msvcp90/string.c b/dlls/msvcp90/string.c index 3384069bd03..10fae252380 100644 --- a/dlls/msvcp90/string.c +++ b/dlls/msvcp90/string.c @@ -19,7 +19,6 @@ #include <stdarg.h>
#include "msvcp90.h" -#include "stdio.h"
#include "windef.h" #include "winbase.h"
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/msvcrt.h | 17 +++++++++++++++++ include/msvcrt/corecrt_wstdio.h | 4 ++++ 2 files changed, 21 insertions(+)
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index dd7fb5895a0..d35412ee6b8 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -20,6 +20,23 @@ #ifndef __WINE_MSVCRT_H #define __WINE_MSVCRT_H
+#if _MSVCR_VER >= 140 +#ifndef _FILE_DEFINED +#define _FILE_DEFINED +typedef struct _iobuf +{ + char* _ptr; + char* _base; + int _cnt; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char* _tmpfname; +} FILE; +#endif +#endif + #include <errno.h> #include <stdarg.h> #include <stdint.h> diff --git a/include/msvcrt/corecrt_wstdio.h b/include/msvcrt/corecrt_wstdio.h index 404f7345c8e..c5c9f180fd9 100644 --- a/include/msvcrt/corecrt_wstdio.h +++ b/include/msvcrt/corecrt_wstdio.h @@ -25,6 +25,9 @@ extern "C" { #include <pshpack8.h> typedef struct _iobuf { +#ifdef _UCRT + void *_Placeholder; +#else char* _ptr; int _cnt; char* _base; @@ -33,6 +36,7 @@ typedef struct _iobuf int _charbuf; int _bufsiz; char* _tmpfname; +#endif } FILE; #include <poppack.h> #endif /* _FILE_DEFINED */
From: Shengdun Wang uwgghhbcad@gmail.com
--- dlls/ucrtbase/tests/file.c | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index 76233be3fa7..9dd5eba4fcc 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -81,7 +81,60 @@ static void test_std_stream_buffering(void) ok(DeleteFileA("std_stream_test.tmp"), "DeleteFile failed\n"); }
+int CDECL _get_stream_buffer_pointers(FILE*,char***,char***,int**); +static void test_iobuf_layout(void) +{ + union + { + FILE *f; + struct + { + char* _ptr; + char* _base; + int _cnt; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char* _tmpfname; + CRITICAL_SECTION _crit; + } *iobuf; + } fp; + char *tempf, *ptr, **file_ptr, **file_base; + int cnt, r, *file_cnt; + + tempf = _tempnam(".","wne"); + fp.f = fopen(tempf, "wb"); + ok(fp.f != NULL, "fopen failed with error: %d\n", errno); + + ok(!(fp.iobuf->_flag & 0x40), "fp.iobuf->_flag = %x\n", fp.iobuf->_flag); + r = fprintf(fp.f, "%s", "init"); + ok(r == 4, "fprintf returned %d\n", r); + todo_wine ok(fp.iobuf->_flag & 0x40, "fp.iobuf->_flag = %x\n", fp.iobuf->_flag); + ok(fp.iobuf->_cnt + 4 == fp.iobuf->_bufsiz, "_cnt = %d, _bufsiz = %d\n", + fp.iobuf->_cnt, fp.iobuf->_bufsiz); + + ptr = fp.iobuf->_ptr; + cnt = fp.iobuf->_cnt; + r = fprintf(fp.f, "%s", "hello"); + ok(r == 5, "fprintf returned %d\n", r); + ok(ptr + 5 == fp.iobuf->_ptr, "fp.iobuf->_ptr = %p, expected %p\n", fp.iobuf->_ptr, ptr + 5); + ok(cnt - 5 == fp.iobuf->_cnt, "fp.iobuf->_cnt = %d, expected %d\n", fp.iobuf->_cnt, cnt - 5); + ok(fp.iobuf->_ptr + fp.iobuf->_cnt == fp.iobuf->_base + fp.iobuf->_bufsiz, + "_ptr = %p, _cnt = %d, _base = %p, _bufsiz = %d\n", + fp.iobuf->_ptr, fp.iobuf->_cnt, fp.iobuf->_base, fp.iobuf->_bufsiz); + + _get_stream_buffer_pointers(fp.f, &file_base, &file_ptr, &file_cnt); + ok(file_base == &fp.iobuf->_base, "_base = %p, expected %p\n", file_base, &fp.iobuf->_base); + ok(file_ptr == &fp.iobuf->_ptr, "_ptr = %p, expected %p\n", file_ptr, &fp.iobuf->_ptr); + ok(file_cnt == &fp.iobuf->_cnt, "_cnt = %p, expected %p\n", file_cnt, &fp.iobuf->_cnt); + + fclose(fp.f); + unlink(tempf); +} + START_TEST(file) { test_std_stream_buffering(); + test_iobuf_layout(); }
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/exit.c | 2 +- dlls/msvcrt/file.c | 56 ++++++++++++++++++++++---------------------- dlls/msvcrt/msvcrt.h | 9 ++++--- dlls/msvcrt/scanf.c | 16 ++++++------- dlls/msvcrt/scanf.h | 4 ++-- 5 files changed, 43 insertions(+), 44 deletions(-)
diff --git a/dlls/msvcrt/exit.c b/dlls/msvcrt/exit.c index cf1e7caeb06..c8db6c405da 100644 --- a/dlls/msvcrt/exit.c +++ b/dlls/msvcrt/exit.c @@ -302,7 +302,7 @@ void DECLSPEC_NORETURN CDECL _wassert(const wchar_t* str, const wchar_t* file, u DoMessageBoxW(L"Assertion failed!", text); } else - fwprintf(MSVCRT_stderr, L"Assertion failed: %ls, file %ls, line %d\n\n", str, file, line); + fwprintf(stderr, L"Assertion failed: %ls, file %ls, line %d\n\n", str, file, line);
raise(SIGABRT); _exit(3); diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 24cca6fb63e..2075d0b4288 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -3915,7 +3915,7 @@ int CDECL _fgetc_nolock(FILE* file) */ int CDECL _fgetchar(void) { - return fgetc(MSVCRT_stdin); + return fgetc(stdin); }
/********************************************************************* @@ -4047,7 +4047,7 @@ wint_t CDECL getwc(FILE* file) */ wint_t CDECL _fgetwchar(void) { - return fgetwc(MSVCRT_stdin); + return fgetwc(stdin); }
/********************************************************************* @@ -4266,7 +4266,7 @@ wint_t CDECL _fputwc_nolock(wint_t wc, FILE* file) */ wint_t CDECL _fputwchar(wint_t wc) { - return fputwc(wc, MSVCRT_stdout); + return fputwc(wc, stdout); }
/********************************************************************* @@ -4424,7 +4424,7 @@ int CDECL _fputc_nolock(int c, FILE* file) */ int CDECL _fputchar(int c) { - return fputc(c, MSVCRT_stdout); + return fputc(c, stdout); }
/********************************************************************* @@ -4839,7 +4839,7 @@ int CDECL fputws(const wchar_t *s, FILE* file) */ int CDECL getchar(void) { - return fgetc(MSVCRT_stdin); + return fgetc(stdin); }
/********************************************************************* @@ -4861,10 +4861,10 @@ char * CDECL gets_s(char *buf, size_t len) if (!MSVCRT_CHECK_PMT(buf != NULL)) return NULL; if (!MSVCRT_CHECK_PMT(len != 0)) return NULL;
- _lock_file(MSVCRT_stdin); - for(cc = _fgetc_nolock(MSVCRT_stdin); + _lock_file(stdin); + for(cc = _fgetc_nolock(stdin); len != 0 && cc != EOF && cc != '\n'; - cc = _fgetc_nolock(MSVCRT_stdin)) + cc = _fgetc_nolock(stdin)) { if (cc != '\r') { @@ -4872,7 +4872,7 @@ char * CDECL gets_s(char *buf, size_t len) len--; } } - _unlock_file(MSVCRT_stdin); + _unlock_file(stdin);
if (!len) { @@ -4908,14 +4908,14 @@ wchar_t* CDECL _getws(wchar_t* buf) wint_t cc; wchar_t* ws = buf;
- _lock_file(MSVCRT_stdin); - for (cc = _fgetwc_nolock(MSVCRT_stdin); cc != WEOF && cc != '\n'; - cc = _fgetwc_nolock(MSVCRT_stdin)) + _lock_file(stdin); + for (cc = _fgetwc_nolock(stdin); cc != WEOF && cc != '\n'; + cc = _fgetwc_nolock(stdin)) { if (cc != '\r') *buf++ = (wchar_t)cc; } - _unlock_file(MSVCRT_stdin); + _unlock_file(stdin);
if ((cc == WEOF) && (ws == buf)) { @@ -4941,7 +4941,7 @@ int CDECL putc(int c, FILE* file) */ int CDECL putchar(int c) { - return fputc(c, MSVCRT_stdout); + return fputc(c, stdout); }
/********************************************************************* @@ -4952,14 +4952,14 @@ int CDECL puts(const char *s) size_t len = strlen(s); int ret;
- _lock_file(MSVCRT_stdout); - if(_fwrite_nolock(s, sizeof(*s), len, MSVCRT_stdout) != len) { - _unlock_file(MSVCRT_stdout); + _lock_file(stdout); + if(_fwrite_nolock(s, sizeof(*s), len, stdout) != len) { + _unlock_file(stdout); return EOF; }
- ret = _fwrite_nolock("\n",1,1,MSVCRT_stdout) == 1 ? 0 : EOF; - _unlock_file(MSVCRT_stdout); + ret = _fwrite_nolock("\n",1,1,stdout) == 1 ? 0 : EOF; + _unlock_file(stdout); return ret; }
@@ -4970,11 +4970,11 @@ int CDECL _putws(const wchar_t *s) { int ret;
- _lock_file(MSVCRT_stdout); - ret = fputws(s, MSVCRT_stdout); + _lock_file(stdout); + ret = fputws(s, stdout); if(ret >= 0) - ret = _fputwc_nolock('\n', MSVCRT_stdout); - _unlock_file(MSVCRT_stdout); + ret = _fputwc_nolock('\n', stdout); + _unlock_file(stdout); return ret >= 0 ? 0 : WEOF; }
@@ -5546,7 +5546,7 @@ int CDECL _vfwprintf_p(FILE* file, const wchar_t *format, va_list valist) */ int CDECL vprintf(const char *format, va_list valist) { - return vfprintf(MSVCRT_stdout,format,valist); + return vfprintf(stdout,format,valist); }
/********************************************************************* @@ -5554,7 +5554,7 @@ int CDECL vprintf(const char *format, va_list valist) */ int CDECL vprintf_s(const char *format, va_list valist) { - return vfprintf_s(MSVCRT_stdout,format,valist); + return vfprintf_s(stdout,format,valist); }
/********************************************************************* @@ -5562,7 +5562,7 @@ int CDECL vprintf_s(const char *format, va_list valist) */ int CDECL vwprintf(const wchar_t *format, va_list valist) { - return vfwprintf(MSVCRT_stdout,format,valist); + return vfwprintf(stdout,format,valist); }
/********************************************************************* @@ -5570,7 +5570,7 @@ int CDECL vwprintf(const wchar_t *format, va_list valist) */ int CDECL vwprintf_s(const wchar_t *format, va_list valist) { - return vfwprintf_s(MSVCRT_stdout,format,valist); + return vfwprintf_s(stdout,format,valist); }
/********************************************************************* @@ -5738,7 +5738,7 @@ int WINAPIV printf(const char *format, ...) va_list valist; int res; va_start(valist, format); - res = vfprintf(MSVCRT_stdout, format, valist); + res = vfprintf(stdout, format, valist); va_end(valist); return res; } diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index d35412ee6b8..35e6e8233a1 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -301,14 +301,13 @@ extern BOOL msvcrt_create_io_inherit_block(WORD*, BYTE**); #define _RT_CRNL 252 #define _RT_BANNER 255
-extern FILE MSVCRT__iob[]; - #define MSVCRT_NO_CONSOLE_FD (-2) #define MSVCRT_NO_CONSOLE ((HANDLE)MSVCRT_NO_CONSOLE_FD)
-#define MSVCRT_stdin (MSVCRT__iob+STDIN_FILENO) -#define MSVCRT_stdout (MSVCRT__iob+STDOUT_FILENO) -#define MSVCRT_stderr (MSVCRT__iob+STDERR_FILENO) +#if _MSVCR_VER < 140 +extern FILE MSVCRT__iob[]; +#define __acrt_iob_func(idx) (MSVCRT__iob+(idx)) +#endif
/* internal file._flag flags */ #define MSVCRT__USERBUF 0x0100 diff --git a/dlls/msvcrt/scanf.c b/dlls/msvcrt/scanf.c index c8bbe15f373..c77649797ed 100644 --- a/dlls/msvcrt/scanf.c +++ b/dlls/msvcrt/scanf.c @@ -211,7 +211,7 @@ int WINAPIV scanf(const char *format, ...) int res;
va_start(valist, format); - res = vfscanf_l(MSVCRT_stdin, format, NULL, valist); + res = vfscanf_l(stdin, format, NULL, valist); va_end(valist); return res; } @@ -225,7 +225,7 @@ int WINAPIV _scanf_l(const char *format, _locale_t locale, ...) int res;
va_start(valist, locale); - res = vfscanf_l(MSVCRT_stdin, format, locale, valist); + res = vfscanf_l(stdin, format, locale, valist); va_end(valist); return res; } @@ -239,7 +239,7 @@ int WINAPIV scanf_s(const char *format, ...) int res;
va_start(valist, format); - res = vfscanf_s_l(MSVCRT_stdin, format, NULL, valist); + res = vfscanf_s_l(stdin, format, NULL, valist); va_end(valist); return res; } @@ -253,7 +253,7 @@ int WINAPIV _scanf_s_l(const char *format, _locale_t locale, ...) int res;
va_start(valist, locale); - res = vfscanf_s_l(MSVCRT_stdin, format, locale, valist); + res = vfscanf_s_l(stdin, format, locale, valist); va_end(valist); return res; } @@ -325,7 +325,7 @@ int WINAPIV wscanf(const wchar_t *format, ...) int res;
va_start(valist, format); - res = vfwscanf_l(MSVCRT_stdin, format, NULL, valist); + res = vfwscanf_l(stdin, format, NULL, valist); va_end(valist); return res; } @@ -340,7 +340,7 @@ int WINAPIV _wscanf_l(const wchar_t *format, int res;
va_start(valist, locale); - res = vfwscanf_l(MSVCRT_stdin, format, locale, valist); + res = vfwscanf_l(stdin, format, locale, valist); va_end(valist); return res; } @@ -354,7 +354,7 @@ int WINAPIV wscanf_s(const wchar_t *format, ...) int res;
va_start(valist, format); - res = vfwscanf_s_l(MSVCRT_stdin, format, NULL, valist); + res = vfwscanf_s_l(stdin, format, NULL, valist); va_end(valist); return res; } @@ -369,7 +369,7 @@ int WINAPIV _wscanf_s_l(const wchar_t *format, int res;
va_start(valist, locale); - res = vfwscanf_s_l(MSVCRT_stdin, format, locale, valist); + res = vfwscanf_s_l(stdin, format, locale, valist); va_end(valist); return res; } diff --git a/dlls/msvcrt/scanf.h b/dlls/msvcrt/scanf.h index 97ecc578760..1d7a92a9c1c 100644 --- a/dlls/msvcrt/scanf.h +++ b/dlls/msvcrt/scanf.h @@ -48,8 +48,8 @@ #define _STRTOD_NAME_(func) console_ ## func #define _GETC_(file) (consumed++, _getch()) #define _UNGETC_(nch, file) do { _ungetch(nch); consumed--; } while(0) -#define _LOCK_FILE_(file) _lock_file(MSVCRT_stdin) -#define _UNLOCK_FILE_(file) _unlock_file(MSVCRT_stdin) +#define _LOCK_FILE_(file) _lock_file(stdin) +#define _UNLOCK_FILE_(file) _unlock_file(stdin) #ifdef WIDE_SCANF #ifdef SECURE #define _FUNCTION_ static int vcwscanf_s_l(const wchar_t *format, _locale_t locale, va_list ap)
From: Shengdun Wang uwgghhbcad@gmail.com
--- dlls/msvcrt/file.c | 78 ++++++++++++++++++++++++++++---------- dlls/ucrtbase/tests/file.c | 3 ++ 2 files changed, 62 insertions(+), 19 deletions(-)
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 2075d0b4288..0bf8510c5c9 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -246,7 +246,34 @@ typedef struct { CRITICAL_SECTION crit; } file_crit;
+#if _MSVCR_VER >= 140 +file_crit MSVCRT__iob[_IOB_ENTRIES] = { 0 }; + +static FILE* iob_get_file(int i) +{ + return &MSVCRT__iob[i].file; +} + +static CRITICAL_SECTION* file_get_cs(FILE *f) +{ + return &((file_crit*)f)->crit; +} +#else FILE MSVCRT__iob[_IOB_ENTRIES] = { { 0 } }; + +static FILE* iob_get_file(int i) +{ + return &MSVCRT__iob[i]; +} + +static CRITICAL_SECTION* file_get_cs(FILE *f) +{ + if (f < iob_get_file(0) || f >= iob_get_file(_IOB_ENTRIES)) + return &((file_crit*)f)->crit; + return NULL; +} +#endif + static file_crit* MSVCRT_fstream[MSVCRT_MAX_FILES/MSVCRT_FD_BLOCK_SIZE]; static int MSVCRT_max_streams = 512, MSVCRT_stream_idx;
@@ -502,7 +529,7 @@ static inline FILE* msvcrt_get_file(int i) return NULL;
if(i < _IOB_ENTRIES) - return &MSVCRT__iob[i]; + return iob_get_file(i);
ret = MSVCRT_fstream[i/MSVCRT_FD_BLOCK_SIZE]; if(!ret) { @@ -604,10 +631,11 @@ static FILE* msvcrt_alloc_fp(void) { if (i == MSVCRT_stream_idx) { - if (file<MSVCRT__iob || file>=MSVCRT__iob+_IOB_ENTRIES) + CRITICAL_SECTION *cs = file_get_cs(file); + if (cs) { - InitializeCriticalSectionEx(&((file_crit*)file)->crit, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); - ((file_crit*)file)->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": file_crit.crit"); + InitializeCriticalSectionEx(cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); + cs->DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": file_crit.crit"); } MSVCRT_stream_idx++; } @@ -784,14 +812,22 @@ void msvcrt_init_io(void) get_ioinfo_nolock(STDOUT_FILENO)->handle, get_ioinfo_nolock(STDERR_FILENO)->handle);
- memset(MSVCRT__iob,0,3*sizeof(FILE)); for (i = 0; i < 3; i++) { + FILE *f = iob_get_file(i); + CRITICAL_SECTION *cs = file_get_cs(f); + /* FILE structs for stdin/out/err are static and never deleted */ - MSVCRT__iob[i]._file = get_ioinfo_nolock(i)->handle == MSVCRT_NO_CONSOLE ? + f->_file = get_ioinfo_nolock(i)->handle == MSVCRT_NO_CONSOLE ? MSVCRT_NO_CONSOLE_FD : i; - MSVCRT__iob[i]._tmpfname = NULL; - MSVCRT__iob[i]._flag = (i == 0) ? _IOREAD : _IOWRT; + f->_tmpfname = NULL; + f->_flag = (i == 0) ? _IOREAD : _IOWRT; + + if (cs) + { + InitializeCriticalSectionEx(cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); + cs->DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": file_crit.crit"); + } } MSVCRT_stream_idx = 3; } @@ -936,7 +972,7 @@ static int msvcrt_int_to_base32_w(int num, wchar_t *str) #undef __iob_func FILE * CDECL __iob_func(void) { - return &MSVCRT__iob[0]; + return iob_get_file(0); }
#if _MSVCR_VER >= 140 @@ -945,7 +981,7 @@ FILE * CDECL __iob_func(void) */ FILE * CDECL __acrt_iob_func(unsigned idx) { - return &MSVCRT__iob[idx]; + return iob_get_file(idx); } #endif
@@ -1390,10 +1426,12 @@ void msvcrt_free_io(void) for(j=0; j<MSVCRT_stream_idx; j++) { FILE *file = msvcrt_get_file(j); - if(file<MSVCRT__iob || file>=MSVCRT__iob+_IOB_ENTRIES) + CRITICAL_SECTION *cs = file_get_cs(file); + + if(cs) { - ((file_crit*)file)->crit.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&((file_crit*)file)->crit); + cs->DebugInfo->Spare[0] = 0; + DeleteCriticalSection(cs); } }
@@ -1461,10 +1499,11 @@ __msvcrt_long CDECL _lseek(int fd, __msvcrt_long offset, int whence) */ void CDECL _lock_file(FILE *file) { - if(file>=MSVCRT__iob && file<MSVCRT__iob+_IOB_ENTRIES) - _lock(_STREAM_LOCKS+(file-MSVCRT__iob)); + CRITICAL_SECTION *cs = file_get_cs(file); + if (!cs) + _lock(_STREAM_LOCKS + (file - iob_get_file(0))); else - EnterCriticalSection(&((file_crit*)file)->crit); + EnterCriticalSection(cs); }
/********************************************************************* @@ -1472,10 +1511,11 @@ void CDECL _lock_file(FILE *file) */ void CDECL _unlock_file(FILE *file) { - if(file>=MSVCRT__iob && file<MSVCRT__iob+_IOB_ENTRIES) - _unlock(_STREAM_LOCKS+(file-MSVCRT__iob)); + CRITICAL_SECTION *cs = file_get_cs(file); + if (!cs) + _unlock(_STREAM_LOCKS + (file - iob_get_file(0))); else - LeaveCriticalSection(&((file_crit*)file)->crit); + LeaveCriticalSection(cs); }
/********************************************************************* diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index 9dd5eba4fcc..c36ea51e825 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -129,6 +129,9 @@ static void test_iobuf_layout(void) ok(file_ptr == &fp.iobuf->_ptr, "_ptr = %p, expected %p\n", file_ptr, &fp.iobuf->_ptr); ok(file_cnt == &fp.iobuf->_cnt, "_cnt = %p, expected %p\n", file_cnt, &fp.iobuf->_cnt);
+ ok(TryEnterCriticalSection(&fp.iobuf->_crit), "TryEnterCriticalSection section returned FALSE\n"); + LeaveCriticalSection(&fp.iobuf->_crit); + fclose(fp.f); unlink(tempf); }
From: Shengdun Wang uwgghhbcad@gmail.com
--- dlls/msvcrt/msvcrt.h | 8 ++++++++ dlls/ucrtbase/tests/file.c | 2 +- include/msvcrt/stdio.h | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 35e6e8233a1..e95b824f3f3 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -34,6 +34,14 @@ typedef struct _iobuf int _bufsiz; char* _tmpfname; } FILE; + +#define _IOREAD 0x0001 +#define _IOWRT 0x0002 +#define _IORW 0x0004 +#define _IOEOF 0x0008 +#define _IOERR 0x0010 +#define _IOMYBUF 0x0040 +#define _IOSTRG 0x1000 #endif #endif
diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index c36ea51e825..e739934de02 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -110,7 +110,7 @@ static void test_iobuf_layout(void) ok(!(fp.iobuf->_flag & 0x40), "fp.iobuf->_flag = %x\n", fp.iobuf->_flag); r = fprintf(fp.f, "%s", "init"); ok(r == 4, "fprintf returned %d\n", r); - todo_wine ok(fp.iobuf->_flag & 0x40, "fp.iobuf->_flag = %x\n", fp.iobuf->_flag); + ok(fp.iobuf->_flag & 0x40, "fp.iobuf->_flag = %x\n", fp.iobuf->_flag); ok(fp.iobuf->_cnt + 4 == fp.iobuf->_bufsiz, "_cnt = %d, _bufsiz = %d\n", fp.iobuf->_cnt, fp.iobuf->_bufsiz);
diff --git a/include/msvcrt/stdio.h b/include/msvcrt/stdio.h index 745257ea5cc..73058a7b135 100644 --- a/include/msvcrt/stdio.h +++ b/include/msvcrt/stdio.h @@ -11,6 +11,7 @@ #include <corecrt_wstdio.h>
/* file._flag flags */ +#ifndef _UCRT #define _IOREAD 0x0001 #define _IOWRT 0x0002 #define _IOMYBUF 0x0008 @@ -18,6 +19,7 @@ #define _IOERR 0x0020 #define _IOSTRG 0x0040 #define _IORW 0x0080 +#endif
#define STDIN_FILENO 0 #define STDOUT_FILENO 1
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=146237
Your paranoid android.
=== debian11b (64 bit WoW report) ===
mfmediaengine: mfmediaengine.c:2564: Test failed: Unexpected time 0.000000.
I've pushed new version of the patches that avoids modifying headers in non-compatible way. It also adds some helpers to avoid casts when accessing _iob table.
This merge request was approved by Piotr Caban.