msvcrt: dont overwrite the standard streams (with test, try 5)
André Hentschel
nerv at dawncrow.de
Sun Sep 6 08:58:09 CDT 2009
Some Apps e.g. mingw-apps use lpReserved2 to pass some data to the child-process, this data starts with 4 Byte of Zeros(unsinged 0) to tell msvcrt not to read that as an inherit-block.
See also Bug 18479
---
dlls/msvcrt/file.c | 2 +-
dlls/msvcrt/tests/Makefile.in | 2 +-
dlls/msvcrt/tests/file.c | 50 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 6671f2f..8f63e8d 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -349,7 +349,7 @@ void msvcrt_init_io(void)
InitializeCriticalSection(&MSVCRT_file_cs);
MSVCRT_file_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MSVCRT_file_cs");
GetStartupInfoA(&si);
- if (si.cbReserved2 != 0 && si.lpReserved2 != NULL)
+ if (si.cbReserved2 != 0 && si.lpReserved2 != NULL && *(unsigned*)si.lpReserved2)
{
char* wxflag_ptr;
HANDLE* handle_ptr;
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..39ad0be 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>
@@ -863,6 +864,14 @@ static void test_file_inherit( const char* selfname )
int fd;
const char* arg_v[5];
char buffer[16];
+ char cmdline[MAX_PATH];
+ BYTE empty[sizeof(unsigned) + sizeof(char) + sizeof(HANDLE)];
+ STARTUPINFO startup;
+ SECURITY_ATTRIBUTES sa;
+ PROCESS_INFORMATION proc;
+ MSG msg;
+ HANDLE hFile;
+ DWORD ret;
fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
ok(fd != -1, "Couldn't create test file\n");
@@ -890,6 +899,41 @@ static void test_file_inherit( const char* selfname )
ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
close (fd);
ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
+
+ /* make file handle inheritable */
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+ hFile = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ &sa, CREATE_ALWAYS, 0, NULL );
+
+ /* pass a empty Reserved2, which should not be recognized as inherit-block */
+ ZeroMemory(&startup, sizeof(STARTUPINFO));
+ ZeroMemory(empty, sizeof(empty));
+ startup.cb = sizeof(startup);
+ startup.cbReserved2 = sizeof(empty);
+ startup.lpReserved2 = empty;
+
+ /* in case it fails pipe the stdout to a file */
+ startup.dwFlags = STARTF_USESTDHANDLES;
+ startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
+ startup.hStdOutput = hFile;
+ startup.hStdError = GetStdHandle( STD_ERROR_HANDLE );
+
+ sprintf(cmdline, "%s file inherit_ow", selfname);
+ CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
+ CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc);
+ while (MsgWaitForMultipleObjects( 1, &proc.hProcess, FALSE, INFINITE, QS_ALLINPUT ) != 0)
+ {
+ while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ }
+
+ SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
+ ReadFile(hFile, buffer, 8, &ret, NULL);
+ CloseHandle(hFile);
+ ok(strcmp(buffer, "Success") == 0 && ret==8, "Found unexpected data (%s)\n", buffer);
+ ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
}
static void test_tmpnam( void )
@@ -1223,6 +1267,12 @@ START_TEST(file)
test_file_inherit_child(arg_v[3]);
else if (strcmp(arg_v[2], "inherit_no") == 0)
test_file_inherit_child_no(arg_v[3]);
+ else if (strcmp(arg_v[2], "inherit_ow") == 0)
+ {
+ char stdfd[2];
+ sprintf(stdfd, "%d", STDOUT_FILENO);
+ test_file_inherit_child(stdfd);
+ }
else if (strcmp(arg_v[2], "pipes") == 0)
test_pipes_child(arg_c, arg_v);
else
--
Best Regards, André Hentschel
More information about the wine-patches
mailing list