mirror of
https://github.com/reactos/reactos.git
synced 2025-05-17 16:27:00 +00:00
[KERNEL32][CONSRV]
- Make CONSRV_API_CONNECTINFO, CONSOLE_ALLOCCONSOLE and CONSOLE_ATTACHCONSOLE Windows 2k3-compatible, so that using either their kernel32 in ROS or our kernel32 in windows, works. For that, complete and fix also the CONSOLE_START_INFO and CONSOLE_PROPERTIES structures. - Rewrite Alloc/AttachConsole and the console initialization functions to match what Windows expects when connecting to the console server, and make them compatible with the fixed structures. - Fix SrvAllocConsole and SrvAttachConsole accordingly, and few other console initialization functions in consrv. - Fix input EXE name support and store also the current directory from which we were started. - Use a temporarily define USE_CONSOLE_INIT_HANDLES that is not enabled yet because we do not use console initialization events (used by Windows for Alloc/AttachConsole and console initialization functions). Until this gets implemented in ReactOS, putting windows' kernel32 in ReactOS will fail when it will try to wait on those events. - For SrvAlloc/SrvAttach/SrvFreeConsole, ConSrvConnect and ConSrvDisconnect: correctly mark the process as console app. - Fix process initialization in ConSrvNewProcess. - Get rid of CONSOLE_PROCESS_DATA::ParentConsoleHandle member. - Temporarily move the link settings retrieval in console.c and hack a bit icon setting. [CONSRV] - Move console title setting from condrv back to consrv where it should belong in fact. CORE-7931 #resolve #comment ConsolepAlloc and ConsolepAttach finally fixed in revision 64079. svn path=/branches/condrv_restructure/; revision=64079
This commit is contained in:
parent
4c18b81f0f
commit
a9feb19181
22 changed files with 1544 additions and 965 deletions
File diff suppressed because it is too large
Load diff
|
@ -22,15 +22,14 @@
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
RTL_CRITICAL_SECTION ConsoleLock;
|
RTL_CRITICAL_SECTION ConsoleLock;
|
||||||
BOOL ConsoleInitialized = FALSE;
|
BOOLEAN ConsoleInitialized = FALSE;
|
||||||
|
|
||||||
extern HANDLE InputWaitHandle;
|
extern HANDLE InputWaitHandle;
|
||||||
|
|
||||||
static HMODULE ConsoleLibrary = NULL;
|
static HMODULE ConsoleLibrary = NULL;
|
||||||
static BOOL AlreadyDisplayingProps = FALSE;
|
static BOOL AlreadyDisplayingProps = FALSE;
|
||||||
|
|
||||||
#define WIN_OBJ_DIR L"\\Windows"
|
static const PWSTR DefaultConsoleTitle = L"ReactOS Console";
|
||||||
#define SESSION_DIR L"\\Sessions"
|
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
@ -41,6 +40,7 @@ PropDialogHandler(IN LPVOID lpThreadParameter)
|
||||||
{
|
{
|
||||||
// NOTE: lpThreadParameter corresponds to the client shared section handle.
|
// NOTE: lpThreadParameter corresponds to the client shared section handle.
|
||||||
|
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
APPLET_PROC CPLFunc;
|
APPLET_PROC CPLFunc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -67,12 +67,11 @@ PropDialogHandler(IN LPVOID lpThreadParameter)
|
||||||
GetSystemDirectoryW(szBuffer, MAX_PATH);
|
GetSystemDirectoryW(szBuffer, MAX_PATH);
|
||||||
wcscat(szBuffer, L"\\console.dll");
|
wcscat(szBuffer, L"\\console.dll");
|
||||||
ConsoleLibrary = LoadLibraryW(szBuffer);
|
ConsoleLibrary = LoadLibraryW(szBuffer);
|
||||||
|
|
||||||
if (ConsoleLibrary == NULL)
|
if (ConsoleLibrary == NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to load console.dll\n");
|
DPRINT1("Failed to load console.dll\n");
|
||||||
AlreadyDisplayingProps = FALSE;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
return STATUS_UNSUCCESSFUL;
|
goto Quit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,203 +79,223 @@ PropDialogHandler(IN LPVOID lpThreadParameter)
|
||||||
CPLFunc = (APPLET_PROC)GetProcAddress(ConsoleLibrary, "CPlApplet");
|
CPLFunc = (APPLET_PROC)GetProcAddress(ConsoleLibrary, "CPlApplet");
|
||||||
if (CPLFunc == NULL)
|
if (CPLFunc == NULL)
|
||||||
{
|
{
|
||||||
DPRINT("Error: Console.dll misses CPlApplet export\n");
|
DPRINT1("Error: Console.dll misses CPlApplet export\n");
|
||||||
AlreadyDisplayingProps = FALSE;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
return STATUS_UNSUCCESSFUL;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CPLFunc(NULL, CPL_INIT, 0, 0) == FALSE)
|
if (CPLFunc(NULL, CPL_INIT, 0, 0) == FALSE)
|
||||||
{
|
{
|
||||||
DPRINT("Error: failed to initialize console.dll\n");
|
DPRINT1("Error: failed to initialize console.dll\n");
|
||||||
AlreadyDisplayingProps = FALSE;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
return STATUS_UNSUCCESSFUL;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CPLFunc(NULL, CPL_GETCOUNT, 0, 0) != 1)
|
if (CPLFunc(NULL, CPL_GETCOUNT, 0, 0) != 1)
|
||||||
{
|
{
|
||||||
DPRINT("Error: console.dll returned unexpected CPL count\n");
|
DPRINT1("Error: console.dll returned unexpected CPL count\n");
|
||||||
AlreadyDisplayingProps = FALSE;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
return STATUS_UNSUCCESSFUL;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPLFunc(NULL, CPL_DBLCLK, (LPARAM)lpThreadParameter, 0);
|
CPLFunc(NULL, CPL_DBLCLK, (LPARAM)lpThreadParameter, 0);
|
||||||
CPLFunc(NULL, CPL_EXIT , 0, 0);
|
CPLFunc(NULL, CPL_EXIT , 0, 0);
|
||||||
|
|
||||||
|
Quit:
|
||||||
AlreadyDisplayingProps = FALSE;
|
AlreadyDisplayingProps = FALSE;
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static INT
|
||||||
|
ParseShellInfo(LPCWSTR lpszShellInfo,
|
||||||
|
LPCWSTR lpszKeyword)
|
||||||
|
{
|
||||||
|
DPRINT1("ParseShellInfo is UNIMPLEMENTED\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE:
|
||||||
|
* The "LPDWORD Length" parameters point on input to the maximum size of
|
||||||
|
* the buffers that can hold data (if != 0), and on output they hold the
|
||||||
|
* real size of the data. If "Length" are == 0 on input, then on output
|
||||||
|
* they receive the full size of the data.
|
||||||
|
* The "LPWSTR* lpTitle" parameter has a double meaning:
|
||||||
|
* - when "CaptureTitle" is TRUE, data is copied to the buffer pointed
|
||||||
|
* by the pointer (*lpTitle).
|
||||||
|
* - when "CaptureTitle" is FALSE, "*lpTitle" is set to the address of
|
||||||
|
* the source data.
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
SetUpConsoleInfo(IN BOOLEAN CaptureTitle,
|
||||||
|
IN OUT LPDWORD pTitleLength,
|
||||||
|
IN OUT LPWSTR* lpTitle OPTIONAL,
|
||||||
|
IN OUT LPDWORD pDesktopLength,
|
||||||
|
IN OUT LPWSTR* lpDesktop OPTIONAL,
|
||||||
|
IN OUT PCONSOLE_START_INFO ConsoleStartInfo)
|
||||||
|
{
|
||||||
|
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
||||||
|
DWORD Length;
|
||||||
|
|
||||||
|
/* Initialize the fields */
|
||||||
|
|
||||||
|
ConsoleStartInfo->IconIndex = 0;
|
||||||
|
ConsoleStartInfo->hIcon = NULL;
|
||||||
|
ConsoleStartInfo->hIconSm = NULL;
|
||||||
|
ConsoleStartInfo->dwStartupFlags = Parameters->WindowFlags;
|
||||||
|
ConsoleStartInfo->nFont = 0;
|
||||||
|
ConsoleStartInfo->nInputBufferSize = 0;
|
||||||
|
ConsoleStartInfo->uCodePage = GetOEMCP();
|
||||||
|
|
||||||
|
if (lpTitle)
|
||||||
|
{
|
||||||
|
LPWSTR Title;
|
||||||
|
|
||||||
|
/* If we don't have any title, use the default one */
|
||||||
|
if (Parameters->WindowTitle.Buffer == NULL)
|
||||||
|
{
|
||||||
|
Title = DefaultConsoleTitle;
|
||||||
|
Length = lstrlenW(DefaultConsoleTitle) * sizeof(WCHAR); // sizeof(DefaultConsoleTitle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Title = Parameters->WindowTitle.Buffer;
|
||||||
|
Length = Parameters->WindowTitle.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve the needed buffer size */
|
||||||
|
Length += sizeof(WCHAR);
|
||||||
|
if (*pTitleLength > 0) Length = min(Length, *pTitleLength);
|
||||||
|
*pTitleLength = Length;
|
||||||
|
|
||||||
|
/* Capture the data if needed, or, return a pointer to it */
|
||||||
|
if (CaptureTitle)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Length is always >= sizeof(WCHAR). Copy everything but the
|
||||||
|
* possible trailing NULL character, and then NULL-terminate.
|
||||||
|
*/
|
||||||
|
Length -= sizeof(WCHAR);
|
||||||
|
RtlCopyMemory(*lpTitle, Title, Length);
|
||||||
|
(*lpTitle)[Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*lpTitle = Title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pTitleLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpDesktop && Parameters->DesktopInfo.Buffer && *Parameters->DesktopInfo.Buffer)
|
||||||
|
{
|
||||||
|
/* Retrieve the needed buffer size */
|
||||||
|
Length = Parameters->DesktopInfo.Length + sizeof(WCHAR);
|
||||||
|
if (*pDesktopLength > 0) Length = min(Length, *pDesktopLength);
|
||||||
|
*pDesktopLength = Length;
|
||||||
|
|
||||||
|
/* Return a pointer to the data */
|
||||||
|
*lpDesktop = Parameters->DesktopInfo.Buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pDesktopLength = 0;
|
||||||
|
if (lpDesktop) *lpDesktop = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Parameters->WindowFlags & STARTF_USEFILLATTRIBUTE)
|
||||||
|
{
|
||||||
|
ConsoleStartInfo->wFillAttribute = (WORD)Parameters->FillAttribute;
|
||||||
|
}
|
||||||
|
if (Parameters->WindowFlags & STARTF_USECOUNTCHARS)
|
||||||
|
{
|
||||||
|
ConsoleStartInfo->dwScreenBufferSize.X = (SHORT)Parameters->CountCharsX;
|
||||||
|
ConsoleStartInfo->dwScreenBufferSize.Y = (SHORT)Parameters->CountCharsY;
|
||||||
|
}
|
||||||
|
if (Parameters->WindowFlags & STARTF_USESHOWWINDOW)
|
||||||
|
{
|
||||||
|
ConsoleStartInfo->wShowWindow = (WORD)Parameters->ShowWindowFlags;
|
||||||
|
}
|
||||||
|
if (Parameters->WindowFlags & STARTF_USEPOSITION)
|
||||||
|
{
|
||||||
|
ConsoleStartInfo->dwWindowOrigin.X = (SHORT)Parameters->StartingX;
|
||||||
|
ConsoleStartInfo->dwWindowOrigin.Y = (SHORT)Parameters->StartingY;
|
||||||
|
}
|
||||||
|
if (Parameters->WindowFlags & STARTF_USESIZE)
|
||||||
|
{
|
||||||
|
ConsoleStartInfo->dwWindowSize.X = (SHORT)Parameters->CountX;
|
||||||
|
ConsoleStartInfo->dwWindowSize.Y = (SHORT)Parameters->CountY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get shell information (ShellInfo.Buffer is NULL-terminated) */
|
||||||
|
if (Parameters->ShellInfo.Buffer != NULL)
|
||||||
|
{
|
||||||
|
ConsoleStartInfo->IconIndex = ParseShellInfo(Parameters->ShellInfo.Buffer, L"dde.");
|
||||||
|
|
||||||
|
if ((Parameters->WindowFlags & STARTF_USEHOTKEY) == 0)
|
||||||
|
ConsoleStartInfo->dwHotKey = ParseShellInfo(Parameters->ShellInfo.Buffer, L"hotkey.");
|
||||||
|
else
|
||||||
|
ConsoleStartInfo->dwHotKey = HandleToUlong(Parameters->StandardInput);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
InitConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
SetUpHandles(IN PCONSOLE_START_INFO ConsoleStartInfo)
|
||||||
IN PUNICODE_STRING ImagePathName)
|
|
||||||
{
|
{
|
||||||
STARTUPINFOW si;
|
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
||||||
SIZE_T Length;
|
|
||||||
|
|
||||||
/* Get the startup information */
|
if (ConsoleStartInfo->dwStartupFlags & STARTF_USEHOTKEY)
|
||||||
GetStartupInfoW(&si);
|
|
||||||
|
|
||||||
/* Initialize the fields */
|
|
||||||
ConsoleStartInfo->dwStartupFlags = si.dwFlags;
|
|
||||||
if (si.dwFlags & STARTF_USEFILLATTRIBUTE)
|
|
||||||
{
|
{
|
||||||
ConsoleStartInfo->wFillAttribute = (WORD)si.dwFillAttribute;
|
Parameters->WindowFlags &= ~STARTF_USEHOTKEY;
|
||||||
}
|
}
|
||||||
if (si.dwFlags & STARTF_USECOUNTCHARS)
|
if (ConsoleStartInfo->dwStartupFlags & STARTF_SHELLPRIVATE)
|
||||||
{
|
{
|
||||||
ConsoleStartInfo->dwScreenBufferSize.X = (SHORT)(si.dwXCountChars);
|
Parameters->WindowFlags &= ~STARTF_SHELLPRIVATE;
|
||||||
ConsoleStartInfo->dwScreenBufferSize.Y = (SHORT)(si.dwYCountChars);
|
|
||||||
}
|
|
||||||
if (si.dwFlags & STARTF_USESHOWWINDOW)
|
|
||||||
{
|
|
||||||
ConsoleStartInfo->wShowWindow = si.wShowWindow;
|
|
||||||
}
|
|
||||||
if (si.dwFlags & STARTF_USEPOSITION)
|
|
||||||
{
|
|
||||||
ConsoleStartInfo->dwWindowOrigin.X = (SHORT)(si.dwX);
|
|
||||||
ConsoleStartInfo->dwWindowOrigin.Y = (SHORT)(si.dwY);
|
|
||||||
}
|
|
||||||
if (si.dwFlags & STARTF_USESIZE)
|
|
||||||
{
|
|
||||||
ConsoleStartInfo->dwWindowSize.X = (SHORT)(si.dwXSize);
|
|
||||||
ConsoleStartInfo->dwWindowSize.Y = (SHORT)(si.dwYSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the title for the console */
|
/* We got the handles, let's set them */
|
||||||
if (si.lpTitle)
|
Parameters->ConsoleHandle = ConsoleStartInfo->ConsoleHandle;
|
||||||
{
|
|
||||||
wcsncpy(ConsoleStartInfo->ConsoleTitle, si.lpTitle, MAX_PATH + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConsoleStartInfo->ConsoleTitle[0] = L'\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve the application path name */
|
if (!(ConsoleStartInfo->dwStartupFlags & STARTF_USESTDHANDLES))
|
||||||
Length = min(sizeof(ConsoleStartInfo->AppPath) / sizeof(ConsoleStartInfo->AppPath[0]) - 1,
|
{
|
||||||
ImagePathName->Length / sizeof(WCHAR));
|
Parameters->StandardInput = ConsoleStartInfo->InputHandle;
|
||||||
wcsncpy(ConsoleStartInfo->AppPath, ImagePathName->Buffer, Length);
|
Parameters->StandardOutput = ConsoleStartInfo->OutputHandle;
|
||||||
ConsoleStartInfo->AppPath[Length] = L'\0';
|
Parameters->StandardError = ConsoleStartInfo->ErrorHandle;
|
||||||
|
}
|
||||||
/* The Console Server will use these fields to set up the console icon */
|
|
||||||
ConsoleStartInfo->IconPath[0] = L'\0';
|
|
||||||
ConsoleStartInfo->IconIndex = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
static BOOLEAN
|
||||||
WINAPI
|
IsConsoleApp(VOID)
|
||||||
BasepInitConsole(VOID)
|
{
|
||||||
|
PIMAGE_NT_HEADERS ImageNtHeader = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
|
||||||
|
return (ImageNtHeader && (ImageNtHeader->OptionalHeader.Subsystem ==
|
||||||
|
IMAGE_SUBSYSTEM_WINDOWS_CUI));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static BOOLEAN
|
||||||
|
ConnectConsole(IN PWSTR SessionDir,
|
||||||
|
IN PCONSRV_API_CONNECTINFO ConnectInfo,
|
||||||
|
OUT PBOOLEAN IsServerProcess)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
ULONG ConnectInfoSize = sizeof(*ConnectInfo);
|
||||||
WCHAR SessionDir[256];
|
|
||||||
ULONG SessionId = NtCurrentPeb()->SessionId;
|
|
||||||
BOOLEAN InServer;
|
|
||||||
|
|
||||||
CONSRV_API_CONNECTINFO ConnectInfo;
|
ASSERT(SessionDir);
|
||||||
ULONG ConnectInfoSize = sizeof(ConnectInfo);
|
|
||||||
|
|
||||||
DPRINT("BasepInitConsole for : %wZ\n", &Parameters->ImagePathName);
|
|
||||||
DPRINT("Our current console handles are: %p, %p, %p %p\n",
|
|
||||||
Parameters->ConsoleHandle, Parameters->StandardInput,
|
|
||||||
Parameters->StandardOutput, Parameters->StandardError);
|
|
||||||
|
|
||||||
/* Initialize our global console DLL lock */
|
|
||||||
Status = RtlInitializeCriticalSection(&ConsoleLock);
|
|
||||||
if (!NT_SUCCESS(Status)) return FALSE;
|
|
||||||
ConsoleInitialized = TRUE;
|
|
||||||
|
|
||||||
/* Do nothing if this isn't a console app... */
|
|
||||||
if (RtlImageNtHeader(GetModuleHandle(NULL))->OptionalHeader.Subsystem !=
|
|
||||||
IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
|
||||||
{
|
|
||||||
DPRINT("Image is not a console application\n");
|
|
||||||
Parameters->ConsoleHandle = NULL;
|
|
||||||
ConnectInfo.ConsoleStartInfo.ConsoleNeeded = FALSE; // ConsoleNeeded is used for knowing whether or not this is a CUI app.
|
|
||||||
|
|
||||||
ConnectInfo.ConsoleStartInfo.ConsoleTitle[0] = L'\0';
|
|
||||||
ConnectInfo.ConsoleStartInfo.AppPath[0] = L'\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LPCWSTR ExeName;
|
|
||||||
|
|
||||||
InitConsoleInfo(&ConnectInfo.ConsoleStartInfo,
|
|
||||||
&Parameters->ImagePathName);
|
|
||||||
|
|
||||||
/* Initialize Input EXE name */
|
|
||||||
ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\\');
|
|
||||||
if (ExeName) SetConsoleInputExeNameW(ExeName + 1);
|
|
||||||
|
|
||||||
/* Assume one is needed */
|
|
||||||
ConnectInfo.ConsoleStartInfo.ConsoleNeeded = TRUE;
|
|
||||||
|
|
||||||
/* Handle the special flags given to us by BasePushProcessParameters */
|
|
||||||
if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS)
|
|
||||||
{
|
|
||||||
/* No console to create */
|
|
||||||
DPRINT("No console to create\n");
|
|
||||||
Parameters->ConsoleHandle = NULL;
|
|
||||||
ConnectInfo.ConsoleStartInfo.ConsoleNeeded = FALSE;
|
|
||||||
}
|
|
||||||
else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE)
|
|
||||||
{
|
|
||||||
/* We'll get the real one soon */
|
|
||||||
DPRINT("Creating new console\n");
|
|
||||||
Parameters->ConsoleHandle = NULL;
|
|
||||||
}
|
|
||||||
else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW)
|
|
||||||
{
|
|
||||||
/* We'll get the real one soon */
|
|
||||||
DPRINT("Creating new invisible console\n");
|
|
||||||
Parameters->ConsoleHandle = NULL;
|
|
||||||
ConnectInfo.ConsoleStartInfo.wShowWindow = SW_HIDE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Parameters->ConsoleHandle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
Parameters->ConsoleHandle = NULL;
|
|
||||||
}
|
|
||||||
DPRINT("Using existing console: %p\n", Parameters->ConsoleHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now use the proper console handle */
|
|
||||||
ConnectInfo.ConsoleHandle = Parameters->ConsoleHandle;
|
|
||||||
|
|
||||||
/* Initialize the Console Ctrl Handler */
|
|
||||||
InitConsoleCtrlHandling();
|
|
||||||
ConnectInfo.ConsoleStartInfo.CtrlDispatcher = ConsoleControlDispatcher;
|
|
||||||
|
|
||||||
/* Initialize the Property Dialog Handler */
|
|
||||||
ConnectInfo.ConsoleStartInfo.PropDispatcher = PropDialogHandler;
|
|
||||||
|
|
||||||
/* Setup the right Object Directory path */
|
|
||||||
if (!SessionId)
|
|
||||||
{
|
|
||||||
/* Use the raw path */
|
|
||||||
wcscpy(SessionDir, WIN_OBJ_DIR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Use the session path */
|
|
||||||
swprintf(SessionDir,
|
|
||||||
L"%ws\\%ld%ws",
|
|
||||||
SESSION_DIR,
|
|
||||||
SessionId,
|
|
||||||
WIN_OBJ_DIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Connect to the Console Server */
|
/* Connect to the Console Server */
|
||||||
DPRINT("Connecting to the Console Server in BasepInitConsole...\n");
|
DPRINT("Connecting to the Console Server...\n");
|
||||||
Status = CsrClientConnectToServer(SessionDir,
|
Status = CsrClientConnectToServer(SessionDir,
|
||||||
CONSRV_SERVERDLL_INDEX,
|
CONSRV_SERVERDLL_INDEX,
|
||||||
&ConnectInfo,
|
ConnectInfo,
|
||||||
&ConnectInfoSize,
|
&ConnectInfoSize,
|
||||||
&InServer);
|
IsServerProcess);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to connect to the Console Server (Status %lx)\n", Status);
|
DPRINT1("Failed to connect to the Console Server (Status %lx)\n", Status);
|
||||||
|
@ -284,36 +303,222 @@ BasepInitConsole(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nothing to do for server-to-server */
|
/* Nothing to do for server-to-server */
|
||||||
if (InServer) return TRUE;
|
if (*IsServerProcess) return TRUE;
|
||||||
|
|
||||||
/* Nothing to do if not a console app */
|
/* Nothing to do if this is not a console app */
|
||||||
if (!ConnectInfo.ConsoleStartInfo.ConsoleNeeded) return TRUE;
|
if (!ConnectInfo->IsConsoleApp) return TRUE;
|
||||||
|
|
||||||
/* We got the handles, let's set them */
|
#ifdef USE_CONSOLE_INIT_HANDLES
|
||||||
if ((Parameters->ConsoleHandle = ConnectInfo.ConsoleHandle))
|
/* Wait for the connection to finish */
|
||||||
|
Status = NtWaitForMultipleObjects(2, ConnectInfo->ConsoleStartInfo.Events,
|
||||||
|
WaitAny, FALSE, NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* If we already had some, don't use the new ones */
|
BaseSetLastNTError(Status);
|
||||||
if (!Parameters->StandardInput)
|
return FALSE;
|
||||||
{
|
|
||||||
Parameters->StandardInput = ConnectInfo.InputHandle;
|
|
||||||
}
|
|
||||||
if (!Parameters->StandardOutput)
|
|
||||||
{
|
|
||||||
Parameters->StandardOutput = ConnectInfo.OutputHandle;
|
|
||||||
}
|
|
||||||
if (!Parameters->StandardError)
|
|
||||||
{
|
|
||||||
Parameters->StandardError = ConnectInfo.ErrorHandle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InputWaitHandle = ConnectInfo.InputWaitHandle;
|
NtClose(ConnectInfo->ConsoleStartInfo.Events[0]);
|
||||||
|
NtClose(ConnectInfo->ConsoleStartInfo.Events[1]);
|
||||||
|
|
||||||
|
if (Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
WINAPI
|
||||||
|
ConDllInitialize(IN ULONG Reason,
|
||||||
|
IN PWSTR SessionDir)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
||||||
|
BOOLEAN IsServerProcess;
|
||||||
|
CONSRV_API_CONNECTINFO ConnectInfo;
|
||||||
|
LCID lcid;
|
||||||
|
|
||||||
|
if (Reason != DLL_PROCESS_ATTACH)
|
||||||
|
{
|
||||||
|
if (Reason != DLL_THREAD_ATTACH || !IsConsoleApp())
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
// Reason == DLL_THREAD_ATTACH and IsConsoleApp;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("ConDllInitialize for: %wZ\n"
|
||||||
|
"Our current console handles are: 0x%p, 0x%p, 0x%p 0x%p\n",
|
||||||
|
&Parameters->ImagePathName,
|
||||||
|
Parameters->ConsoleHandle,
|
||||||
|
Parameters->StandardInput,
|
||||||
|
Parameters->StandardOutput,
|
||||||
|
Parameters->StandardError);
|
||||||
|
|
||||||
|
/* Initialize our global console DLL lock */
|
||||||
|
Status = RtlInitializeCriticalSection(&ConsoleLock);
|
||||||
|
if (!NT_SUCCESS(Status)) return FALSE;
|
||||||
|
ConsoleInitialized = TRUE;
|
||||||
|
|
||||||
|
/* Show by default the console window when applicable */
|
||||||
|
ConnectInfo.IsWindowVisible = TRUE;
|
||||||
|
/* If this is a console app, a console will be created/opened */
|
||||||
|
ConnectInfo.IsConsoleApp = IsConsoleApp();
|
||||||
|
|
||||||
|
/* Do nothing if this is not a console app... */
|
||||||
|
if (!ConnectInfo.IsConsoleApp)
|
||||||
|
{
|
||||||
|
DPRINT("Image is not a console application\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle the special flags given to us by BasePushProcessParameters.
|
||||||
|
*/
|
||||||
|
if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS)
|
||||||
|
{
|
||||||
|
/* No console to create */
|
||||||
|
DPRINT("No console to create\n");
|
||||||
|
/*
|
||||||
|
* The new process does not inherit its parent's console and cannot
|
||||||
|
* attach to the console of its parent. The new process can call the
|
||||||
|
* AllocConsole function at a later time to create a console.
|
||||||
|
*/
|
||||||
|
Parameters->ConsoleHandle = NULL; // Do not inherit the parent's console.
|
||||||
|
ConnectInfo.IsConsoleApp = FALSE; // Do not create any console.
|
||||||
|
}
|
||||||
|
else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE)
|
||||||
|
{
|
||||||
|
/* We'll get the real one soon */
|
||||||
|
DPRINT("Creating a new separate console\n");
|
||||||
|
/*
|
||||||
|
* The new process has a new console, instead of inheriting
|
||||||
|
* its parent's console.
|
||||||
|
*/
|
||||||
|
Parameters->ConsoleHandle = NULL; // Do not inherit the parent's console.
|
||||||
|
}
|
||||||
|
else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW)
|
||||||
|
{
|
||||||
|
/* We'll get the real one soon */
|
||||||
|
DPRINT("Creating a new invisible console\n");
|
||||||
|
/*
|
||||||
|
* The process is a console application that is being run
|
||||||
|
* without a console window. Therefore, the console handle
|
||||||
|
* for the application is not set.
|
||||||
|
*/
|
||||||
|
Parameters->ConsoleHandle = NULL; // Do not inherit the parent's console.
|
||||||
|
ConnectInfo.IsWindowVisible = FALSE; // A console is created but is not shown to the user.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("Using existing console: 0x%p\n", Parameters->ConsoleHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do nothing if this is not a console app... */
|
||||||
|
if (!ConnectInfo.IsConsoleApp)
|
||||||
|
{
|
||||||
|
/* Do not inherit the parent's console if we are not a console app */
|
||||||
|
Parameters->ConsoleHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now use the proper console handle */
|
||||||
|
ConnectInfo.ConsoleStartInfo.ConsoleHandle = Parameters->ConsoleHandle;
|
||||||
|
|
||||||
|
/* Initialize the console dispatchers */
|
||||||
|
ConnectInfo.CtrlRoutine = ConsoleControlDispatcher;
|
||||||
|
ConnectInfo.PropRoutine = PropDialogHandler;
|
||||||
|
// ConnectInfo.ImeRoutine = ImeRoutine;
|
||||||
|
|
||||||
|
/* Set up the console properties */
|
||||||
|
if (ConnectInfo.IsConsoleApp && Parameters->ConsoleHandle == NULL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We can set up the console properties only if we create a new one
|
||||||
|
* (we do not inherit it from our parent).
|
||||||
|
*/
|
||||||
|
|
||||||
|
LPWSTR ConsoleTitle = ConnectInfo.ConsoleTitle;
|
||||||
|
|
||||||
|
ConnectInfo.TitleLength = sizeof(ConnectInfo.ConsoleTitle);
|
||||||
|
ConnectInfo.DesktopLength = 0; // SetUpConsoleInfo will give us the real length.
|
||||||
|
|
||||||
|
SetUpConsoleInfo(TRUE,
|
||||||
|
&ConnectInfo.TitleLength,
|
||||||
|
&ConsoleTitle,
|
||||||
|
&ConnectInfo.DesktopLength,
|
||||||
|
&ConnectInfo.Desktop,
|
||||||
|
&ConnectInfo.ConsoleStartInfo);
|
||||||
|
DPRINT("ConsoleTitle = '%S' - Desktop = '%S'\n",
|
||||||
|
ConsoleTitle, ConnectInfo.Desktop);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConnectInfo.TitleLength = 0;
|
||||||
|
ConnectInfo.DesktopLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the Input EXE name */
|
||||||
|
if (ConnectInfo.IsConsoleApp)
|
||||||
|
{
|
||||||
|
LPWSTR CurDir = ConnectInfo.CurDir;
|
||||||
|
LPWSTR AppName = ConnectInfo.AppName;
|
||||||
|
|
||||||
|
InitExeName();
|
||||||
|
|
||||||
|
ConnectInfo.CurDirLength = sizeof(ConnectInfo.CurDir);
|
||||||
|
ConnectInfo.AppNameLength = sizeof(ConnectInfo.AppName);
|
||||||
|
|
||||||
|
SetUpAppName(TRUE,
|
||||||
|
&ConnectInfo.CurDirLength,
|
||||||
|
&CurDir,
|
||||||
|
&ConnectInfo.AppNameLength,
|
||||||
|
&AppName);
|
||||||
|
DPRINT("CurDir = '%S' - AppName = '%S'\n",
|
||||||
|
CurDir, AppName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConnectInfo.CurDirLength = 0;
|
||||||
|
ConnectInfo.AppNameLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize Console Ctrl Handling, that needs to be supported by
|
||||||
|
* all applications, especially because it is used at shutdown.
|
||||||
|
*/
|
||||||
|
InitializeCtrlHandling();
|
||||||
|
|
||||||
|
/* Connect to the Console Server */
|
||||||
|
if (!ConnectConsole(SessionDir,
|
||||||
|
&ConnectInfo,
|
||||||
|
&IsServerProcess))
|
||||||
|
{
|
||||||
|
// DPRINT1("Failed to connect to the Console Server (Status %lx)\n", Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we are not doing server-to-server init and if this is a console app... */
|
||||||
|
if (!IsServerProcess && ConnectInfo.IsConsoleApp)
|
||||||
|
{
|
||||||
|
/* ... set the handles that we got */
|
||||||
|
if (Parameters->ConsoleHandle == NULL)
|
||||||
|
SetUpHandles(&ConnectInfo.ConsoleStartInfo);
|
||||||
|
|
||||||
|
InputWaitHandle = ConnectInfo.ConsoleStartInfo.InputWaitHandle;
|
||||||
|
Exit:
|
||||||
|
SetTEBLangID(lcid);
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("Console setup: 0x%p, 0x%p, 0x%p, 0x%p\n",
|
||||||
|
Parameters->ConsoleHandle,
|
||||||
|
Parameters->StandardInput,
|
||||||
|
Parameters->StandardOutput,
|
||||||
|
Parameters->StandardError);
|
||||||
|
|
||||||
DPRINT("Console setup: %p, %p, %p, %p\n",
|
|
||||||
Parameters->ConsoleHandle,
|
|
||||||
Parameters->StandardInput,
|
|
||||||
Parameters->StandardOutput,
|
|
||||||
Parameters->StandardError);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,6 @@
|
||||||
* Read functions *
|
* Read functions *
|
||||||
******************/
|
******************/
|
||||||
|
|
||||||
DWORD
|
|
||||||
WINAPI
|
|
||||||
GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer);
|
|
||||||
|
|
||||||
static
|
static
|
||||||
BOOL
|
BOOL
|
||||||
IntReadConsole(IN HANDLE hConsoleInput,
|
IntReadConsole(IN HANDLE hConsoleInput,
|
||||||
|
@ -58,26 +54,12 @@ IntReadConsole(IN HANDLE hConsoleInput,
|
||||||
ReadConsoleRequest->Unicode = bUnicode;
|
ReadConsoleRequest->Unicode = bUnicode;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve the current console executable name string and length (always
|
* Retrieve the (current) Input EXE name string and length,
|
||||||
* in UNICODE format).
|
* not NULL-terminated (always in UNICODE format).
|
||||||
* FIXME: Do not use GetConsoleInputExeNameW but use something else...
|
|
||||||
*/
|
*/
|
||||||
// 1- Get the exe name length in characters, including NULL character.
|
|
||||||
ReadConsoleRequest->ExeLength =
|
ReadConsoleRequest->ExeLength =
|
||||||
(USHORT)GetConsoleInputExeNameW(0, (PWCHAR)ReadConsoleRequest->StaticBuffer);
|
GetCurrentExeName((PWCHAR)ReadConsoleRequest->StaticBuffer,
|
||||||
// 2- Get the exe name (GetConsoleInputExeNameW returns 1 in case of success).
|
sizeof(ReadConsoleRequest->StaticBuffer));
|
||||||
if (GetConsoleInputExeNameW(ReadConsoleRequest->ExeLength,
|
|
||||||
(PWCHAR)ReadConsoleRequest->StaticBuffer) != 1)
|
|
||||||
{
|
|
||||||
// Nothing
|
|
||||||
ReadConsoleRequest->ExeLength = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Remove the NULL character, and convert in number of bytes.
|
|
||||||
ReadConsoleRequest->ExeLength--;
|
|
||||||
ReadConsoleRequest->ExeLength *= sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** For DEBUGGING purposes ***/
|
/*** For DEBUGGING purposes ***/
|
||||||
{
|
{
|
||||||
|
|
|
@ -200,7 +200,7 @@ DllMain(HANDLE hDll,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize Console Support */
|
/* Initialize Console Support */
|
||||||
if (!BasepInitConsole())
|
if (!ConDllInitialize(dwReason, SessionDir))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to set up console\n");
|
DPRINT1("Failed to set up console\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -726,7 +726,7 @@ BasePushProcessParameters(IN ULONG ParameterFlags,
|
||||||
ProcessParameters->StandardError = StartupInfo->hStdError;
|
ProcessParameters->StandardError = StartupInfo->hStdError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use Special Flags for BasepInitConsole in Kernel32 */
|
/* Use Special Flags for ConDllInitialize in Kernel32 */
|
||||||
if (CreationFlags & DETACHED_PROCESS)
|
if (CreationFlags & DETACHED_PROCESS)
|
||||||
{
|
{
|
||||||
ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
|
ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
|
||||||
|
|
|
@ -10,26 +10,35 @@
|
||||||
|
|
||||||
/* CONSTANTS ******************************************************************/
|
/* CONSTANTS ******************************************************************/
|
||||||
|
|
||||||
#define HANDLE_DETACHED_PROCESS (HANDLE)-2
|
#define HANDLE_DETACHED_PROCESS (HANDLE)-1
|
||||||
#define HANDLE_CREATE_NEW_CONSOLE (HANDLE)-3
|
#define HANDLE_CREATE_NEW_CONSOLE (HANDLE)-2
|
||||||
#define HANDLE_CREATE_NO_WINDOW (HANDLE)-4
|
#define HANDLE_CREATE_NO_WINDOW (HANDLE)-3
|
||||||
|
|
||||||
|
// Enable (and then get rid of) this define when support for
|
||||||
|
// console initialization handles is implemented in CONSRV.
|
||||||
|
// #define USE_CONSOLE_INIT_HANDLES
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTION PROTOTYPES ********************************************************/
|
/* FUNCTION PROTOTYPES ********************************************************/
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOLEAN
|
||||||
BasepInitConsole(VOID);
|
WINAPI
|
||||||
|
ConDllInitialize(IN ULONG Reason,
|
||||||
|
IN PWSTR SessionDir);
|
||||||
|
|
||||||
VOID WINAPI
|
VOID
|
||||||
|
WINAPI
|
||||||
BasepUninitConsole(VOID);
|
BasepUninitConsole(VOID);
|
||||||
|
|
||||||
VOID WINAPI
|
VOID
|
||||||
InitConsoleCtrlHandling(VOID);
|
InitializeCtrlHandling(VOID);
|
||||||
|
|
||||||
DWORD WINAPI
|
DWORD
|
||||||
|
WINAPI
|
||||||
ConsoleControlDispatcher(IN LPVOID lpThreadParameter);
|
ConsoleControlDispatcher(IN LPVOID lpThreadParameter);
|
||||||
|
|
||||||
DWORD WINAPI
|
DWORD
|
||||||
|
WINAPI
|
||||||
PropDialogHandler(IN LPVOID lpThreadParameter);
|
PropDialogHandler(IN LPVOID lpThreadParameter);
|
||||||
|
|
||||||
HANDLE WINAPI
|
HANDLE WINAPI
|
||||||
|
@ -59,9 +68,32 @@ GetConsoleInputWaitHandle(VOID);
|
||||||
HANDLE
|
HANDLE
|
||||||
TranslateStdHandle(HANDLE hHandle);
|
TranslateStdHandle(HANDLE hHandle);
|
||||||
|
|
||||||
|
#define SetTEBLangID(p) (p)
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
InitConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
SetUpConsoleInfo(IN BOOLEAN CaptureTitle,
|
||||||
IN PUNICODE_STRING ImagePathName);
|
IN OUT LPDWORD pTitleLength,
|
||||||
|
IN OUT LPWSTR* lpTitle OPTIONAL,
|
||||||
|
IN OUT LPDWORD pDesktopLength,
|
||||||
|
IN OUT LPWSTR* lpDesktop OPTIONAL,
|
||||||
|
IN OUT PCONSOLE_START_INFO ConsoleStartInfo);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetUpHandles(IN PCONSOLE_START_INFO ConsoleStartInfo);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
InitExeName(VOID);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
SetUpAppName(IN BOOLEAN CaptureStrings,
|
||||||
|
IN OUT LPDWORD CurDirLength,
|
||||||
|
IN OUT LPWSTR* CurDir,
|
||||||
|
IN OUT LPDWORD AppNameLength,
|
||||||
|
IN OUT LPWSTR* AppName);
|
||||||
|
|
||||||
|
USHORT
|
||||||
|
GetCurrentExeName(OUT PWCHAR ExeName,
|
||||||
|
IN USHORT BufferSize);
|
||||||
|
|
||||||
LPCWSTR
|
LPCWSTR
|
||||||
IntCheckForConsoleFileName(IN LPCWSTR pszName,
|
IntCheckForConsoleFileName(IN LPCWSTR pszName,
|
||||||
|
@ -73,7 +105,4 @@ OpenConsoleW(LPCWSTR wsName,
|
||||||
BOOL bInheritHandle,
|
BOOL bInheritHandle,
|
||||||
DWORD dwShareMode);
|
DWORD dwShareMode);
|
||||||
|
|
||||||
BOOL WINAPI
|
|
||||||
SetConsoleInputExeNameW(LPCWSTR lpInputExeName);
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -119,6 +119,13 @@ typedef enum _CONSRV_API_NUMBER
|
||||||
//
|
//
|
||||||
typedef struct _CONSOLE_PROPERTIES
|
typedef struct _CONSOLE_PROPERTIES
|
||||||
{
|
{
|
||||||
|
INT IconIndex;
|
||||||
|
HICON hIcon;
|
||||||
|
HICON hIconSm;
|
||||||
|
DWORD dwHotKey;
|
||||||
|
DWORD dwStartupFlags;
|
||||||
|
|
||||||
|
// NT_CONSOLE_PROPS
|
||||||
WORD wFillAttribute;
|
WORD wFillAttribute;
|
||||||
WORD wPopupFillAttribute;
|
WORD wPopupFillAttribute;
|
||||||
|
|
||||||
|
@ -134,62 +141,60 @@ typedef struct _CONSOLE_PROPERTIES
|
||||||
DWORD nFont;
|
DWORD nFont;
|
||||||
DWORD nInputBufferSize;
|
DWORD nInputBufferSize;
|
||||||
COORD dwFontSize;
|
COORD dwFontSize;
|
||||||
UINT uFontFamily;
|
UINT uFontFamily;
|
||||||
UINT uFontWeight;
|
UINT uFontWeight;
|
||||||
WCHAR FaceName[LF_FACESIZE];
|
WCHAR FaceName[LF_FACESIZE];
|
||||||
UINT uCursorSize;
|
UINT uCursorSize;
|
||||||
BOOL bFullScreen;
|
BOOL bFullScreen;
|
||||||
BOOL bQuickEdit;
|
BOOL bQuickEdit;
|
||||||
BOOL bInsertMode;
|
BOOL bInsertMode;
|
||||||
BOOL bAutoPosition;
|
BOOL bAutoPosition;
|
||||||
UINT uHistoryBufferSize;
|
UINT uHistoryBufferSize;
|
||||||
UINT uNumberOfHistoryBuffers;
|
UINT uNumberOfHistoryBuffers;
|
||||||
BOOL bHistoryNoDup;
|
BOOL bHistoryNoDup;
|
||||||
COLORREF ColorTable[16];
|
COLORREF ColorTable[16];
|
||||||
|
|
||||||
//NT_FE_CONSOLE_PROPS
|
// NT_FE_CONSOLE_PROPS
|
||||||
UINT uCodePage;
|
UINT uCodePage;
|
||||||
} CONSOLE_PROPERTIES;
|
} CONSOLE_PROPERTIES;
|
||||||
|
|
||||||
//
|
|
||||||
// To minimize code changes, some fields were put here even though they really only belong in
|
|
||||||
// CONSRV_API_CONNECTINFO. Do not change the ordering however, as it's required for Windows
|
|
||||||
// compatibility.
|
|
||||||
//
|
|
||||||
typedef struct _CONSOLE_START_INFO
|
typedef struct _CONSOLE_START_INFO
|
||||||
{
|
|
||||||
INT IconIndex;
|
|
||||||
HICON IconHandle1;
|
|
||||||
HICON IconHandle2;
|
|
||||||
DWORD dwHotKey;
|
|
||||||
DWORD dwStartupFlags;
|
|
||||||
CONSOLE_PROPERTIES;
|
|
||||||
|
|
||||||
BOOLEAN ConsoleNeeded; // Used for GUI apps only.
|
|
||||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
|
||||||
LPTHREAD_START_ROUTINE ImeDispatcher;
|
|
||||||
LPTHREAD_START_ROUTINE PropDispatcher;
|
|
||||||
ULONG TitleLength;
|
|
||||||
WCHAR ConsoleTitle[MAX_PATH + 1]; // Console title or full path to the startup shortcut
|
|
||||||
ULONG DesktopLength;
|
|
||||||
PWCHAR DesktopPath;
|
|
||||||
ULONG AppNameLength;
|
|
||||||
WCHAR AppPath[128]; // Full path of the launched app
|
|
||||||
ULONG IconPathLength;
|
|
||||||
WCHAR IconPath[MAX_PATH + 1]; // Path to the file containing the icon
|
|
||||||
} CONSOLE_START_INFO, *PCONSOLE_START_INFO;
|
|
||||||
|
|
||||||
typedef struct _CONSRV_API_CONNECTINFO
|
|
||||||
{
|
{
|
||||||
HANDLE ConsoleHandle;
|
HANDLE ConsoleHandle;
|
||||||
HANDLE InputWaitHandle;
|
HANDLE InputWaitHandle;
|
||||||
HANDLE InputHandle;
|
HANDLE InputHandle;
|
||||||
HANDLE OutputHandle;
|
HANDLE OutputHandle;
|
||||||
HANDLE ErrorHandle;
|
HANDLE ErrorHandle;
|
||||||
HANDLE Event1;
|
HANDLE Events[2];
|
||||||
HANDLE Event2;
|
|
||||||
/* Adapted from CONSOLE_ALLOCCONSOLE */
|
CONSOLE_PROPERTIES;
|
||||||
|
} CONSOLE_START_INFO, *PCONSOLE_START_INFO;
|
||||||
|
|
||||||
|
#if defined(_M_IX86)
|
||||||
|
C_ASSERT(sizeof(CONSOLE_START_INFO) == 0xFC);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _CONSRV_API_CONNECTINFO
|
||||||
|
{
|
||||||
CONSOLE_START_INFO ConsoleStartInfo;
|
CONSOLE_START_INFO ConsoleStartInfo;
|
||||||
|
|
||||||
|
BOOLEAN IsConsoleApp;
|
||||||
|
BOOLEAN IsWindowVisible;
|
||||||
|
|
||||||
|
// USHORT Padding;
|
||||||
|
|
||||||
|
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||||
|
LPTHREAD_START_ROUTINE PropRoutine;
|
||||||
|
LPTHREAD_START_ROUTINE ImeRoutine;
|
||||||
|
|
||||||
|
ULONG TitleLength;
|
||||||
|
WCHAR ConsoleTitle[MAX_PATH + 1]; // Console title or full path to the startup shortcut
|
||||||
|
ULONG DesktopLength;
|
||||||
|
PWCHAR Desktop;
|
||||||
|
ULONG AppNameLength;
|
||||||
|
WCHAR AppName[128]; // Full path of the launched app
|
||||||
|
ULONG CurDirLength;
|
||||||
|
WCHAR CurDir[MAX_PATH + 1];
|
||||||
} CONSRV_API_CONNECTINFO, *PCONSRV_API_CONNECTINFO;
|
} CONSRV_API_CONNECTINFO, *PCONSRV_API_CONNECTINFO;
|
||||||
|
|
||||||
#if defined(_M_IX86)
|
#if defined(_M_IX86)
|
||||||
|
@ -259,25 +264,31 @@ typedef struct _CONSOLE_ALLOCCONSOLE
|
||||||
{
|
{
|
||||||
PCONSOLE_START_INFO ConsoleStartInfo;
|
PCONSOLE_START_INFO ConsoleStartInfo;
|
||||||
|
|
||||||
HANDLE ConsoleHandle;
|
ULONG TitleLength;
|
||||||
HANDLE InputHandle;
|
PWCHAR ConsoleTitle; // Console title or full path to the startup shortcut
|
||||||
HANDLE OutputHandle;
|
ULONG DesktopLength;
|
||||||
HANDLE ErrorHandle;
|
PWCHAR Desktop;
|
||||||
HANDLE InputWaitHandle;
|
ULONG AppNameLength;
|
||||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
PWCHAR AppName; // Full path of the launched app
|
||||||
LPTHREAD_START_ROUTINE PropDispatcher;
|
ULONG CurDirLength;
|
||||||
|
PWCHAR CurDir;
|
||||||
|
|
||||||
|
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||||
|
LPTHREAD_START_ROUTINE PropRoutine;
|
||||||
} CONSOLE_ALLOCCONSOLE, *PCONSOLE_ALLOCCONSOLE;
|
} CONSOLE_ALLOCCONSOLE, *PCONSOLE_ALLOCCONSOLE;
|
||||||
|
|
||||||
typedef struct _CONSOLE_ATTACHCONSOLE
|
typedef struct _CONSOLE_ATTACHCONSOLE
|
||||||
{
|
{
|
||||||
DWORD ProcessId; // If ProcessId == ATTACH_PARENT_PROCESS == -1, then attach the current process to its parent process console.
|
/*
|
||||||
HANDLE ConsoleHandle;
|
* If ProcessId == ATTACH_PARENT_PROCESS == -1, then attach
|
||||||
HANDLE InputHandle;
|
* the current process to its parent process console.
|
||||||
HANDLE OutputHandle;
|
*/
|
||||||
HANDLE ErrorHandle;
|
DWORD ProcessId;
|
||||||
HANDLE InputWaitHandle;
|
|
||||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
PCONSOLE_START_INFO ConsoleStartInfo;
|
||||||
LPTHREAD_START_ROUTINE PropDispatcher;
|
|
||||||
|
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||||
|
LPTHREAD_START_ROUTINE PropRoutine;
|
||||||
} CONSOLE_ATTACHCONSOLE, *PCONSOLE_ATTACHCONSOLE;
|
} CONSOLE_ATTACHCONSOLE, *PCONSOLE_ATTACHCONSOLE;
|
||||||
|
|
||||||
typedef struct _CONSOLE_FREECONSOLE
|
typedef struct _CONSOLE_FREECONSOLE
|
||||||
|
|
|
@ -76,35 +76,6 @@ RemoveConsole(IN PCONSOLE Console)
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID NTAPI
|
VOID NTAPI
|
||||||
ConDrvPause(PCONSOLE Console)
|
ConDrvPause(PCONSOLE Console)
|
||||||
{
|
{
|
||||||
|
@ -194,9 +165,6 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
|
||||||
TEXTMODE_BUFFER_INFO ScreenBufferInfo;
|
TEXTMODE_BUFFER_INFO ScreenBufferInfo;
|
||||||
PCONSOLE Console;
|
PCONSOLE Console;
|
||||||
PCONSOLE_SCREEN_BUFFER NewBuffer;
|
PCONSOLE_SCREEN_BUFFER NewBuffer;
|
||||||
#if 0
|
|
||||||
WCHAR DefaultTitle[128];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (NewConsole == NULL || ConsoleInfo == NULL)
|
if (NewConsole == NULL || ConsoleInfo == NULL)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -272,28 +240,6 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
|
||||||
Console->ActiveBuffer = NewBuffer;
|
Console->ActiveBuffer = NewBuffer;
|
||||||
Console->UnpauseEvent = NULL;
|
Console->UnpauseEvent = NULL;
|
||||||
|
|
||||||
/* Initialize the console title */
|
|
||||||
ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo->ConsoleTitle);
|
|
||||||
#if 0
|
|
||||||
if (ConsoleInfo.ConsoleTitle[0] == L'\0')
|
|
||||||
{
|
|
||||||
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
|
|
||||||
ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo->ConsoleTitle);
|
|
||||||
#if 0
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DPRINT("Console initialized\n");
|
DPRINT("Console initialized\n");
|
||||||
|
|
||||||
/* All went right, so add the console to the list */
|
/* All went right, so add the console to the list */
|
||||||
|
@ -460,9 +406,6 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
|
||||||
|
|
||||||
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
|
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
|
||||||
|
|
||||||
ConsoleFreeUnicodeString(&Console->OriginalTitle);
|
|
||||||
ConsoleFreeUnicodeString(&Console->Title);
|
|
||||||
|
|
||||||
DPRINT("ConDrvDeleteConsole - Unlocking\n");
|
DPRINT("ConDrvDeleteConsole - Unlocking\n");
|
||||||
LeaveCriticalSection(&Console->Lock);
|
LeaveCriticalSection(&Console->Lock);
|
||||||
DPRINT("ConDrvDeleteConsole - Destroying lock\n");
|
DPRINT("ConDrvDeleteConsole - Destroying lock\n");
|
||||||
|
@ -566,111 +509,6 @@ ConDrvSetConsoleMode(IN PCONSOLE Console,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
|
||||||
ConDrvGetConsoleTitle(IN PCONSOLE Console,
|
|
||||||
IN BOOLEAN Unicode,
|
|
||||||
IN OUT PVOID TitleBuffer,
|
|
||||||
IN OUT PULONG BufLength)
|
|
||||||
{
|
|
||||||
ULONG Length;
|
|
||||||
|
|
||||||
if (Console == NULL || TitleBuffer == NULL || BufLength == NULL)
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
/* Copy title of the console to the user title buffer */
|
|
||||||
if (Unicode)
|
|
||||||
{
|
|
||||||
if (*BufLength >= sizeof(WCHAR))
|
|
||||||
{
|
|
||||||
Length = min(*BufLength - sizeof(WCHAR), Console->Title.Length);
|
|
||||||
RtlCopyMemory(TitleBuffer, Console->Title.Buffer, Length);
|
|
||||||
((PWCHAR)TitleBuffer)[Length / sizeof(WCHAR)] = L'\0';
|
|
||||||
*BufLength = Length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*BufLength = Console->Title.Length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (*BufLength >= sizeof(CHAR))
|
|
||||||
{
|
|
||||||
Length = min(*BufLength - sizeof(CHAR), Console->Title.Length / sizeof(WCHAR));
|
|
||||||
Length = WideCharToMultiByte(Console->InputCodePage, 0,
|
|
||||||
Console->Title.Buffer, Length,
|
|
||||||
TitleBuffer, Length,
|
|
||||||
NULL, NULL);
|
|
||||||
((PCHAR)TitleBuffer)[Length] = '\0';
|
|
||||||
*BufLength = Length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*BufLength = Console->Title.Length / sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
|
||||||
ConDrvSetConsoleTitle(IN PCONSOLE Console,
|
|
||||||
IN BOOLEAN Unicode,
|
|
||||||
IN PVOID TitleBuffer,
|
|
||||||
IN ULONG BufLength)
|
|
||||||
{
|
|
||||||
PWCHAR Buffer;
|
|
||||||
ULONG Length;
|
|
||||||
|
|
||||||
if (Console == NULL || TitleBuffer == NULL)
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
if (Unicode)
|
|
||||||
{
|
|
||||||
/* Length is in bytes */
|
|
||||||
Length = BufLength;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Use the console input CP for the conversion */
|
|
||||||
Length = MultiByteToWideChar(Console->InputCodePage, 0,
|
|
||||||
TitleBuffer, BufLength,
|
|
||||||
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) return STATUS_NO_MEMORY;
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
if (Unicode)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(Console->Title.Buffer, TitleBuffer, Console->Title.Length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MultiByteToWideChar(Console->InputCodePage, 0,
|
|
||||||
TitleBuffer, BufLength,
|
|
||||||
Console->Title.Buffer,
|
|
||||||
Console->Title.Length / sizeof(WCHAR));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NULL-terminate */
|
|
||||||
Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
|
|
||||||
|
|
||||||
// TermChangeTitle(Console);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
ConDrvGetConsoleCP(IN PCONSOLE Console,
|
ConDrvGetConsoleCP(IN PCONSOLE Console,
|
||||||
OUT PUINT CodePage,
|
OUT PUINT CodePage,
|
||||||
|
|
|
@ -108,11 +108,6 @@ DummyReleaseScreenBuffer(IN OUT PTERMINAL This,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID NTAPI
|
|
||||||
DummyChangeTitle(IN OUT PTERMINAL This)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID NTAPI
|
static VOID NTAPI
|
||||||
DummyGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
|
DummyGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
|
||||||
PCOORD pSize)
|
PCOORD pSize)
|
||||||
|
@ -148,7 +143,6 @@ static TERMINAL_VTBL DummyVtbl =
|
||||||
DummyResizeTerminal,
|
DummyResizeTerminal,
|
||||||
DummySetActiveScreenBuffer,
|
DummySetActiveScreenBuffer,
|
||||||
DummyReleaseScreenBuffer,
|
DummyReleaseScreenBuffer,
|
||||||
DummyChangeTitle,
|
|
||||||
DummyGetLargestConsoleWindowSize,
|
DummyGetLargestConsoleWindowSize,
|
||||||
DummySetPalette,
|
DummySetPalette,
|
||||||
DummyShowMouseCursor,
|
DummyShowMouseCursor,
|
||||||
|
|
|
@ -14,6 +14,11 @@
|
||||||
|
|
||||||
#include <ndk/psfuncs.h>
|
#include <ndk/psfuncs.h>
|
||||||
|
|
||||||
|
/* This is for COM usage */
|
||||||
|
#define COBJMACROS
|
||||||
|
#include <shlobj.h>
|
||||||
|
|
||||||
|
|
||||||
#include <alias.h>
|
#include <alias.h>
|
||||||
#include <history.h>
|
#include <history.h>
|
||||||
#include "procinit.h"
|
#include "procinit.h"
|
||||||
|
@ -209,6 +214,35 @@ ConSrvValidateConsole(OUT PCONSRV_CONSOLE* Console,
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ConioPause(PCONSRV_CONSOLE Console, UINT Flags)
|
ConioPause(PCONSRV_CONSOLE Console, UINT Flags)
|
||||||
{
|
{
|
||||||
|
@ -317,10 +351,157 @@ ConSrvInitTerminal(IN OUT PTERMINAL Terminal,
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
ConSrvDeinitTerminal(IN OUT PTERMINAL Terminal);
|
ConSrvDeinitTerminal(IN OUT PTERMINAL Terminal);
|
||||||
|
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
LoadShellLinkConsoleInfo(IN OUT PCONSOLE_INFO ConsoleInfo,
|
||||||
|
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,
|
||||||
|
NULL,
|
||||||
|
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")
|
||||||
|
sizeof(ConsoleInfo->ConsoleTitle) / sizeof(ConsoleInfo->ConsoleTitle[0]) - 1);
|
||||||
|
wcsncpy(ConsoleInfo->ConsoleTitle, LinkName, Length);
|
||||||
|
ConsoleInfo->ConsoleTitle[Length] = L'\0';
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
DPRINT1("IconPath = '%S' ; IconIndex = %lu\n",
|
||||||
|
IconPath, ConsoleInitInfo->ConsoleStartInfo->IconIndex);
|
||||||
|
if (IconPath && *IconPath)
|
||||||
|
{
|
||||||
|
HICON hIcon = NULL, hIconSm = NULL;
|
||||||
|
PrivateExtractIconExW(IconPath,
|
||||||
|
ConsoleInitInfo->ConsoleStartInfo->IconIndex,
|
||||||
|
&hIcon,
|
||||||
|
&hIconSm,
|
||||||
|
1);
|
||||||
|
DPRINT1("hIcon = 0x%p ; hIconSm = 0x%p\n", hIcon, hIconSm);
|
||||||
|
if (hIcon != NULL) ConsoleInitInfo->ConsoleStartInfo->hIcon = hIcon;
|
||||||
|
if (hIconSm != NULL) ConsoleInitInfo->ConsoleStartInfo->hIconSm = hIconSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: See the previous FIXME above.
|
||||||
|
RetVal = FALSE;
|
||||||
|
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||||
OUT PCONSRV_CONSOLE* NewConsole,
|
OUT PCONSRV_CONSOLE* NewConsole,
|
||||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
|
||||||
IN ULONG ConsoleLeaderProcessId)
|
IN ULONG ConsoleLeaderProcessId)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -331,7 +512,7 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||||
|
|
||||||
TERMINAL Terminal; /* The ConSrv terminal for this console */
|
TERMINAL Terminal; /* The ConSrv terminal for this console */
|
||||||
|
|
||||||
if (NewConsole == NULL || ConsoleStartInfo == NULL)
|
if (NewConsole == NULL || ConsoleInitInfo == NULL)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
*NewConsole = NULL;
|
*NewConsole = NULL;
|
||||||
|
@ -344,15 +525,15 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||||
ConSrvGetDefaultSettings(&ConsoleInfo, ConsoleLeaderProcessId);
|
ConSrvGetDefaultSettings(&ConsoleInfo, ConsoleLeaderProcessId);
|
||||||
|
|
||||||
/* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */
|
/* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */
|
||||||
Length = min(wcslen(ConsoleStartInfo->ConsoleTitle),
|
Length = min(ConsoleInitInfo->TitleLength,
|
||||||
sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1);
|
sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1);
|
||||||
wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length);
|
wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleInitInfo->ConsoleTitle, Length);
|
||||||
ConsoleInfo.ConsoleTitle[Length] = L'\0';
|
ConsoleInfo.ConsoleTitle[Length] = L'\0'; // NULL-terminate it.
|
||||||
|
|
||||||
/* 3. Initialize the ConSrv terminal */
|
/* 3. Initialize the ConSrv terminal */
|
||||||
Status = ConSrvInitTerminal(&Terminal,
|
Status = ConSrvInitTerminal(&Terminal,
|
||||||
&ConsoleInfo,
|
&ConsoleInfo,
|
||||||
ConsoleStartInfo,
|
ConsoleInitInfo,
|
||||||
ConsoleLeaderProcessId);
|
ConsoleLeaderProcessId);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -361,10 +542,25 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||||
}
|
}
|
||||||
DPRINT("CONSRV: Terminal initialized\n");
|
DPRINT("CONSRV: Terminal initialized\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load per-application terminal settings.
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
if (!LoadShellLinkConsoleInfo(&ConsoleInfo, ConsoleInitInfo))
|
||||||
|
{
|
||||||
|
ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags &= ~STARTF_TITLEISLINKNAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 4. Load the remaining console settings via the registry.
|
* 4. Load the remaining console settings via the registry.
|
||||||
*/
|
*/
|
||||||
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
if ((ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Either we weren't created by an app launched via a shell-link,
|
* Either we weren't created by an app launched via a shell-link,
|
||||||
|
@ -379,17 +575,17 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||||
* (and which was transmitted via the ConsoleStartInfo structure).
|
* (and which was transmitted via the ConsoleStartInfo structure).
|
||||||
* We therefore overwrite the values read in the registry.
|
* We therefore overwrite the values read in the registry.
|
||||||
*/
|
*/
|
||||||
if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
|
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
|
||||||
{
|
{
|
||||||
ConsoleInfo.ScreenAttrib = (USHORT)ConsoleStartInfo->wFillAttribute;
|
ConsoleInfo.ScreenAttrib = (USHORT)ConsoleInitInfo->ConsoleStartInfo->wFillAttribute;
|
||||||
}
|
}
|
||||||
if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
|
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
|
||||||
{
|
{
|
||||||
ConsoleInfo.ScreenBufferSize = ConsoleStartInfo->dwScreenBufferSize;
|
ConsoleInfo.ScreenBufferSize = ConsoleInitInfo->ConsoleStartInfo->dwScreenBufferSize;
|
||||||
}
|
}
|
||||||
if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
|
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
|
||||||
{
|
{
|
||||||
ConsoleInfo.ConsoleSize = ConsoleStartInfo->dwWindowSize;
|
ConsoleInfo.ConsoleSize = ConsoleInitInfo->ConsoleStartInfo->dwWindowSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,6 +606,31 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||||
|
|
||||||
/*** Register ConSrv features ***/
|
/*** Register ConSrv features ***/
|
||||||
|
|
||||||
|
/* Initialize the console title */
|
||||||
|
#if 0
|
||||||
|
WCHAR DefaultTitle[128];
|
||||||
|
#endif
|
||||||
|
ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo.ConsoleTitle);
|
||||||
|
#if 0
|
||||||
|
if (ConsoleInfo.ConsoleTitle[0] == L'\0')
|
||||||
|
{
|
||||||
|
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
|
||||||
|
ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo.ConsoleTitle);
|
||||||
|
#if 0
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialize process support */
|
/* Initialize process support */
|
||||||
InitializeListHead(&Console->ProcessList);
|
InitializeListHead(&Console->ProcessList);
|
||||||
Console->NotifiedLastCloseProcess = NULL;
|
Console->NotifiedLastCloseProcess = NULL;
|
||||||
|
@ -482,6 +703,10 @@ ConSrvDeleteConsole(PCONSRV_CONSOLE Console)
|
||||||
IntDeleteAllAliases(Console);
|
IntDeleteAllAliases(Console);
|
||||||
HistoryDeleteBuffers(Console);
|
HistoryDeleteBuffers(Console);
|
||||||
|
|
||||||
|
/* Free the console title */
|
||||||
|
ConsoleFreeUnicodeString(&Console->OriginalTitle);
|
||||||
|
ConsoleFreeUnicodeString(&Console->Title);
|
||||||
|
|
||||||
/* Now, call the driver. ConDrvDeregisterTerminal is called on-demand. */
|
/* Now, call the driver. ConDrvDeregisterTerminal is called on-demand. */
|
||||||
ConDrvDeleteConsole((PCONSOLE)Console);
|
ConDrvDeleteConsole((PCONSOLE)Console);
|
||||||
|
|
||||||
|
@ -504,7 +729,7 @@ ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
|
||||||
|
|
||||||
DPRINT("ConSrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
|
DPRINT("ConSrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
|
||||||
|
|
||||||
if (ProcessData->CtrlDispatcher)
|
if (ProcessData->CtrlRoutine)
|
||||||
{
|
{
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
|
@ -513,7 +738,7 @@ ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
||||||
ProcessData->CtrlDispatcher,
|
ProcessData->CtrlRoutine,
|
||||||
UlongToPtr(CtrlEvent), 0, NULL);
|
UlongToPtr(CtrlEvent), 0, NULL);
|
||||||
if (NULL == Thread)
|
if (NULL == Thread)
|
||||||
{
|
{
|
||||||
|
@ -522,7 +747,8 @@ ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT("ProcessData->CtrlDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
DPRINT("ProcessData->CtrlRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
|
||||||
|
ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
||||||
WaitForSingleObject(Thread, Timeout);
|
WaitForSingleObject(Thread, Timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -628,9 +854,6 @@ ConSrvConsoleProcessCtrlEvent(IN PCONSRV_CONSOLE Console,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* PUBLIC SERVER APIS *********************************************************/
|
/* PUBLIC SERVER APIS *********************************************************/
|
||||||
|
|
||||||
CSR_API(SrvAllocConsole)
|
CSR_API(SrvAllocConsole)
|
||||||
|
@ -639,6 +862,7 @@ CSR_API(SrvAllocConsole)
|
||||||
PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
|
PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
|
||||||
PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process;
|
PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process;
|
||||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||||
|
CONSOLE_INIT_INFO ConsoleInitInfo;
|
||||||
|
|
||||||
if (ProcessData->ConsoleHandle != NULL)
|
if (ProcessData->ConsoleHandle != NULL)
|
||||||
{
|
{
|
||||||
|
@ -646,33 +870,64 @@ CSR_API(SrvAllocConsole)
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
if ( !CsrValidateMessageBuffer(ApiMessage,
|
||||||
(PVOID*)&AllocConsoleRequest->ConsoleStartInfo,
|
(PVOID*)&AllocConsoleRequest->ConsoleStartInfo,
|
||||||
1,
|
1,
|
||||||
sizeof(CONSOLE_START_INFO)))
|
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)) )
|
||||||
{
|
{
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the console initialization info structure */
|
||||||
|
ConsoleInitInfo.ConsoleStartInfo = AllocConsoleRequest->ConsoleStartInfo;
|
||||||
|
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;
|
||||||
|
|
||||||
/* Initialize a new Console owned by the Console Leader Process */
|
/* Initialize a new Console owned by the Console Leader Process */
|
||||||
Status = ConSrvAllocateConsole(ProcessData,
|
Status = ConSrvAllocateConsole(ProcessData,
|
||||||
&AllocConsoleRequest->InputHandle,
|
&AllocConsoleRequest->ConsoleStartInfo->InputHandle,
|
||||||
&AllocConsoleRequest->OutputHandle,
|
&AllocConsoleRequest->ConsoleStartInfo->OutputHandle,
|
||||||
&AllocConsoleRequest->ErrorHandle,
|
&AllocConsoleRequest->ConsoleStartInfo->ErrorHandle,
|
||||||
AllocConsoleRequest->ConsoleStartInfo);
|
&ConsoleInitInfo);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Console allocation failed\n");
|
DPRINT1("Console allocation failed\n");
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark the process as having a console */
|
||||||
|
ProcessData->ConsoleApp = TRUE;
|
||||||
|
CsrProcess->Flags |= CsrProcessIsConsoleApp;
|
||||||
|
|
||||||
/* Return the console handle and the input wait handle to the caller */
|
/* Return the console handle and the input wait handle to the caller */
|
||||||
AllocConsoleRequest->ConsoleHandle = ProcessData->ConsoleHandle;
|
AllocConsoleRequest->ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
|
||||||
AllocConsoleRequest->InputWaitHandle = ProcessData->InputWaitHandle;
|
AllocConsoleRequest->ConsoleStartInfo->InputWaitHandle = ProcessData->InputWaitHandle;
|
||||||
|
|
||||||
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
||||||
ProcessData->PropDispatcher = AllocConsoleRequest->PropDispatcher;
|
ProcessData->PropRoutine = AllocConsoleRequest->PropRoutine;
|
||||||
ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher;
|
ProcessData->CtrlRoutine = AllocConsoleRequest->CtrlRoutine;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -694,6 +949,14 @@ CSR_API(SrvAttachConsole)
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||||
|
(PVOID*)&AttachConsoleRequest->ConsoleStartInfo,
|
||||||
|
1,
|
||||||
|
sizeof(CONSOLE_START_INFO)))
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check whether we try to attach to the parent's console */
|
/* Check whether we try to attach to the parent's console */
|
||||||
if (ProcessId == ULongToHandle(ATTACH_PARENT_PROCESS))
|
if (ProcessId == ULongToHandle(ATTACH_PARENT_PROCESS))
|
||||||
{
|
{
|
||||||
|
@ -734,22 +997,26 @@ CSR_API(SrvAttachConsole)
|
||||||
Status = ConSrvInheritConsole(TargetProcessData,
|
Status = ConSrvInheritConsole(TargetProcessData,
|
||||||
SourceProcessData->ConsoleHandle,
|
SourceProcessData->ConsoleHandle,
|
||||||
TRUE,
|
TRUE,
|
||||||
&AttachConsoleRequest->InputHandle,
|
&AttachConsoleRequest->ConsoleStartInfo->InputHandle,
|
||||||
&AttachConsoleRequest->OutputHandle,
|
&AttachConsoleRequest->ConsoleStartInfo->OutputHandle,
|
||||||
&AttachConsoleRequest->ErrorHandle);
|
&AttachConsoleRequest->ConsoleStartInfo->ErrorHandle);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Console inheritance failed\n");
|
DPRINT1("Console inheritance failed\n");
|
||||||
goto Quit;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark the process as having a console */
|
||||||
|
TargetProcessData->ConsoleApp = TRUE;
|
||||||
|
TargetProcess->Flags |= CsrProcessIsConsoleApp;
|
||||||
|
|
||||||
/* Return the console handle and the input wait handle to the caller */
|
/* Return the console handle and the input wait handle to the caller */
|
||||||
AttachConsoleRequest->ConsoleHandle = TargetProcessData->ConsoleHandle;
|
AttachConsoleRequest->ConsoleStartInfo->ConsoleHandle = TargetProcessData->ConsoleHandle;
|
||||||
AttachConsoleRequest->InputWaitHandle = TargetProcessData->InputWaitHandle;
|
AttachConsoleRequest->ConsoleStartInfo->InputWaitHandle = TargetProcessData->InputWaitHandle;
|
||||||
|
|
||||||
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
||||||
TargetProcessData->PropDispatcher = AttachConsoleRequest->PropDispatcher;
|
TargetProcessData->PropRoutine = AttachConsoleRequest->PropRoutine;
|
||||||
TargetProcessData->CtrlDispatcher = AttachConsoleRequest->CtrlDispatcher;
|
TargetProcessData->CtrlRoutine = AttachConsoleRequest->CtrlRoutine;
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
@ -761,7 +1028,15 @@ Quit:
|
||||||
|
|
||||||
CSR_API(SrvFreeConsole)
|
CSR_API(SrvFreeConsole)
|
||||||
{
|
{
|
||||||
|
PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process;
|
||||||
|
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||||
|
|
||||||
ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
|
ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
|
||||||
|
|
||||||
|
/* Mark the process as not having a console anymore */
|
||||||
|
ProcessData->ConsoleApp = FALSE;
|
||||||
|
CsrProcess->Flags &= ~CsrProcessIsConsoleApp;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,16 +1140,12 @@ CSR_API(SrvSetConsoleMode)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
|
||||||
ConDrvGetConsoleTitle(IN PCONSOLE Console,
|
|
||||||
IN BOOLEAN Unicode,
|
|
||||||
IN OUT PVOID TitleBuffer,
|
|
||||||
IN OUT PULONG BufLength);
|
|
||||||
CSR_API(SrvGetConsoleTitle)
|
CSR_API(SrvGetConsoleTitle)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
|
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
|
||||||
PCONSRV_CONSOLE Console;
|
PCONSRV_CONSOLE Console;
|
||||||
|
ULONG Length;
|
||||||
|
|
||||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||||
(PVOID)&TitleRequest->Title,
|
(PVOID)&TitleRequest->Title,
|
||||||
|
@ -891,26 +1162,52 @@ CSR_API(SrvGetConsoleTitle)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ConDrvGetConsoleTitle(Console,
|
/* Copy title of the console to the user title buffer */
|
||||||
TitleRequest->Unicode,
|
if (TitleRequest->Unicode)
|
||||||
TitleRequest->Title,
|
{
|
||||||
&TitleRequest->Length);
|
if (TitleRequest->Length >= sizeof(WCHAR))
|
||||||
|
{
|
||||||
|
Length = min(TitleRequest->Length - sizeof(WCHAR), Console->Title.Length);
|
||||||
|
RtlCopyMemory(TitleRequest->Title, Console->Title.Buffer, Length);
|
||||||
|
((PWCHAR)TitleRequest->Title)[Length / sizeof(WCHAR)] = L'\0';
|
||||||
|
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);
|
||||||
|
((PCHAR)TitleRequest->Title)[Length] = '\0';
|
||||||
|
TitleRequest->Length = Length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TitleRequest->Length = Console->Title.Length / sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConSrvReleaseConsole(Console, TRUE);
|
ConSrvReleaseConsole(Console, TRUE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
|
||||||
ConDrvSetConsoleTitle(IN PCONSOLE Console,
|
|
||||||
IN BOOLEAN Unicode,
|
|
||||||
IN PVOID TitleBuffer,
|
|
||||||
IN ULONG BufLength);
|
|
||||||
CSR_API(SrvSetConsoleTitle)
|
CSR_API(SrvSetConsoleTitle)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
|
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
|
||||||
PCONSRV_CONSOLE Console;
|
PCONSRV_CONSOLE Console;
|
||||||
|
|
||||||
|
PWCHAR Buffer;
|
||||||
|
ULONG Length;
|
||||||
|
|
||||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||||
(PVOID)&TitleRequest->Title,
|
(PVOID)&TitleRequest->Title,
|
||||||
TitleRequest->Length,
|
TitleRequest->Length,
|
||||||
|
@ -926,13 +1223,56 @@ CSR_API(SrvSetConsoleTitle)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ConDrvSetConsoleTitle(Console,
|
if (TitleRequest->Unicode)
|
||||||
TitleRequest->Unicode,
|
{
|
||||||
TitleRequest->Title,
|
/* Length is in bytes */
|
||||||
TitleRequest->Length);
|
Length = TitleRequest->Length;
|
||||||
// FIXME: Keep this call here, or put it in ConDrvSetConsoleTitle ??
|
}
|
||||||
if (NT_SUCCESS(Status)) TermChangeTitle(Console);
|
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);
|
||||||
|
|
||||||
|
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 */
|
||||||
|
Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
|
||||||
|
|
||||||
|
TermChangeTitle(Console);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
Quit:
|
||||||
ConSrvReleaseConsole(Console, TRUE);
|
ConSrvReleaseConsole(Console, TRUE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,27 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct _CONSOLE_INIT_INFO
|
||||||
|
{
|
||||||
|
PCONSOLE_START_INFO ConsoleStartInfo;
|
||||||
|
|
||||||
|
ULONG TitleLength;
|
||||||
|
PWCHAR ConsoleTitle;
|
||||||
|
ULONG DesktopLength;
|
||||||
|
PWCHAR Desktop;
|
||||||
|
ULONG AppNameLength;
|
||||||
|
PWCHAR AppName;
|
||||||
|
ULONG CurDirLength;
|
||||||
|
PWCHAR CurDir;
|
||||||
|
} CONSOLE_INIT_INFO, *PCONSOLE_INIT_INFO;
|
||||||
|
|
||||||
VOID NTAPI
|
VOID NTAPI
|
||||||
ConSrvInitConsoleSupport(VOID);
|
ConSrvInitConsoleSupport(VOID);
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||||
OUT struct _CONSRV_CONSOLE** /* PCONSRV_CONSOLE* */ NewConsole,
|
OUT struct _CONSRV_CONSOLE** /* PCONSRV_CONSOLE* */ NewConsole,
|
||||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
|
||||||
IN ULONG ConsoleLeaderProcessId);
|
IN ULONG ConsoleLeaderProcessId);
|
||||||
VOID NTAPI ConSrvDeleteConsole(struct _CONSRV_CONSOLE* /* PCONSRV_CONSOLE */ Console);
|
VOID NTAPI ConSrvDeleteConsole(struct _CONSRV_CONSOLE* /* PCONSRV_CONSOLE */ Console);
|
||||||
|
|
||||||
|
|
|
@ -51,10 +51,9 @@ typedef struct _CONSOLE_PROCESS_DATA
|
||||||
{
|
{
|
||||||
LIST_ENTRY ConsoleLink;
|
LIST_ENTRY ConsoleLink;
|
||||||
PCSR_PROCESS Process; // Process owning this structure.
|
PCSR_PROCESS Process; // Process owning this structure.
|
||||||
HANDLE InputWaitHandle;
|
|
||||||
|
|
||||||
HANDLE ConsoleHandle;
|
HANDLE ConsoleHandle;
|
||||||
HANDLE ParentConsoleHandle;
|
HANDLE InputWaitHandle;
|
||||||
|
|
||||||
BOOLEAN ConsoleApp; // TRUE if it is a CUI app, FALSE otherwise.
|
BOOLEAN ConsoleApp; // TRUE if it is a CUI app, FALSE otherwise.
|
||||||
|
|
||||||
|
@ -62,8 +61,9 @@ typedef struct _CONSOLE_PROCESS_DATA
|
||||||
ULONG HandleTableSize;
|
ULONG HandleTableSize;
|
||||||
struct _CONSOLE_IO_HANDLE* /* PCONSOLE_IO_HANDLE */ HandleTable; // Length-varying table
|
struct _CONSOLE_IO_HANDLE* /* PCONSOLE_IO_HANDLE */ HandleTable; // Length-varying table
|
||||||
|
|
||||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||||
LPTHREAD_START_ROUTINE PropDispatcher; // We hold the property dialog handler there, till all the GUI thingie moves out from CSRSS.
|
LPTHREAD_START_ROUTINE PropRoutine; // We hold the property dialog handler there, till all the GUI thingie moves out from CSRSS.
|
||||||
|
// LPTHREAD_START_ROUTINE ImeRoutine;
|
||||||
} CONSOLE_PROCESS_DATA, *PCONSOLE_PROCESS_DATA;
|
} CONSOLE_PROCESS_DATA, *PCONSOLE_PROCESS_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -372,7 +372,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the properties dialog */
|
/* Start the properties dialog */
|
||||||
if (ProcessData->PropDispatcher)
|
if (ProcessData->PropRoutine)
|
||||||
{
|
{
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
|
@ -381,7 +381,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
||||||
ProcessData->PropDispatcher,
|
ProcessData->PropRoutine,
|
||||||
(PVOID)hClientSection, 0, NULL);
|
(PVOID)hClientSection, 0, NULL);
|
||||||
if (NULL == Thread)
|
if (NULL == Thread)
|
||||||
{
|
{
|
||||||
|
@ -389,7 +389,8 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT("ProcessData->PropDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
|
||||||
|
ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
||||||
/// WaitForSingleObject(Thread, INFINITE);
|
/// WaitForSingleObject(Thread, INFINITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
|
|
||||||
#include <consrv.h>
|
#include <consrv.h>
|
||||||
|
|
||||||
#define COBJMACROS
|
|
||||||
#include <shlobj.h>
|
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
@ -405,9 +402,7 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
||||||
PGUI_CONSOLE_DATA GuiData;
|
PGUI_CONSOLE_DATA GuiData;
|
||||||
GUI_CONSOLE_INFO TermInfo;
|
GUI_CONSOLE_INFO TermInfo;
|
||||||
|
|
||||||
SIZE_T Length = 0;
|
SIZE_T Length = 0;
|
||||||
LPWSTR IconPath = NULL;
|
|
||||||
INT IconIndex = 0;
|
|
||||||
|
|
||||||
if (This == NULL || Console == NULL || This->OldData == NULL)
|
if (This == NULL || Console == NULL || This->OldData == NULL)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -422,10 +417,6 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
||||||
ConsoleInfo = GuiInitInfo->ConsoleInfo;
|
ConsoleInfo = GuiInitInfo->ConsoleInfo;
|
||||||
ConsoleStartInfo = GuiInitInfo->ConsoleStartInfo;
|
ConsoleStartInfo = GuiInitInfo->ConsoleStartInfo;
|
||||||
|
|
||||||
IconPath = ConsoleStartInfo->IconPath;
|
|
||||||
IconIndex = ConsoleStartInfo->IconIndex;
|
|
||||||
|
|
||||||
|
|
||||||
/* Terminal data allocation */
|
/* Terminal data allocation */
|
||||||
GuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(GUI_CONSOLE_DATA));
|
GuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(GUI_CONSOLE_DATA));
|
||||||
if (!GuiData)
|
if (!GuiData)
|
||||||
|
@ -451,10 +442,10 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
||||||
/* 1. Load the default settings */
|
/* 1. Load the default settings */
|
||||||
GuiConsoleGetDefaultSettings(&TermInfo, GuiInitInfo->ProcessId);
|
GuiConsoleGetDefaultSettings(&TermInfo, GuiInitInfo->ProcessId);
|
||||||
|
|
||||||
/* 3. Load the remaining console settings via the registry. */
|
/* 3. Load the remaining console settings via the registry */
|
||||||
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
||||||
{
|
{
|
||||||
/* Load the terminal infos from the registry. */
|
/* Load the terminal infos from the registry */
|
||||||
GuiConsoleReadUserSettings(&TermInfo,
|
GuiConsoleReadUserSettings(&TermInfo,
|
||||||
ConsoleInfo->ConsoleTitle,
|
ConsoleInfo->ConsoleTitle,
|
||||||
GuiInitInfo->ProcessId);
|
GuiInitInfo->ProcessId);
|
||||||
|
@ -500,29 +491,17 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
||||||
GuiData->GuiInfo.AutoPosition = TermInfo.AutoPosition;
|
GuiData->GuiInfo.AutoPosition = TermInfo.AutoPosition;
|
||||||
GuiData->GuiInfo.WindowOrigin = TermInfo.WindowOrigin;
|
GuiData->GuiInfo.WindowOrigin = TermInfo.WindowOrigin;
|
||||||
|
|
||||||
/* Initialize the icon handles to their default values */
|
/* Initialize the icon handles */
|
||||||
GuiData->hIcon = ghDefaultIcon;
|
if (ConsoleStartInfo->hIcon != NULL)
|
||||||
GuiData->hIconSm = ghDefaultIconSm;
|
GuiData->hIcon = ConsoleStartInfo->hIcon;
|
||||||
|
else
|
||||||
|
GuiData->hIcon = ghDefaultIcon;
|
||||||
|
|
||||||
|
if (ConsoleStartInfo->hIconSm != NULL)
|
||||||
|
GuiData->hIconSm = ConsoleStartInfo->hIconSm;
|
||||||
|
else
|
||||||
|
GuiData->hIconSm = ghDefaultIconSm;
|
||||||
|
|
||||||
/* Get the associated icon, if any */
|
|
||||||
if (IconPath == NULL || IconPath[0] == L'\0')
|
|
||||||
{
|
|
||||||
IconPath = ConsoleStartInfo->AppPath;
|
|
||||||
IconIndex = 0;
|
|
||||||
}
|
|
||||||
DPRINT("IconPath = %S ; IconIndex = %lu\n", (IconPath ? IconPath : L"n/a"), IconIndex);
|
|
||||||
if (IconPath && IconPath[0] != L'\0')
|
|
||||||
{
|
|
||||||
HICON hIcon = NULL, hIconSm = NULL;
|
|
||||||
PrivateExtractIconExW(IconPath,
|
|
||||||
IconIndex,
|
|
||||||
&hIcon,
|
|
||||||
&hIconSm,
|
|
||||||
1);
|
|
||||||
DPRINT("hIcon = 0x%p ; hIconSm = 0x%p\n", hIcon, hIconSm);
|
|
||||||
if (hIcon != NULL) GuiData->hIcon = hIcon;
|
|
||||||
if (hIconSm != NULL) GuiData->hIconSm = hIconSm;
|
|
||||||
}
|
|
||||||
ASSERT(GuiData->hIcon && GuiData->hIconSm);
|
ASSERT(GuiData->hIcon && GuiData->hIconSm);
|
||||||
|
|
||||||
/* Mouse is shown by default with its default cursor shape */
|
/* Mouse is shown by default with its default cursor shape */
|
||||||
|
@ -1114,138 +1093,21 @@ static FRONTEND_VTBL GuiVtbl =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static BOOL
|
|
||||||
LoadShellLinkConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
|
||||||
IN OUT PCONSOLE_INFO ConsoleInfo)
|
|
||||||
{
|
|
||||||
#define PATH_SEPARATOR L'\\'
|
|
||||||
|
|
||||||
BOOL RetVal = FALSE;
|
|
||||||
HRESULT hRes = S_OK;
|
|
||||||
LPWSTR LinkName = NULL;
|
|
||||||
SIZE_T Length = 0;
|
|
||||||
|
|
||||||
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
ConsoleStartInfo->IconPath[0] = L'\0';
|
|
||||||
ConsoleStartInfo->IconIndex = 0;
|
|
||||||
|
|
||||||
/* 1- Find the last path separator if any */
|
|
||||||
LinkName = wcsrchr(ConsoleStartInfo->ConsoleTitle, PATH_SEPARATOR);
|
|
||||||
if (LinkName == NULL)
|
|
||||||
{
|
|
||||||
LinkName = ConsoleStartInfo->ConsoleTitle;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Skip the path separator */
|
|
||||||
++LinkName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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,
|
|
||||||
NULL,
|
|
||||||
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, ConsoleStartInfo->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")
|
|
||||||
sizeof(ConsoleInfo->ConsoleTitle) / sizeof(ConsoleInfo->ConsoleTitle[0]) - 1);
|
|
||||||
wcsncpy(ConsoleInfo->ConsoleTitle, LinkName, Length);
|
|
||||||
ConsoleInfo->ConsoleTitle[Length] = L'\0';
|
|
||||||
|
|
||||||
/* Get the window showing command */
|
|
||||||
hRes = IShellLinkW_GetShowCmd(pshl, &ShowCmd);
|
|
||||||
if (SUCCEEDED(hRes)) ConsoleStartInfo->wShowWindow = (WORD)ShowCmd;
|
|
||||||
|
|
||||||
/* Get the hotkey */
|
|
||||||
// hRes = pshl->GetHotkey(&ShowCmd);
|
|
||||||
// if (SUCCEEDED(hRes)) ConsoleStartInfo->HotKey = HotKey;
|
|
||||||
|
|
||||||
/* Get the icon location, if any */
|
|
||||||
hRes = IShellLinkW_GetIconLocation(pshl,
|
|
||||||
ConsoleStartInfo->IconPath,
|
|
||||||
sizeof(ConsoleStartInfo->IconPath)/sizeof(ConsoleStartInfo->IconPath[0]) - 1, // == MAX_PATH
|
|
||||||
&ConsoleStartInfo->IconIndex);
|
|
||||||
if (!SUCCEEDED(hRes))
|
|
||||||
{
|
|
||||||
ConsoleStartInfo->IconPath[0] = L'\0';
|
|
||||||
ConsoleStartInfo->IconIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 = FALSE;
|
|
||||||
}
|
|
||||||
IPersistFile_Release(ppf);
|
|
||||||
}
|
|
||||||
IShellLinkW_Release(pshl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CoUninitialize();
|
|
||||||
|
|
||||||
return RetVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
|
GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
|
||||||
IN OUT PCONSOLE_INFO ConsoleInfo,
|
IN OUT PCONSOLE_INFO ConsoleInfo,
|
||||||
IN OUT PVOID ExtraConsoleInfo,
|
IN OUT PVOID ExtraConsoleInfo,
|
||||||
IN ULONG ProcessId)
|
IN ULONG ProcessId)
|
||||||
{
|
{
|
||||||
PCONSOLE_START_INFO ConsoleStartInfo = ExtraConsoleInfo;
|
PCONSOLE_INIT_INFO ConsoleInitInfo = ExtraConsoleInfo;
|
||||||
PGUI_INIT_INFO GuiInitInfo;
|
PGUI_INIT_INFO GuiInitInfo;
|
||||||
|
|
||||||
if (FrontEnd == NULL || ConsoleInfo == NULL || ConsoleStartInfo == NULL)
|
if (FrontEnd == NULL || ConsoleInfo == NULL || ConsoleInitInfo == NULL)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
/* Initialize GUI terminal emulator common functionalities */
|
/* Initialize GUI terminal emulator common functionalities */
|
||||||
if (!GuiInit()) return STATUS_UNSUCCESSFUL;
|
if (!GuiInit()) return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
/*
|
|
||||||
* Load per-application terminal settings.
|
|
||||||
*
|
|
||||||
* 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 (ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME)
|
|
||||||
{
|
|
||||||
if (!LoadShellLinkConsoleInfo(ConsoleStartInfo, ConsoleInfo))
|
|
||||||
{
|
|
||||||
ConsoleStartInfo->dwStartupFlags &= ~STARTF_TITLEISLINKNAME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize a private initialization info structure for later use.
|
* Initialize a private initialization info structure for later use.
|
||||||
* It must be freed by a call to GuiUnloadFrontEnd or GuiInitFrontEnd.
|
* It must be freed by a call to GuiUnloadFrontEnd or GuiInitFrontEnd.
|
||||||
|
@ -1255,9 +1117,10 @@ GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
|
||||||
|
|
||||||
// HACK: We suppose that the pointers will be valid in GuiInitFrontEnd...
|
// HACK: We suppose that the pointers will be valid in GuiInitFrontEnd...
|
||||||
GuiInitInfo->ConsoleInfo = ConsoleInfo;
|
GuiInitInfo->ConsoleInfo = ConsoleInfo;
|
||||||
GuiInitInfo->ConsoleStartInfo = ConsoleStartInfo;
|
GuiInitInfo->ConsoleStartInfo = ConsoleInitInfo->ConsoleStartInfo;
|
||||||
GuiInitInfo->ProcessId = ProcessId;
|
GuiInitInfo->ProcessId = ProcessId;
|
||||||
|
|
||||||
|
|
||||||
/* Finally, initialize the frontend structure */
|
/* Finally, initialize the frontend structure */
|
||||||
FrontEnd->Vtbl = &GuiVtbl;
|
FrontEnd->Vtbl = &GuiVtbl;
|
||||||
FrontEnd->Data = NULL;
|
FrontEnd->Data = NULL;
|
||||||
|
|
|
@ -14,13 +14,6 @@
|
||||||
#include "guisettings.h"
|
#include "guisettings.h"
|
||||||
#include "conwnd.h"
|
#include "conwnd.h"
|
||||||
|
|
||||||
NTSTATUS GuiInitConsole(PCONSOLE Console,
|
|
||||||
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
|
|
||||||
PCONSOLE_INFO ConsoleInfo,
|
|
||||||
DWORD ProcessId,
|
|
||||||
LPCWSTR IconPath,
|
|
||||||
INT IconIndex);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData);
|
GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData);
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,8 @@ ConSrvTermInitTerminal(IN OUT PTERMINAL This,
|
||||||
Console->FrontEndIFace = *FrontEnd;
|
Console->FrontEndIFace = *FrontEnd;
|
||||||
|
|
||||||
Status = FrontEnd->Vtbl->InitFrontEnd(FrontEnd, FrontEnd->Console);
|
Status = FrontEnd->Vtbl->InitFrontEnd(FrontEnd, FrontEnd->Console);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
DPRINT1("InitFrontEnd failed, Status = 0x%08lx\n", Status);
|
||||||
|
|
||||||
/** HACK HACK!! Be sure FrontEndIFace is correctly updated in the console!! **/
|
/** HACK HACK!! Be sure FrontEndIFace is correctly updated in the console!! **/
|
||||||
DPRINT1("Using FrontEndIFace HACK(2), should be removed after proper implementation!\n");
|
DPRINT1("Using FrontEndIFace HACK(2), should be removed after proper implementation!\n");
|
||||||
|
@ -697,13 +699,6 @@ ConSrvTermReleaseScreenBuffer(IN OUT PTERMINAL This,
|
||||||
FrontEnd->Vtbl->ReleaseScreenBuffer(FrontEnd, ScreenBuffer);
|
FrontEnd->Vtbl->ReleaseScreenBuffer(FrontEnd, ScreenBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID NTAPI
|
|
||||||
ConSrvTermChangeTitle(IN OUT PTERMINAL This)
|
|
||||||
{
|
|
||||||
PFRONTEND FrontEnd = This->Data;
|
|
||||||
FrontEnd->Vtbl->ChangeTitle(FrontEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID NTAPI
|
static VOID NTAPI
|
||||||
ConSrvTermGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
|
ConSrvTermGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
|
||||||
PCOORD pSize)
|
PCOORD pSize)
|
||||||
|
@ -743,7 +738,6 @@ static TERMINAL_VTBL ConSrvTermVtbl =
|
||||||
ConSrvTermResizeTerminal,
|
ConSrvTermResizeTerminal,
|
||||||
ConSrvTermSetActiveScreenBuffer,
|
ConSrvTermSetActiveScreenBuffer,
|
||||||
ConSrvTermReleaseScreenBuffer,
|
ConSrvTermReleaseScreenBuffer,
|
||||||
ConSrvTermChangeTitle,
|
|
||||||
ConSrvTermGetLargestConsoleWindowSize,
|
ConSrvTermGetLargestConsoleWindowSize,
|
||||||
ConSrvTermSetPalette,
|
ConSrvTermSetPalette,
|
||||||
ConSrvTermShowMouseCursor,
|
ConSrvTermShowMouseCursor,
|
||||||
|
|
|
@ -470,15 +470,12 @@ ConSrvReleaseObject(IN PCONSOLE_IO_OBJECT Object,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
PHANDLE pInputHandle,
|
PHANDLE pInputHandle,
|
||||||
PHANDLE pOutputHandle,
|
PHANDLE pOutputHandle,
|
||||||
PHANDLE pErrorHandle,
|
PHANDLE pErrorHandle,
|
||||||
PCONSOLE_START_INFO ConsoleStartInfo)
|
PCONSOLE_INIT_INFO ConsoleInitInfo)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
HANDLE ConsoleHandle;
|
HANDLE ConsoleHandle;
|
||||||
|
@ -499,7 +496,7 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
/* Initialize a new Console owned by this process */
|
/* Initialize a new Console owned by this process */
|
||||||
Status = ConSrvInitConsole(&ConsoleHandle,
|
Status = ConSrvInitConsole(&ConsoleHandle,
|
||||||
&Console,
|
&Console,
|
||||||
ConsoleStartInfo,
|
ConsoleInitInfo,
|
||||||
HandleToUlong(ProcessData->Process->ClientId.UniqueProcess));
|
HandleToUlong(ProcessData->Process->ClientId.UniqueProcess));
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
|
@ -251,7 +251,6 @@ typedef struct _TERMINAL_VTBL
|
||||||
/*
|
/*
|
||||||
* External interface (functions corresponding to the Console API)
|
* External interface (functions corresponding to the Console API)
|
||||||
*/
|
*/
|
||||||
VOID (NTAPI *ChangeTitle)(IN OUT PTERMINAL This);
|
|
||||||
VOID (NTAPI *GetLargestConsoleWindowSize)(IN OUT PTERMINAL This,
|
VOID (NTAPI *GetLargestConsoleWindowSize)(IN OUT PTERMINAL This,
|
||||||
PCOORD pSize);
|
PCOORD pSize);
|
||||||
BOOL (NTAPI *SetPalette)(IN OUT PTERMINAL This,
|
BOOL (NTAPI *SetPalette)(IN OUT PTERMINAL This,
|
||||||
|
@ -326,9 +325,6 @@ typedef struct _CONSOLE
|
||||||
UINT OutputCodePage;
|
UINT OutputCodePage;
|
||||||
|
|
||||||
/****************************** Other properties ******************************/
|
/****************************** Other properties ******************************/
|
||||||
UNICODE_STRING OriginalTitle; /* Original title of console, the one defined when the console leader is launched; it never changes. Always NULL-terminated */
|
|
||||||
UNICODE_STRING Title; /* Title of console. Always NULL-terminated */
|
|
||||||
|
|
||||||
COORD ConsoleSize; /* The current size of the console, for text-mode only */
|
COORD ConsoleSize; /* The current size of the console, for text-mode only */
|
||||||
BOOLEAN FixedSize; /* TRUE if the console is of fixed size */
|
BOOLEAN FixedSize; /* TRUE if the console is of fixed size */
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,9 @@ typedef struct _WINSRV_CONSOLE
|
||||||
HANDLE ErrorHardwareEvent;
|
HANDLE ErrorHardwareEvent;
|
||||||
|
|
||||||
/****************************** Other properties ******************************/
|
/****************************** Other properties ******************************/
|
||||||
LIST_ENTRY PopupWindows; /*List of popup windows */
|
LIST_ENTRY PopupWindows; /* List of popup windows */
|
||||||
|
UNICODE_STRING OriginalTitle; /* Original title of console, the one defined when the console leader is launched; it never changes. Always NULL-terminated */
|
||||||
|
UNICODE_STRING Title; /* Title of console. Always NULL-terminated */
|
||||||
COLORREF Colors[16]; /* Colour palette */
|
COLORREF Colors[16]; /* Colour palette */
|
||||||
|
|
||||||
} WINSRV_CONSOLE; // , *PWINSRV_CONSOLE;
|
} WINSRV_CONSOLE; // , *PWINSRV_CONSOLE;
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
(Console)->TermIFace.Vtbl->SetActiveScreenBuffer(&(Console)->TermIFace)
|
(Console)->TermIFace.Vtbl->SetActiveScreenBuffer(&(Console)->TermIFace)
|
||||||
#define TermReleaseScreenBuffer(Console, ScreenBuffer) \
|
#define TermReleaseScreenBuffer(Console, ScreenBuffer) \
|
||||||
(Console)->TermIFace.Vtbl->ReleaseScreenBuffer(&(Console)->TermIFace, (ScreenBuffer))
|
(Console)->TermIFace.Vtbl->ReleaseScreenBuffer(&(Console)->TermIFace, (ScreenBuffer))
|
||||||
#define TermChangeTitle(Console) \
|
|
||||||
(Console)->TermIFace.Vtbl->ChangeTitle(&(Console)->TermIFace)
|
|
||||||
#define TermGetLargestConsoleWindowSize(Console, pSize) \
|
#define TermGetLargestConsoleWindowSize(Console, pSize) \
|
||||||
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize(&(Console)->TermIFace, (pSize))
|
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize(&(Console)->TermIFace, (pSize))
|
||||||
#define TermSetPalette(Console, PaletteHandle, PaletteUsage) \
|
#define TermSetPalette(Console, PaletteHandle, PaletteUsage) \
|
||||||
|
@ -45,6 +43,8 @@
|
||||||
|
|
||||||
#define TermRefreshInternalInfo(Console) \
|
#define TermRefreshInternalInfo(Console) \
|
||||||
(Console)->FrontEndIFace.Vtbl->RefreshInternalInfo(&(Console)->FrontEndIFace)
|
(Console)->FrontEndIFace.Vtbl->RefreshInternalInfo(&(Console)->FrontEndIFace)
|
||||||
|
#define TermChangeTitle(Console) \
|
||||||
|
(Console)->FrontEndIFace.Vtbl->ChangeTitle(&(Console)->FrontEndIFace)
|
||||||
#define TermChangeIcon(Console, IconHandle) \
|
#define TermChangeIcon(Console, IconHandle) \
|
||||||
(Console)->FrontEndIFace.Vtbl->ChangeIcon(&(Console)->FrontEndIFace, (IconHandle))
|
(Console)->FrontEndIFace.Vtbl->ChangeIcon(&(Console)->FrontEndIFace, (IconHandle))
|
||||||
#define TermGetConsoleWindowHandle(Console) \
|
#define TermGetConsoleWindowHandle(Console) \
|
||||||
|
|
|
@ -354,8 +354,8 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
|
RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
|
||||||
TargetProcessData->Process = TargetProcess;
|
TargetProcessData->Process = TargetProcess;
|
||||||
TargetProcessData->InputWaitHandle = NULL;
|
TargetProcessData->InputWaitHandle = NULL;
|
||||||
TargetProcessData->ConsoleHandle = TargetProcessData->ParentConsoleHandle = NULL;
|
TargetProcessData->ConsoleHandle = NULL;
|
||||||
TargetProcessData->ConsoleApp = ((TargetProcess->Flags & CsrProcessIsConsoleApp) ? TRUE : FALSE);
|
TargetProcessData->ConsoleApp = FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The handles table gets initialized either when inheriting from
|
* The handles table gets initialized either when inheriting from
|
||||||
|
@ -377,7 +377,7 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
* handles table: this can happen if it is a GUI application having called
|
* handles table: this can happen if it is a GUI application having called
|
||||||
* AllocConsole), then try to inherit handles from the parent process.
|
* AllocConsole), then try to inherit handles from the parent process.
|
||||||
*/
|
*/
|
||||||
if (TargetProcessData->ConsoleApp /* && SourceProcessData->ConsoleApp */)
|
if (TargetProcess->Flags & CsrProcessIsConsoleApp /* && SourceProcessData->ConsoleHandle != NULL */)
|
||||||
{
|
{
|
||||||
PCONSOLE_PROCESS_DATA SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
PCONSOLE_PROCESS_DATA SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
||||||
PCONSRV_CONSOLE SourceConsole;
|
PCONSRV_CONSOLE SourceConsole;
|
||||||
|
@ -389,10 +389,9 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
{
|
{
|
||||||
/* Inherit the parent's handles table */
|
/* Inherit the parent's handles table */
|
||||||
Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
|
Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
|
||||||
if (NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Temporary save the parent's console too */
|
DPRINT1("Inheriting handles table failed\n");
|
||||||
TargetProcessData->ParentConsoleHandle = SourceProcessData->ConsoleHandle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock the parent's console */
|
/* Unlock the parent's console */
|
||||||
|
@ -416,28 +415,37 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PCONSRV_API_CONNECTINFO ConnectInfo = (PCONSRV_API_CONNECTINFO)ConnectionInfo;
|
PCONSRV_API_CONNECTINFO ConnectInfo = (PCONSRV_API_CONNECTINFO)ConnectionInfo;
|
||||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||||
|
CONSOLE_INIT_INFO ConsoleInitInfo;
|
||||||
|
|
||||||
if ( ConnectionInfo == NULL ||
|
if ( ConnectionInfo == NULL ||
|
||||||
ConnectionInfoLength == NULL ||
|
ConnectionInfoLength == NULL ||
|
||||||
*ConnectionInfoLength != sizeof(CONSRV_API_CONNECTINFO) )
|
*ConnectionInfoLength != sizeof(*ConnectInfo) )
|
||||||
{
|
{
|
||||||
DPRINT1("CONSRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), wanted %lu\n",
|
DPRINT1("CONSRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), wanted %lu\n",
|
||||||
ConnectionInfo,
|
ConnectionInfo,
|
||||||
ConnectionInfoLength,
|
ConnectionInfoLength,
|
||||||
ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
|
ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
|
||||||
sizeof(CONSRV_API_CONNECTINFO));
|
sizeof(*ConnectInfo));
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't need a console, then get out of here */
|
/* If we don't need a console, then get out of here */
|
||||||
if (!ConnectInfo->ConsoleStartInfo.ConsoleNeeded || !ProcessData->ConsoleApp) // In fact, it is for GUI apps.
|
DPRINT("ConnectInfo->IsConsoleApp = %s\n", ConnectInfo->IsConsoleApp ? "True" : "False");
|
||||||
{
|
if (!ConnectInfo->IsConsoleApp) return STATUS_SUCCESS;
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we don't have a console, then create a new one... */
|
/* Initialize the console initialization info structure */
|
||||||
if (!ConnectInfo->ConsoleHandle ||
|
ConsoleInitInfo.ConsoleStartInfo = &ConnectInfo->ConsoleStartInfo;
|
||||||
ConnectInfo->ConsoleHandle != ProcessData->ParentConsoleHandle)
|
ConsoleInitInfo.TitleLength = ConnectInfo->TitleLength;
|
||||||
|
ConsoleInitInfo.ConsoleTitle = ConnectInfo->ConsoleTitle;
|
||||||
|
ConsoleInitInfo.DesktopLength = ConnectInfo->DesktopLength;
|
||||||
|
ConsoleInitInfo.Desktop = ConnectInfo->Desktop;
|
||||||
|
ConsoleInitInfo.AppNameLength = ConnectInfo->AppNameLength;
|
||||||
|
ConsoleInitInfo.AppName = ConnectInfo->AppName;
|
||||||
|
ConsoleInitInfo.CurDirLength = ConnectInfo->CurDirLength;
|
||||||
|
ConsoleInitInfo.CurDir = ConnectInfo->CurDir;
|
||||||
|
|
||||||
|
/* If we don't inherit from an existing console, then create a new one... */
|
||||||
|
if (ConnectInfo->ConsoleStartInfo.ConsoleHandle == NULL)
|
||||||
{
|
{
|
||||||
DPRINT("ConSrvConnect - Allocate a new console\n");
|
DPRINT("ConSrvConnect - Allocate a new console\n");
|
||||||
|
|
||||||
|
@ -454,10 +462,10 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
|
|
||||||
/* Initialize a new Console owned by the Console Leader Process */
|
/* Initialize a new Console owned by the Console Leader Process */
|
||||||
Status = ConSrvAllocateConsole(ProcessData,
|
Status = ConSrvAllocateConsole(ProcessData,
|
||||||
&ConnectInfo->InputHandle,
|
&ConnectInfo->ConsoleStartInfo.InputHandle,
|
||||||
&ConnectInfo->OutputHandle,
|
&ConnectInfo->ConsoleStartInfo.OutputHandle,
|
||||||
&ConnectInfo->ErrorHandle,
|
&ConnectInfo->ConsoleStartInfo.ErrorHandle,
|
||||||
&ConnectInfo->ConsoleStartInfo);
|
&ConsoleInitInfo);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Console allocation failed\n");
|
DPRINT1("Console allocation failed\n");
|
||||||
|
@ -470,11 +478,11 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
|
|
||||||
/* Reuse our current console */
|
/* Reuse our current console */
|
||||||
Status = ConSrvInheritConsole(ProcessData,
|
Status = ConSrvInheritConsole(ProcessData,
|
||||||
ConnectInfo->ConsoleHandle,
|
ConnectInfo->ConsoleStartInfo.ConsoleHandle,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL, // &ConnectInfo->InputHandle,
|
NULL, // &ConnectInfo->ConsoleStartInfo.InputHandle,
|
||||||
NULL, // &ConnectInfo->OutputHandle,
|
NULL, // &ConnectInfo->ConsoleStartInfo.OutputHandle,
|
||||||
NULL); // &ConnectInfo->ErrorHandle);
|
NULL); // &ConnectInfo->ConsoleStartInfo.ErrorHandle);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Console inheritance failed\n");
|
DPRINT1("Console inheritance failed\n");
|
||||||
|
@ -482,13 +490,17 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark the process as having a console */
|
||||||
|
ProcessData->ConsoleApp = TRUE;
|
||||||
|
// ProcessData->Flags |= CsrProcessIsConsoleApp;
|
||||||
|
|
||||||
/* Return the console handle and the input wait handle to the caller */
|
/* Return the console handle and the input wait handle to the caller */
|
||||||
ConnectInfo->ConsoleHandle = ProcessData->ConsoleHandle;
|
ConnectInfo->ConsoleStartInfo.ConsoleHandle = ProcessData->ConsoleHandle;
|
||||||
ConnectInfo->InputWaitHandle = ProcessData->InputWaitHandle;
|
ConnectInfo->ConsoleStartInfo.InputWaitHandle = ProcessData->InputWaitHandle;
|
||||||
|
|
||||||
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
||||||
ProcessData->PropDispatcher = ConnectInfo->ConsoleStartInfo.PropDispatcher;
|
ProcessData->PropRoutine = ConnectInfo->PropRoutine;
|
||||||
ProcessData->CtrlDispatcher = ConnectInfo->ConsoleStartInfo.CtrlDispatcher;
|
ProcessData->CtrlRoutine = ConnectInfo->CtrlRoutine;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -508,6 +520,10 @@ ConSrvDisconnect(PCSR_PROCESS Process)
|
||||||
{
|
{
|
||||||
DPRINT("ConSrvDisconnect - calling ConSrvRemoveConsole\n");
|
DPRINT("ConSrvDisconnect - calling ConSrvRemoveConsole\n");
|
||||||
ConSrvRemoveConsole(ProcessData);
|
ConSrvRemoveConsole(ProcessData);
|
||||||
|
|
||||||
|
/* Mark the process as not having a console anymore */
|
||||||
|
ProcessData->ConsoleApp = FALSE;
|
||||||
|
Process->Flags &= ~CsrProcessIsConsoleApp;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
|
RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
|
@ -12,7 +12,7 @@ NTSTATUS ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
PHANDLE pInputHandle,
|
PHANDLE pInputHandle,
|
||||||
PHANDLE pOutputHandle,
|
PHANDLE pOutputHandle,
|
||||||
PHANDLE pErrorHandle,
|
PHANDLE pErrorHandle,
|
||||||
PCONSOLE_START_INFO ConsoleStartInfo);
|
PCONSOLE_INIT_INFO ConsoleInitInfo);
|
||||||
NTSTATUS ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
NTSTATUS ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
HANDLE ConsoleHandle,
|
HANDLE ConsoleHandle,
|
||||||
BOOLEAN CreateNewHandlesTable,
|
BOOLEAN CreateNewHandlesTable,
|
||||||
|
|
Loading…
Reference in a new issue