Allow launching of console apps from GUI apps

svn path=/trunk/; revision=7107
This commit is contained in:
Gé van Geldorp 2003-12-18 09:51:08 +00:00
parent 41b4cb6b5a
commit 78aaee0a8b
8 changed files with 166 additions and 76 deletions

View file

@ -32,6 +32,7 @@ typedef struct
typedef struct
{
HANDLE Console;
HANDLE InputHandle;
HANDLE OutputHandle;
} CSRSS_CREATE_PROCESS_REPLY, *PCSRSS_CREATE_PROCESS_REPLY;
@ -77,6 +78,7 @@ typedef struct
typedef struct
{
HANDLE Console;
HANDLE InputHandle;
HANDLE OutputHandle;
} CSRSS_ALLOC_CONSOLE_REPLY, *PCSRSS_ALLOC_CONSOLE_REPLY;

View file

@ -1,4 +1,4 @@
/* $Id: console.c,v 1.70 2003/12/02 11:38:46 gvg Exp $
/* $Id: console.c,v 1.71 2003/12/18 09:51:08 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -1253,6 +1253,7 @@ WINBOOL STDCALL AllocConsole(VOID)
SetLastErrorByStatus ( Status );
return FALSE;
}
NtCurrentPeb()->ProcessParameters->hConsole = Reply.Data.AllocConsoleReply.Console;
SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
hStdError = DuplicateConsoleHandle(Reply.Data.AllocConsoleReply.OutputHandle,

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.72 2003/10/31 16:27:01 navaraf Exp $
/* $Id: create.c,v 1.73 2003/12/18 09:51:08 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -712,6 +712,8 @@ CreateProcessW
WCHAR TempCommandLineNameW[256];
UNICODE_STRING RuntimeInfo_U;
PVOID ImageBaseAddress;
BOOL InputSet, OutputSet, ErrorSet;
BOOL InputDup, OutputDup, ErrorDup;
DPRINT("CreateProcessW(lpApplicationName '%S', lpCommandLine '%S')\n",
lpApplicationName, lpCommandLine);
@ -1044,11 +1046,18 @@ CreateProcessW
CsrRequest.Data.CreateProcessRequest.NewProcessId =
ProcessBasicInfo.UniqueProcessId;
if (Sii.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)
{
/* Do not create a console for GUI applications */
dwCreationFlags &= ~CREATE_NEW_CONSOLE;
dwCreationFlags |= DETACHED_PROCESS;
}
{
/* Do not create a console for GUI applications */
dwCreationFlags &= ~CREATE_NEW_CONSOLE;
dwCreationFlags |= DETACHED_PROCESS;
}
else if (Sii.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
{
if (NULL == Ppb->hConsole)
{
dwCreationFlags |= CREATE_NEW_CONSOLE;
}
}
CsrRequest.Data.CreateProcessRequest.Flags = dwCreationFlags;
CsrRequest.Data.CreateProcessRequest.CtrlDispatcher = ConsoleControlDispatcher;
Status = CsrClientCallServer(&CsrRequest,
@ -1059,92 +1068,163 @@ CreateProcessW
{
DbgPrint("Failed to tell csrss about new process. Expect trouble.\n");
}
else if (Sii.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
{
Ppb->hConsole = CsrReply.Data.CreateProcessReply.Console;
}
// Set the child console handles
Ppb->hStdInput = NtCurrentPeb()->ProcessParameters->hStdInput;
Ppb->hStdOutput = NtCurrentPeb()->ProcessParameters->hStdOutput;
Ppb->hStdError = NtCurrentPeb()->ProcessParameters->hStdError;
InputSet = FALSE;
OutputSet = FALSE;
ErrorSet = FALSE;
/* Set the child console handles */
/* First check if handles were passed in startup info */
if (lpStartupInfo && (lpStartupInfo->dwFlags & STARTF_USESTDHANDLES))
{
if (lpStartupInfo->hStdInput)
{
Ppb->hStdInput = lpStartupInfo->hStdInput;
InputSet = TRUE;
InputDup = TRUE;
}
if (lpStartupInfo->hStdOutput)
{
Ppb->hStdOutput = lpStartupInfo->hStdOutput;
OutputSet = TRUE;
OutputDup = TRUE;
}
if (lpStartupInfo->hStdError)
{
Ppb->hStdError = lpStartupInfo->hStdError;
}
if (IsConsoleHandle(Ppb->hStdInput))
{
Ppb->hStdInput = CsrReply.Data.CreateProcessReply.InputHandle;
}
else
{
DPRINT("Duplicate input handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
Ppb->hStdInput,
hProcess,
&Ppb->hStdInput,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
if(!NT_SUCCESS(Status))
{
DPRINT("NtDuplicateObject failed, status %x\n", Status);
ErrorSet = TRUE;
ErrorDup = TRUE;
}
}
if (IsConsoleHandle(Ppb->hStdOutput))
/* Check if new console was created, use it for input and output if
not overridden */
if (0 != (dwCreationFlags & CREATE_NEW_CONSOLE)
&& NT_SUCCESS(Status) && NT_SUCCESS(CsrReply.Status))
{
Ppb->hStdOutput = CsrReply.Data.CreateProcessReply.OutputHandle;
}
else
{
DPRINT("Duplicate output handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
Ppb->hStdOutput,
hProcess,
&Ppb->hStdOutput,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
if(!NT_SUCCESS(Status))
if (! InputSet)
{
DPRINT("NtDuplicateObject failed, status %x\n", Status);
Ppb->hStdInput = CsrReply.Data.CreateProcessReply.InputHandle;
InputSet = TRUE;
InputDup = FALSE;
}
if (! OutputSet)
{
Ppb->hStdOutput = CsrReply.Data.CreateProcessReply.OutputHandle;
OutputSet = TRUE;
OutputDup = FALSE;
}
if (! ErrorSet)
{
Ppb->hStdError = CsrReply.Data.CreateProcessReply.OutputHandle;
ErrorSet = TRUE;
ErrorDup = FALSE;
}
}
if (IsConsoleHandle(Ppb->hStdError))
/* Use existing handles otherwise */
if (! InputSet)
{
CsrRequest.Type = CSRSS_DUPLICATE_HANDLE;
CsrRequest.Data.DuplicateHandleRequest.ProcessId = ProcessBasicInfo.UniqueProcessId;
CsrRequest.Data.DuplicateHandleRequest.Handle = CsrReply.Data.CreateProcessReply.OutputHandle;
Status = CsrClientCallServer(&CsrRequest,
&CsrReply,
sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
Ppb->hStdInput = NtCurrentPeb()->ProcessParameters->hStdInput;
InputDup = TRUE;
}
if (! OutputSet)
{
Ppb->hStdOutput = NtCurrentPeb()->ProcessParameters->hStdOutput;
OutputDup = TRUE;
}
if (! ErrorSet)
{
Ppb->hStdError = NtCurrentPeb()->ProcessParameters->hStdError;
ErrorDup = TRUE;
}
/* Now duplicate handles if required */
if (InputDup)
{
if (IsConsoleHandle(Ppb->hStdInput))
{
Ppb->hStdError = INVALID_HANDLE_VALUE;
Ppb->hStdInput = CsrReply.Data.CreateProcessReply.InputHandle;
}
else
{
Ppb->hStdError = CsrReply.Data.DuplicateHandleReply.Handle;
DPRINT("Duplicate input handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
Ppb->hStdInput,
hProcess,
&Ppb->hStdInput,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
if(!NT_SUCCESS(Status))
{
DPRINT("NtDuplicateObject failed, status %x\n", Status);
}
}
}
else
if (OutputDup)
{
DPRINT("Duplicate error handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
Ppb->hStdError,
hProcess,
&Ppb->hStdError,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
if(!NT_SUCCESS(Status))
if (IsConsoleHandle(Ppb->hStdOutput))
{
DPRINT("NtDuplicateObject failed, status %x\n", Status);
Ppb->hStdOutput = CsrReply.Data.CreateProcessReply.OutputHandle;
}
else
{
DPRINT("Duplicate output handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
Ppb->hStdOutput,
hProcess,
&Ppb->hStdOutput,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
if(!NT_SUCCESS(Status))
{
DPRINT("NtDuplicateObject failed, status %x\n", Status);
}
}
}
if (ErrorDup)
{
if (IsConsoleHandle(Ppb->hStdError))
{
CsrRequest.Type = CSRSS_DUPLICATE_HANDLE;
CsrRequest.Data.DuplicateHandleRequest.ProcessId = ProcessBasicInfo.UniqueProcessId;
CsrRequest.Data.DuplicateHandleRequest.Handle = CsrReply.Data.CreateProcessReply.OutputHandle;
Status = CsrClientCallServer(&CsrRequest,
&CsrReply,
sizeof(CSRSS_API_REQUEST),
sizeof(CSRSS_API_REPLY));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
{
Ppb->hStdError = INVALID_HANDLE_VALUE;
}
else
{
Ppb->hStdError = CsrReply.Data.DuplicateHandleReply.Handle;
}
}
else
{
DPRINT("Duplicate error handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
Ppb->hStdError,
hProcess,
&Ppb->hStdError,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
if(!NT_SUCCESS(Status))
{
DPRINT("NtDuplicateObject failed, status %x\n", Status);
}
}
}

View file

@ -1,4 +1,4 @@
/* $Id: process.c,v 1.30 2003/12/02 11:38:47 gvg Exp $
/* $Id: process.c,v 1.31 2003/12/18 09:51:08 gvg Exp $
*
* reactos/subsys/csrss/api/process.c
*
@ -252,6 +252,8 @@ CSR_API(CsrCreateProcess)
RtlLeaveCriticalSection(&ProcessDataLock);
}
Reply->Data.CreateProcessReply.Console = NewProcessData->Console;
Reply->Status = STATUS_SUCCESS;
return(STATUS_SUCCESS);
}

View file

@ -1,4 +1,4 @@
/* $Id: conio.c,v 1.1 2003/12/02 11:38:46 gvg Exp $
/* $Id: conio.c,v 1.2 2003/12/18 09:51:08 gvg Exp $
*
* reactos/subsys/csrss/win32csr/conio.c
*
@ -314,6 +314,7 @@ CSR_API(CsrAllocConsole)
return Reply->Status;
}
ProcessData->Console = Console;
Reply->Data.AllocConsoleReply.Console = Console;
/* add a reference count because the process is tied to the console */
Console->Header.ReferenceCount++;

View file

@ -1,4 +1,4 @@
/* $Id: guiconsole.c,v 1.3 2003/12/07 23:02:57 gvg Exp $
/* $Id: guiconsole.c,v 1.4 2003/12/18 09:51:08 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -482,6 +482,7 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
NULL,
(HINSTANCE) GetModuleHandleW(NULL),
(PVOID) Console);
Console->hWindow = NewWindow;
if (NULL != NewWindow)
{
SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1);
@ -645,9 +646,15 @@ GuiConsoleInitConsole(PCSRSS_CONSOLE Console)
{
Console->Size.X = 80;
Console->Size.Y = 25;
#ifdef TODO
Console->hWindow = (HWND) SendMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console);
return NULL != Console->hWindow;
#else
PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console);
return TRUE;
#endif
}
VOID STDCALL

View file

@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.7 2003/08/18 11:55:43 hbirr Exp $
/* $Id: cmd.c,v 1.8 2003/12/18 09:51:08 gvg Exp $
*
* CMD.C - command-line interface.
*
@ -1228,9 +1228,6 @@ int main (int argc, char *argv[])
SetFileApisToOEM();
AllocConsole();
hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);

View file

@ -1,4 +1,4 @@
/* $Id: winlogon.c,v 1.22 2003/12/07 00:04:20 weiden Exp $
/* $Id: winlogon.c,v 1.23 2003/12/18 09:51:08 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -372,7 +372,7 @@ static BOOL DoLoginUser(PWCHAR Name, PWCHAR Password)
NULL,
NULL,
FALSE,
DETACHED_PROCESS,
CREATE_NEW_CONSOLE,
NULL,
CurrentDirectory,
&StartupInfo,