msvcrt: Fix IO initialization when invalid handles are passed.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
206162365d
commit
31bf13e92b
|
@ -581,30 +581,57 @@ void msvcrt_init_io(void)
|
|||
fdinfo = get_ioinfo_alloc_fd(MSVCRT_STDIN_FILENO);
|
||||
if (!(fdinfo->wxflag & WX_OPEN) || fdinfo->handle == INVALID_HANDLE_VALUE) {
|
||||
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD flags = WX_OPEN | WX_TEXT;
|
||||
DWORD type = GetFileType(h);
|
||||
|
||||
msvcrt_set_fd(fdinfo, h, WX_OPEN|WX_TEXT|((type&0xf)==FILE_TYPE_CHAR ? WX_TTY : 0)
|
||||
|((type&0xf)==FILE_TYPE_PIPE ? WX_PIPE : 0));
|
||||
if (type == FILE_TYPE_UNKNOWN) {
|
||||
h = MSVCRT_NO_CONSOLE;
|
||||
flags |= WX_TTY;
|
||||
} else if ((type & 0xf) == FILE_TYPE_CHAR) {
|
||||
flags |= WX_TTY;
|
||||
} else if ((type & 0xf) == FILE_TYPE_PIPE) {
|
||||
flags |= WX_PIPE;
|
||||
}
|
||||
|
||||
msvcrt_set_fd(fdinfo, h, flags);
|
||||
}
|
||||
release_ioinfo(fdinfo);
|
||||
|
||||
fdinfo = get_ioinfo_alloc_fd(MSVCRT_STDOUT_FILENO);
|
||||
if (!(fdinfo->wxflag & WX_OPEN) || fdinfo->handle == INVALID_HANDLE_VALUE) {
|
||||
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD flags = WX_OPEN | WX_TEXT;
|
||||
DWORD type = GetFileType(h);
|
||||
|
||||
msvcrt_set_fd(fdinfo, h, WX_OPEN|WX_TEXT|((type&0xf)==FILE_TYPE_CHAR ? WX_TTY : 0)
|
||||
|((type&0xf)==FILE_TYPE_PIPE ? WX_PIPE : 0));
|
||||
if (type == FILE_TYPE_UNKNOWN) {
|
||||
h = MSVCRT_NO_CONSOLE;
|
||||
flags |= WX_TTY;
|
||||
} else if ((type & 0xf) == FILE_TYPE_CHAR) {
|
||||
flags |= WX_TTY;
|
||||
} else if ((type & 0xf) == FILE_TYPE_PIPE) {
|
||||
flags |= WX_PIPE;
|
||||
}
|
||||
|
||||
msvcrt_set_fd(fdinfo, h, flags);
|
||||
}
|
||||
release_ioinfo(fdinfo);
|
||||
|
||||
fdinfo = get_ioinfo_alloc_fd(MSVCRT_STDERR_FILENO);
|
||||
if (!(fdinfo->wxflag & WX_OPEN) || fdinfo->handle == INVALID_HANDLE_VALUE) {
|
||||
HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
|
||||
DWORD flags = WX_OPEN | WX_TEXT;
|
||||
DWORD type = GetFileType(h);
|
||||
|
||||
msvcrt_set_fd(fdinfo, h, WX_OPEN|WX_TEXT|((type&0xf)==FILE_TYPE_CHAR ? WX_TTY : 0)
|
||||
|((type&0xf)==FILE_TYPE_PIPE ? WX_PIPE : 0));
|
||||
if (type == FILE_TYPE_UNKNOWN) {
|
||||
h = MSVCRT_NO_CONSOLE;
|
||||
flags |= WX_TTY;
|
||||
} else if ((type & 0xf) == FILE_TYPE_CHAR) {
|
||||
flags |= WX_TTY;
|
||||
} else if ((type & 0xf) == FILE_TYPE_PIPE) {
|
||||
flags |= WX_PIPE;
|
||||
}
|
||||
|
||||
msvcrt_set_fd(fdinfo, h, flags);
|
||||
}
|
||||
release_ioinfo(fdinfo);
|
||||
|
||||
|
@ -616,7 +643,8 @@ void msvcrt_init_io(void)
|
|||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
/* FILE structs for stdin/out/err are static and never deleted */
|
||||
MSVCRT__iob[i]._file = i;
|
||||
MSVCRT__iob[i]._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) ? MSVCRT__IOREAD : MSVCRT__IOWRT;
|
||||
}
|
||||
|
|
|
@ -742,6 +742,9 @@ struct MSVCRT__stat64 {
|
|||
#define MSVCRT_SEEK_CUR 1
|
||||
#define MSVCRT_SEEK_END 2
|
||||
|
||||
#define MSVCRT_NO_CONSOLE_FD (-2)
|
||||
#define MSVCRT_NO_CONSOLE ((HANDLE)MSVCRT_NO_CONSOLE_FD)
|
||||
|
||||
#define MSVCRT_STDIN_FILENO 0
|
||||
#define MSVCRT_STDOUT_FILENO 1
|
||||
#define MSVCRT_STDERR_FILENO 2
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
TESTDLL = msvcrt.dll
|
||||
APPMODE = -mno-cygwin
|
||||
EXTRAINCL = -I$(srcdir)/..
|
||||
IMPORTS = advapi32
|
||||
|
||||
C_SRCS = \
|
||||
cpp.c \
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winnls.h>
|
||||
#include <winreg.h>
|
||||
#include <process.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
|
@ -1522,6 +1523,61 @@ static void test_file_inherit( const char* selfname )
|
|||
DeleteFileA("fdopen.tst");
|
||||
}
|
||||
|
||||
static void test_invalid_stdin_child( void )
|
||||
{
|
||||
HANDLE handle;
|
||||
ioinfo *info;
|
||||
|
||||
errno = 0xdeadbeef;
|
||||
handle = (HANDLE)_get_osfhandle(STDIN_FILENO);
|
||||
ok(handle == (HANDLE)-2, "handle = %p\n", handle);
|
||||
ok(errno == 0xdeadbeef, "errno = %d\n", errno);
|
||||
|
||||
info = &__pioinfo[STDIN_FILENO/MSVCRT_FD_BLOCK_SIZE][STDIN_FILENO%MSVCRT_FD_BLOCK_SIZE];
|
||||
ok(info->handle == (HANDLE)-2, "info->handle = %p\n", info->handle);
|
||||
ok(info->wxflag == 0xc1, "info->wxflag = %x\n", info->wxflag);
|
||||
|
||||
ok(stdin->_file == -2, "stdin->_file = %d\n", stdin->_file);
|
||||
}
|
||||
|
||||
static void test_invalid_stdin( const char* selfname )
|
||||
{
|
||||
char cmdline[MAX_PATH];
|
||||
PROCESS_INFORMATION proc;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
STARTUPINFOA startup;
|
||||
HKEY key;
|
||||
LONG ret;
|
||||
|
||||
if(!p_fopen_s) {
|
||||
/* Behaviour of the dll has changed in newer version */
|
||||
win_skip("skipping invalid stdin tests\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = RegOpenCurrentUser(KEY_READ, &key);
|
||||
ok(!ret, "RegOpenCurrentUser failed: %x\n", ret);
|
||||
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = TRUE;
|
||||
|
||||
memset(&startup, 0, sizeof(startup));
|
||||
startup.cb = sizeof(startup);
|
||||
startup.dwFlags = STARTF_USESTDHANDLES;
|
||||
startup.hStdInput = key;
|
||||
startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
startup.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
sprintf(cmdline, "%s file stdin", selfname);
|
||||
CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
|
||||
CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc);
|
||||
winetest_wait_child_process(proc.hProcess);
|
||||
|
||||
ret = RegCloseKey(key);
|
||||
ok(!ret, "RegCloseKey failed: %x\n", ret);
|
||||
}
|
||||
|
||||
static void test_tmpnam( void )
|
||||
{
|
||||
char name[MAX_PATH] = "abc";
|
||||
|
@ -2461,12 +2517,15 @@ START_TEST(file)
|
|||
test_file_inherit_child_no(arg_v[3]);
|
||||
else if (strcmp(arg_v[2], "pipes") == 0)
|
||||
test_pipes_child(arg_c, arg_v);
|
||||
else if (strcmp(arg_v[2], "stdin") == 0)
|
||||
test_invalid_stdin_child();
|
||||
else
|
||||
ok(0, "invalid argument '%s'\n", arg_v[2]);
|
||||
return;
|
||||
}
|
||||
test_dup2();
|
||||
test_file_inherit(arg_v[0]);
|
||||
test_invalid_stdin(arg_v[0]);
|
||||
test_file_write_read();
|
||||
test_chsize();
|
||||
test_stat();
|
||||
|
|
Loading…
Reference in New Issue