[PATCH 3/5] msvcrt: Use newer ioinfo structure for _MSVC_VER >= 80.
Paul Gofman
pgofman at codeweavers.com
Mon Apr 4 10:52:19 CDT 2022
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
dlls/msvcr80/tests/msvcr80.c | 18 ++---
dlls/msvcrt/file.c | 140 +++++++++++++++++++++++++++--------
2 files changed, 118 insertions(+), 40 deletions(-)
diff --git a/dlls/msvcr80/tests/msvcr80.c b/dlls/msvcr80/tests/msvcr80.c
index a9c51654e5e..c74cd8b93a2 100644
--- a/dlls/msvcr80/tests/msvcr80.c
+++ b/dlls/msvcr80/tests/msvcr80.c
@@ -97,17 +97,17 @@ static void test_ioinfo_flags(void)
info = &__pioinfo[tempfd / MSVCRT_FD_BLOCK_SIZE][tempfd % MSVCRT_FD_BLOCK_SIZE];
ok(!!info, "NULL info.\n");
ok(info->handle == handle, "Unexpected handle %p, expected %p.\n", info->handle, handle);
- todo_wine ok(info->exflag == 1, "Unexpected exflag %#x.\n", info->exflag);
+ ok(info->exflag == 1, "Unexpected exflag %#x.\n", info->exflag);
ok(info->wxflag == (WX_TEXT | WX_OPEN), "Unexpected wxflag %#x.\n", info->wxflag);
- todo_wine ok(info->unicode, "Unicode is not set.\n");
- todo_wine ok(info->textmode == 2, "Unexpected textmode %d.\n", info->textmode);
+ ok(info->unicode, "Unicode is not set.\n");
+ ok(info->textmode == 2, "Unexpected textmode %d.\n", info->textmode);
p__close(tempfd);
ok(info->handle == INVALID_HANDLE_VALUE, "Unexpected handle %p.\n", info->handle);
- todo_wine ok(info->exflag == 1, "Unexpected exflag %#x.\n", info->exflag);
- todo_wine ok(info->unicode, "Unicode is not set.\n");
+ ok(info->exflag == 1, "Unexpected exflag %#x.\n", info->exflag);
+ ok(info->unicode, "Unicode is not set.\n");
ok(!info->wxflag, "Unexpected wxflag %#x.\n", info->wxflag);
- todo_wine ok(info->textmode == 2, "Unexpected textmode %d.\n", info->textmode);
+ ok(info->textmode == 2, "Unexpected textmode %d.\n", info->textmode);
info = &__pioinfo[(tempfd + 4) / MSVCRT_FD_BLOCK_SIZE][(tempfd + 4) % MSVCRT_FD_BLOCK_SIZE];
ok(!!info, "NULL info.\n");
@@ -119,7 +119,7 @@ static void test_ioinfo_flags(void)
ok(tempfd != -1, "_open failed with error: %d\n", errno);
info = &__pioinfo[tempfd / MSVCRT_FD_BLOCK_SIZE][tempfd % MSVCRT_FD_BLOCK_SIZE];
ok(!!info, "NULL info.\n");
- todo_wine ok(info->exflag == 1, "Unexpected exflag %#x.\n", info->exflag);
+ ok(info->exflag == 1, "Unexpected exflag %#x.\n", info->exflag);
ok(info->wxflag == (WX_TEXT | WX_OPEN), "Unexpected wxflag %#x.\n", info->wxflag);
ok(!info->unicode, "Unicode is not set.\n");
ok(!info->textmode, "Unexpected textmode %d.\n", info->textmode);
@@ -129,10 +129,10 @@ static void test_ioinfo_flags(void)
ok(tempfd != -1, "_open failed with error: %d\n", errno);
info = &__pioinfo[tempfd / MSVCRT_FD_BLOCK_SIZE][tempfd % MSVCRT_FD_BLOCK_SIZE];
ok(!!info, "NULL info.\n");
- todo_wine ok(info->exflag == 1, "Unexpected exflag %#x.\n", info->exflag);
+ ok(info->exflag == 1, "Unexpected exflag %#x.\n", info->exflag);
ok(info->wxflag == (WX_TEXT | WX_OPEN), "Unexpected wxflag %#x.\n", info->wxflag);
ok(!info->unicode, "Unicode is not set.\n");
- todo_wine ok(info->textmode == 1, "Unexpected textmode %d.\n", info->textmode);
+ ok(info->textmode == 1, "Unexpected textmode %d.\n", info->textmode);
p__close(tempfd);
unlink(tempf);
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 3497205e12c..637cc614fad 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -86,22 +86,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
#define WX_TTY 0x40
#define WX_TEXT 0x80
-/* values for exflag - it's used differently in msvcr90.dll*/
-#define EF_UTF8 0x01
-#define EF_UTF16 0x02
-#define EF_CRIT_INIT 0x04
-#define EF_UNK_UNICODE 0x08
-
static char utf8_bom[3] = { 0xef, 0xbb, 0xbf };
static char utf16_bom[2] = { 0xff, 0xfe };
+enum textmode
+{
+ TEXTMODE_ANSI,
+ TEXTMODE_UTF8,
+ TEXTMODE_UTF16LE,
+};
+
/* FIXME: this should be allocated dynamically */
#define MSVCRT_MAX_FILES 2048
#define MSVCRT_FD_BLOCK_SIZE 32
#define MSVCRT_INTERNAL_BUFSIZ 4096
-/* ioinfo structure size is different in msvcrXX.dll's */
typedef struct {
HANDLE handle;
unsigned char wxflag;
@@ -130,6 +130,82 @@ ioinfo * MSVCRT___pioinfo[MSVCRT_MAX_FILES/MSVCRT_FD_BLOCK_SIZE] = { 0 };
*/
ioinfo MSVCRT___badioinfo = { INVALID_HANDLE_VALUE, WX_TEXT };
+#if _MSVCR_VER >= 80
+static inline BOOL ioinfo_is_crit_init(ioinfo *info)
+{
+ return info->exflag & 1;
+}
+
+static inline void ioinfo_set_crit_init(ioinfo *info)
+{
+ info->exflag |= 1;
+}
+
+static inline enum textmode ioinfo_get_textmode(ioinfo *info)
+{
+ return info->textmode;
+}
+
+static inline void ioinfo_set_textmode(ioinfo *info, enum textmode mode)
+{
+ info->textmode = mode;
+}
+
+static inline void ioinfo_set_unicode(ioinfo *info, BOOL unicode)
+{
+ info->unicode = !!unicode;
+}
+#else
+
+#define EF_UTF8 0x01
+#define EF_UTF16 0x02
+#define EF_CRIT_INIT 0x04
+#define EF_UNK_UNICODE 0x08
+
+static inline BOOL ioinfo_is_crit_init(ioinfo *info)
+{
+ return info->exflag & EF_CRIT_INIT;
+}
+
+static inline void ioinfo_set_crit_init(ioinfo *info)
+{
+ info->exflag |= EF_CRIT_INIT;
+}
+
+static inline enum textmode ioinfo_get_textmode(ioinfo *info)
+{
+ if (info->exflag & EF_UTF8)
+ return TEXTMODE_UTF8;
+ if (info->exflag & EF_UTF16)
+ return TEXTMODE_UTF16LE;
+ return TEXTMODE_ANSI;
+}
+
+static inline void ioinfo_set_textmode(ioinfo *info, enum textmode mode)
+{
+ info->exflag &= EF_CRIT_INIT | EF_UNK_UNICODE;
+ switch (mode)
+ {
+ case TEXTMODE_ANSI:
+ break;
+ case TEXTMODE_UTF8:
+ info->exflag |= EF_UTF8;
+ break;
+ case TEXTMODE_UTF16LE:
+ info->exflag |= EF_UTF16;
+ break;
+ }
+}
+
+static inline void ioinfo_set_unicode(ioinfo *info, BOOL unicode)
+{
+ if (unicode)
+ info->exflag |= EF_UNK_UNICODE;
+ else
+ info->exflag &= ~EF_UNK_UNICODE;
+}
+#endif
+
typedef struct {
FILE file;
CRITICAL_SECTION crit;
@@ -270,11 +346,11 @@ static inline ioinfo* get_ioinfo_nolock(int fd)
static inline void init_ioinfo_cs(ioinfo *info)
{
- if(!(info->exflag & EF_CRIT_INIT)) {
+ if(!ioinfo_is_crit_init(info)) {
LOCK_FILES();
- if(!(info->exflag & EF_CRIT_INIT)) {
+ if(!ioinfo_is_crit_init(info)) {
InitializeCriticalSection(&info->crit);
- info->exflag |= EF_CRIT_INIT;
+ ioinfo_set_crit_init(info);
}
UNLOCK_FILES();
}
@@ -364,7 +440,7 @@ static inline ioinfo* get_ioinfo_alloc(int *fd)
static inline void release_ioinfo(ioinfo *info)
{
- if(info!=&MSVCRT___badioinfo && info->exflag & EF_CRIT_INIT)
+ if(info!=&MSVCRT___badioinfo && ioinfo_is_crit_init(info))
LeaveCriticalSection(&info->crit);
}
@@ -431,7 +507,8 @@ static void msvcrt_set_fd(ioinfo *fdinfo, HANDLE hand, int flag)
fdinfo->lookahead[0] = '\n';
fdinfo->lookahead[1] = '\n';
fdinfo->lookahead[2] = '\n';
- fdinfo->exflag &= EF_CRIT_INIT;
+ ioinfo_set_unicode(fdinfo, FALSE);
+ ioinfo_set_textmode(fdinfo, TEXTMODE_ANSI);
if (hand == MSVCRT_NO_CONSOLE) hand = 0;
switch (fdinfo-MSVCRT___pioinfo[0])
@@ -1260,7 +1337,7 @@ void msvcrt_free_io(void)
for(j=0; j<MSVCRT_FD_BLOCK_SIZE; j++)
{
- if(MSVCRT___pioinfo[i][j].exflag & EF_CRIT_INIT)
+ if(ioinfo_is_crit_init(&MSVCRT___pioinfo[i][j]))
DeleteCriticalSection(&MSVCRT___pioinfo[i][j].crit);
}
free(MSVCRT___pioinfo[i]);
@@ -2379,12 +2456,12 @@ int CDECL _wsopen_dispatch( const wchar_t* path, int oflags, int shflags, int pm
return *_errno();
if (oflags & _O_WTEXT)
- get_ioinfo_nolock(*fd)->exflag |= EF_UNK_UNICODE;
+ ioinfo_set_unicode(get_ioinfo_nolock(*fd), TRUE);
if (oflags & _O_U16TEXT)
- get_ioinfo_nolock(*fd)->exflag |= EF_UTF16;
+ ioinfo_set_textmode(get_ioinfo_nolock(*fd), TEXTMODE_UTF16LE);
else if (oflags & _O_U8TEXT)
- get_ioinfo_nolock(*fd)->exflag |= EF_UTF8;
+ ioinfo_set_textmode(get_ioinfo_nolock(*fd), TEXTMODE_UTF8);
TRACE(":fd (%d) handle (%p)\n", *fd, hand);
return 0;
@@ -2801,14 +2878,14 @@ static int read_i(int fd, ioinfo *fdinfo, void *buf, unsigned int count)
return -1;
}
- utf16 = (fdinfo->exflag & EF_UTF16) != 0;
- if (((fdinfo->exflag&EF_UTF8) || utf16) && count&1)
+ utf16 = ioinfo_get_textmode(fdinfo) == TEXTMODE_UTF16LE;
+ if (ioinfo_get_textmode(fdinfo) != TEXTMODE_ANSI && count&1)
{
*_errno() = EINVAL;
return -1;
}
- if((fdinfo->wxflag&WX_TEXT) && (fdinfo->exflag&EF_UTF8))
+ if((fdinfo->wxflag&WX_TEXT) && ioinfo_get_textmode(fdinfo) == TEXTMODE_UTF8)
return read_utf8(fdinfo, buf, count);
if (fdinfo->lookahead[0]!='\n' || ReadFile(fdinfo->handle, bufstart, count, &num_read, NULL))
@@ -2964,7 +3041,8 @@ int CDECL _setmode(int fd,int mode)
{
ioinfo *info = get_ioinfo(fd);
int ret = info->wxflag & WX_TEXT ? _O_TEXT : _O_BINARY;
- if(ret==_O_TEXT && (info->exflag & (EF_UTF8|EF_UTF16)))
+
+ if(ret==_O_TEXT && ioinfo_get_textmode(info) != TEXTMODE_ANSI)
ret = _O_WTEXT;
if(mode!=_O_TEXT && mode!=_O_BINARY && mode!=_O_WTEXT
@@ -2981,18 +3059,18 @@ int CDECL _setmode(int fd,int mode)
if(mode == _O_BINARY) {
info->wxflag &= ~WX_TEXT;
- info->exflag &= ~(EF_UTF8|EF_UTF16);
+ ioinfo_set_textmode(info, TEXTMODE_ANSI);
release_ioinfo(info);
return ret;
}
info->wxflag |= WX_TEXT;
if(mode == _O_TEXT)
- info->exflag &= ~(EF_UTF8|EF_UTF16);
+ ioinfo_set_textmode(info, TEXTMODE_ANSI);
else if(mode == _O_U8TEXT)
- info->exflag = (info->exflag & ~EF_UTF16) | EF_UTF8;
+ ioinfo_set_textmode(info, TEXTMODE_UTF8);
else
- info->exflag = (info->exflag & ~EF_UTF8) | EF_UTF16;
+ ioinfo_set_textmode(info, TEXTMODE_UTF16LE);
release_ioinfo(info);
return ret;
@@ -3452,7 +3530,7 @@ int CDECL _write(int fd, const void* buf, unsigned int count)
return -1;
}
- if (((info->exflag&EF_UTF8) || (info->exflag&EF_UTF16)) && count&1)
+ if (ioinfo_get_textmode(info) != TEXTMODE_ANSI && count&1)
{
*_errno() = EINVAL;
release_ioinfo(info);
@@ -3485,7 +3563,7 @@ int CDECL _write(int fd, const void* buf, unsigned int count)
char lfbuf[2048];
DWORD j = 0;
- if (!(info->exflag & (EF_UTF8|EF_UTF16)) && console)
+ if (ioinfo_get_textmode(info) == TEXTMODE_ANSI && console)
{
char conv[sizeof(lfbuf)];
size_t len = 0;
@@ -3537,7 +3615,7 @@ int CDECL _write(int fd, const void* buf, unsigned int count)
}
j = len * 2;
}
- else if (!(info->exflag & (EF_UTF8|EF_UTF16)))
+ else if (ioinfo_get_textmode(info) == TEXTMODE_ANSI)
{
for (j = 0; i < count && j < sizeof(lfbuf)-1; i++, j++)
{
@@ -3546,7 +3624,7 @@ int CDECL _write(int fd, const void* buf, unsigned int count)
lfbuf[j] = s[i];
}
}
- else if (info->exflag & EF_UTF16 || console)
+ else if (ioinfo_get_textmode(info) == TEXTMODE_UTF16LE || console)
{
for (j = 0; i < count && j < sizeof(lfbuf)-3; i++, j++)
{
@@ -3827,7 +3905,7 @@ wint_t CDECL _fgetwc_nolock(FILE* file)
wint_t ret;
int ch;
- if((get_ioinfo_nolock(file->_file)->exflag & (EF_UTF8 | EF_UTF16))
+ if(ioinfo_get_textmode(get_ioinfo_nolock(file->_file)) != TEXTMODE_ANSI
|| !(get_ioinfo_nolock(file->_file)->wxflag & WX_TEXT)) {
char *p;
@@ -4098,7 +4176,7 @@ wint_t CDECL _fputwc_nolock(wint_t wc, FILE* file)
fdinfo = get_ioinfo_nolock(file->_file);
- if((fdinfo->wxflag&WX_TEXT) && !(fdinfo->exflag&(EF_UTF8|EF_UTF16))) {
+ if((fdinfo->wxflag&WX_TEXT) && ioinfo_get_textmode(fdinfo) == TEXTMODE_ANSI) {
char buf[MB_LEN_MAX];
int char_len;
@@ -5611,7 +5689,7 @@ wint_t CDECL _ungetwc_nolock(wint_t wc, FILE * file)
if (wc == WEOF)
return WEOF;
- if((get_ioinfo_nolock(file->_file)->exflag & (EF_UTF8 | EF_UTF16))
+ if(ioinfo_get_textmode(get_ioinfo_nolock(file->_file)) != TEXTMODE_ANSI
|| !(get_ioinfo_nolock(file->_file)->wxflag & WX_TEXT)) {
unsigned char * pp = (unsigned char *)&mwc;
int i;
--
2.35.1
More information about the wine-devel
mailing list