msvcrt: Use newer ioinfo structure for _MSVC_VER >= 80.
Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4c90f58bb5
commit
1c9e9ec360
|
@ -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);
|
||||
|
|
|
@ -85,22 +85,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;
|
||||
|
@ -129,6 +129,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;
|
||||
|
@ -269,11 +345,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();
|
||||
}
|
||||
|
@ -363,7 +439,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);
|
||||
}
|
||||
|
||||
|
@ -430,7 +506,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])
|
||||
|
@ -1244,7 +1321,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]);
|
||||
|
@ -2363,12 +2440,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;
|
||||
|
@ -2785,14 +2862,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))
|
||||
|
@ -2948,7 +3025,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
|
||||
|
@ -2965,18 +3043,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;
|
||||
|
@ -3436,7 +3514,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);
|
||||
|
@ -3469,7 +3547,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;
|
||||
|
@ -3521,7 +3599,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++)
|
||||
{
|
||||
|
@ -3530,7 +3608,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++)
|
||||
{
|
||||
|
@ -3811,7 +3889,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;
|
||||
|
||||
|
@ -4082,7 +4160,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;
|
||||
|
||||
|
@ -5595,7 +5673,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;
|
||||
|
|
Loading…
Reference in New Issue