[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