2010-05-31 06:28:55 +00:00
|
|
|
|
/*
|
2012-10-25 20:40:41 +00:00
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
|
* PROJECT: ReactOS Console Server DLL
|
2015-10-05 12:21:25 +00:00
|
|
|
|
* FILE: win32ss/user/winsrv/consrv/console.c
|
2013-04-07 23:18:59 +00:00
|
|
|
|
* PURPOSE: Console Management Functions
|
2013-04-10 20:22:30 +00:00
|
|
|
|
* PROGRAMMERS: G<EFBFBD> van Geldorp
|
|
|
|
|
* Jeffrey Morlan
|
|
|
|
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2013-03-19 22:05:38 +00:00
|
|
|
|
/* INCLUDES *******************************************************************/
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2012-10-23 22:31:36 +00:00
|
|
|
|
#include "consrv.h"
|
2014-02-04 19:54:42 +00:00
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
/* This is for COM usage */
|
|
|
|
|
#define COBJMACROS
|
|
|
|
|
#include <shlobj.h>
|
|
|
|
|
|
|
|
|
|
|
2014-05-04 00:01:48 +00:00
|
|
|
|
#include <alias.h>
|
2014-08-29 19:45:45 +00:00
|
|
|
|
#include <history.h>
|
2013-04-07 23:18:59 +00:00
|
|
|
|
#include "procinit.h"
|
2013-03-24 17:08:10 +00:00
|
|
|
|
|
2013-03-30 18:44:56 +00:00
|
|
|
|
#define NDEBUG
|
2010-05-31 06:28:55 +00:00
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
/* GLOBALS ********************************************************************/
|
2012-10-23 22:31:36 +00:00
|
|
|
|
|
2014-09-05 21:12:42 +00:00
|
|
|
|
/* The list of the ConSrv consoles */
|
2014-05-04 00:01:48 +00:00
|
|
|
|
static ULONG ConsoleListSize;
|
2014-09-05 21:12:42 +00:00
|
|
|
|
static PCONSRV_CONSOLE* ConsoleList;
|
2014-05-04 00:01:48 +00:00
|
|
|
|
static RTL_RESOURCE ListLock;
|
|
|
|
|
|
|
|
|
|
#define ConSrvLockConsoleListExclusive() \
|
|
|
|
|
RtlAcquireResourceExclusive(&ListLock, TRUE)
|
|
|
|
|
|
|
|
|
|
#define ConSrvLockConsoleListShared() \
|
|
|
|
|
RtlAcquireResourceShared(&ListLock, TRUE)
|
|
|
|
|
|
|
|
|
|
#define ConSrvUnlockConsoleList() \
|
|
|
|
|
RtlReleaseResource(&ListLock)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static NTSTATUS
|
|
|
|
|
InsertConsole(OUT PHANDLE Handle,
|
2014-08-12 14:59:13 +00:00
|
|
|
|
IN PCONSRV_CONSOLE Console)
|
2014-05-04 00:01:48 +00:00
|
|
|
|
{
|
|
|
|
|
#define CONSOLE_HANDLES_INCREMENT 2 * 3
|
|
|
|
|
|
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
|
ULONG i = 0;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE* Block;
|
2014-05-04 00:01:48 +00:00
|
|
|
|
|
|
|
|
|
ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
|
|
|
|
|
(ConsoleList != NULL && ConsoleListSize != 0) );
|
|
|
|
|
|
|
|
|
|
/* All went right, so add the console to the list */
|
|
|
|
|
ConSrvLockConsoleListExclusive();
|
2014-11-08 22:19:07 +00:00
|
|
|
|
DPRINT("Insert in the list\n");
|
2014-05-04 00:01:48 +00:00
|
|
|
|
|
|
|
|
|
if (ConsoleList)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < ConsoleListSize; i++)
|
|
|
|
|
{
|
|
|
|
|
if (ConsoleList[i] == NULL) break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i >= ConsoleListSize)
|
|
|
|
|
{
|
2014-11-08 22:19:07 +00:00
|
|
|
|
DPRINT("Creation of a new handles table\n");
|
2014-05-04 00:01:48 +00:00
|
|
|
|
/* Allocate a new handles table */
|
|
|
|
|
Block = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
|
|
|
|
|
(ConsoleListSize +
|
2014-08-12 14:59:13 +00:00
|
|
|
|
CONSOLE_HANDLES_INCREMENT) * sizeof(PCONSRV_CONSOLE));
|
2014-05-04 00:01:48 +00:00
|
|
|
|
if (Block == NULL)
|
|
|
|
|
{
|
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
|
goto Quit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we previously had a handles table, free it and use the new one */
|
|
|
|
|
if (ConsoleList)
|
|
|
|
|
{
|
|
|
|
|
/* Copy the handles from the old table to the new one */
|
|
|
|
|
RtlCopyMemory(Block,
|
|
|
|
|
ConsoleList,
|
2014-08-12 14:59:13 +00:00
|
|
|
|
ConsoleListSize * sizeof(PCONSRV_CONSOLE));
|
2014-05-04 00:01:48 +00:00
|
|
|
|
ConsoleFreeHeap(ConsoleList);
|
|
|
|
|
}
|
|
|
|
|
ConsoleList = Block;
|
|
|
|
|
ConsoleListSize += CONSOLE_HANDLES_INCREMENT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ConsoleList[i] = Console;
|
|
|
|
|
*Handle = ULongToHandle((i << 2) | 0x3);
|
|
|
|
|
|
|
|
|
|
Quit:
|
|
|
|
|
/* Unlock the console list and return status */
|
|
|
|
|
ConSrvUnlockConsoleList();
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Unused */
|
|
|
|
|
#if 0
|
|
|
|
|
static NTSTATUS
|
|
|
|
|
RemoveConsoleByHandle(IN HANDLE Handle)
|
|
|
|
|
{
|
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2014-05-04 00:01:48 +00:00
|
|
|
|
|
|
|
|
|
BOOLEAN ValidHandle = ((HandleToULong(Handle) & 0x3) == 0x3);
|
|
|
|
|
ULONG Index = HandleToULong(Handle) >> 2;
|
|
|
|
|
|
|
|
|
|
if (!ValidHandle) return STATUS_INVALID_HANDLE;
|
|
|
|
|
|
|
|
|
|
ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
|
|
|
|
|
(ConsoleList != NULL && ConsoleListSize != 0) );
|
|
|
|
|
|
|
|
|
|
/* Remove the console from the list */
|
|
|
|
|
ConSrvLockConsoleListExclusive();
|
|
|
|
|
|
|
|
|
|
if (Index >= ConsoleListSize ||
|
|
|
|
|
(Console = ConsoleList[Index]) == NULL)
|
|
|
|
|
{
|
|
|
|
|
Status = STATUS_INVALID_HANDLE;
|
|
|
|
|
goto Quit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ConsoleList[Index] = NULL;
|
|
|
|
|
|
|
|
|
|
Quit:
|
|
|
|
|
/* Unlock the console list and return status */
|
|
|
|
|
ConSrvUnlockConsoleList();
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static NTSTATUS
|
2014-08-12 14:59:13 +00:00
|
|
|
|
RemoveConsoleByPointer(IN PCONSRV_CONSOLE Console)
|
2014-05-04 00:01:48 +00:00
|
|
|
|
{
|
|
|
|
|
ULONG i = 0;
|
|
|
|
|
|
|
|
|
|
if (!Console) return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
|
|
|
|
|
(ConsoleList != NULL && ConsoleListSize != 0) );
|
|
|
|
|
|
|
|
|
|
/* Remove the console from the list */
|
|
|
|
|
ConSrvLockConsoleListExclusive();
|
|
|
|
|
|
|
|
|
|
if (ConsoleList)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < ConsoleListSize; i++)
|
|
|
|
|
{
|
|
|
|
|
if (ConsoleList[i] == Console) ConsoleList[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-05 21:12:42 +00:00
|
|
|
|
/* Unlock the console list and return */
|
2014-05-04 00:01:48 +00:00
|
|
|
|
ConSrvUnlockConsoleList();
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN NTAPI
|
2014-08-12 14:59:13 +00:00
|
|
|
|
ConSrvValidateConsole(OUT PCONSRV_CONSOLE* Console,
|
2014-05-04 00:01:48 +00:00
|
|
|
|
IN HANDLE ConsoleHandle,
|
|
|
|
|
IN CONSOLE_STATE ExpectedState,
|
|
|
|
|
IN BOOLEAN LockConsole)
|
|
|
|
|
{
|
|
|
|
|
BOOLEAN RetVal = FALSE;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE ValidatedConsole;
|
2014-05-04 00:01:48 +00:00
|
|
|
|
|
|
|
|
|
BOOLEAN ValidHandle = ((HandleToULong(ConsoleHandle) & 0x3) == 0x3);
|
|
|
|
|
ULONG Index = HandleToULong(ConsoleHandle) >> 2;
|
|
|
|
|
|
|
|
|
|
if (!ValidHandle) return FALSE;
|
|
|
|
|
|
|
|
|
|
if (!Console) return FALSE;
|
|
|
|
|
*Console = NULL;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Forbid creation or deletion of consoles when
|
|
|
|
|
* checking for the existence of a console.
|
|
|
|
|
*/
|
|
|
|
|
ConSrvLockConsoleListShared();
|
|
|
|
|
|
|
|
|
|
if (Index >= ConsoleListSize ||
|
|
|
|
|
(ValidatedConsole = ConsoleList[Index]) == NULL)
|
|
|
|
|
{
|
2014-09-05 21:12:42 +00:00
|
|
|
|
/* Unlock the console list and return */
|
2014-05-04 00:01:48 +00:00
|
|
|
|
ConSrvUnlockConsoleList();
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ValidatedConsole = ConsoleList[Index];
|
|
|
|
|
|
|
|
|
|
/* Unlock the console list and return */
|
|
|
|
|
ConSrvUnlockConsoleList();
|
|
|
|
|
|
2014-09-05 21:12:42 +00:00
|
|
|
|
RetVal = ConDrvValidateConsoleUnsafe((PCONSOLE)ValidatedConsole,
|
2014-05-04 00:01:48 +00:00
|
|
|
|
ExpectedState,
|
|
|
|
|
LockConsole);
|
|
|
|
|
if (RetVal) *Console = ValidatedConsole;
|
|
|
|
|
|
|
|
|
|
return RetVal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
2013-01-24 22:41:33 +00:00
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
// Adapted from reactos/lib/rtl/unicode.c, RtlCreateUnicodeString line 2180
|
|
|
|
|
static BOOLEAN
|
|
|
|
|
ConsoleCreateUnicodeString(IN OUT PUNICODE_STRING UniDest,
|
|
|
|
|
IN PCWSTR Source)
|
|
|
|
|
{
|
|
|
|
|
SIZE_T Size = (wcslen(Source) + 1) * sizeof(WCHAR);
|
|
|
|
|
if (Size > MAXUSHORT) return FALSE;
|
|
|
|
|
|
|
|
|
|
UniDest->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size);
|
|
|
|
|
if (UniDest->Buffer == NULL) return FALSE;
|
|
|
|
|
|
|
|
|
|
RtlCopyMemory(UniDest->Buffer, Source, Size);
|
|
|
|
|
UniDest->MaximumLength = (USHORT)Size;
|
|
|
|
|
UniDest->Length = (USHORT)Size - sizeof(WCHAR);
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Adapted from reactos/lib/rtl/unicode.c, RtlFreeUnicodeString line 431
|
|
|
|
|
static VOID
|
|
|
|
|
ConsoleFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
|
|
|
|
|
{
|
|
|
|
|
if (UnicodeString->Buffer)
|
|
|
|
|
{
|
|
|
|
|
ConsoleFreeHeap(UnicodeString->Buffer);
|
|
|
|
|
RtlZeroMemory(UnicodeString, sizeof(UNICODE_STRING));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
VOID
|
2014-08-11 20:28:40 +00:00
|
|
|
|
ConioPause(PCONSRV_CONSOLE Console, UINT Flags)
|
2013-01-24 22:41:33 +00:00
|
|
|
|
{
|
|
|
|
|
Console->PauseFlags |= Flags;
|
2014-09-05 21:12:42 +00:00
|
|
|
|
ConDrvPause((PCONSOLE)Console);
|
2013-01-24 22:41:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
VOID
|
2014-08-11 20:28:40 +00:00
|
|
|
|
ConioUnpause(PCONSRV_CONSOLE Console, UINT Flags)
|
2013-01-24 22:41:33 +00:00
|
|
|
|
{
|
|
|
|
|
Console->PauseFlags &= ~Flags;
|
|
|
|
|
|
|
|
|
|
// if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
|
2014-05-02 16:46:13 +00:00
|
|
|
|
if (Console->PauseFlags == 0)
|
2013-01-24 22:41:33 +00:00
|
|
|
|
{
|
2014-09-05 21:12:42 +00:00
|
|
|
|
ConDrvUnpause((PCONSOLE)Console);
|
2013-01-24 22:41:33 +00:00
|
|
|
|
|
|
|
|
|
CsrNotifyWait(&Console->WriteWaitQueue,
|
2013-10-05 22:17:34 +00:00
|
|
|
|
TRUE,
|
2013-01-24 22:41:33 +00:00
|
|
|
|
NULL,
|
|
|
|
|
NULL);
|
2013-01-26 16:12:05 +00:00
|
|
|
|
if (!IsListEmpty(&Console->WriteWaitQueue))
|
|
|
|
|
{
|
|
|
|
|
CsrDereferenceWait(&Console->WriteWaitQueue);
|
|
|
|
|
}
|
2013-01-24 22:41:33 +00:00
|
|
|
|
}
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
2013-04-07 23:18:59 +00:00
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
NTSTATUS
|
2014-05-04 00:01:48 +00:00
|
|
|
|
ConSrvGetConsole(IN PCONSOLE_PROCESS_DATA ProcessData,
|
2014-08-12 14:59:13 +00:00
|
|
|
|
OUT PCONSRV_CONSOLE* Console,
|
2014-05-04 00:01:48 +00:00
|
|
|
|
IN BOOLEAN LockConsole)
|
2013-04-07 23:18:59 +00:00
|
|
|
|
{
|
2014-05-04 00:01:48 +00:00
|
|
|
|
NTSTATUS Status = STATUS_INVALID_HANDLE;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE GrabConsole;
|
2013-04-07 23:18:59 +00:00
|
|
|
|
|
2014-05-04 00:01:48 +00:00
|
|
|
|
// if (Console == NULL) return STATUS_INVALID_PARAMETER;
|
2013-06-23 00:18:47 +00:00
|
|
|
|
ASSERT(Console);
|
|
|
|
|
*Console = NULL;
|
|
|
|
|
|
2014-05-04 00:01:48 +00:00
|
|
|
|
if (ConSrvValidateConsole(&GrabConsole,
|
|
|
|
|
ProcessData->ConsoleHandle,
|
|
|
|
|
CONSOLE_RUNNING,
|
|
|
|
|
LockConsole))
|
|
|
|
|
{
|
|
|
|
|
InterlockedIncrement(&GrabConsole->ReferenceCount);
|
|
|
|
|
*Console = GrabConsole;
|
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
}
|
2013-04-07 23:18:59 +00:00
|
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
VOID
|
2014-08-12 14:59:13 +00:00
|
|
|
|
ConSrvReleaseConsole(IN PCONSRV_CONSOLE Console,
|
2018-06-10 01:23:01 +00:00
|
|
|
|
IN BOOLEAN IsConsoleLocked)
|
2013-04-07 23:18:59 +00:00
|
|
|
|
{
|
2014-05-04 00:01:48 +00:00
|
|
|
|
LONG RefCount = 0;
|
|
|
|
|
|
|
|
|
|
if (!Console) return;
|
|
|
|
|
// if (Console->ReferenceCount == 0) return; // This shouldn't happen
|
|
|
|
|
ASSERT(Console->ReferenceCount > 0);
|
|
|
|
|
|
|
|
|
|
/* The console must be locked */
|
|
|
|
|
// ASSERT(Console_locked);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Decrement the reference count. Save the new value too,
|
|
|
|
|
* because Console->ReferenceCount might be modified after
|
|
|
|
|
* the console gets unlocked but before we check whether we
|
|
|
|
|
* can destroy it.
|
|
|
|
|
*/
|
|
|
|
|
RefCount = _InterlockedDecrement(&Console->ReferenceCount);
|
|
|
|
|
|
|
|
|
|
/* Unlock the console if needed */
|
2018-06-10 01:23:01 +00:00
|
|
|
|
if (IsConsoleLocked) LeaveCriticalSection(&Console->Lock);
|
2014-05-04 00:01:48 +00:00
|
|
|
|
|
|
|
|
|
/* Delete the console if needed */
|
|
|
|
|
if (RefCount <= 0) ConSrvDeleteConsole(Console);
|
2013-03-30 18:44:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-02-10 12:36:57 +00:00
|
|
|
|
|
2014-05-04 00:01:48 +00:00
|
|
|
|
/* CONSOLE INITIALIZATION FUNCTIONS *******************************************/
|
|
|
|
|
|
|
|
|
|
VOID NTAPI
|
|
|
|
|
ConSrvInitConsoleSupport(VOID)
|
|
|
|
|
{
|
|
|
|
|
DPRINT("CONSRV: ConSrvInitConsoleSupport()\n");
|
|
|
|
|
|
|
|
|
|
/* Initialize the console list and its lock */
|
|
|
|
|
ConsoleListSize = 0;
|
|
|
|
|
ConsoleList = NULL;
|
|
|
|
|
RtlInitializeResource(&ListLock);
|
|
|
|
|
|
|
|
|
|
/* Should call LoadKeyboardLayout */
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-03 01:59:28 +00:00
|
|
|
|
NTSTATUS NTAPI
|
|
|
|
|
ConSrvInitTerminal(IN OUT PTERMINAL Terminal,
|
2015-03-24 23:58:44 +00:00
|
|
|
|
IN OUT PCONSOLE_STATE_INFO ConsoleInfo,
|
|
|
|
|
IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
|
|
|
|
|
IN HANDLE ConsoleLeaderProcessHandle);
|
2014-05-03 01:59:28 +00:00
|
|
|
|
NTSTATUS NTAPI
|
|
|
|
|
ConSrvDeinitTerminal(IN OUT PTERMINAL Terminal);
|
2014-05-02 18:44:26 +00:00
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
|
|
|
|
|
static BOOL
|
2015-03-24 23:58:44 +00:00
|
|
|
|
LoadShellLinkConsoleInfo(IN OUT PCONSOLE_STATE_INFO ConsoleInfo,
|
2014-09-07 22:53:49 +00:00
|
|
|
|
IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo)
|
|
|
|
|
{
|
|
|
|
|
#define PATH_SEPARATOR L'\\'
|
|
|
|
|
|
|
|
|
|
BOOL RetVal = FALSE;
|
|
|
|
|
HRESULT hRes = S_OK;
|
|
|
|
|
SIZE_T Length = 0;
|
|
|
|
|
LPWSTR LinkName = NULL;
|
|
|
|
|
LPWSTR IconPath = NULL;
|
|
|
|
|
WCHAR Buffer[MAX_PATH + 1];
|
|
|
|
|
|
|
|
|
|
ConsoleInitInfo->ConsoleStartInfo->IconIndex = 0;
|
|
|
|
|
|
|
|
|
|
if ((ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
|
|
|
|
{
|
|
|
|
|
// return FALSE; // FIXME!! (for icon loading)
|
|
|
|
|
RetVal = TRUE;
|
|
|
|
|
goto Finish;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 1- Find the last path separator if any */
|
|
|
|
|
LinkName = wcsrchr(ConsoleInfo->ConsoleTitle, PATH_SEPARATOR);
|
|
|
|
|
if (LinkName == NULL)
|
|
|
|
|
LinkName = ConsoleInfo->ConsoleTitle;
|
|
|
|
|
else
|
|
|
|
|
++LinkName; // Skip the path separator
|
|
|
|
|
|
|
|
|
|
/* 2- Check for the link extension. The name ".lnk" is considered invalid. */
|
|
|
|
|
Length = wcslen(LinkName);
|
|
|
|
|
if ( (Length <= 4) || (wcsicmp(LinkName + (Length - 4), L".lnk") != 0) )
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
/* 3- It may be a link. Try to retrieve some properties */
|
|
|
|
|
hRes = CoInitialize(NULL);
|
|
|
|
|
if (SUCCEEDED(hRes))
|
|
|
|
|
{
|
|
|
|
|
/* Get a pointer to the IShellLink interface */
|
|
|
|
|
IShellLinkW* pshl = NULL;
|
|
|
|
|
hRes = CoCreateInstance(&CLSID_ShellLink,
|
2014-11-08 22:19:07 +00:00
|
|
|
|
NULL,
|
2014-09-07 22:53:49 +00:00
|
|
|
|
CLSCTX_INPROC_SERVER,
|
|
|
|
|
&IID_IShellLinkW,
|
|
|
|
|
(LPVOID*)&pshl);
|
|
|
|
|
if (SUCCEEDED(hRes))
|
|
|
|
|
{
|
|
|
|
|
/* Get a pointer to the IPersistFile interface */
|
|
|
|
|
IPersistFile* ppf = NULL;
|
|
|
|
|
hRes = IPersistFile_QueryInterface(pshl, &IID_IPersistFile, (LPVOID*)&ppf);
|
|
|
|
|
if (SUCCEEDED(hRes))
|
|
|
|
|
{
|
|
|
|
|
/* Load the shortcut */
|
|
|
|
|
hRes = IPersistFile_Load(ppf, ConsoleInfo->ConsoleTitle, STGM_READ);
|
|
|
|
|
if (SUCCEEDED(hRes))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* Finally we can get the properties !
|
|
|
|
|
* Update the old ones if needed.
|
|
|
|
|
*/
|
|
|
|
|
INT ShowCmd = 0;
|
|
|
|
|
// WORD HotKey = 0;
|
|
|
|
|
|
|
|
|
|
/* Reset the name of the console with the name of the shortcut */
|
|
|
|
|
Length = min(/*Length*/ Length - 4, // 4 == len(".lnk")
|
2015-03-24 23:58:44 +00:00
|
|
|
|
(ConsoleInfo->cbSize - FIELD_OFFSET(CONSOLE_STATE_INFO, ConsoleTitle) - sizeof(UNICODE_NULL)) / sizeof(WCHAR));
|
2014-09-07 22:53:49 +00:00
|
|
|
|
wcsncpy(ConsoleInfo->ConsoleTitle, LinkName, Length);
|
2015-03-24 23:58:44 +00:00
|
|
|
|
ConsoleInfo->ConsoleTitle[Length] = UNICODE_NULL;
|
2014-09-07 22:53:49 +00:00
|
|
|
|
|
|
|
|
|
/* Get the window showing command */
|
|
|
|
|
hRes = IShellLinkW_GetShowCmd(pshl, &ShowCmd);
|
|
|
|
|
if (SUCCEEDED(hRes)) ConsoleInitInfo->ConsoleStartInfo->wShowWindow = (WORD)ShowCmd;
|
|
|
|
|
|
|
|
|
|
/* Get the hotkey */
|
|
|
|
|
// hRes = pshl->GetHotkey(&ShowCmd);
|
|
|
|
|
// if (SUCCEEDED(hRes)) ConsoleInitInfo->ConsoleStartInfo->HotKey = HotKey;
|
|
|
|
|
|
|
|
|
|
/* Get the icon location, if any */
|
|
|
|
|
hRes = IShellLinkW_GetIconLocation(pshl,
|
|
|
|
|
Buffer,
|
|
|
|
|
sizeof(Buffer)/sizeof(Buffer[0]) - 1, // == MAX_PATH
|
|
|
|
|
&ConsoleInitInfo->ConsoleStartInfo->IconIndex);
|
|
|
|
|
if (!SUCCEEDED(hRes))
|
|
|
|
|
{
|
|
|
|
|
ConsoleInitInfo->ConsoleStartInfo->IconIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
IconPath = Buffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: Since we still don't load console properties from the shortcut,
|
|
|
|
|
// return false. When this will be done, we will return true instead.
|
|
|
|
|
RetVal = TRUE; // FALSE;
|
|
|
|
|
}
|
|
|
|
|
IPersistFile_Release(ppf);
|
|
|
|
|
}
|
|
|
|
|
IShellLinkW_Release(pshl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CoUninitialize();
|
|
|
|
|
|
|
|
|
|
Finish:
|
|
|
|
|
|
|
|
|
|
if (RetVal)
|
|
|
|
|
{
|
|
|
|
|
/* Get the associated icon, if any */
|
|
|
|
|
if (IconPath == NULL)
|
|
|
|
|
{
|
|
|
|
|
// Question: How to retrieve the full path name
|
|
|
|
|
// of the app we are going to run??
|
|
|
|
|
Length = RtlDosSearchPath_U(ConsoleInitInfo->CurDir,
|
|
|
|
|
ConsoleInitInfo->AppName,
|
|
|
|
|
NULL,
|
|
|
|
|
sizeof(Buffer),
|
|
|
|
|
Buffer,
|
|
|
|
|
NULL);
|
|
|
|
|
if (Length > 0 && Length < sizeof(Buffer))
|
|
|
|
|
IconPath = Buffer;
|
|
|
|
|
else
|
|
|
|
|
IconPath = ConsoleInitInfo->AppName;
|
|
|
|
|
|
|
|
|
|
// ConsoleInitInfo->ConsoleStartInfo->IconIndex = 0;
|
|
|
|
|
}
|
2014-11-08 22:19:07 +00:00
|
|
|
|
DPRINT("IconPath = '%S' ; IconIndex = %lu\n",
|
|
|
|
|
IconPath, ConsoleInitInfo->ConsoleStartInfo->IconIndex);
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if (IconPath && *IconPath)
|
|
|
|
|
{
|
|
|
|
|
HICON hIcon = NULL, hIconSm = NULL;
|
2015-03-08 14:28:19 +00:00
|
|
|
|
/*
|
|
|
|
|
* FIXME!! Because of a strange bug we have in PrivateExtractIconExW
|
|
|
|
|
* (see r65683 for more details), we cannot use this API to extract
|
|
|
|
|
* at the same time the large and small icons from the app.
|
|
|
|
|
* Instead we just use PrivateExtractIconsW.
|
|
|
|
|
*
|
2014-09-07 22:53:49 +00:00
|
|
|
|
PrivateExtractIconExW(IconPath,
|
|
|
|
|
ConsoleInitInfo->ConsoleStartInfo->IconIndex,
|
|
|
|
|
&hIcon,
|
|
|
|
|
&hIconSm,
|
|
|
|
|
1);
|
2015-03-08 14:28:19 +00:00
|
|
|
|
*/
|
|
|
|
|
PrivateExtractIconsW(IconPath,
|
|
|
|
|
ConsoleInitInfo->ConsoleStartInfo->IconIndex,
|
|
|
|
|
32, 32,
|
|
|
|
|
&hIcon, NULL, 1, LR_COPYFROMRESOURCE);
|
|
|
|
|
PrivateExtractIconsW(IconPath,
|
|
|
|
|
ConsoleInitInfo->ConsoleStartInfo->IconIndex,
|
|
|
|
|
16, 16,
|
|
|
|
|
&hIconSm, NULL, 1, LR_COPYFROMRESOURCE);
|
|
|
|
|
|
2014-11-08 22:19:07 +00:00
|
|
|
|
DPRINT("hIcon = 0x%p ; hIconSm = 0x%p\n", hIcon, hIconSm);
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if (hIcon != NULL) ConsoleInitInfo->ConsoleStartInfo->hIcon = hIcon;
|
|
|
|
|
if (hIconSm != NULL) ConsoleInitInfo->ConsoleStartInfo->hIconSm = hIconSm;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: See the previous FIXME above.
|
|
|
|
|
RetVal = FALSE;
|
|
|
|
|
|
|
|
|
|
return RetVal;
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-12 15:44:22 +00:00
|
|
|
|
NTSTATUS NTAPI
|
2013-07-06 19:47:53 +00:00
|
|
|
|
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
2014-08-12 14:59:13 +00:00
|
|
|
|
OUT PCONSRV_CONSOLE* NewConsole,
|
2014-09-07 22:53:49 +00:00
|
|
|
|
IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
|
2015-03-11 01:21:29 +00:00
|
|
|
|
IN PCSR_PROCESS ConsoleLeaderProcess)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
|
|
|
|
NTSTATUS Status;
|
2013-07-06 19:47:53 +00:00
|
|
|
|
HANDLE ConsoleHandle;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2015-03-24 23:58:44 +00:00
|
|
|
|
|
|
|
|
|
BYTE ConsoleInfoBuffer[sizeof(CONSOLE_STATE_INFO) + MAX_PATH * sizeof(WCHAR)]; // CONSRV console information
|
|
|
|
|
PCONSOLE_STATE_INFO ConsoleInfo = (PCONSOLE_STATE_INFO)&ConsoleInfoBuffer;
|
|
|
|
|
CONSOLE_INFO DrvConsoleInfo; // Console information for CONDRV
|
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
SIZE_T Length = 0;
|
2014-05-02 18:44:26 +00:00
|
|
|
|
|
2014-05-03 01:59:28 +00:00
|
|
|
|
TERMINAL Terminal; /* The ConSrv terminal for this console */
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if (NewConsole == NULL || ConsoleInitInfo == NULL)
|
2013-06-23 00:18:47 +00:00
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
2013-01-02 00:32:20 +00:00
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
*NewConsole = NULL;
|
2013-01-02 00:32:20 +00:00
|
|
|
|
|
2013-02-10 12:36:57 +00:00
|
|
|
|
/*
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
* Load the console settings
|
|
|
|
|
*/
|
2015-03-24 23:58:44 +00:00
|
|
|
|
RtlZeroMemory(ConsoleInfo, sizeof(ConsoleInfoBuffer));
|
|
|
|
|
ConsoleInfo->cbSize = sizeof(ConsoleInfoBuffer);
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
|
2015-04-05 23:04:42 +00:00
|
|
|
|
/* 1. Get the title of the console (initialize ConsoleInfo->ConsoleTitle) */
|
2014-09-07 22:53:49 +00:00
|
|
|
|
Length = min(ConsoleInitInfo->TitleLength,
|
2015-03-24 23:58:44 +00:00
|
|
|
|
(ConsoleInfo->cbSize - FIELD_OFFSET(CONSOLE_STATE_INFO, ConsoleTitle) - sizeof(UNICODE_NULL)) / sizeof(WCHAR));
|
|
|
|
|
wcsncpy(ConsoleInfo->ConsoleTitle, ConsoleInitInfo->ConsoleTitle, Length);
|
|
|
|
|
ConsoleInfo->ConsoleTitle[Length] = UNICODE_NULL; // NULL-terminate it.
|
2013-06-23 00:18:47 +00:00
|
|
|
|
|
2015-04-05 23:04:42 +00:00
|
|
|
|
/* 2. Impersonate the caller in order to retrieve settings in its context */
|
|
|
|
|
if (!CsrImpersonateClient(NULL))
|
|
|
|
|
return STATUS_BAD_IMPERSONATION_LEVEL;
|
|
|
|
|
|
|
|
|
|
/* 3. Load the default settings */
|
|
|
|
|
ConCfgGetDefaultSettings(ConsoleInfo);
|
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
/*
|
2015-04-05 23:04:42 +00:00
|
|
|
|
* 4. Load per-application terminal settings.
|
2014-09-07 22:53:49 +00:00
|
|
|
|
*
|
|
|
|
|
* Check whether the process creating the console was launched via
|
|
|
|
|
* a shell-link. ConsoleInfo->ConsoleTitle may be updated with the
|
|
|
|
|
* name of the shortcut, and ConsoleStartInfo->Icon[Path|Index] too.
|
|
|
|
|
*/
|
|
|
|
|
// if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) // FIXME!! (for icon loading)
|
|
|
|
|
{
|
2015-03-24 23:58:44 +00:00
|
|
|
|
if (!LoadShellLinkConsoleInfo(ConsoleInfo, ConsoleInitInfo))
|
2014-09-07 22:53:49 +00:00
|
|
|
|
{
|
|
|
|
|
ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags &= ~STARTF_TITLEISLINKNAME;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
/*
|
2015-04-05 23:04:42 +00:00
|
|
|
|
* 5. Load the remaining console settings via the registry.
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
*/
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if ((ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* Either we weren't created by an app launched via a shell-link,
|
|
|
|
|
* or we failed to load shell-link console properties.
|
|
|
|
|
* Therefore, load the console infos for the application from the registry.
|
|
|
|
|
*/
|
2015-04-05 23:04:42 +00:00
|
|
|
|
ConCfgReadUserSettings(ConsoleInfo, FALSE);
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Now, update them with the properties the user might gave to us
|
|
|
|
|
* via the STARTUPINFO structure before calling CreateProcess
|
|
|
|
|
* (and which was transmitted via the ConsoleStartInfo structure).
|
2013-03-24 17:08:10 +00:00
|
|
|
|
* We therefore overwrite the values read in the registry.
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
*/
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
{
|
2015-03-24 23:58:44 +00:00
|
|
|
|
ConsoleInfo->ScreenAttributes = (USHORT)ConsoleInitInfo->ConsoleStartInfo->wFillAttribute;
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
}
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
{
|
2015-03-24 23:58:44 +00:00
|
|
|
|
ConsoleInfo->ScreenBufferSize = ConsoleInitInfo->ConsoleStartInfo->dwScreenBufferSize;
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
}
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
{
|
2015-03-24 23:58:44 +00:00
|
|
|
|
ConsoleInfo->WindowSize = ConsoleInitInfo->ConsoleStartInfo->dwWindowSize;
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
}
|
2015-03-24 23:58:44 +00:00
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
/*
|
|
|
|
|
* Now, update them with the properties the user might gave to us
|
|
|
|
|
* via the STARTUPINFO structure before calling CreateProcess
|
|
|
|
|
* (and which was transmitted via the ConsoleStartInfo structure).
|
|
|
|
|
* We therefore overwrite the values read in the registry.
|
|
|
|
|
*/
|
|
|
|
|
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USEPOSITION)
|
|
|
|
|
{
|
|
|
|
|
ConsoleInfo->AutoPosition = FALSE;
|
|
|
|
|
ConsoleInfo->WindowPosition.x = ConsoleInitInfo->ConsoleStartInfo->dwWindowOrigin.X;
|
|
|
|
|
ConsoleInfo->WindowPosition.y = ConsoleInitInfo->ConsoleStartInfo->dwWindowOrigin.Y;
|
|
|
|
|
}
|
|
|
|
|
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN)
|
|
|
|
|
{
|
|
|
|
|
ConsoleInfo->FullScreen = TRUE;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2011-04-09 12:01:36 +00:00
|
|
|
|
}
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2015-04-05 23:04:42 +00:00
|
|
|
|
/* 6. Revert impersonation */
|
2015-03-24 23:58:44 +00:00
|
|
|
|
CsrRevertToSelf();
|
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
/* Set-up the code page */
|
2015-03-24 23:58:44 +00:00
|
|
|
|
ConsoleInfo->CodePage = GetOEMCP();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Initialize the ConSrv terminal and give it a chance to load
|
|
|
|
|
* its own settings and override the console settings.
|
|
|
|
|
*/
|
|
|
|
|
Status = ConSrvInitTerminal(&Terminal,
|
|
|
|
|
ConsoleInfo,
|
|
|
|
|
ConsoleInitInfo,
|
|
|
|
|
ConsoleLeaderProcess->ProcessHandle);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("CONSRV: Failed to initialize a terminal, Status = 0x%08lx\n", Status);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
DPRINT("CONSRV: Terminal initialized\n");
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2014-05-02 18:44:26 +00:00
|
|
|
|
/* Initialize a new console via the driver */
|
2015-03-24 23:58:44 +00:00
|
|
|
|
// DrvConsoleInfo.InputBufferSize = 0;
|
|
|
|
|
DrvConsoleInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize;
|
|
|
|
|
DrvConsoleInfo.ConsoleSize = ConsoleInfo->WindowSize;
|
|
|
|
|
DrvConsoleInfo.CursorSize = ConsoleInfo->CursorSize;
|
|
|
|
|
// DrvConsoleInfo.CursorBlinkOn = ConsoleInfo->CursorBlinkOn;
|
|
|
|
|
DrvConsoleInfo.ScreenAttrib = ConsoleInfo->ScreenAttributes;
|
|
|
|
|
DrvConsoleInfo.PopupAttrib = ConsoleInfo->PopupAttributes;
|
|
|
|
|
DrvConsoleInfo.CodePage = ConsoleInfo->CodePage;
|
|
|
|
|
Status = ConDrvInitConsole(&Console, &DrvConsoleInfo);
|
2013-02-10 12:36:57 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2013-06-23 00:18:47 +00:00
|
|
|
|
DPRINT1("Creating a new console failed, Status = 0x%08lx\n", Status);
|
2014-05-03 01:59:28 +00:00
|
|
|
|
ConSrvDeinitTerminal(&Terminal);
|
2013-02-10 12:36:57 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
ASSERT(Console);
|
|
|
|
|
DPRINT("Console initialized\n");
|
2012-11-24 12:40:56 +00:00
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
/*** Register ConSrv features ***/
|
2014-05-02 18:44:26 +00:00
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
/* Initialize the console title */
|
|
|
|
|
#if 0
|
|
|
|
|
WCHAR DefaultTitle[128];
|
|
|
|
|
#endif
|
2015-03-24 23:58:44 +00:00
|
|
|
|
ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo->ConsoleTitle);
|
2014-09-07 22:53:49 +00:00
|
|
|
|
#if 0
|
2015-03-24 23:58:44 +00:00
|
|
|
|
if (ConsoleInfo->ConsoleTitle[0] == UNICODE_NULL)
|
2014-09-07 22:53:49 +00:00
|
|
|
|
{
|
|
|
|
|
if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, DefaultTitle, sizeof(DefaultTitle) / sizeof(DefaultTitle[0])))
|
|
|
|
|
{
|
|
|
|
|
ConsoleCreateUnicodeString(&Console->Title, DefaultTitle);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#endif
|
2015-03-24 23:58:44 +00:00
|
|
|
|
ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo->ConsoleTitle);
|
2014-09-07 22:53:49 +00:00
|
|
|
|
#if 0
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2014-05-02 18:44:26 +00:00
|
|
|
|
/* Initialize process support */
|
2014-05-02 16:46:13 +00:00
|
|
|
|
InitializeListHead(&Console->ProcessList);
|
|
|
|
|
Console->NotifiedLastCloseProcess = NULL;
|
|
|
|
|
Console->NotifyLastClose = FALSE;
|
2015-08-15 17:05:13 +00:00
|
|
|
|
Console->HasFocus = FALSE;
|
2014-05-02 18:44:26 +00:00
|
|
|
|
|
|
|
|
|
/* Initialize pausing support */
|
|
|
|
|
Console->PauseFlags = 0;
|
2014-05-02 16:46:13 +00:00
|
|
|
|
InitializeListHead(&Console->ReadWaitQueue);
|
|
|
|
|
InitializeListHead(&Console->WriteWaitQueue);
|
|
|
|
|
|
2014-05-04 00:01:48 +00:00
|
|
|
|
/* Initialize the alias and history buffers */
|
|
|
|
|
Console->Aliases = NULL;
|
|
|
|
|
InitializeListHead(&Console->HistoryBuffers);
|
2015-03-24 23:58:44 +00:00
|
|
|
|
Console->HistoryBufferSize = ConsoleInfo->HistoryBufferSize;
|
|
|
|
|
Console->NumberOfHistoryBuffers = ConsoleInfo->NumberOfHistoryBuffers;
|
|
|
|
|
Console->HistoryNoDup = ConsoleInfo->HistoryNoDup;
|
2014-05-04 00:01:48 +00:00
|
|
|
|
|
2014-08-29 19:45:45 +00:00
|
|
|
|
/* Initialize the Input Line Discipline */
|
|
|
|
|
Console->LineBuffer = NULL;
|
|
|
|
|
Console->LinePos = Console->LineMaxSize = Console->LineSize = 0;
|
|
|
|
|
Console->LineComplete = Console->LineUpPressed = FALSE;
|
|
|
|
|
// LineWakeupMask
|
|
|
|
|
Console->LineInsertToggle =
|
2015-03-24 23:58:44 +00:00
|
|
|
|
Console->InsertMode = ConsoleInfo->InsertMode;
|
|
|
|
|
Console->QuickEdit = ConsoleInfo->QuickEdit;
|
2014-05-02 18:44:26 +00:00
|
|
|
|
|
2014-08-30 16:20:32 +00:00
|
|
|
|
/* Popup windows */
|
|
|
|
|
InitializeListHead(&Console->PopupWindows);
|
|
|
|
|
|
2014-08-11 20:28:40 +00:00
|
|
|
|
/* Colour table */
|
2015-03-24 23:58:44 +00:00
|
|
|
|
RtlCopyMemory(Console->Colors, ConsoleInfo->ColorTable,
|
|
|
|
|
sizeof(ConsoleInfo->ColorTable));
|
2014-08-11 20:28:40 +00:00
|
|
|
|
|
2014-11-22 22:13:08 +00:00
|
|
|
|
/* Create the Initialization Events */
|
|
|
|
|
Status = NtCreateEvent(&Console->InitEvents[INIT_SUCCESS], EVENT_ALL_ACCESS,
|
|
|
|
|
NULL, NotificationEvent, FALSE);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("NtCreateEvent(InitEvents[INIT_SUCCESS]) failed: %lu\n", Status);
|
|
|
|
|
ConDrvDeleteConsole(Console);
|
|
|
|
|
ConSrvDeinitTerminal(&Terminal);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
Status = NtCreateEvent(&Console->InitEvents[INIT_FAILURE], EVENT_ALL_ACCESS,
|
|
|
|
|
NULL, NotificationEvent, FALSE);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("NtCreateEvent(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
|
|
|
|
|
NtClose(Console->InitEvents[INIT_SUCCESS]);
|
|
|
|
|
ConDrvDeleteConsole(Console);
|
|
|
|
|
ConSrvDeinitTerminal(&Terminal);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-05 21:12:42 +00:00
|
|
|
|
/*
|
|
|
|
|
* Attach the ConSrv terminal to the console.
|
|
|
|
|
* This call makes a copy of our local Terminal variable.
|
|
|
|
|
*/
|
2015-03-24 23:58:44 +00:00
|
|
|
|
Status = ConDrvAttachTerminal(Console, &Terminal);
|
2013-06-23 00:18:47 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2014-05-03 01:59:28 +00:00
|
|
|
|
DPRINT1("Failed to register terminal to the given console, Status = 0x%08lx\n", Status);
|
2014-11-22 22:13:08 +00:00
|
|
|
|
NtClose(Console->InitEvents[INIT_FAILURE]);
|
|
|
|
|
NtClose(Console->InitEvents[INIT_SUCCESS]);
|
2013-06-23 00:18:47 +00:00
|
|
|
|
ConDrvDeleteConsole(Console);
|
2014-05-03 01:59:28 +00:00
|
|
|
|
ConSrvDeinitTerminal(&Terminal);
|
2013-06-23 00:18:47 +00:00
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
2015-03-24 23:58:44 +00:00
|
|
|
|
DPRINT("Terminal attached\n");
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2014-05-04 00:01:48 +00:00
|
|
|
|
/* All went right, so add the console to the list */
|
|
|
|
|
Status = InsertConsole(&ConsoleHandle, Console);
|
|
|
|
|
|
2014-11-22 22:13:08 +00:00
|
|
|
|
// FIXME! We do not support at all asynchronous console creation!
|
|
|
|
|
NtSetEvent(Console->InitEvents[INIT_SUCCESS], NULL);
|
|
|
|
|
// NtSetEvent(Console->InitEvents[INIT_FAILURE], NULL);
|
|
|
|
|
|
[CONSOLE.DLL-KERNEL32-CONSRV]
Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).
[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.
[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.
svn path=/branches/ros-csrss/; revision=58415
2013-03-03 15:35:12 +00:00
|
|
|
|
/* Return the newly created console to the caller and a success code too */
|
2013-07-06 19:47:53 +00:00
|
|
|
|
*NewConsoleHandle = ConsoleHandle;
|
|
|
|
|
*NewConsole = Console;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-12 15:44:22 +00:00
|
|
|
|
VOID NTAPI
|
2014-08-12 14:59:13 +00:00
|
|
|
|
ConSrvDeleteConsole(PCONSRV_CONSOLE Console)
|
2013-01-24 22:41:33 +00:00
|
|
|
|
{
|
2013-04-06 13:40:34 +00:00
|
|
|
|
DPRINT("ConSrvDeleteConsole\n");
|
2013-01-24 22:41:33 +00:00
|
|
|
|
|
2014-05-04 00:01:48 +00:00
|
|
|
|
// FIXME: Send a terminate message to all the processes owning this console
|
|
|
|
|
|
|
|
|
|
/* Remove the console from the list */
|
|
|
|
|
RemoveConsoleByPointer(Console);
|
|
|
|
|
|
2014-11-22 22:13:08 +00:00
|
|
|
|
/* Destroy the Initialization Events */
|
|
|
|
|
NtClose(Console->InitEvents[INIT_FAILURE]);
|
|
|
|
|
NtClose(Console->InitEvents[INIT_SUCCESS]);
|
|
|
|
|
|
2014-08-31 14:04:03 +00:00
|
|
|
|
/* Clean the Input Line Discipline */
|
|
|
|
|
if (Console->LineBuffer) ConsoleFreeHeap(Console->LineBuffer);
|
|
|
|
|
|
2014-05-04 00:01:48 +00:00
|
|
|
|
/* Clean aliases and history */
|
|
|
|
|
IntDeleteAllAliases(Console);
|
|
|
|
|
HistoryDeleteBuffers(Console);
|
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
/* Free the console title */
|
|
|
|
|
ConsoleFreeUnicodeString(&Console->OriginalTitle);
|
|
|
|
|
ConsoleFreeUnicodeString(&Console->Title);
|
|
|
|
|
|
2015-03-24 23:58:44 +00:00
|
|
|
|
/* Now, call the driver. ConDrvDetachTerminal is called on-demand. */
|
2014-09-05 21:12:42 +00:00
|
|
|
|
ConDrvDeleteConsole((PCONSOLE)Console);
|
|
|
|
|
|
|
|
|
|
/* Deinit the ConSrv terminal */
|
|
|
|
|
// FIXME!!
|
2014-12-14 21:18:40 +00:00
|
|
|
|
// ConSrvDeinitTerminal(&Terminal);
|
2013-01-24 22:41:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-03-19 22:05:38 +00:00
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-01-03 12:26:57 +00:00
|
|
|
|
NTSTATUS
|
2014-05-02 16:46:13 +00:00
|
|
|
|
ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
|
|
|
|
|
IN PCONSOLE_PROCESS_DATA ProcessData,
|
|
|
|
|
IN ULONG Timeout)
|
|
|
|
|
{
|
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
|
|
DPRINT("ConSrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
|
|
|
|
|
|
2015-03-24 23:58:44 +00:00
|
|
|
|
/*
|
|
|
|
|
* Be sure we effectively have a control routine. It resides in kernel32.dll (client).
|
|
|
|
|
*/
|
|
|
|
|
if (ProcessData->CtrlRoutine == NULL) return Status;
|
|
|
|
|
|
|
|
|
|
_SEH2_TRY
|
2014-05-02 16:46:13 +00:00
|
|
|
|
{
|
2015-03-24 23:58:44 +00:00
|
|
|
|
HANDLE Thread = NULL;
|
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
_SEH2_TRY
|
|
|
|
|
{
|
2015-03-24 23:58:44 +00:00
|
|
|
|
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
|
|
|
|
ProcessData->CtrlRoutine,
|
|
|
|
|
UlongToPtr(CtrlEvent), 0, NULL);
|
|
|
|
|
if (NULL == Thread)
|
2014-05-02 16:46:13 +00:00
|
|
|
|
{
|
2015-03-24 23:58:44 +00:00
|
|
|
|
Status = RtlGetLastNtStatus();
|
|
|
|
|
DPRINT1("Failed thread creation, Status = 0x%08lx\n", Status);
|
2014-05-02 16:46:13 +00:00
|
|
|
|
}
|
2015-03-24 23:58:44 +00:00
|
|
|
|
else
|
2014-05-02 16:46:13 +00:00
|
|
|
|
{
|
2015-03-24 23:58:44 +00:00
|
|
|
|
DPRINT("ProcessData->CtrlRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
|
|
|
|
|
ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
|
|
|
|
WaitForSingleObject(Thread, Timeout);
|
2014-05-02 16:46:13 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-24 23:58:44 +00:00
|
|
|
|
_SEH2_FINALLY
|
2014-05-02 16:46:13 +00:00
|
|
|
|
{
|
2015-03-24 23:58:44 +00:00
|
|
|
|
CloseHandle(Thread);
|
2014-05-02 16:46:13 +00:00
|
|
|
|
}
|
|
|
|
|
_SEH2_END;
|
|
|
|
|
}
|
2015-03-24 23:58:44 +00:00
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
|
{
|
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
|
DPRINT1("ConSrvConsoleCtrlEventTimeout - Caught an exception, Status = 0x%08lx\n", Status);
|
|
|
|
|
}
|
|
|
|
|
_SEH2_END;
|
2014-05-02 16:46:13 +00:00
|
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
|
ConSrvConsoleCtrlEvent(IN ULONG CtrlEvent,
|
|
|
|
|
IN PCONSOLE_PROCESS_DATA ProcessData)
|
|
|
|
|
{
|
|
|
|
|
return ConSrvConsoleCtrlEventTimeout(CtrlEvent, ProcessData, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PCONSOLE_PROCESS_DATA NTAPI
|
2014-08-11 20:28:40 +00:00
|
|
|
|
ConSrvGetConsoleLeaderProcess(IN PCONSRV_CONSOLE Console)
|
2014-05-02 16:46:13 +00:00
|
|
|
|
{
|
|
|
|
|
if (Console == NULL) return NULL;
|
|
|
|
|
|
|
|
|
|
return CONTAINING_RECORD(Console->ProcessList.Blink,
|
|
|
|
|
CONSOLE_PROCESS_DATA,
|
|
|
|
|
ConsoleLink);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NTSTATUS NTAPI
|
2014-08-12 14:59:13 +00:00
|
|
|
|
ConSrvGetConsoleProcessList(IN PCONSRV_CONSOLE Console,
|
2014-05-02 16:46:13 +00:00
|
|
|
|
IN OUT PULONG ProcessIdsList,
|
|
|
|
|
IN ULONG MaxIdListItems,
|
|
|
|
|
OUT PULONG ProcessIdsTotal)
|
|
|
|
|
{
|
|
|
|
|
PCONSOLE_PROCESS_DATA current;
|
|
|
|
|
PLIST_ENTRY current_entry;
|
|
|
|
|
|
|
|
|
|
if (Console == NULL || ProcessIdsList == NULL || ProcessIdsTotal == NULL)
|
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
*ProcessIdsTotal = 0;
|
|
|
|
|
|
|
|
|
|
for (current_entry = Console->ProcessList.Flink;
|
|
|
|
|
current_entry != &Console->ProcessList;
|
|
|
|
|
current_entry = current_entry->Flink)
|
|
|
|
|
{
|
|
|
|
|
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
|
|
|
|
|
if (++(*ProcessIdsTotal) <= MaxIdListItems)
|
|
|
|
|
{
|
|
|
|
|
*ProcessIdsList++ = HandleToUlong(current->Process->ClientId.UniqueProcess);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ConSrvGenerateConsoleCtrlEvent
|
|
|
|
|
NTSTATUS NTAPI
|
2014-08-11 20:28:40 +00:00
|
|
|
|
ConSrvConsoleProcessCtrlEvent(IN PCONSRV_CONSOLE Console,
|
2014-05-02 16:46:13 +00:00
|
|
|
|
IN ULONG ProcessGroupId,
|
|
|
|
|
IN ULONG CtrlEvent)
|
|
|
|
|
{
|
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
|
PLIST_ENTRY current_entry;
|
|
|
|
|
PCONSOLE_PROCESS_DATA current;
|
|
|
|
|
|
|
|
|
|
/* If the console is already being destroyed, just return */
|
2014-09-05 21:12:42 +00:00
|
|
|
|
if (!ConDrvValidateConsoleState((PCONSOLE)Console, CONSOLE_RUNNING))
|
2014-05-02 16:46:13 +00:00
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Loop through the process list, from the most recent process
|
|
|
|
|
* (the active one) to the oldest one (the first created, i.e.
|
|
|
|
|
* the console leader process), and for each, send an event
|
|
|
|
|
* (new processes are inserted at the head of the console process list).
|
|
|
|
|
*/
|
|
|
|
|
current_entry = Console->ProcessList.Flink;
|
|
|
|
|
while (current_entry != &Console->ProcessList)
|
|
|
|
|
{
|
|
|
|
|
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
|
|
|
|
|
current_entry = current_entry->Flink;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Only processes belonging to the same process group are signaled.
|
|
|
|
|
* If the process group ID is zero, then all the processes are signaled.
|
|
|
|
|
*/
|
|
|
|
|
if (ProcessGroupId == 0 || current->Process->ProcessGroupId == ProcessGroupId)
|
|
|
|
|
{
|
|
|
|
|
Status = ConSrvConsoleCtrlEvent(CtrlEvent, current);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-15 17:05:13 +00:00
|
|
|
|
VOID
|
|
|
|
|
ConSrvSetProcessFocus(IN PCSR_PROCESS CsrProcess,
|
|
|
|
|
IN BOOLEAN SetForeground)
|
|
|
|
|
{
|
|
|
|
|
// FIXME: Call NtUserSetInformationProcess (currently unimplemented!)
|
|
|
|
|
// for setting Win32 foreground/background flags.
|
|
|
|
|
|
|
|
|
|
if (SetForeground)
|
|
|
|
|
CsrSetForegroundPriority(CsrProcess);
|
|
|
|
|
else
|
|
|
|
|
CsrSetBackgroundPriority(CsrProcess);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NTSTATUS NTAPI
|
|
|
|
|
ConSrvSetConsoleProcessFocus(IN PCONSRV_CONSOLE Console,
|
|
|
|
|
IN BOOLEAN SetForeground)
|
|
|
|
|
{
|
|
|
|
|
PLIST_ENTRY current_entry;
|
|
|
|
|
PCONSOLE_PROCESS_DATA current;
|
|
|
|
|
|
|
|
|
|
/* If the console is already being destroyed, just return */
|
|
|
|
|
if (!ConDrvValidateConsoleState((PCONSOLE)Console, CONSOLE_RUNNING))
|
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Loop through the process list, from the most recent process
|
|
|
|
|
* to the oldest one, and for each, set its foreground priority.
|
|
|
|
|
*/
|
|
|
|
|
current_entry = Console->ProcessList.Flink;
|
|
|
|
|
while (current_entry != &Console->ProcessList)
|
|
|
|
|
{
|
|
|
|
|
current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
|
|
|
|
|
current_entry = current_entry->Flink;
|
|
|
|
|
|
|
|
|
|
ConSrvSetProcessFocus(current->Process, SetForeground);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
|
2013-03-19 22:05:38 +00:00
|
|
|
|
/* PUBLIC SERVER APIS *********************************************************/
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepAlloc */
|
2012-10-22 23:55:51 +00:00
|
|
|
|
CSR_API(SrvAllocConsole)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2012-11-18 13:10:03 +00:00
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2013-01-05 23:10:12 +00:00
|
|
|
|
PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
|
2013-02-10 12:36:57 +00:00
|
|
|
|
PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process;
|
|
|
|
|
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
2014-09-07 22:53:49 +00:00
|
|
|
|
CONSOLE_INIT_INFO ConsoleInitInfo;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2013-07-06 19:47:53 +00:00
|
|
|
|
if (ProcessData->ConsoleHandle != NULL)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
|
|
|
|
DPRINT1("Process already has a console\n");
|
2013-01-13 17:07:25 +00:00
|
|
|
|
return STATUS_ACCESS_DENIED;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if ( !CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
|
(PVOID*)&AllocConsoleRequest->ConsoleStartInfo,
|
|
|
|
|
1,
|
|
|
|
|
sizeof(CONSOLE_START_INFO)) ||
|
|
|
|
|
!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
|
(PVOID*)&AllocConsoleRequest->ConsoleTitle,
|
|
|
|
|
AllocConsoleRequest->TitleLength,
|
|
|
|
|
sizeof(BYTE)) ||
|
|
|
|
|
!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
|
(PVOID*)&AllocConsoleRequest->Desktop,
|
|
|
|
|
AllocConsoleRequest->DesktopLength,
|
|
|
|
|
sizeof(BYTE)) ||
|
|
|
|
|
!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
|
(PVOID*)&AllocConsoleRequest->CurDir,
|
|
|
|
|
AllocConsoleRequest->CurDirLength,
|
|
|
|
|
sizeof(BYTE)) ||
|
|
|
|
|
!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
|
(PVOID*)&AllocConsoleRequest->AppName,
|
|
|
|
|
AllocConsoleRequest->AppNameLength,
|
|
|
|
|
sizeof(BYTE)) )
|
2013-02-10 12:36:57 +00:00
|
|
|
|
{
|
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
/* Initialize the console initialization info structure */
|
|
|
|
|
ConsoleInitInfo.ConsoleStartInfo = AllocConsoleRequest->ConsoleStartInfo;
|
2014-11-23 23:04:45 +00:00
|
|
|
|
ConsoleInitInfo.IsWindowVisible = TRUE; // The console window is always visible.
|
2014-09-07 22:53:49 +00:00
|
|
|
|
ConsoleInitInfo.TitleLength = AllocConsoleRequest->TitleLength;
|
|
|
|
|
ConsoleInitInfo.ConsoleTitle = AllocConsoleRequest->ConsoleTitle;
|
|
|
|
|
ConsoleInitInfo.DesktopLength = AllocConsoleRequest->DesktopLength;
|
|
|
|
|
ConsoleInitInfo.Desktop = AllocConsoleRequest->Desktop;
|
|
|
|
|
ConsoleInitInfo.AppNameLength = AllocConsoleRequest->AppNameLength;
|
|
|
|
|
ConsoleInitInfo.AppName = AllocConsoleRequest->AppName;
|
|
|
|
|
ConsoleInitInfo.CurDirLength = AllocConsoleRequest->CurDirLength;
|
|
|
|
|
ConsoleInitInfo.CurDir = AllocConsoleRequest->CurDir;
|
|
|
|
|
|
2013-01-04 00:41:10 +00:00
|
|
|
|
/* Initialize a new Console owned by the Console Leader Process */
|
2013-01-24 22:41:33 +00:00
|
|
|
|
Status = ConSrvAllocateConsole(ProcessData,
|
2014-09-07 22:53:49 +00:00
|
|
|
|
&AllocConsoleRequest->ConsoleStartInfo->InputHandle,
|
|
|
|
|
&AllocConsoleRequest->ConsoleStartInfo->OutputHandle,
|
|
|
|
|
&AllocConsoleRequest->ConsoleStartInfo->ErrorHandle,
|
|
|
|
|
&ConsoleInitInfo);
|
2013-01-02 00:32:20 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2013-01-16 22:25:12 +00:00
|
|
|
|
DPRINT1("Console allocation failed\n");
|
2013-01-02 00:32:20 +00:00
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-06 19:47:53 +00:00
|
|
|
|
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
2014-09-07 22:53:49 +00:00
|
|
|
|
ProcessData->PropRoutine = AllocConsoleRequest->PropRoutine;
|
|
|
|
|
ProcessData->CtrlRoutine = AllocConsoleRequest->CtrlRoutine;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepAttach */
|
2013-01-13 17:07:25 +00:00
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
|
|
|
|
|
|
2013-07-06 19:47:53 +00:00
|
|
|
|
if (TargetProcessData->ConsoleHandle != NULL)
|
2013-01-13 17:07:25 +00:00
|
|
|
|
{
|
|
|
|
|
DPRINT1("Process already has a console\n");
|
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
|
(PVOID*)&AttachConsoleRequest->ConsoleStartInfo,
|
|
|
|
|
1,
|
|
|
|
|
sizeof(CONSOLE_START_INFO)))
|
|
|
|
|
{
|
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-01 23:36:23 +00:00
|
|
|
|
/* Check whether we try to attach to the parent's console */
|
2013-01-13 17:07:25 +00:00
|
|
|
|
if (ProcessId == ULongToHandle(ATTACH_PARENT_PROCESS))
|
|
|
|
|
{
|
|
|
|
|
PROCESS_BASIC_INFORMATION ProcessInfo;
|
|
|
|
|
ULONG Length = sizeof(ProcessInfo);
|
|
|
|
|
|
2015-04-05 23:04:42 +00:00
|
|
|
|
/* Get the real parent's PID */
|
2013-01-13 17:07:25 +00:00
|
|
|
|
|
|
|
|
|
Status = NtQueryInformationProcess(TargetProcess->ProcessHandle,
|
|
|
|
|
ProcessBasicInformation,
|
|
|
|
|
&ProcessInfo,
|
|
|
|
|
Length, &Length);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2014-12-04 23:15:18 +00:00
|
|
|
|
DPRINT1("SrvAttachConsole - Cannot retrieve basic process info, Status = 0x%08lx\n", Status);
|
2013-01-13 17:07:25 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProcessId = ULongToHandle(ProcessInfo.InheritedFromUniqueProcessId);
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-01 23:36:23 +00:00
|
|
|
|
/* Lock the source process via its PID */
|
2013-01-13 17:07:25 +00:00
|
|
|
|
Status = CsrLockProcessByClientId(ProcessId, &SourceProcess);
|
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
|
|
SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
|
|
|
|
|
2013-07-06 19:47:53 +00:00
|
|
|
|
if (SourceProcessData->ConsoleHandle == NULL)
|
2013-02-01 23:36:23 +00:00
|
|
|
|
{
|
|
|
|
|
Status = STATUS_INVALID_HANDLE;
|
|
|
|
|
goto Quit;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-13 17:07:25 +00:00
|
|
|
|
/*
|
|
|
|
|
* Inherit the console from the parent,
|
|
|
|
|
* if any, otherwise return an error.
|
|
|
|
|
*/
|
2013-02-01 23:36:23 +00:00
|
|
|
|
Status = ConSrvInheritConsole(TargetProcessData,
|
2013-07-06 19:47:53 +00:00
|
|
|
|
SourceProcessData->ConsoleHandle,
|
2013-02-01 23:36:23 +00:00
|
|
|
|
TRUE,
|
2014-09-07 22:53:49 +00:00
|
|
|
|
&AttachConsoleRequest->ConsoleStartInfo->InputHandle,
|
|
|
|
|
&AttachConsoleRequest->ConsoleStartInfo->OutputHandle,
|
2014-11-22 22:13:08 +00:00
|
|
|
|
&AttachConsoleRequest->ConsoleStartInfo->ErrorHandle,
|
|
|
|
|
AttachConsoleRequest->ConsoleStartInfo);
|
2013-01-13 17:07:25 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
|
{
|
2013-02-01 23:36:23 +00:00
|
|
|
|
DPRINT1("Console inheritance failed\n");
|
2013-01-13 17:07:25 +00:00
|
|
|
|
goto Quit;
|
|
|
|
|
}
|
2013-01-16 22:25:12 +00:00
|
|
|
|
|
2013-07-06 19:47:53 +00:00
|
|
|
|
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
2014-09-07 22:53:49 +00:00
|
|
|
|
TargetProcessData->PropRoutine = AttachConsoleRequest->PropRoutine;
|
|
|
|
|
TargetProcessData->CtrlRoutine = AttachConsoleRequest->CtrlRoutine;
|
2013-01-13 17:07:25 +00:00
|
|
|
|
|
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
|
|
Quit:
|
2013-02-01 23:36:23 +00:00
|
|
|
|
/* Unlock the "source" process and exit */
|
2013-01-13 17:07:25 +00:00
|
|
|
|
CsrUnlockProcess(SourceProcess);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepFree */
|
2012-10-22 23:55:51 +00:00
|
|
|
|
CSR_API(SrvFreeConsole)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2014-11-23 14:26:37 +00:00
|
|
|
|
return ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
NTSTATUS NTAPI
|
|
|
|
|
ConDrvGetConsoleMode(IN PCONSOLE Console,
|
|
|
|
|
IN PCONSOLE_IO_OBJECT Object,
|
|
|
|
|
OUT PULONG ConsoleMode);
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepGetMode */
|
2013-04-07 23:39:39 +00:00
|
|
|
|
CSR_API(SrvGetConsoleMode)
|
|
|
|
|
{
|
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
|
2013-06-23 00:18:47 +00:00
|
|
|
|
PCONSOLE_IO_OBJECT Object;
|
2013-04-07 23:39:39 +00:00
|
|
|
|
|
2014-08-29 19:45:45 +00:00
|
|
|
|
PULONG ConsoleMode = &ConsoleModeRequest->Mode;
|
|
|
|
|
|
2013-04-07 23:39:39 +00:00
|
|
|
|
Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
2014-04-20 11:25:38 +00:00
|
|
|
|
ConsoleModeRequest->Handle,
|
2013-04-07 23:39:39 +00:00
|
|
|
|
&Object, NULL, GENERIC_READ, TRUE, 0);
|
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
2014-08-29 19:45:45 +00:00
|
|
|
|
/* Get the standard console modes */
|
2013-06-23 00:18:47 +00:00
|
|
|
|
Status = ConDrvGetConsoleMode(Object->Console, Object,
|
2014-08-29 19:45:45 +00:00
|
|
|
|
ConsoleMode);
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* If getting the console modes succeeds, then retrieve
|
|
|
|
|
* the extended CONSRV-specific input modes.
|
|
|
|
|
*/
|
|
|
|
|
if (INPUT_BUFFER == Object->Type)
|
|
|
|
|
{
|
|
|
|
|
if (Object->Console->InsertMode || Object->Console->QuickEdit)
|
|
|
|
|
{
|
2014-09-05 21:12:42 +00:00
|
|
|
|
/* Windows also adds ENABLE_EXTENDED_FLAGS, even if it's not documented on MSDN */
|
2014-08-29 19:45:45 +00:00
|
|
|
|
*ConsoleMode |= ENABLE_EXTENDED_FLAGS;
|
|
|
|
|
|
|
|
|
|
if (Object->Console->InsertMode) *ConsoleMode |= ENABLE_INSERT_MODE;
|
|
|
|
|
if (Object->Console->QuickEdit ) *ConsoleMode |= ENABLE_QUICK_EDIT_MODE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-04-07 23:39:39 +00:00
|
|
|
|
|
|
|
|
|
ConSrvReleaseObject(Object, TRUE);
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
NTSTATUS NTAPI
|
|
|
|
|
ConDrvSetConsoleMode(IN PCONSOLE Console,
|
|
|
|
|
IN PCONSOLE_IO_OBJECT Object,
|
|
|
|
|
IN ULONG ConsoleMode);
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepSetMode */
|
2012-10-22 23:55:51 +00:00
|
|
|
|
CSR_API(SrvSetConsoleMode)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2014-08-29 19:45:45 +00:00
|
|
|
|
#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS | \
|
|
|
|
|
ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE )
|
2020-02-08 23:18:40 +00:00
|
|
|
|
// NOTE: Vista+ ENABLE_AUTO_POSITION is also a control mode.
|
2014-08-29 19:45:45 +00:00
|
|
|
|
|
2010-05-31 06:28:55 +00:00
|
|
|
|
NTSTATUS Status;
|
2013-01-05 23:10:12 +00:00
|
|
|
|
PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
|
2013-06-23 00:18:47 +00:00
|
|
|
|
PCONSOLE_IO_OBJECT Object;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2014-08-29 19:45:45 +00:00
|
|
|
|
ULONG ConsoleMode = ConsoleModeRequest->Mode;
|
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
2014-04-20 11:25:38 +00:00
|
|
|
|
ConsoleModeRequest->Handle,
|
2013-04-01 00:23:34 +00:00
|
|
|
|
&Object, NULL, GENERIC_WRITE, TRUE, 0);
|
2012-11-17 23:07:59 +00:00
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2014-08-29 19:45:45 +00:00
|
|
|
|
/* Set the standard console modes (without the CONSRV-specific input modes) */
|
|
|
|
|
ConsoleMode &= ~CONSOLE_VALID_CONTROL_MODES; // Remove CONSRV-specific input modes.
|
2013-06-23 00:18:47 +00:00
|
|
|
|
Status = ConDrvSetConsoleMode(Object->Console, Object,
|
2014-08-29 19:45:45 +00:00
|
|
|
|
ConsoleMode);
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* If setting the console modes succeeds, then set
|
|
|
|
|
* the extended CONSRV-specific input modes.
|
|
|
|
|
*/
|
|
|
|
|
if (INPUT_BUFFER == Object->Type)
|
|
|
|
|
{
|
|
|
|
|
ConsoleMode = ConsoleModeRequest->Mode;
|
|
|
|
|
|
|
|
|
|
if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* If we use control mode flags without ENABLE_EXTENDED_FLAGS,
|
|
|
|
|
* then consider the flags invalid.
|
|
|
|
|
*/
|
|
|
|
|
if ((ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0)
|
|
|
|
|
{
|
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Object->Console->InsertMode = !!(ConsoleMode & ENABLE_INSERT_MODE);
|
|
|
|
|
Object->Console->QuickEdit = !!(ConsoleMode & ENABLE_QUICK_EDIT_MODE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-11-17 23:07:59 +00:00
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
ConSrvReleaseObject(Object, TRUE);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepGetTitle */
|
2013-04-07 23:39:39 +00:00
|
|
|
|
CSR_API(SrvGetConsoleTitle)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
|
|
|
|
NTSTATUS Status;
|
2013-04-07 23:39:39 +00:00
|
|
|
|
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2014-09-07 22:53:49 +00:00
|
|
|
|
ULONG Length;
|
2012-11-17 23:07:59 +00:00
|
|
|
|
|
2013-04-07 23:39:39 +00:00
|
|
|
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
|
(PVOID)&TitleRequest->Title,
|
|
|
|
|
TitleRequest->Length,
|
|
|
|
|
sizeof(BYTE)))
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2013-04-07 23:39:39 +00:00
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
2013-04-07 23:39:39 +00:00
|
|
|
|
|
|
|
|
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2015-03-27 10:10:42 +00:00
|
|
|
|
DPRINT1("Can't get console, status %lx\n", Status);
|
2013-04-07 23:39:39 +00:00
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
2013-04-07 23:39:39 +00:00
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
/* Copy title of the console to the user title buffer */
|
|
|
|
|
if (TitleRequest->Unicode)
|
|
|
|
|
{
|
|
|
|
|
if (TitleRequest->Length >= sizeof(WCHAR))
|
|
|
|
|
{
|
|
|
|
|
Length = min(TitleRequest->Length - sizeof(WCHAR), Console->Title.Length);
|
|
|
|
|
RtlCopyMemory(TitleRequest->Title, Console->Title.Buffer, Length);
|
2015-03-24 23:58:44 +00:00
|
|
|
|
((PWCHAR)TitleRequest->Title)[Length / sizeof(WCHAR)] = UNICODE_NULL;
|
2014-09-07 22:53:49 +00:00
|
|
|
|
TitleRequest->Length = Length;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TitleRequest->Length = Console->Title.Length;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (TitleRequest->Length >= sizeof(CHAR))
|
|
|
|
|
{
|
|
|
|
|
Length = min(TitleRequest->Length - sizeof(CHAR), Console->Title.Length / sizeof(WCHAR));
|
|
|
|
|
Length = WideCharToMultiByte(Console->InputCodePage, 0,
|
|
|
|
|
Console->Title.Buffer, Length,
|
|
|
|
|
TitleRequest->Title, Length,
|
|
|
|
|
NULL, NULL);
|
2015-03-24 23:58:44 +00:00
|
|
|
|
((PCHAR)TitleRequest->Title)[Length] = ANSI_NULL;
|
2014-09-07 22:53:49 +00:00
|
|
|
|
TitleRequest->Length = Length;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TitleRequest->Length = Console->Title.Length / sizeof(WCHAR);
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-04-07 23:39:39 +00:00
|
|
|
|
|
|
|
|
|
ConSrvReleaseConsole(Console, TRUE);
|
2013-06-23 00:18:47 +00:00
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepSetTitle */
|
2012-10-22 23:55:51 +00:00
|
|
|
|
CSR_API(SrvSetConsoleTitle)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
|
|
|
|
NTSTATUS Status;
|
2013-01-05 23:10:12 +00:00
|
|
|
|
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
PWCHAR Buffer;
|
|
|
|
|
ULONG Length;
|
|
|
|
|
|
2012-11-18 13:10:03 +00:00
|
|
|
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
|
|
|
|
(PVOID)&TitleRequest->Title,
|
|
|
|
|
TitleRequest->Length,
|
|
|
|
|
sizeof(BYTE)))
|
|
|
|
|
{
|
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
}
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
2013-02-10 12:36:57 +00:00
|
|
|
|
if (!NT_SUCCESS(Status))
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2015-03-27 10:10:42 +00:00
|
|
|
|
DPRINT1("Can't get console, status %lx\n", Status);
|
2013-02-10 12:36:57 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
2012-11-18 13:10:03 +00:00
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if (TitleRequest->Unicode)
|
|
|
|
|
{
|
|
|
|
|
/* Length is in bytes */
|
|
|
|
|
Length = TitleRequest->Length;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Use the console input CP for the conversion */
|
|
|
|
|
Length = MultiByteToWideChar(Console->InputCodePage, 0,
|
|
|
|
|
TitleRequest->Title, TitleRequest->Length,
|
|
|
|
|
NULL, 0);
|
|
|
|
|
/* The returned Length was in number of wchars, convert it in bytes */
|
|
|
|
|
Length *= sizeof(WCHAR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Allocate a new buffer to hold the new title (NULL-terminated) */
|
|
|
|
|
Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Length + sizeof(WCHAR));
|
|
|
|
|
if (!Buffer)
|
|
|
|
|
{
|
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
|
goto Quit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free the old title */
|
|
|
|
|
ConsoleFreeUnicodeString(&Console->Title);
|
|
|
|
|
|
|
|
|
|
/* Copy title to console */
|
|
|
|
|
Console->Title.Buffer = Buffer;
|
|
|
|
|
Console->Title.Length = Length;
|
|
|
|
|
Console->Title.MaximumLength = Console->Title.Length + sizeof(WCHAR);
|
2012-11-18 13:10:03 +00:00
|
|
|
|
|
2014-09-07 22:53:49 +00:00
|
|
|
|
if (TitleRequest->Unicode)
|
|
|
|
|
{
|
|
|
|
|
RtlCopyMemory(Console->Title.Buffer, TitleRequest->Title, Console->Title.Length);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MultiByteToWideChar(Console->InputCodePage, 0,
|
|
|
|
|
TitleRequest->Title, TitleRequest->Length,
|
|
|
|
|
Console->Title.Buffer,
|
|
|
|
|
Console->Title.Length / sizeof(WCHAR));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* NULL-terminate */
|
2015-03-24 23:58:44 +00:00
|
|
|
|
Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
2014-09-07 22:53:49 +00:00
|
|
|
|
|
|
|
|
|
TermChangeTitle(Console);
|
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
|
|
Quit:
|
2013-01-24 22:41:33 +00:00
|
|
|
|
ConSrvReleaseConsole(Console, TRUE);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
NTSTATUS NTAPI
|
|
|
|
|
ConDrvGetConsoleCP(IN PCONSOLE Console,
|
|
|
|
|
OUT PUINT CodePage,
|
2014-03-08 15:31:05 +00:00
|
|
|
|
IN BOOLEAN OutputCP);
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepGetCP */
|
2012-10-22 23:55:51 +00:00
|
|
|
|
CSR_API(SrvGetConsoleCP)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
|
|
|
|
NTSTATUS Status;
|
2014-03-08 15:31:05 +00:00
|
|
|
|
PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetConsoleCPRequest;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2012-11-18 13:10:03 +00:00
|
|
|
|
DPRINT("SrvGetConsoleCP, getting %s Code Page\n",
|
2014-03-08 15:31:05 +00:00
|
|
|
|
GetConsoleCPRequest->OutputCP ? "Output" : "Input");
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
2012-11-18 13:10:03 +00:00
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
Status = ConDrvGetConsoleCP(Console,
|
2014-03-08 15:31:05 +00:00
|
|
|
|
&GetConsoleCPRequest->CodePage,
|
|
|
|
|
GetConsoleCPRequest->OutputCP);
|
2013-06-23 00:18:47 +00:00
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
ConSrvReleaseConsole(Console, TRUE);
|
2013-06-23 00:18:47 +00:00
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
NTSTATUS NTAPI
|
|
|
|
|
ConDrvSetConsoleCP(IN PCONSOLE Console,
|
|
|
|
|
IN UINT CodePage,
|
2014-03-08 15:31:05 +00:00
|
|
|
|
IN BOOLEAN OutputCP);
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepSetCP */
|
2012-10-22 23:55:51 +00:00
|
|
|
|
CSR_API(SrvSetConsoleCP)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2013-06-23 00:18:47 +00:00
|
|
|
|
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
2014-03-08 15:31:05 +00:00
|
|
|
|
PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetConsoleCPRequest;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2012-11-18 13:10:03 +00:00
|
|
|
|
DPRINT("SrvSetConsoleCP, setting %s Code Page\n",
|
2014-03-08 15:31:05 +00:00
|
|
|
|
SetConsoleCPRequest->OutputCP ? "Output" : "Input");
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
2012-11-18 13:10:03 +00:00
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2013-06-23 00:18:47 +00:00
|
|
|
|
Status = ConDrvSetConsoleCP(Console,
|
2014-03-08 15:31:05 +00:00
|
|
|
|
SetConsoleCPRequest->CodePage,
|
|
|
|
|
SetConsoleCPRequest->OutputCP);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
ConSrvReleaseConsole(Console, TRUE);
|
2013-06-23 00:18:47 +00:00
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepGetProcessList */
|
2012-10-22 23:55:51 +00:00
|
|
|
|
CSR_API(SrvGetConsoleProcessList)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2012-11-18 13:10:03 +00:00
|
|
|
|
NTSTATUS Status;
|
2013-01-05 23:10:12 +00:00
|
|
|
|
PCONSOLE_GETPROCESSLIST GetProcessListRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetProcessListRequest;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2012-11-18 13:10:03 +00:00
|
|
|
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
2014-03-08 15:31:05 +00:00
|
|
|
|
(PVOID)&GetProcessListRequest->ProcessIdsList,
|
|
|
|
|
GetProcessListRequest->ProcessCount,
|
2012-11-18 13:10:03 +00:00
|
|
|
|
sizeof(DWORD)))
|
|
|
|
|
{
|
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
2012-11-18 13:10:03 +00:00
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
Status = ConSrvGetConsoleProcessList(Console,
|
2014-03-08 15:31:05 +00:00
|
|
|
|
GetProcessListRequest->ProcessIdsList,
|
|
|
|
|
GetProcessListRequest->ProcessCount,
|
|
|
|
|
&GetProcessListRequest->ProcessCount);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
ConSrvReleaseConsole(Console, TRUE);
|
2013-06-23 00:18:47 +00:00
|
|
|
|
return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepGenerateCtrlEvent */
|
2012-10-22 23:55:51 +00:00
|
|
|
|
CSR_API(SrvGenerateConsoleCtrlEvent)
|
2010-05-31 06:28:55 +00:00
|
|
|
|
{
|
2012-11-18 13:10:03 +00:00
|
|
|
|
NTSTATUS Status;
|
2013-01-05 23:10:12 +00:00
|
|
|
|
PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GenerateCtrlEventRequest;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
2012-11-18 13:10:03 +00:00
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2014-05-02 16:46:13 +00:00
|
|
|
|
Status = ConSrvConsoleProcessCtrlEvent(Console,
|
2014-04-20 11:25:38 +00:00
|
|
|
|
GenerateCtrlEventRequest->ProcessGroupId,
|
|
|
|
|
GenerateCtrlEventRequest->CtrlEvent);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
|
2013-01-24 22:41:33 +00:00
|
|
|
|
ConSrvReleaseConsole(Console, TRUE);
|
2010-05-31 06:28:55 +00:00
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepNotifyLastClose */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvConsoleNotifyLastClose)
|
|
|
|
|
{
|
2014-04-21 01:22:17 +00:00
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2014-04-21 01:22:17 +00:00
|
|
|
|
|
|
|
|
|
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
|
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
|
|
/* Only one process is allowed to be registered for last close notification */
|
|
|
|
|
if (!Console->NotifyLastClose)
|
|
|
|
|
{
|
|
|
|
|
Console->NotifyLastClose = TRUE;
|
2014-04-22 00:47:24 +00:00
|
|
|
|
Console->NotifiedLastCloseProcess = ProcessData;
|
2014-04-21 01:22:17 +00:00
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Status = STATUS_ACCESS_DENIED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ConSrvReleaseConsole(Console, TRUE);
|
|
|
|
|
return Status;
|
2013-08-30 17:53:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepGetMouseInfo */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvGetConsoleMouseInfo)
|
|
|
|
|
{
|
2014-07-28 13:20:54 +00:00
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
PCONSOLE_GETMOUSEINFO GetMouseInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetMouseInfoRequest;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2014-07-28 13:20:54 +00:00
|
|
|
|
|
|
|
|
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
|
|
/* Just retrieve the number of buttons of the mouse attached to this console */
|
|
|
|
|
GetMouseInfoRequest->NumButtons = GetSystemMetrics(SM_CMOUSEBUTTONS);
|
|
|
|
|
|
|
|
|
|
ConSrvReleaseConsole(Console, TRUE);
|
|
|
|
|
return STATUS_SUCCESS;
|
2013-08-30 17:53:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepSetKeyShortcuts */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvSetConsoleKeyShortcuts)
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepGetKeyboardLayoutName */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvGetConsoleKeyboardLayoutName)
|
|
|
|
|
{
|
2014-08-06 21:01:23 +00:00
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
PCONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetKbdLayoutNameRequest;
|
2014-08-12 14:59:13 +00:00
|
|
|
|
PCONSRV_CONSOLE Console;
|
2014-08-06 21:01:23 +00:00
|
|
|
|
|
|
|
|
|
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
|
|
/* Retrieve the keyboard layout name of the system */
|
|
|
|
|
if (GetKbdLayoutNameRequest->Ansi)
|
|
|
|
|
GetKeyboardLayoutNameA((PCHAR)GetKbdLayoutNameRequest->LayoutBuffer);
|
|
|
|
|
else
|
|
|
|
|
GetKeyboardLayoutNameW((PWCHAR)GetKbdLayoutNameRequest->LayoutBuffer);
|
|
|
|
|
|
|
|
|
|
ConSrvReleaseConsole(Console, TRUE);
|
|
|
|
|
return STATUS_SUCCESS;
|
2013-08-30 17:53:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepCharType */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvGetConsoleCharType)
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepSetLocalEUDC */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvSetConsoleLocalEUDC)
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepSetCursorMode */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvSetConsoleCursorMode)
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepGetCursorMode */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvGetConsoleCursorMode)
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepGetNlsMode */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvGetConsoleNlsMode)
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepSetNlsMode */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvSetConsoleNlsMode)
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-31 00:21:42 +00:00
|
|
|
|
/* API_NUMBER: ConsolepGetLangId */
|
2013-08-30 17:53:45 +00:00
|
|
|
|
CSR_API(SrvGetConsoleLangId)
|
|
|
|
|
{
|
|
|
|
|
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-31 06:28:55 +00:00
|
|
|
|
/* EOF */
|