WaitAll,
NULL,
(PVOID)Entry);
- // TODO: Dereference the notified waits.
+ if (!IsListEmpty(&InputBuffer->ReadWaitQueue))
+ {
+ CsrDereferenceWait(&InputBuffer->ReadWaitQueue);
+ }
}
/* If the last handle to a screen buffer is closed, delete it... */
/* Insert the Input handle */
Status = ConSrvInsertObject(ProcessData,
- &InputHandle,
- &ProcessData->Console->InputBuffer.Header,
- GENERIC_READ | GENERIC_WRITE,
- TRUE,
- FILE_SHARE_READ | FILE_SHARE_WRITE);
+ &InputHandle,
+ &ProcessData->Console->InputBuffer.Header,
+ GENERIC_READ | GENERIC_WRITE,
+ TRUE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the input handle\n");
/* Insert the Output handle */
Status = ConSrvInsertObject(ProcessData,
- &OutputHandle,
- &ProcessData->Console->ActiveBuffer->Header,
- GENERIC_READ | GENERIC_WRITE,
- TRUE,
- FILE_SHARE_READ | FILE_SHARE_WRITE);
+ &OutputHandle,
+ &ProcessData->Console->ActiveBuffer->Header,
+ GENERIC_READ | GENERIC_WRITE,
+ TRUE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the output handle\n");
/* Insert the Error handle */
Status = ConSrvInsertObject(ProcessData,
- &ErrorHandle,
- &ProcessData->Console->ActiveBuffer->Header,
- GENERIC_READ | GENERIC_WRITE,
- TRUE,
- FILE_SHARE_READ | FILE_SHARE_WRITE);
+ &ErrorHandle,
+ &ProcessData->Console->ActiveBuffer->Header,
+ GENERIC_READ | GENERIC_WRITE,
+ TRUE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the error handle\n");
(HandleEntry->Access & Access) == 0 ||
(Type != 0 && ObjectEntry->Type != Type) )
{
- DPRINT1("CsrGetObject returning invalid handle (%x) of type %lu with access %lu\n", Handle, Type, Access);
+ DPRINT1("ConSrvGetObject returning invalid handle (%x) of type %lu with access %lu\n", Handle, Type, Access);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
NTSTATUS
FASTCALL
ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
+ LPCWSTR AppPath,
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
PHANDLE pErrorHandle,
- int ShowCmd,
- PCSR_PROCESS CsrProcess)
+ PCONSOLE_START_INFO ConsoleStartInfo)
{
NTSTATUS Status = STATUS_SUCCESS;
- /* Initialize a new Console owned by the Console Leader Process */
- Status = ConSrvInitConsole(&ProcessData->Console, ShowCmd, CsrProcess);
+ /* Initialize a new Console owned by this process */
+ Status = ConSrvInitConsole(&ProcessData->Console, AppPath, ConsoleStartInfo, ProcessData->Process);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console initialization failed\n");
/* Initialize the handles table */
Status = ConSrvInitHandlesTable(ProcessData,
- pInputHandle,
- pOutputHandle,
- pErrorHandle);
+ pInputHandle,
+ pOutputHandle,
+ pErrorHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to initialize the handles table\n");
+ ConSrvDeleteConsole(ProcessData->Console);
+ ProcessData->Console = NULL;
+ return Status;
+ }
- // ConSrvRemoveConsole(ProcessData);
+ /* Duplicate the Input Event */
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ ProcessData->Console->InputBuffer.ActiveEvent,
+ ProcessData->Process->ProcessHandle,
+ &ProcessData->ConsoleEvent,
+ EVENT_ALL_ACCESS, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
+ ConSrvFreeHandlesTable(ProcessData);
ConSrvDeleteConsole(ProcessData->Console);
ProcessData->Console = NULL;
+ return Status;
+ }
+
+ /* Insert the process into the processes list of the console */
+ InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
+
+ /* Add a reference count because the process is tied to the console */
+ _InterlockedIncrement(&ProcessData->Console->ReferenceCount);
+
+ return STATUS_SUCCESS;
+}
+NTSTATUS
+FASTCALL
+ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
+ PCONSOLE Console,
+ BOOL CreateNewHandlesTable,
+ PHANDLE pInputHandle,
+ PHANDLE pOutputHandle,
+ PHANDLE pErrorHandle)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ /* Inherit the console */
+ ProcessData->Console = Console;
+
+ if (CreateNewHandlesTable)
+ {
+ /* Initialize the handles table */
+ Status = ConSrvInitHandlesTable(ProcessData,
+ pInputHandle,
+ pOutputHandle,
+ pErrorHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to initialize the handles table\n");
+ ProcessData->Console = NULL;
+ return Status;
+ }
+ }
+
+ /* Duplicate the Input Event */
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ ProcessData->Console->InputBuffer.ActiveEvent,
+ ProcessData->Process->ProcessHandle,
+ &ProcessData->ConsoleEvent,
+ EVENT_ALL_ACCESS, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
+ ConSrvFreeHandlesTable(ProcessData); // NOTE: Always free the handles table.
+ ProcessData->Console = NULL;
return Status;
}
- return Status;
+ /* Insert the process into the processes list of the console */
+ InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
+
+ /* Add a reference count because the process is tied to the console */
+ _InterlockedIncrement(&ProcessData->Console->ReferenceCount);
+
+ return STATUS_SUCCESS;
}
VOID
{
DPRINT1("ConSrvRemoveConsole - Console->ReferenceCount = %lu - We are going to decrement it !\n", Console->ReferenceCount);
ProcessData->Console = NULL;
+
EnterCriticalSection(&Console->Lock);
DPRINT1("ConSrvRemoveConsole - Locking OK\n");
+
+ /* Remove ourselves from the console's list of processes */
RemoveEntryList(&ProcessData->ConsoleLink);
+
+ /* Update the console leader process */
+ // SetConsoleWndConsoleLeaderCID(Console);
+
+ /* Release the console */
ConSrvReleaseConsole(Console, TRUE);
//CloseHandle(ProcessData->ConsoleEvent);
//ProcessData->ConsoleEvent = NULL;
ConSrvDeleteConsole(Console);
}
-
-
NTSTATUS
NTAPI
ConSrvNewProcess(PCSR_PROCESS SourceProcess,
PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
- DPRINT1("ConSrvNewProcess inside\n");
- DPRINT1("SourceProcess = 0x%p ; TargetProcess = 0x%p\n", SourceProcess, TargetProcess);
-
/* An empty target process is invalid */
- if (!TargetProcess)
- return STATUS_INVALID_PARAMETER;
-
- DPRINT1("ConSrvNewProcess - OK\n");
+ if (!TargetProcess) return STATUS_INVALID_PARAMETER;
TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
- DPRINT1("TargetProcessData = 0x%p\n", TargetProcessData);
/**** HACK !!!! ****/ RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
TargetProcessData->HandleTableSize = 0;
TargetProcessData->HandleTable = NULL;
- /**** HACK !!!! ****/ RtlZeroMemory(&TargetProcessData->HandleTableLock, sizeof(RTL_CRITICAL_SECTION));
RtlInitializeCriticalSection(&TargetProcessData->HandleTableLock);
/* Do nothing if the source process is NULL */
- if (!SourceProcess)
- return STATUS_SUCCESS;
+ if (!SourceProcess) return STATUS_SUCCESS;
SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
- DPRINT1("SourceProcessData = 0x%p\n", SourceProcessData);
/*
* If both of the processes (parent and new child) are console applications,
NTSTATUS Status;
Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
+ if (!NT_SUCCESS(Status)) return Status;
- /* Temporary "inherit" the console from the parent */
+ /* Temporary save the parent's console */
TargetProcessData->ParentConsole = SourceProcessData->Console;
}
- else
- {
- DPRINT1("ConSrvNewProcess - We don't launch a Console process : SourceProcessData->Console = 0x%p ; TargetProcess->Flags = %lu\n", SourceProcessData->Console, TargetProcess->Flags);
- }
return STATUS_SUCCESS;
}
PCONSOLE_CONNECTION_INFO ConnectInfo = (PCONSOLE_CONNECTION_INFO)ConnectionInfo;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
- DPRINT1("ConSrvConnect\n");
-
if ( ConnectionInfo == NULL ||
ConnectionInfoLength == NULL ||
*ConnectionInfoLength != sizeof(CONSOLE_CONNECTION_INFO) )
/* If we don't need a console, then get out of here */
if (!ConnectInfo->ConsoleNeeded || !ProcessData->ConsoleApp) // In fact, it is for GUI apps.
{
- DPRINT("ConSrvConnect - No console needed\n");
return STATUS_SUCCESS;
}
/* Initialize a new Console owned by the Console Leader Process */
Status = ConSrvAllocateConsole(ProcessData,
- &ConnectInfo->InputHandle,
- &ConnectInfo->OutputHandle,
- &ConnectInfo->ErrorHandle,
- ConnectInfo->ShowCmd,
- CsrProcess);
+ ConnectInfo->AppPath,
+ &ConnectInfo->InputHandle,
+ &ConnectInfo->OutputHandle,
+ &ConnectInfo->ErrorHandle,
+ &ConnectInfo->ConsoleStartInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console allocation failed\n");
DPRINT1("ConSrvConnect - Reuse current (parent's) console\n");
/* Reuse our current console */
- ProcessData->Console = ConnectInfo->Console;
- }
-
- /* Add a reference count because the process is tied to the console */
- _InterlockedIncrement(&ProcessData->Console->ReferenceCount);
-
- /* Insert the process into the processes list of the console */
- InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
-
- /// TODO: Move this up ?
- /* Duplicate the Event */
- Status = NtDuplicateObject(NtCurrentProcess(),
- ProcessData->Console->InputBuffer.ActiveEvent,
- ProcessData->Process->ProcessHandle,
- &ProcessData->ConsoleEvent,
- EVENT_ALL_ACCESS, 0, 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
- ConSrvRemoveConsole(ProcessData);
- return Status;
+ Status = ConSrvInheritConsole(ProcessData,
+ ConnectInfo->Console,
+ FALSE,
+ NULL, // &ConnectInfo->InputHandle,
+ NULL, // &ConnectInfo->OutputHandle,
+ NULL); // &ConnectInfo->ErrorHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Console inheritance failed\n");
+ return Status;
+ }
}
/* Return it to the caller */
/* Input Wait Handle */
ConnectInfo->InputWaitHandle = ProcessData->ConsoleEvent;
+ /* Set the Property Dialog Handler */
+ ProcessData->PropDispatcher = ConnectInfo->PropDispatcher;
+
/* Set the Ctrl Dispatcher */
ProcessData->CtrlDispatcher = ConnectInfo->CtrlDispatcher;
- DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
return STATUS_SUCCESS;
}
VOID
-WINAPI
+NTAPI
ConSrvDisconnect(PCSR_PROCESS Process)
{
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(Process);
* This function is called whenever a new process (GUI or CUI) is destroyed.
**************************************************************************/
- DPRINT1("ConSrvDisconnect called\n");
+ DPRINT1("ConSrvDisconnect\n");
+
if ( ProcessData->Console != NULL ||
ProcessData->HandleTable != NULL )
{
Index >= ProcessData->HandleTableSize ||
ProcessData->HandleTable[Index].Object == NULL)
{
- DPRINT("CsrVerifyObject failed\n");
+ DPRINT("SrvVerifyConsoleIoHandle failed\n");
Status = STATUS_INVALID_HANDLE;
}
}
ApiMessage->Status = ConSrvInsertObject(ProcessData,
- &DuplicateHandleRequest->ConsoleHandle, // Use the new handle value!
- Entry->Object,
- DesiredAccess,
- DuplicateHandleRequest->Inheritable,
- Entry->ShareMode);
+ &DuplicateHandleRequest->ConsoleHandle, // Use the new handle value!
+ Entry->Object,
+ DesiredAccess,
+ DuplicateHandleRequest->Inheritable,
+ Entry->ShareMode);
if (NT_SUCCESS(ApiMessage->Status) &&
DuplicateHandleRequest->Options & DUPLICATE_CLOSE_SOURCE)
{
return ApiMessage->Status;
}
-/**
-CSR_API(CsrGetInputWaitHandle)
-{
- PCSRSS_GET_INPUT_WAIT_HANDLE GetConsoleInputWaitHandle = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetConsoleInputWaitHandle;
-
- GetConsoleInputWaitHandle->InputWaitHandle =
- ConsoleGetPerProcessData(CsrGetClientThread()->Process)->ConsoleEvent;
-
- return STATUS_SUCCESS;
-}
-**/
-
/* EOF */