mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 15:52:57 +00:00
Added support for piping.
svn path=/trunk/; revision=2924
This commit is contained in:
parent
deb8a30fce
commit
e11e2826a9
1 changed files with 107 additions and 44 deletions
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -31,25 +31,6 @@
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* 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
|
WINBOOL STDCALL
|
||||||
CreateProcessA (LPCSTR lpApplicationName,
|
CreateProcessA (LPCSTR lpApplicationName,
|
||||||
LPSTR lpCommandLine,
|
LPSTR lpCommandLine,
|
||||||
|
@ -339,8 +320,7 @@ KlCreateFirstThread(HANDLE ProcessHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
KlMapFile(LPCWSTR lpApplicationName,
|
KlMapFile(LPCWSTR lpApplicationName)
|
||||||
LPCWSTR lpCommandLine)
|
|
||||||
{
|
{
|
||||||
HANDLE hFile;
|
HANDLE hFile;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
@ -549,6 +529,7 @@ CreateProcessW(LPCWSTR lpApplicationName,
|
||||||
WCHAR TempCurrentDirectoryW[256];
|
WCHAR TempCurrentDirectoryW[256];
|
||||||
WCHAR TempApplicationNameW[256];
|
WCHAR TempApplicationNameW[256];
|
||||||
WCHAR TempCommandLineNameW[256];
|
WCHAR TempCommandLineNameW[256];
|
||||||
|
UNICODE_STRING RuntimeInfo_U;
|
||||||
|
|
||||||
DPRINT("CreateProcessW(lpApplicationName '%S', lpCommandLine '%S')\n",
|
DPRINT("CreateProcessW(lpApplicationName '%S', lpCommandLine '%S')\n",
|
||||||
lpApplicationName, lpCommandLine);
|
lpApplicationName, lpCommandLine);
|
||||||
|
@ -686,7 +667,7 @@ CreateProcessW(LPCWSTR lpApplicationName,
|
||||||
* Create a section for the executable
|
* Create a section for the executable
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hSection = KlMapFile (ImagePathName, lpCommandLine);
|
hSection = KlMapFile (ImagePathName);
|
||||||
if (hSection == NULL)
|
if (hSection == NULL)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -703,6 +684,28 @@ CreateProcessW(LPCWSTR lpApplicationName,
|
||||||
hSection,
|
hSection,
|
||||||
NULL,
|
NULL,
|
||||||
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
|
* Create the PPB
|
||||||
*/
|
*/
|
||||||
|
@ -715,7 +718,11 @@ CreateProcessW(LPCWSTR lpApplicationName,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
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
|
* Translate some handles for the new process
|
||||||
|
@ -727,7 +734,7 @@ CreateProcessW(LPCWSTR lpApplicationName,
|
||||||
hProcess,
|
hProcess,
|
||||||
&Ppb->CurrentDirectory.Handle,
|
&Ppb->CurrentDirectory.Handle,
|
||||||
0,
|
0,
|
||||||
FALSE,
|
TRUE,
|
||||||
DUPLICATE_SAME_ACCESS);
|
DUPLICATE_SAME_ACCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,7 +745,7 @@ CreateProcessW(LPCWSTR lpApplicationName,
|
||||||
hProcess,
|
hProcess,
|
||||||
&Ppb->ConsoleHandle,
|
&Ppb->ConsoleHandle,
|
||||||
0,
|
0,
|
||||||
FALSE,
|
TRUE,
|
||||||
DUPLICATE_SAME_ACCESS);
|
DUPLICATE_SAME_ACCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,7 +757,6 @@ CreateProcessW(LPCWSTR lpApplicationName,
|
||||||
&Sii,
|
&Sii,
|
||||||
sizeof(Sii),
|
sizeof(Sii),
|
||||||
&i);
|
&i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close the section
|
* Close the section
|
||||||
*/
|
*/
|
||||||
|
@ -784,22 +790,79 @@ CreateProcessW(LPCWSTR lpApplicationName,
|
||||||
DbgPrint("Failed to tell csrss about new process. Expect trouble.\n");
|
DbgPrint("Failed to tell csrss about new process. Expect trouble.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the child console handles
|
||||||
|
Ppb->InputHandle = NtCurrentPeb()->ProcessParameters->InputHandle;
|
||||||
|
Ppb->OutputHandle = NtCurrentPeb()->ProcessParameters->OutputHandle;
|
||||||
|
Ppb->ErrorHandle = NtCurrentPeb()->ProcessParameters->ErrorHandle;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsConsoleHandle(Ppb->InputHandle))
|
||||||
|
{
|
||||||
Ppb->InputHandle = CsrReply.Data.CreateProcessReply.InputHandle;
|
Ppb->InputHandle = CsrReply.Data.CreateProcessReply.InputHandle;
|
||||||
Ppb->OutputHandle = CsrReply.Data.CreateProcessReply.OutputHandle;;
|
}
|
||||||
Ppb->ErrorHandle = Ppb->OutputHandle;
|
else
|
||||||
|
{
|
||||||
// Replace the child console handles, if the parent console handles are file handles.
|
DPRINT("Duplicate input handle\n");
|
||||||
DuplicateFileHandle(NtCurrentPeb()->ProcessParameters->InputHandle,
|
Status = NtDuplicateObject (NtCurrentProcess(),
|
||||||
|
Ppb->InputHandle,
|
||||||
hProcess,
|
hProcess,
|
||||||
&Ppb->InputHandle);
|
&Ppb->InputHandle,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtDuplicateObject failed, status %x\n", Status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DuplicateFileHandle(NtCurrentPeb()->ProcessParameters->OutputHandle,
|
if (IsConsoleHandle(Ppb->OutputHandle))
|
||||||
|
{
|
||||||
|
Ppb->OutputHandle = CsrReply.Data.CreateProcessReply.OutputHandle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Duplicate output handle\n");
|
||||||
|
Status = NtDuplicateObject (NtCurrentProcess(),
|
||||||
|
Ppb->OutputHandle,
|
||||||
hProcess,
|
hProcess,
|
||||||
&Ppb->OutputHandle);
|
&Ppb->OutputHandle,
|
||||||
|
0,
|
||||||
DuplicateFileHandle(NtCurrentPeb()->ProcessParameters->ErrorHandle,
|
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,
|
hProcess,
|
||||||
&Ppb->ErrorHandle);
|
&Ppb->ErrorHandle,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtDuplicateObject failed, status %x\n", Status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create Process Environment Block
|
* Create Process Environment Block
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue