From e11e2826a92eaef28e4d31f083ce0991b90920ea Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Tue, 7 May 2002 22:25:40 +0000 Subject: [PATCH] Added support for piping. svn path=/trunk/; revision=2924 --- reactos/lib/kernel32/process/create.c | 145 ++++++++++++++++++-------- 1 file changed, 104 insertions(+), 41 deletions(-) diff --git a/reactos/lib/kernel32/process/create.c b/reactos/lib/kernel32/process/create.c index 1934433d4da..2cde70432be 100644 --- a/reactos/lib/kernel32/process/create.c +++ b/reactos/lib/kernel32/process/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.45 2002/04/27 19:26:54 hbirr Exp $ +/* $Id: create.c,v 1.46 2002/05/07 22:25:40 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -31,25 +31,6 @@ /* FUNCTIONS ****************************************************************/ -void DuplicateFileHandle(HANDLE Source, HANDLE hProcess, PHANDLE Destination) -{ - NTSTATUS Status; - PFILE_OBJECT FileObject; - DWORD FileType; - - FileType = GetFileType(Source); - if (FileType == FILE_TYPE_DISK || FileType == FILE_TYPE_PIPE) - { - Status = NtDuplicateObject (NtCurrentProcess(), - Source, - hProcess, - Destination, - 0, - FALSE, - DUPLICATE_SAME_ACCESS); - } -} - WINBOOL STDCALL CreateProcessA (LPCSTR lpApplicationName, LPSTR lpCommandLine, @@ -339,8 +320,7 @@ KlCreateFirstThread(HANDLE ProcessHandle, } HANDLE -KlMapFile(LPCWSTR lpApplicationName, - LPCWSTR lpCommandLine) +KlMapFile(LPCWSTR lpApplicationName) { HANDLE hFile; IO_STATUS_BLOCK IoStatusBlock; @@ -549,6 +529,7 @@ CreateProcessW(LPCWSTR lpApplicationName, WCHAR TempCurrentDirectoryW[256]; WCHAR TempApplicationNameW[256]; WCHAR TempCommandLineNameW[256]; + UNICODE_STRING RuntimeInfo_U; DPRINT("CreateProcessW(lpApplicationName '%S', lpCommandLine '%S')\n", lpApplicationName, lpCommandLine); @@ -686,7 +667,7 @@ CreateProcessW(LPCWSTR lpApplicationName, * Create a section for the executable */ - hSection = KlMapFile (ImagePathName, lpCommandLine); + hSection = KlMapFile (ImagePathName); if (hSection == NULL) { return FALSE; @@ -703,6 +684,28 @@ CreateProcessW(LPCWSTR lpApplicationName, hSection, NULL, NULL); + if (lpStartupInfo) + { + if (lpStartupInfo->lpReserved2) + { + ULONG i, Count = *(ULONG*)lpStartupInfo->lpReserved2; + HANDLE * hFile; + HANDLE hTemp; + PRTL_USER_PROCESS_PARAMETERS CurrPpb = NtCurrentPeb()->ProcessParameters; + + + /* FIXME: + * ROUND_UP(xxx,2) + 2 is a dirty hack. RtlCreateProcessParameters assumes that + * the runtimeinfo is a unicode string and use RtlCopyUnicodeString for duplication. + * If is possible that this function overwrite the last information in runtimeinfo + * with the null terminator for the unicode string. + */ + RuntimeInfo_U.Length = RuntimeInfo_U.MaximumLength = ROUND_UP(lpStartupInfo->cbReserved2, 2) + 2; + RuntimeInfo_U.Buffer = RtlAllocateHeap(GetProcessHeap(), 0, RuntimeInfo_U.Length); + memcpy(RuntimeInfo_U.Buffer, lpStartupInfo->lpReserved2, lpStartupInfo->cbReserved2); + } + } + /* * Create the PPB */ @@ -715,7 +718,11 @@ CreateProcessW(LPCWSTR lpApplicationName, NULL, NULL, NULL, - NULL); + lpStartupInfo && lpStartupInfo->lpReserved2 ? &RuntimeInfo_U : NULL); + + if (lpStartupInfo && lpStartupInfo->lpReserved2) + RtlFreeHeap(GetProcessHeap(), 0, RuntimeInfo_U.Buffer); + /* * Translate some handles for the new process @@ -727,7 +734,7 @@ CreateProcessW(LPCWSTR lpApplicationName, hProcess, &Ppb->CurrentDirectory.Handle, 0, - FALSE, + TRUE, DUPLICATE_SAME_ACCESS); } @@ -738,7 +745,7 @@ CreateProcessW(LPCWSTR lpApplicationName, hProcess, &Ppb->ConsoleHandle, 0, - FALSE, + TRUE, DUPLICATE_SAME_ACCESS); } @@ -750,7 +757,6 @@ CreateProcessW(LPCWSTR lpApplicationName, &Sii, sizeof(Sii), &i); - /* * Close the section */ @@ -783,24 +789,81 @@ CreateProcessW(LPCWSTR lpApplicationName, { DbgPrint("Failed to tell csrss about new process. Expect trouble.\n"); } - - Ppb->InputHandle = CsrReply.Data.CreateProcessReply.InputHandle; - Ppb->OutputHandle = CsrReply.Data.CreateProcessReply.OutputHandle;; - Ppb->ErrorHandle = Ppb->OutputHandle; - // Replace the child console handles, if the parent console handles are file handles. - DuplicateFileHandle(NtCurrentPeb()->ProcessParameters->InputHandle, - hProcess, - &Ppb->InputHandle); + // Set the child console handles + Ppb->InputHandle = NtCurrentPeb()->ProcessParameters->InputHandle; + Ppb->OutputHandle = NtCurrentPeb()->ProcessParameters->OutputHandle; + Ppb->ErrorHandle = NtCurrentPeb()->ProcessParameters->ErrorHandle; - DuplicateFileHandle(NtCurrentPeb()->ProcessParameters->OutputHandle, - hProcess, - &Ppb->OutputHandle); + if (lpStartupInfo && (lpStartupInfo->dwFlags & STARTF_USESTDHANDLES)) + { + if (lpStartupInfo->hStdInput) + Ppb->InputHandle = lpStartupInfo->hStdInput; + if (lpStartupInfo->hStdOutput) + Ppb->OutputHandle = lpStartupInfo->hStdOutput; + if (lpStartupInfo->hStdError) + Ppb->ErrorHandle = lpStartupInfo->hStdError; + } - DuplicateFileHandle(NtCurrentPeb()->ProcessParameters->ErrorHandle, - hProcess, - &Ppb->ErrorHandle); + if (IsConsoleHandle(Ppb->InputHandle)) + { + Ppb->InputHandle = CsrReply.Data.CreateProcessReply.InputHandle; + } + else + { + DPRINT("Duplicate input handle\n"); + Status = NtDuplicateObject (NtCurrentProcess(), + Ppb->InputHandle, + hProcess, + &Ppb->InputHandle, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + if(!NT_SUCCESS(Status)) + { + DPRINT("NtDuplicateObject failed, status %x\n", Status); + } + } + if (IsConsoleHandle(Ppb->OutputHandle)) + { + Ppb->OutputHandle = CsrReply.Data.CreateProcessReply.OutputHandle; + } + else + { + DPRINT("Duplicate output handle\n"); + Status = NtDuplicateObject (NtCurrentProcess(), + Ppb->OutputHandle, + hProcess, + &Ppb->OutputHandle, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + if(!NT_SUCCESS(Status)) + { + DPRINT("NtDuplicateObject failed, status %x\n", Status); + } + } + if (IsConsoleHandle(Ppb->ErrorHandle)) + { + Ppb->ErrorHandle = CsrReply.Data.CreateProcessReply.OutputHandle; + } + else + { + DPRINT("Duplicate error handle\n"); + Status = NtDuplicateObject (NtCurrentProcess(), + Ppb->ErrorHandle, + hProcess, + &Ppb->ErrorHandle, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + if(!NT_SUCCESS(Status)) + { + DPRINT("NtDuplicateObject failed, status %x\n", Status); + } + } + /* * Create Process Environment Block */ -- 2.17.1