mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[KERNEL32]
- Correct a error return code (in AllocConsole). - Implement AttachConsole (inspired by AllocConsole). [CONSRV] - Correct a error return code (in AllocConsole). - Introduce helper functions to simplify console-initialization code. - Implement server-side of AttachConsole (I used pieces of code from ConsoleNewProcess, ConsoleConnect and SrvAllocConsole). Some debug prints were introduced (for debug-purposes :P), will be removed when all things work. TODO: have a look on the handles code. svn path=/branches/ros-csrss/; revision=58166
This commit is contained in:
parent
074466b15e
commit
df7477717c
6 changed files with 416 additions and 213 deletions
|
@ -802,8 +802,8 @@ AllocConsole(VOID)
|
|||
|
||||
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
|
||||
{
|
||||
DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
|
||||
BaseSetLastNTError (STATUS_OBJECT_NAME_EXISTS);
|
||||
DPRINT1("AllocConsole: Allocate duplicate console to the same Process\n");
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -824,7 +824,6 @@ AllocConsole(VOID)
|
|||
}
|
||||
|
||||
NtCurrentPeb()->ProcessParameters->ConsoleHandle = AllocConsoleRequest->Console;
|
||||
|
||||
SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle );
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
|
||||
SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle );
|
||||
|
@ -1910,13 +1909,50 @@ GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
|
|||
/*--------------------------------------------------------------
|
||||
* AttachConsole
|
||||
*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*
|
||||
* @note Strongly inspired by AllocConsole.
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
AttachConsole(DWORD dwProcessId)
|
||||
{
|
||||
DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
|
||||
NTSTATUS Status;
|
||||
CONSOLE_API_MESSAGE ApiMessage;
|
||||
PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest;
|
||||
|
||||
DPRINT1("AttachConsole(%lu)\n", dwProcessId);
|
||||
|
||||
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
|
||||
{
|
||||
DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
AttachConsoleRequest->ProcessId = dwProcessId;
|
||||
AttachConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
|
||||
|
||||
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
|
||||
NULL,
|
||||
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach),
|
||||
sizeof(CONSOLE_ATTACHCONSOLE));
|
||||
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NtCurrentPeb()->ProcessParameters->ConsoleHandle = AttachConsoleRequest->Console;
|
||||
SetStdHandle(STD_INPUT_HANDLE , AttachConsoleRequest->InputHandle );
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, AttachConsoleRequest->OutputHandle);
|
||||
SetStdHandle(STD_ERROR_HANDLE , AttachConsoleRequest->ErrorHandle );
|
||||
|
||||
/* Initialize Console Ctrl Handler */
|
||||
InitConsoleCtrlHandling();
|
||||
|
||||
InputWaitHandle = AttachConsoleRequest->InputWaitHandle;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ typedef enum _CONSRV_API_NUMBER
|
|||
// ConsolepRegisterConsoleIME,
|
||||
// ConsolepUnregisterConsoleIME,
|
||||
// ConsolepGetLangId,
|
||||
// ConsolepAttach,
|
||||
ConsolepAttach,
|
||||
ConsolepGetSelectionInfo,
|
||||
ConsolepGetProcessList,
|
||||
ConsolepGetHistory,
|
||||
|
@ -177,6 +177,17 @@ typedef struct
|
|||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||
} CONSOLE_ALLOCCONSOLE, *PCONSOLE_ALLOCCONSOLE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD ProcessId; // If ProcessId == ATTACH_PARENT_PROCESS == -1, then attach the current process to its parent process 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;
|
||||
} CONSOLE_ATTACHCONSOLE, *PCONSOLE_ATTACHCONSOLE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG Dummy;
|
||||
|
@ -543,6 +554,7 @@ typedef struct _CONSOLE_API_MESSAGE
|
|||
union
|
||||
{
|
||||
CONSOLE_ALLOCCONSOLE AllocConsoleRequest;
|
||||
CONSOLE_ATTACHCONSOLE AttachConsoleRequest;
|
||||
CONSOLE_FREECONSOLE FreeConsoleRequest;
|
||||
|
||||
/* Handles */
|
||||
|
|
|
@ -301,58 +301,52 @@ CSR_API(SrvAllocConsole)
|
|||
if (ProcessData->Console != NULL)
|
||||
{
|
||||
DPRINT1("Process already has a console\n");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
/******************************************************************************/
|
||||
/** This comes from ConsoleConnect!! **/
|
||||
DPRINT1("SrvAllocConsole - Checkpoint 1\n");
|
||||
|
||||
#if 0000
|
||||
/*
|
||||
* We are about to create a new console. However when ConsoleNewProcess
|
||||
* was called, we didn't know that we wanted to create a new console and
|
||||
* therefore, we by default inherited the handles table from our parent
|
||||
* process. It's only now that we notice that in fact we do not need
|
||||
* them, because we've created a new console and thus we must use it.
|
||||
*
|
||||
* Therefore, free the console we can have and our handles table,
|
||||
* and recreate a new one later on.
|
||||
*/
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
// Win32CsrFreeHandlesTable(ProcessData);
|
||||
#endif
|
||||
|
||||
/* Initialize a new Console owned by the Console Leader Process */
|
||||
Status = CsrInitConsole(&ProcessData->Console, AllocConsoleRequest->ShowCmd, ConsoleLeader);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Console initialization failed\n");
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Return it to the caller */
|
||||
AllocConsoleRequest->Console = ProcessData->Console;
|
||||
|
||||
/* Add a reference count because the process is tied to the console */
|
||||
_InterlockedIncrement(&ProcessData->Console->ReferenceCount);
|
||||
|
||||
#if 0000
|
||||
/*
|
||||
* We've just created a new console. However when ConsoleNewProcess was
|
||||
* called, we didn't know that we wanted to create a new console and
|
||||
* therefore, we by default inherited the handles table from our parent
|
||||
* process. It's only now that we notice that in fact we do not need
|
||||
* them, because we've created a new console and thus we must use it.
|
||||
*
|
||||
* Therefore, free our handles table and recreate a new one.
|
||||
*/
|
||||
|
||||
ULONG i;
|
||||
|
||||
/* Close all console handles and free the handle table memory */
|
||||
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
||||
{
|
||||
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
|
||||
}
|
||||
ProcessData->HandleTableSize = 0;
|
||||
RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
|
||||
ProcessData->HandleTable = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create a new handle table - Insert the IO handles
|
||||
*/
|
||||
|
||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
/* Insert the Input handle */
|
||||
Status = Win32CsrInsertObject(ProcessData,
|
||||
&AllocConsoleRequest->InputHandle,
|
||||
|
@ -363,9 +357,10 @@ CSR_API(SrvAllocConsole)
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to insert the input handle\n");
|
||||
ConioDeleteConsole(ProcessData->Console);
|
||||
ProcessData->Console = NULL;
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
// ConioDeleteConsole(ProcessData->Console);
|
||||
// ProcessData->Console = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -379,11 +374,12 @@ CSR_API(SrvAllocConsole)
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to insert the output handle\n");
|
||||
ConioDeleteConsole(ProcessData->Console);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
AllocConsoleRequest->InputHandle);
|
||||
ProcessData->Console = NULL;
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// AllocConsoleRequest->InputHandle);
|
||||
// ConioDeleteConsole(ProcessData->Console);
|
||||
// ProcessData->Console = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -397,16 +393,19 @@ CSR_API(SrvAllocConsole)
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to insert the error handle\n");
|
||||
ConioDeleteConsole(ProcessData->Console);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
AllocConsoleRequest->OutputHandle);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
AllocConsoleRequest->InputHandle);
|
||||
ProcessData->Console = NULL;
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// AllocConsoleRequest->OutputHandle);
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// AllocConsoleRequest->InputHandle);
|
||||
// ConioDeleteConsole(ProcessData->Console);
|
||||
// ProcessData->Console = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
/* Duplicate the Event */
|
||||
Status = NtDuplicateObject(NtCurrentProcess(),
|
||||
ProcessData->Console->ActiveEvent,
|
||||
|
@ -416,18 +415,18 @@ CSR_API(SrvAllocConsole)
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
|
||||
ConioDeleteConsole(ProcessData->Console);
|
||||
// if (NewConsole /* || !ProcessData->bInheritHandles */)
|
||||
{
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
AllocConsoleRequest->ErrorHandle);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
AllocConsoleRequest->OutputHandle);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
AllocConsoleRequest->InputHandle);
|
||||
}
|
||||
ProcessData->Console = NULL;
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
// if (NewConsole)
|
||||
// {
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// AllocConsoleRequest->ErrorHandle);
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// AllocConsoleRequest->OutputHandle);
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// AllocConsoleRequest->InputHandle);
|
||||
// }
|
||||
// ConioDeleteConsole(ProcessData->Console); // FIXME: Just release the console ?
|
||||
// ProcessData->Console = NULL;
|
||||
return Status;
|
||||
}
|
||||
/* Input Wait Handle */
|
||||
|
@ -436,15 +435,149 @@ CSR_API(SrvAllocConsole)
|
|||
/* Set the Ctrl Dispatcher */
|
||||
ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher;
|
||||
DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
|
||||
/******************************************************************************/
|
||||
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CSR_API(SrvAttachConsole)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AttachConsoleRequest;
|
||||
PCSR_PROCESS SourceProcess = NULL; // The parent process.
|
||||
PCSR_PROCESS TargetProcess = CsrGetClientThread()->Process; // Ourselves.
|
||||
HANDLE ProcessId = ULongToHandle(AttachConsoleRequest->ProcessId);
|
||||
PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
|
||||
|
||||
DPRINT("SrvAttachConsole\n");
|
||||
|
||||
TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
|
||||
|
||||
if (TargetProcessData->Console != NULL)
|
||||
{
|
||||
DPRINT1("Process already has a console\n");
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (ProcessId == ULongToHandle(ATTACH_PARENT_PROCESS))
|
||||
{
|
||||
PROCESS_BASIC_INFORMATION ProcessInfo;
|
||||
ULONG Length = sizeof(ProcessInfo);
|
||||
|
||||
/* Get the real parent's ID */
|
||||
|
||||
Status = NtQueryInformationProcess(TargetProcess->ProcessHandle,
|
||||
ProcessBasicInformation,
|
||||
&ProcessInfo,
|
||||
Length, &Length);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("SrvAttachConsole - Cannot retrieve basic process info, Status = %lu\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
DPRINT("We, process (ID) %lu;%lu\n", TargetProcess->ClientId.UniqueProcess, TargetProcess->ClientId.UniqueThread);
|
||||
ProcessId = ULongToHandle(ProcessInfo.InheritedFromUniqueProcessId);
|
||||
DPRINT("Parent process ID = %lu\n", ProcessId);
|
||||
}
|
||||
|
||||
/* Lock the target process via its PID */
|
||||
DPRINT1("Lock process Id %lu\n", ProcessId);
|
||||
Status = CsrLockProcessByClientId(ProcessId, &SourceProcess);
|
||||
DPRINT1("Lock process Status %lu\n", Status);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
DPRINT1("AttachConsole OK\n");
|
||||
|
||||
/******************************************************************************/
|
||||
/** This comes from ConsoleNewProcess!! **/
|
||||
SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
||||
|
||||
/*
|
||||
* Inherit the console from the parent,
|
||||
* if any, otherwise return an error.
|
||||
*/
|
||||
DPRINT1("SourceProcessData->Console = 0x%p\n", SourceProcessData->Console);
|
||||
if (SourceProcessData->Console == NULL)
|
||||
{
|
||||
Status = STATUS_INVALID_HANDLE;
|
||||
goto Quit;
|
||||
}
|
||||
TargetProcessData->Console = SourceProcessData->Console;
|
||||
|
||||
DPRINT1("SrvAttachConsole - Copy the handle table (1)\n");
|
||||
Status = Win32CsrInheritHandlesTable(SourceProcessData, TargetProcessData);
|
||||
DPRINT1("SrvAttachConsole - Copy the handle table (2)\n");
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/** This comes from ConsoleConnect / SrvAllocConsole!! **/
|
||||
/* Add a reference count because the process is tied to the console */
|
||||
_InterlockedIncrement(&TargetProcessData->Console->ReferenceCount);
|
||||
|
||||
/* Insert the process into the processes list of the console */
|
||||
InsertHeadList(&TargetProcessData->Console->ProcessList, &TargetProcessData->ConsoleLink);
|
||||
|
||||
/* Return it to the caller */
|
||||
AttachConsoleRequest->Console = TargetProcessData->Console;
|
||||
|
||||
/** Here, we inherited the console handles from the "source" process,
|
||||
** so no need to reinitialize the handles table. **/
|
||||
|
||||
DPRINT1("SrvAttachConsole - Checkpoint\n");
|
||||
|
||||
/* Duplicate the Event */
|
||||
Status = NtDuplicateObject(NtCurrentProcess(),
|
||||
TargetProcessData->Console->ActiveEvent,
|
||||
TargetProcessData->Process->ProcessHandle,
|
||||
&TargetProcessData->ConsoleEvent,
|
||||
EVENT_ALL_ACCESS, 0, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
|
||||
Win32CsrReleaseConsole(TargetProcessData);
|
||||
// #if 0
|
||||
// if (NewConsole)
|
||||
// {
|
||||
// Win32CsrReleaseObject(TargetProcessData,
|
||||
// AttachConsoleRequest->ErrorHandle);
|
||||
// Win32CsrReleaseObject(TargetProcessData,
|
||||
// AttachConsoleRequest->OutputHandle);
|
||||
// Win32CsrReleaseObject(TargetProcessData,
|
||||
// AttachConsoleRequest->InputHandle);
|
||||
// }
|
||||
// #endif
|
||||
// ConioDeleteConsole(TargetProcessData->Console); // FIXME: Just release the console ?
|
||||
// TargetProcessData->Console = NULL;
|
||||
goto Quit;
|
||||
}
|
||||
/* Input Wait Handle */
|
||||
AttachConsoleRequest->InputWaitHandle = TargetProcessData->ConsoleEvent;
|
||||
|
||||
/* Set the Ctrl Dispatcher */
|
||||
TargetProcessData->CtrlDispatcher = AttachConsoleRequest->CtrlDispatcher;
|
||||
DPRINT("CONSRV: CtrlDispatcher address: %x\n", TargetProcessData->CtrlDispatcher);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
/******************************************************************************/
|
||||
|
||||
Quit:
|
||||
DPRINT1("SrvAttachConsole - exiting 1\n");
|
||||
/* Unlock the "source" process */
|
||||
CsrUnlockProcess(SourceProcess);
|
||||
DPRINT1("SrvAttachConsole - exiting 2\n");
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvFreeConsole)
|
||||
{
|
||||
DPRINT1("SrvFreeConsole\n");
|
||||
Win32CsrReleaseConsole(CsrGetClientThread()->Process);
|
||||
Win32CsrReleaseConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,6 @@ typedef struct _CONSOLE_PROCESS_DATA
|
|||
/* PCONSOLE */ struct _CONSOLE* Console;
|
||||
/* PCONSOLE */ struct _CONSOLE* ParentConsole;
|
||||
|
||||
// BOOL bInheritHandles;
|
||||
BOOL ConsoleApp; // TRUE if it is a CUI app, FALSE otherwise.
|
||||
|
||||
RTL_CRITICAL_SECTION HandleTableLock;
|
||||
|
@ -118,6 +117,7 @@ CSR_API(SrvSetConsoleScreenBufferSize);
|
|||
/* console.c */
|
||||
CSR_API(SrvOpenConsole);
|
||||
CSR_API(SrvAllocConsole);
|
||||
CSR_API(SrvAttachConsole);
|
||||
CSR_API(SrvFreeConsole);
|
||||
CSR_API(SrvSetConsoleMode);
|
||||
CSR_API(SrvGetConsoleMode);
|
||||
|
@ -139,6 +139,9 @@ CSR_API(SrvVerifyConsoleIoHandle);
|
|||
CSR_API(SrvDuplicateHandle);
|
||||
/// CSR_API(CsrGetInputWaitHandle);
|
||||
|
||||
NTSTATUS FASTCALL Win32CsrInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
|
||||
IN PCONSOLE_PROCESS_DATA TargetProcessData);
|
||||
VOID FASTCALL Win32CsrFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData);
|
||||
NTSTATUS FASTCALL Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
PHANDLE Handle,
|
||||
Object_t *Object,
|
||||
|
@ -153,6 +156,7 @@ NTSTATUS FASTCALL Win32CsrLockObject(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
VOID FASTCALL Win32CsrUnlockObject(Object_t *Object);
|
||||
NTSTATUS FASTCALL Win32CsrReleaseObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
HANDLE Handle);
|
||||
VOID FASTCALL Win32CsrReleaseConsole(PCONSOLE_PROCESS_DATA ProcessData);
|
||||
|
||||
NTSTATUS NTAPI ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
||||
PCSR_PROCESS TargetProcess);
|
||||
|
@ -160,7 +164,6 @@ NTSTATUS NTAPI ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
|||
IN OUT PVOID ConnectionInfo,
|
||||
IN OUT PULONG ConnectionInfoLength);
|
||||
VOID NTAPI ConsoleDisconnect(PCSR_PROCESS Process);
|
||||
VOID NTAPI Win32CsrReleaseConsole(PCSR_PROCESS Process);
|
||||
|
||||
/* lineinput.c */
|
||||
CSR_API(SrvGetConsoleCommandHistoryLength);
|
||||
|
|
|
@ -79,6 +79,85 @@ Win32CsrCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
FASTCALL
|
||||
Win32CsrInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData,
|
||||
IN PCONSOLE_PROCESS_DATA TargetProcessData)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG i;
|
||||
|
||||
RtlEnterCriticalSection(&SourceProcessData->HandleTableLock);
|
||||
|
||||
/* Inherit a handles table only if there is no already */
|
||||
if (TargetProcessData->HandleTable != NULL /* || TargetProcessData->HandleTableSize != 0 */)
|
||||
{
|
||||
Status = STATUS_UNSUCCESSFUL; /* STATUS_INVALID_PARAMETER */
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/* Allocate a new handle table for the child process */
|
||||
TargetProcessData->HandleTable = RtlAllocateHeap(ConSrvHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
SourceProcessData->HandleTableSize
|
||||
* sizeof(CONSOLE_IO_HANDLE));
|
||||
if (TargetProcessData->HandleTable == NULL)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize;
|
||||
|
||||
/*
|
||||
* Parse the parent process' handles table and, for each handle,
|
||||
* do a copy of it and reference it, if the handle is inheritable.
|
||||
*/
|
||||
for (i = 0; i < SourceProcessData->HandleTableSize; i++)
|
||||
{
|
||||
if (SourceProcessData->HandleTable[i].Object != NULL &&
|
||||
SourceProcessData->HandleTable[i].Inheritable)
|
||||
{
|
||||
/*
|
||||
* Copy the handle data and increment the reference count of the
|
||||
* pointed object (via the call to Win32CsrCreateHandleEntry).
|
||||
*/
|
||||
TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
|
||||
Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Quit:
|
||||
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
Win32CsrFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
|
||||
{
|
||||
DPRINT1("Win32CsrFreeHandlesTable\n");
|
||||
|
||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
if (ProcessData->HandleTable != NULL)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
/* Close all console handles and free the handle table memory */
|
||||
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
||||
{
|
||||
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
|
||||
}
|
||||
RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
|
||||
ProcessData->HandleTable = NULL;
|
||||
}
|
||||
|
||||
ProcessData->HandleTableSize = 0;
|
||||
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FASTCALL
|
||||
Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
|
@ -122,7 +201,8 @@ Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
ProcessData->HandleTable[i].Inheritable = Inheritable;
|
||||
ProcessData->HandleTable[i].ShareMode = ShareMode;
|
||||
Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i]);
|
||||
*Handle = UlongToHandle((i << 2) | 0x3);
|
||||
*Handle = ULongToHandle((i << 2) | 0x3);
|
||||
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -202,9 +282,33 @@ Win32CsrUnlockObject(Object_t *Object)
|
|||
Win32CsrUnlockConsole(Object->Console);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
Win32CsrReleaseConsole(PCONSOLE_PROCESS_DATA ProcessData)
|
||||
{
|
||||
PCONSOLE Console;
|
||||
|
||||
DPRINT1("Win32CsrReleaseConsole\n");
|
||||
|
||||
/* Close all console handles and free the handle table memory */
|
||||
Win32CsrFreeHandlesTable(ProcessData);
|
||||
|
||||
/* Detach process from console */
|
||||
Console = ProcessData->Console;
|
||||
if (Console != NULL)
|
||||
{
|
||||
DPRINT1("Win32CsrReleaseConsole - Console->ReferenceCount = %lu - We are going to decrement it !\n", Console->ReferenceCount);
|
||||
ProcessData->Console = NULL;
|
||||
EnterCriticalSection(&Console->Lock);
|
||||
RemoveEntryList(&ProcessData->ConsoleLink);
|
||||
Win32CsrUnlockConsole(Console);
|
||||
//CloseHandle(ProcessData->ConsoleEvent);
|
||||
//ProcessData->ConsoleEvent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Remark: this function can be called by SrvAttachConsole (not yet implemented) **/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
||||
|
@ -223,7 +327,6 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
|||
**************************************************************************/
|
||||
|
||||
PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
|
||||
ULONG i;
|
||||
|
||||
DPRINT1("ConsoleNewProcess inside\n");
|
||||
DPRINT1("SourceProcess = 0x%p ; TargetProcess = 0x%p\n", SourceProcess, TargetProcess);
|
||||
|
@ -243,14 +346,13 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
|||
TargetProcessData->Process = TargetProcess;
|
||||
TargetProcessData->ConsoleEvent = NULL;
|
||||
TargetProcessData->Console = TargetProcessData->ParentConsole = NULL;
|
||||
// TargetProcessData->bInheritHandles = FALSE;
|
||||
TargetProcessData->ConsoleApp = ((TargetProcess->Flags & CsrProcessIsConsoleApp) ? TRUE : FALSE);
|
||||
|
||||
// Testing
|
||||
TargetProcessData->HandleTableSize = 0;
|
||||
TargetProcessData->HandleTable = NULL;
|
||||
|
||||
/* HACK */ RtlZeroMemory(&TargetProcessData->HandleTableLock, sizeof(RTL_CRITICAL_SECTION));
|
||||
/**** HACK !!!! ****/ RtlZeroMemory(&TargetProcessData->HandleTableLock, sizeof(RTL_CRITICAL_SECTION));
|
||||
RtlInitializeCriticalSection(&TargetProcessData->HandleTableLock);
|
||||
|
||||
/* Do nothing if the source process is NULL */
|
||||
|
@ -267,51 +369,17 @@ ConsoleNewProcess(PCSR_PROCESS SourceProcess,
|
|||
if ( SourceProcessData->Console != NULL && /* SourceProcessData->ConsoleApp */
|
||||
TargetProcessData->ConsoleApp )
|
||||
{
|
||||
/*
|
||||
if (TargetProcessData->HandleTableSize)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
*/
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT1("ConsoleNewProcess - Copy the handle table (1)\n");
|
||||
Status = Win32CsrInheritHandlesTable(SourceProcessData, TargetProcessData);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
// FIXME: Do it before, or after the handles table inheritance ??
|
||||
/* Temporary "inherit" the console from the parent */
|
||||
TargetProcessData->ParentConsole = SourceProcessData->Console;
|
||||
RtlEnterCriticalSection(&SourceProcessData->HandleTableLock);
|
||||
DPRINT1("ConsoleNewProcess - Copy the handle table (2)\n");
|
||||
|
||||
/* Allocate a new handle table for the child process */
|
||||
TargetProcessData->HandleTable = RtlAllocateHeap(ConSrvHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
SourceProcessData->HandleTableSize
|
||||
* sizeof(CONSOLE_IO_HANDLE));
|
||||
if (TargetProcessData->HandleTable == NULL)
|
||||
{
|
||||
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize;
|
||||
|
||||
/*
|
||||
* Parse the parent process' handles table and, for each handle,
|
||||
* do a copy of it and reference it, if the handle is inheritable.
|
||||
*/
|
||||
for (i = 0; i < SourceProcessData->HandleTableSize; i++)
|
||||
{
|
||||
if (SourceProcessData->HandleTable[i].Object != NULL &&
|
||||
SourceProcessData->HandleTable[i].Inheritable)
|
||||
{
|
||||
/*
|
||||
* Copy the handle data and increment the reference count of the
|
||||
* pointed object (via the call to Win32CsrCreateHandleEntry).
|
||||
*/
|
||||
TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
|
||||
Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]);
|
||||
}
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -335,7 +403,6 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
|||
PCONSOLE_CONNECTION_INFO ConnectInfo = (PCONSOLE_CONNECTION_INFO)ConnectionInfo;
|
||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||
BOOLEAN NewConsole = FALSE;
|
||||
// PCONSOLE Console = NULL;
|
||||
|
||||
DPRINT1("ConsoleConnect\n");
|
||||
|
||||
|
@ -354,21 +421,30 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
/* If we don't have a console, then create a new one... */
|
||||
if (!ConnectInfo->Console ||
|
||||
ConnectInfo->Console != ProcessData->ParentConsole)
|
||||
{
|
||||
DPRINT1("ConsoleConnect - Allocate a new console\n");
|
||||
|
||||
/*
|
||||
* We are about to create a new console. However when ConsoleNewProcess
|
||||
* was called, we didn't know that we wanted to create a new console and
|
||||
* therefore, we by default inherited the handles table from our parent
|
||||
* process. It's only now that we notice that in fact we do not need
|
||||
* them, because we've created a new console and thus we must use it.
|
||||
*
|
||||
* Therefore, free the console we can have and our handles table,
|
||||
* and recreate a new one later on.
|
||||
*/
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
|
||||
/* Initialize a new Console owned by the Console Leader Process */
|
||||
NewConsole = TRUE;
|
||||
Status = CsrInitConsole(&ProcessData->Console, ConnectInfo->ShowCmd, CsrProcess);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Console initialization failed\n");
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
@ -381,42 +457,23 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
|||
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);
|
||||
|
||||
/* Return it to the caller */
|
||||
ConnectInfo->Console = ProcessData->Console;
|
||||
|
||||
/* Add a reference count because the process is tied to the console */
|
||||
_InterlockedIncrement(&ProcessData->Console->ReferenceCount);
|
||||
|
||||
if (NewConsole /* || !ProcessData->bInheritHandles */)
|
||||
if (NewConsole)
|
||||
{
|
||||
/*
|
||||
* We've just created a new console. However when ConsoleNewProcess was
|
||||
* called, we didn't know that we wanted to create a new console and
|
||||
* therefore, we by default inherited the handles table from our parent
|
||||
* process. It's only now that we notice that in fact we do not need
|
||||
* them, because we've created a new console and thus we must use it.
|
||||
*
|
||||
* Therefore, free our handles table and recreate a new one.
|
||||
*/
|
||||
|
||||
ULONG i;
|
||||
|
||||
/* Close all console handles and free the handle table memory */
|
||||
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
||||
{
|
||||
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
|
||||
}
|
||||
ProcessData->HandleTableSize = 0;
|
||||
RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
|
||||
ProcessData->HandleTable = NULL;
|
||||
|
||||
/*
|
||||
* Create a new handle table - Insert the IO handles
|
||||
*/
|
||||
|
||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
/* Insert the Input handle */
|
||||
Status = Win32CsrInsertObject(ProcessData,
|
||||
&ConnectInfo->InputHandle,
|
||||
|
@ -427,9 +484,10 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to insert the input handle\n");
|
||||
ConioDeleteConsole(ProcessData->Console);
|
||||
ProcessData->Console = NULL;
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
// ConioDeleteConsole(ProcessData->Console);
|
||||
// ProcessData->Console = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -443,11 +501,12 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to insert the output handle\n");
|
||||
ConioDeleteConsole(ProcessData->Console);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
ConnectInfo->InputHandle);
|
||||
ProcessData->Console = NULL;
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// ConnectInfo->InputHandle);
|
||||
// ConioDeleteConsole(ProcessData->Console);
|
||||
// ProcessData->Console = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -461,15 +520,18 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to insert the error handle\n");
|
||||
ConioDeleteConsole(ProcessData->Console);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
ConnectInfo->OutputHandle);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
ConnectInfo->InputHandle);
|
||||
ProcessData->Console = NULL;
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// ConnectInfo->OutputHandle);
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// ConnectInfo->InputHandle);
|
||||
// ConioDeleteConsole(ProcessData->Console);
|
||||
// ProcessData->Console = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
}
|
||||
|
||||
/* Duplicate the Event */
|
||||
|
@ -481,18 +543,18 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
|
||||
ConioDeleteConsole(ProcessData->Console);
|
||||
if (NewConsole /* || !ProcessData->bInheritHandles */)
|
||||
{
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
ConnectInfo->ErrorHandle);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
ConnectInfo->OutputHandle);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
ConnectInfo->InputHandle);
|
||||
}
|
||||
ProcessData->Console = NULL;
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
// if (NewConsole)
|
||||
// {
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// ConnectInfo->ErrorHandle);
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// ConnectInfo->OutputHandle);
|
||||
// Win32CsrReleaseObject(ProcessData,
|
||||
// ConnectInfo->InputHandle);
|
||||
// }
|
||||
// ConioDeleteConsole(ProcessData->Console); // FIXME: Just release the console ?
|
||||
// ProcessData->Console = NULL;
|
||||
return Status;
|
||||
}
|
||||
/* Input Wait Handle */
|
||||
|
@ -500,49 +562,11 @@ ConsoleConnect(IN PCSR_PROCESS CsrProcess,
|
|||
|
||||
/* Set the Ctrl Dispatcher */
|
||||
ProcessData->CtrlDispatcher = ConnectInfo->CtrlDispatcher;
|
||||
DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
|
||||
DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
|
||||
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
Win32CsrReleaseConsole(PCSR_PROCESS Process)
|
||||
{
|
||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(Process);
|
||||
PCONSOLE Console;
|
||||
ULONG i;
|
||||
|
||||
DPRINT1("Win32CsrReleaseConsole\n");
|
||||
|
||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
/* Close all console handles and free the handle table memory */
|
||||
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
||||
{
|
||||
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
|
||||
}
|
||||
ProcessData->HandleTableSize = 0;
|
||||
RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
|
||||
ProcessData->HandleTable = NULL;
|
||||
|
||||
/* Detach process from console */
|
||||
Console = ProcessData->Console;
|
||||
if (Console != NULL)
|
||||
{
|
||||
DPRINT1("Win32CsrReleaseConsole - Console->ReferenceCount = %lu - We are going to decrement it !\n", Console->ReferenceCount);
|
||||
ProcessData->Console = NULL;
|
||||
EnterCriticalSection(&Console->Lock);
|
||||
RemoveEntryList(&ProcessData->ConsoleLink);
|
||||
Win32CsrUnlockConsole(Console);
|
||||
//CloseHandle(ProcessData->ConsoleEvent);
|
||||
//ProcessData->ConsoleEvent = NULL;
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||
}
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
ConsoleDisconnect(PCSR_PROCESS Process)
|
||||
|
@ -551,19 +575,14 @@ ConsoleDisconnect(PCSR_PROCESS Process)
|
|||
|
||||
/**************************************************************************
|
||||
* This function is called whenever a new process (GUI or CUI) is destroyed.
|
||||
*
|
||||
* Only do something if the process is a CUI. <-- modify this behaviour if
|
||||
* we deal with a GUI which
|
||||
* quits and acquired a
|
||||
* console...
|
||||
**************************************************************************/
|
||||
|
||||
DPRINT1("ConsoleDisconnect called\n");
|
||||
// if (ProcessData->Console != NULL)
|
||||
if (ProcessData->ConsoleApp)
|
||||
if ( ProcessData->Console != NULL ||
|
||||
ProcessData->HandleTable != NULL )
|
||||
{
|
||||
DPRINT1("ConsoleDisconnect - calling Win32CsrReleaseConsole\n");
|
||||
Win32CsrReleaseConsole(Process);
|
||||
Win32CsrReleaseConsole(ProcessData);
|
||||
}
|
||||
|
||||
RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
|
|
@ -107,7 +107,7 @@ PCSR_API_ROUTINE ConsoleServerApiDispatchTable[ConsolepMaxApiNumber] =
|
|||
// SrvRegisterConsoleIME,
|
||||
// SrvUnregisterConsoleIME,
|
||||
// SrvGetConsoleLangId,
|
||||
// SrvAttachConsole,
|
||||
SrvAttachConsole,
|
||||
SrvGetConsoleSelectionInfo,
|
||||
SrvGetConsoleProcessList,
|
||||
SrvGetConsoleHistory,
|
||||
|
@ -198,7 +198,7 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber] =
|
|||
// FALSE, // SrvRegisterConsoleIME,
|
||||
// FALSE, // SrvUnregisterConsoleIME,
|
||||
// FALSE, // SrvGetConsoleLangId,
|
||||
// FALSE, // SrvAttachConsole,
|
||||
FALSE, // SrvAttachConsole,
|
||||
FALSE, // SrvGetConsoleSelectionInfo,
|
||||
FALSE, // SrvGetConsoleProcessList,
|
||||
FALSE, // SrvGetConsoleHistory,
|
||||
|
@ -291,7 +291,7 @@ PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber] =
|
|||
// "RegisterConsoleIME",
|
||||
// "UnregisterConsoleIME",
|
||||
// "GetConsoleLangId",
|
||||
// "AttachConsole",
|
||||
"AttachConsole",
|
||||
"GetConsoleSelectionInfo",
|
||||
"GetConsoleProcessList",
|
||||
"GetConsoleHistory",
|
||||
|
|
Loading…
Reference in a new issue