msvcrt: dont overwrite the standard streams (with test, try4)

André Hentschel nerv at dawncrow.de
Fri Aug 21 12:32:38 CDT 2009


MSVCRT_fdend is initialized with "static int MSVCRT_fdend = 3; /* highest allocated fd */",
but in msvcrt_init_io it might be overwritten with lpReserved2 which might be 0.
This has the effect that stdin, stdout and stderr are invalid. This patch fixes this.
It also fixes Bug 18479

try3: added testcase
try4: fix build(forgot the Makefile.in)

---
 dlls/msvcrt/file.c            |    2 +-
 dlls/msvcrt/tests/Makefile.in |    2 +-
 dlls/msvcrt/tests/file.c      |   38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 6671f2f..0816f1e 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -354,7 +354,7 @@ void msvcrt_init_io(void)
     char*       wxflag_ptr;
     HANDLE*     handle_ptr;
 
-    MSVCRT_fdend = *(unsigned*)si.lpReserved2;
+    MSVCRT_fdend = max(3,*(unsigned*)si.lpReserved2);
 
     wxflag_ptr = (char*)(si.lpReserved2 + sizeof(unsigned));
     handle_ptr = (HANDLE*)(wxflag_ptr + MSVCRT_fdend * sizeof(char));
diff --git a/dlls/msvcrt/tests/Makefile.in b/dlls/msvcrt/tests/Makefile.in
index 74199e1..8c71971 100644
--- a/dlls/msvcrt/tests/Makefile.in
+++ b/dlls/msvcrt/tests/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 TESTDLL   = msvcrt.dll
 APPMODE   = -mno-cygwin
-IMPORTS   = kernel32
+IMPORTS   = kernel32 user32
 MODCFLAGS = @BUILTINFLAG@
 EXTRAINCL = -I$(TOPSRCDIR)/include/msvcrt -I$(SRCDIR)/..
 
diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c
index d405656..c9104b2 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 <winuser.h>
 #include <process.h>
 #include <errno.h>
 
@@ -1014,6 +1015,40 @@ static void test_get_osfhandle(void)
     _unlink(fname);
 }
 
+void test_ioinit_child(void)
+{
+    ExitProcess(_close(0));
+}
+
+static void test_ioinit(const char* selfname)
+{
+    WCHAR empty[MAX_PATH];
+    char buffer[MAX_PATH];
+    STARTUPINFO startup;
+    PROCESS_INFORMATION proc;
+    MSG msg;
+    DWORD res;
+
+    ZeroMemory(empty, sizeof(empty));
+    ZeroMemory(&startup, sizeof(STARTUPINFO));
+    sprintf(buffer, "%s file ioinit", selfname);
+    startup.cb = sizeof(startup);
+    startup.dwFlags = STARTF_USESHOWWINDOW;
+    startup.cbReserved2 = MAX_PATH;
+    startup.lpReserved2 = (void *)empty;
+
+    CreateProcessA(NULL, buffer, NULL, NULL, FALSE,
+                   CREATE_NO_WINDOW, NULL, NULL, &startup, &proc);
+
+    while (MsgWaitForMultipleObjects( 1, &proc.hProcess, FALSE, INFINITE, QS_ALLINPUT ) != 0)
+    {
+        while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+    }
+
+    GetExitCodeProcess( proc.hProcess, &res );
+    ok (res != -1, "unable to close stdin\n");
+}
+
 static void test_setmaxstdio(void)
 {
     ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048));
@@ -1225,6 +1260,8 @@ 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], "ioinit") == 0)
+            test_ioinit_child();
         else
             ok(0, "invalid argument '%s'\n", arg_v[2]);
         return;
@@ -1254,6 +1291,7 @@ START_TEST(file)
     test_get_osfhandle();
     test_setmaxstdio();
     test_pipes(arg_v[0]);
+    test_ioinit(arg_v[0]);
 
     /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
      * file contains lines in the correct order
-- 

Best Regards, André Hentschel



More information about the wine-patches mailing list