mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[KERNEL32/BASESRV/CONSRV]
- Fix console apps initialization. - Introduce a helper function InitConsoleCtrlHandling for initializing console control handling. - We now initialize the new created console when connecting the client (kernel32) to the server (consrv) by calling CsrClientConnectToServer with real parameters (not dummy ones). - Add/activate some debug prints (will be removed when all things work). Part 1/2 svn path=/branches/ros-csrss/; revision=58096
This commit is contained in:
parent
0444a3a392
commit
d820098fa6
6 changed files with 102 additions and 85 deletions
|
@ -29,6 +29,8 @@ PHANDLER_ROUTINE* CtrlHandlers;
|
|||
ULONG NrCtrlHandlers;
|
||||
ULONG NrAllocatedHandlers;
|
||||
|
||||
HANDLE InputWaitHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
#define INPUTEXENAME_BUFLEN 256
|
||||
static WCHAR InputExeName[INPUTEXENAME_BUFLEN];
|
||||
|
||||
|
@ -76,7 +78,7 @@ ConsoleControlDispatcher(IN LPVOID lpThreadParameter)
|
|||
UINT i;
|
||||
EXCEPTION_RECORD erException;
|
||||
|
||||
DPRINT("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode);
|
||||
DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode);
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
|
||||
|
||||
switch(nCode)
|
||||
|
@ -174,6 +176,16 @@ ConsoleControlDispatcher(IN LPVOID lpThreadParameter)
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
InitConsoleCtrlHandling(VOID)
|
||||
{
|
||||
/* Initialize Console Ctrl Handler */
|
||||
NrAllocatedHandlers = NrCtrlHandlers = 1;
|
||||
CtrlHandlers = InitialHandler;
|
||||
CtrlHandlers[0] = DefaultConsoleCtrlHandler;
|
||||
}
|
||||
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
|
@ -321,10 +333,6 @@ HANDLE
|
|||
WINAPI
|
||||
GetConsoleInputWaitHandle(VOID)
|
||||
{
|
||||
/// HACK !!!!!!!!!!!!!
|
||||
ASSERT(FALSE);
|
||||
return NULL;
|
||||
|
||||
#if 0
|
||||
NTSTATUS Status;
|
||||
CONSOLE_API_MESSAGE ApiMessage;
|
||||
|
@ -341,6 +349,8 @@ GetConsoleInputWaitHandle(VOID)
|
|||
|
||||
return ApiMessage.Data.GetConsoleInputWaitHandle.InputWaitHandle;
|
||||
#endif
|
||||
|
||||
return InputWaitHandle;
|
||||
}
|
||||
|
||||
|
||||
|
@ -786,9 +796,10 @@ AllocConsole(VOID)
|
|||
NTSTATUS Status;
|
||||
CONSOLE_API_MESSAGE ApiMessage;
|
||||
PCSRSS_ALLOC_CONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest;
|
||||
HANDLE hStdError;
|
||||
STARTUPINFO si;
|
||||
|
||||
DPRINT1("AllocConsole called !!!!\n");
|
||||
|
||||
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
|
||||
{
|
||||
DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
|
||||
|
@ -798,9 +809,9 @@ AllocConsole(VOID)
|
|||
|
||||
GetStartupInfo(&si);
|
||||
|
||||
AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
|
||||
AllocConsoleRequest->ConsoleNeeded = TRUE;
|
||||
AllocConsoleRequest->ShowCmd = si.wShowWindow;
|
||||
AllocConsoleRequest->Console = NULL;
|
||||
AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
|
||||
|
||||
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
NULL,
|
||||
|
@ -814,15 +825,15 @@ AllocConsole(VOID)
|
|||
|
||||
NtCurrentPeb()->ProcessParameters->ConsoleHandle = AllocConsoleRequest->Console;
|
||||
|
||||
SetStdHandle(STD_INPUT_HANDLE, AllocConsoleRequest->InputHandle);
|
||||
SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle );
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
|
||||
SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle );
|
||||
|
||||
hStdError = DuplicateConsoleHandle(AllocConsoleRequest->OutputHandle,
|
||||
0,
|
||||
TRUE,
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
/* Initialize Console Ctrl Handler */
|
||||
InitConsoleCtrlHandling();
|
||||
|
||||
InputWaitHandle = AllocConsoleRequest->InputWaitHandle;
|
||||
|
||||
SetStdHandle(STD_ERROR_HANDLE, hStdError);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -853,6 +864,10 @@ FreeConsole(VOID)
|
|||
}
|
||||
|
||||
NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
|
||||
|
||||
CloseHandle(InputWaitHandle);
|
||||
InputWaitHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,12 +36,9 @@ static BOOL DllInitialized = FALSE;
|
|||
RTL_CRITICAL_SECTION BaseDllDirectoryLock;
|
||||
RTL_CRITICAL_SECTION ConsoleLock;
|
||||
|
||||
extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
|
||||
extern DWORD WINAPI ConsoleControlDispatcher(IN LPVOID lpThreadParameter);
|
||||
extern PHANDLER_ROUTINE InitialHandler[1];
|
||||
extern PHANDLER_ROUTINE* CtrlHandlers;
|
||||
extern ULONG NrCtrlHandlers;
|
||||
extern ULONG NrAllocatedHandlers;
|
||||
extern HANDLE InputWaitHandle;
|
||||
|
||||
extern BOOL FASTCALL NlsInit(VOID);
|
||||
extern VOID FASTCALL NlsUninit(VOID);
|
||||
|
||||
|
@ -55,9 +52,6 @@ WINAPI
|
|||
BasepInitConsole(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
CONSOLE_API_MESSAGE ApiMessage;
|
||||
PCSRSS_ALLOC_CONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest;
|
||||
BOOLEAN NotConsole = FALSE;
|
||||
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
||||
LPCWSTR ExeName;
|
||||
STARTUPINFO si;
|
||||
|
@ -65,12 +59,8 @@ BasepInitConsole(VOID)
|
|||
ULONG SessionId = NtCurrentPeb()->SessionId;
|
||||
BOOLEAN InServer;
|
||||
|
||||
// HACK
|
||||
/*
|
||||
CSR_CONNECTION_INFO CsrConnectionInfo;
|
||||
ULONG ConnectionSize = sizeof(CsrConnectionInfo);
|
||||
*/
|
||||
// END HACK
|
||||
CONSOLE_CONNECTION_INFO ConnectInfo;
|
||||
ULONG ConnectInfoSize = sizeof(ConnectInfo);
|
||||
|
||||
WCHAR lpTest[MAX_PATH];
|
||||
GetModuleFileNameW(NULL, lpTest, MAX_PATH);
|
||||
|
@ -79,28 +69,33 @@ BasepInitConsole(VOID)
|
|||
Parameters->ConsoleHandle, Parameters->StandardInput,
|
||||
Parameters->StandardOutput, Parameters->StandardError);
|
||||
|
||||
/* Initialize our global console DLL lock */
|
||||
Status = RtlInitializeCriticalSection(&ConsoleLock);
|
||||
if (!NT_SUCCESS(Status)) return FALSE;
|
||||
ConsoleInitialized = TRUE;
|
||||
|
||||
/* We have nothing to do if this isn't a console app... */
|
||||
if (RtlImageNtHeader(GetModuleHandle(NULL))->OptionalHeader.Subsystem !=
|
||||
IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
||||
{
|
||||
DPRINT("Image is not a console application\n");
|
||||
Parameters->ConsoleHandle = NULL;
|
||||
AllocConsoleRequest->ConsoleNeeded = FALSE;
|
||||
ConnectInfo.ConsoleNeeded = FALSE; // ConsoleNeeded is used for knowing whether or not this is a CUI app.
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Assume one is needed */
|
||||
GetStartupInfo(&si);
|
||||
AllocConsoleRequest->ConsoleNeeded = TRUE;
|
||||
AllocConsoleRequest->ShowCmd = si.wShowWindow;
|
||||
ConnectInfo.ConsoleNeeded = TRUE;
|
||||
ConnectInfo.ShowCmd = si.wShowWindow;
|
||||
|
||||
/* Handle the special flags given to us by BasepInitializeEnvironment */
|
||||
/* Handle the special flags given to us by BasePushProcessParameters */
|
||||
if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS)
|
||||
{
|
||||
/* No console to create */
|
||||
DPRINT("No console to create\n");
|
||||
Parameters->ConsoleHandle = NULL;
|
||||
AllocConsoleRequest->ConsoleNeeded = FALSE;
|
||||
ConnectInfo.ConsoleNeeded = FALSE;
|
||||
}
|
||||
else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE)
|
||||
{
|
||||
|
@ -113,33 +108,29 @@ BasepInitConsole(VOID)
|
|||
/* We'll get the real one soon */
|
||||
DPRINT("Creating new invisible console\n");
|
||||
Parameters->ConsoleHandle = NULL;
|
||||
AllocConsoleRequest->ShowCmd = SW_HIDE;
|
||||
ConnectInfo.ShowCmd = SW_HIDE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Parameters->ConsoleHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Parameters->ConsoleHandle = 0;
|
||||
Parameters->ConsoleHandle = NULL;
|
||||
}
|
||||
DPRINT("Using existing console: %x\n", Parameters->ConsoleHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now use the proper console handle */
|
||||
ConnectInfo.Console = Parameters->ConsoleHandle;
|
||||
|
||||
/* Initialize Console Ctrl Handler and input EXE name */
|
||||
ConsoleInitialized = TRUE;
|
||||
RtlInitializeCriticalSection(&ConsoleLock);
|
||||
NrAllocatedHandlers = 1;
|
||||
NrCtrlHandlers = 1;
|
||||
CtrlHandlers = InitialHandler;
|
||||
CtrlHandlers[0] = DefaultConsoleCtrlHandler;
|
||||
InitConsoleCtrlHandling();
|
||||
ConnectInfo.CtrlDispatcher = ConsoleControlDispatcher;
|
||||
|
||||
ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\\');
|
||||
if (ExeName)
|
||||
SetConsoleInputExeNameW(ExeName + 1);
|
||||
|
||||
/* Now use the proper console handle */
|
||||
AllocConsoleRequest->Console = Parameters->ConsoleHandle;
|
||||
|
||||
/* Setup the right Object Directory path */
|
||||
if (!SessionId)
|
||||
{
|
||||
|
@ -156,61 +147,45 @@ BasepInitConsole(VOID)
|
|||
WIN_OBJ_DIR);
|
||||
}
|
||||
|
||||
/* Connect to the base server */
|
||||
DPRINT("Connecting to CSR in BasepInitConsole...\n");
|
||||
/* Connect to the Console Server */
|
||||
DPRINT("Connecting to the Console Server in BasepInitConsole...\n");
|
||||
Status = CsrClientConnectToServer(SessionDir,
|
||||
CONSRV_SERVERDLL_INDEX,
|
||||
/* &CsrConnectionInfo, */ NULL, // TODO: Give it a console connection info
|
||||
/* &ConnectionSize, */ NULL, // TODO: Give it a console connection info
|
||||
&ConnectInfo,
|
||||
&ConnectInfoSize,
|
||||
&InServer);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to connect to CSR (Status %lx)\n", Status);
|
||||
DPRINT1("Failed to connect to the Console Server (Status %lx)\n", Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Nothing to do for server-to-server */
|
||||
if (InServer) return TRUE;
|
||||
|
||||
/*
|
||||
* Normally, we should be connecting to the Console CSR Server...
|
||||
* but we don't have one yet, so we will instead simply send a create
|
||||
* console message to the Base Server. When we finally have a Console
|
||||
* Server, this code should be changed to send connection data instead.
|
||||
*/
|
||||
AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
|
||||
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
NULL,
|
||||
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc),
|
||||
sizeof(CSRSS_ALLOC_CONSOLE));
|
||||
if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
|
||||
{
|
||||
DPRINT1("CSR Failed to give us a console\n");
|
||||
/* We're lying here, so at least the process can load... */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Nothing to do if not a console app */
|
||||
if (NotConsole) return TRUE;
|
||||
if (!ConnectInfo.ConsoleNeeded) return TRUE;
|
||||
|
||||
/* We got the handles, let's set them */
|
||||
if ((Parameters->ConsoleHandle = AllocConsoleRequest->Console))
|
||||
if ((Parameters->ConsoleHandle = ConnectInfo.Console))
|
||||
{
|
||||
/* If we already had some, don't use the new ones */
|
||||
if (!Parameters->StandardInput)
|
||||
{
|
||||
Parameters->StandardInput = AllocConsoleRequest->InputHandle;
|
||||
Parameters->StandardInput = ConnectInfo.InputHandle;
|
||||
}
|
||||
if (!Parameters->StandardOutput)
|
||||
{
|
||||
Parameters->StandardOutput = AllocConsoleRequest->OutputHandle;
|
||||
Parameters->StandardOutput = ConnectInfo.OutputHandle;
|
||||
}
|
||||
if (!Parameters->StandardError)
|
||||
{
|
||||
Parameters->StandardError = AllocConsoleRequest->OutputHandle;
|
||||
Parameters->StandardError = ConnectInfo.ErrorHandle;
|
||||
}
|
||||
}
|
||||
|
||||
InputWaitHandle = ConnectInfo.InputWaitHandle;
|
||||
|
||||
DPRINT("Console setup: %lx, %lx, %lx, %lx\n",
|
||||
Parameters->ConsoleHandle,
|
||||
Parameters->StandardInput,
|
||||
|
@ -403,9 +378,9 @@ DllMain(HANDLE hDll,
|
|||
if (ConsoleInitialized == TRUE)
|
||||
{
|
||||
ConsoleInitialized = FALSE;
|
||||
RtlDeleteCriticalSection (&ConsoleLock);
|
||||
RtlDeleteCriticalSection(&ConsoleLock);
|
||||
}
|
||||
RtlDeleteCriticalSection (&BaseDllDirectoryLock);
|
||||
RtlDeleteCriticalSection(&BaseDllDirectoryLock);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -581,6 +581,16 @@ BasepCreateFirstThread(HANDLE ProcessHandle,
|
|||
CreateProcessRequest->CreationFlags = dwCreationFlags;
|
||||
CreateProcessRequest->bInheritHandles = InheritHandles;
|
||||
|
||||
/*
|
||||
* For GUI applications we turn on the 2nd bit. This also allows
|
||||
* us to know whether or not the application is a GUI or CUI app.
|
||||
*/
|
||||
if (IMAGE_SUBSYSTEM_WINDOWS_GUI == SectionImageInfo->SubSystemType)
|
||||
{
|
||||
CreateProcessRequest->ProcessHandle = (HANDLE)
|
||||
((ULONG_PTR)CreateProcessRequest->ProcessHandle | 2);
|
||||
}
|
||||
|
||||
/* Call CSR */
|
||||
DPRINT1("Calling CsrClientCallServer from BasepCreateFirstThread...\n");
|
||||
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
|
@ -937,19 +947,19 @@ BasePushProcessParameters(IN ULONG ParameterFlags,
|
|||
ProcessParameters->StandardError = StartupInfo->hStdError;
|
||||
}
|
||||
|
||||
/* Use Special Flags for ConDllInitialize in Kernel32 */
|
||||
/* Use Special Flags for BasepInitConsole in Kernel32 */
|
||||
if (CreationFlags & DETACHED_PROCESS)
|
||||
{
|
||||
ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
|
||||
}
|
||||
else if (CreationFlags & CREATE_NO_WINDOW)
|
||||
{
|
||||
ProcessParameters->ConsoleHandle = HANDLE_CREATE_NO_WINDOW;
|
||||
}
|
||||
else if (CreationFlags & CREATE_NEW_CONSOLE)
|
||||
{
|
||||
ProcessParameters->ConsoleHandle = HANDLE_CREATE_NEW_CONSOLE;
|
||||
}
|
||||
else if (CreationFlags & CREATE_NO_WINDOW)
|
||||
{
|
||||
ProcessParameters->ConsoleHandle = HANDLE_CREATE_NO_WINDOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Inherit our Console Handle */
|
||||
|
|
|
@ -186,6 +186,8 @@ VOID
|
|||
NTAPI
|
||||
BaseDllInitializeMemoryManager(VOID);
|
||||
|
||||
VOID WINAPI InitConsoleCtrlHandling(VOID);
|
||||
|
||||
BOOL WINAPI VerifyConsoleIoHandle(HANDLE Handle);
|
||||
|
||||
BOOL WINAPI CloseConsoleHandle(HANDLE Handle);
|
||||
|
|
|
@ -114,7 +114,16 @@ typedef enum _CONSRV_API_NUMBER
|
|||
|
||||
typedef struct _CONSOLE_CONNECTION_INFO
|
||||
{
|
||||
ULONG Dummy;
|
||||
BOOL ConsoleNeeded; // Used for GUI apps only.
|
||||
|
||||
/* Copied from CSRSS_ALLOC_CONSOLE */
|
||||
INT ShowCmd;
|
||||
HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !!
|
||||
HANDLE InputHandle;
|
||||
HANDLE OutputHandle;
|
||||
HANDLE ErrorHandle;
|
||||
HANDLE InputWaitHandle;
|
||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||
} CONSOLE_CONNECTION_INFO, *PCONSOLE_CONNECTION_INFO;
|
||||
|
||||
|
||||
|
@ -157,12 +166,13 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||
BOOL ConsoleNeeded;
|
||||
INT ShowCmd;
|
||||
HANDLE Console;
|
||||
HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !!
|
||||
HANDLE InputHandle;
|
||||
HANDLE OutputHandle;
|
||||
HANDLE ErrorHandle;
|
||||
HANDLE InputWaitHandle;
|
||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||
} CSRSS_ALLOC_CONSOLE, *PCSRSS_ALLOC_CONSOLE;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -81,6 +81,11 @@ CSR_API(BaseSrvCreateProcess)
|
|||
{
|
||||
DebugFlags |= CsrProcessCreateNewGroup;
|
||||
}
|
||||
if ((Flags & 2) == 0)
|
||||
{
|
||||
DPRINT1("BaseSrvCreateProcess - Launching a Console process\n");
|
||||
DebugFlags |= CsrProcessIsConsoleApp;
|
||||
}
|
||||
|
||||
/* FIXME: SxS Stuff */
|
||||
|
||||
|
@ -129,8 +134,8 @@ CSR_API(BaseSrvCreateThread)
|
|||
if (!CurrentThread)
|
||||
{
|
||||
DPRINT1("Server Thread TID: [%lx.%lx]\n",
|
||||
CreateThreadRequest->ClientId.UniqueProcess,
|
||||
CreateThreadRequest->ClientId.UniqueThread);
|
||||
CreateThreadRequest->ClientId.UniqueProcess,
|
||||
CreateThreadRequest->ClientId.UniqueThread);
|
||||
return STATUS_SUCCESS; // server-to-server
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue