Piotr Caban : msvcrt: Fix IO initialization when invalid handles are passed.
Alexandre Julliard
julliard at winehq.org
Wed Nov 15 16:46:00 CST 2017
Module: wine
Branch: master
Commit: 31bf13e92b1c6a7092a44240b763605ae315c328
URL: http://source.winehq.org/git/wine.git/?a=commit;h=31bf13e92b1c6a7092a44240b763605ae315c328
Author: Piotr Caban <piotr at codeweavers.com>
Date: Wed Nov 15 09:47:23 2017 +0100
msvcrt: Fix IO initialization when invalid handles are passed.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/msvcrt/file.c | 42 +++++++++++++++++++++++++-----
dlls/msvcrt/msvcrt.h | 3 +++
dlls/msvcrt/tests/Makefile.in | 1 +
dlls/msvcrt/tests/file.c | 59 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 98 insertions(+), 7 deletions(-)
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index b22cbeb..2516570 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -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;
}
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 1b117c8..a380613 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -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
diff --git a/dlls/msvcrt/tests/Makefile.in b/dlls/msvcrt/tests/Makefile.in
index 2db553d..0867ac0 100644
--- a/dlls/msvcrt/tests/Makefile.in
+++ b/dlls/msvcrt/tests/Makefile.in
@@ -1,6 +1,7 @@
TESTDLL = msvcrt.dll
APPMODE = -mno-cygwin
EXTRAINCL = -I$(srcdir)/..
+IMPORTS = advapi32
C_SRCS = \
cpp.c \
diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c
index d92a6e4..e0b94cf 100644
--- a/dlls/msvcrt/tests/file.c
+++ b/dlls/msvcrt/tests/file.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();
More information about the wine-cvs
mailing list