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 ********************************************************************/
|
||||
|
||||
RTL_CRITICAL_SECTION ConsoleLock;
|
||||
BOOL ConsoleInitialized = FALSE;
|
||||
BOOLEAN ConsoleInitialized = FALSE;
|
||||
|
||||
extern HANDLE InputWaitHandle;
|
||||
|
||||
static HMODULE ConsoleLibrary = NULL;
|
||||
static BOOL AlreadyDisplayingProps = FALSE;
|
||||
|
||||
#define WIN_OBJ_DIR L"\\Windows"
|
||||
#define SESSION_DIR L"\\Sessions"
|
||||
static const PWSTR DefaultConsoleTitle = L"ReactOS Console";
|
||||
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
@ -41,6 +40,7 @@ PropDialogHandler(IN LPVOID lpThreadParameter)
|
|||
{
|
||||
// NOTE: lpThreadParameter corresponds to the client shared section handle.
|
||||
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
APPLET_PROC CPLFunc;
|
||||
|
||||
/*
|
||||
|
@ -67,12 +67,11 @@ PropDialogHandler(IN LPVOID lpThreadParameter)
|
|||
GetSystemDirectoryW(szBuffer, MAX_PATH);
|
||||
wcscat(szBuffer, L"\\console.dll");
|
||||
ConsoleLibrary = LoadLibraryW(szBuffer);
|
||||
|
||||
if (ConsoleLibrary == NULL)
|
||||
{
|
||||
DPRINT1("Failed to load console.dll\n");
|
||||
AlreadyDisplayingProps = FALSE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto Quit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,203 +79,223 @@ PropDialogHandler(IN LPVOID lpThreadParameter)
|
|||
CPLFunc = (APPLET_PROC)GetProcAddress(ConsoleLibrary, "CPlApplet");
|
||||
if (CPLFunc == NULL)
|
||||
{
|
||||
DPRINT("Error: Console.dll misses CPlApplet export\n");
|
||||
AlreadyDisplayingProps = FALSE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
DPRINT1("Error: Console.dll misses CPlApplet export\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
if (CPLFunc(NULL, CPL_INIT, 0, 0) == FALSE)
|
||||
{
|
||||
DPRINT("Error: failed to initialize console.dll\n");
|
||||
AlreadyDisplayingProps = FALSE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
DPRINT1("Error: failed to initialize console.dll\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
if (CPLFunc(NULL, CPL_GETCOUNT, 0, 0) != 1)
|
||||
{
|
||||
DPRINT("Error: console.dll returned unexpected CPL count\n");
|
||||
AlreadyDisplayingProps = FALSE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
DPRINT1("Error: console.dll returned unexpected CPL count\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
CPLFunc(NULL, CPL_DBLCLK, (LPARAM)lpThreadParameter, 0);
|
||||
CPLFunc(NULL, CPL_EXIT , 0, 0);
|
||||
|
||||
Quit:
|
||||
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
|
||||
InitConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
IN PUNICODE_STRING ImagePathName)
|
||||
SetUpHandles(IN PCONSOLE_START_INFO ConsoleStartInfo)
|
||||
{
|
||||
STARTUPINFOW si;
|
||||
SIZE_T Length;
|
||||
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
||||
|
||||
/* Get the startup information */
|
||||
GetStartupInfoW(&si);
|
||||
|
||||
/* Initialize the fields */
|
||||
ConsoleStartInfo->dwStartupFlags = si.dwFlags;
|
||||
if (si.dwFlags & STARTF_USEFILLATTRIBUTE)
|
||||
if (ConsoleStartInfo->dwStartupFlags & STARTF_USEHOTKEY)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
Parameters->WindowFlags &= ~STARTF_SHELLPRIVATE;
|
||||
}
|
||||
|
||||
/* Set up the title for the console */
|
||||
if (si.lpTitle)
|
||||
{
|
||||
wcsncpy(ConsoleStartInfo->ConsoleTitle, si.lpTitle, MAX_PATH + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleStartInfo->ConsoleTitle[0] = L'\0';
|
||||
}
|
||||
/* We got the handles, let's set them */
|
||||
Parameters->ConsoleHandle = ConsoleStartInfo->ConsoleHandle;
|
||||
|
||||
/* Retrieve the application path name */
|
||||
Length = min(sizeof(ConsoleStartInfo->AppPath) / sizeof(ConsoleStartInfo->AppPath[0]) - 1,
|
||||
ImagePathName->Length / sizeof(WCHAR));
|
||||
wcsncpy(ConsoleStartInfo->AppPath, ImagePathName->Buffer, Length);
|
||||
ConsoleStartInfo->AppPath[Length] = L'\0';
|
||||
|
||||
/* The Console Server will use these fields to set up the console icon */
|
||||
ConsoleStartInfo->IconPath[0] = L'\0';
|
||||
ConsoleStartInfo->IconIndex = 0;
|
||||
if (!(ConsoleStartInfo->dwStartupFlags & STARTF_USESTDHANDLES))
|
||||
{
|
||||
Parameters->StandardInput = ConsoleStartInfo->InputHandle;
|
||||
Parameters->StandardOutput = ConsoleStartInfo->OutputHandle;
|
||||
Parameters->StandardError = ConsoleStartInfo->ErrorHandle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
BasepInitConsole(VOID)
|
||||
static BOOLEAN
|
||||
IsConsoleApp(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;
|
||||
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
||||
WCHAR SessionDir[256];
|
||||
ULONG SessionId = NtCurrentPeb()->SessionId;
|
||||
BOOLEAN InServer;
|
||||
ULONG ConnectInfoSize = sizeof(*ConnectInfo);
|
||||
|
||||
CONSRV_API_CONNECTINFO ConnectInfo;
|
||||
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);
|
||||
}
|
||||
ASSERT(SessionDir);
|
||||
|
||||
/* Connect to the Console Server */
|
||||
DPRINT("Connecting to the Console Server in BasepInitConsole...\n");
|
||||
DPRINT("Connecting to the Console Server...\n");
|
||||
Status = CsrClientConnectToServer(SessionDir,
|
||||
CONSRV_SERVERDLL_INDEX,
|
||||
&ConnectInfo,
|
||||
ConnectInfo,
|
||||
&ConnectInfoSize,
|
||||
&InServer);
|
||||
IsServerProcess);
|
||||
if (!NT_SUCCESS(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 */
|
||||
if (InServer) return TRUE;
|
||||
if (*IsServerProcess) return TRUE;
|
||||
|
||||
/* Nothing to do if not a console app */
|
||||
if (!ConnectInfo.ConsoleStartInfo.ConsoleNeeded) return TRUE;
|
||||
/* Nothing to do if this is not a console app */
|
||||
if (!ConnectInfo->IsConsoleApp) return TRUE;
|
||||
|
||||
/* We got the handles, let's set them */
|
||||
if ((Parameters->ConsoleHandle = ConnectInfo.ConsoleHandle))
|
||||
#ifdef USE_CONSOLE_INIT_HANDLES
|
||||
/* 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 */
|
||||
if (!Parameters->StandardInput)
|
||||
{
|
||||
Parameters->StandardInput = ConnectInfo.InputHandle;
|
||||
}
|
||||
if (!Parameters->StandardOutput)
|
||||
{
|
||||
Parameters->StandardOutput = ConnectInfo.OutputHandle;
|
||||
}
|
||||
if (!Parameters->StandardError)
|
||||
{
|
||||
Parameters->StandardError = ConnectInfo.ErrorHandle;
|
||||
}
|
||||
BaseSetLastNTError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,10 +31,6 @@
|
|||
* Read functions *
|
||||
******************/
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer);
|
||||
|
||||
static
|
||||
BOOL
|
||||
IntReadConsole(IN HANDLE hConsoleInput,
|
||||
|
@ -58,26 +54,12 @@ IntReadConsole(IN HANDLE hConsoleInput,
|
|||
ReadConsoleRequest->Unicode = bUnicode;
|
||||
|
||||
/*
|
||||
* Retrieve the current console executable name string and length (always
|
||||
* in UNICODE format).
|
||||
* FIXME: Do not use GetConsoleInputExeNameW but use something else...
|
||||
* Retrieve the (current) Input EXE name string and length,
|
||||
* not NULL-terminated (always in UNICODE format).
|
||||
*/
|
||||
// 1- Get the exe name length in characters, including NULL character.
|
||||
ReadConsoleRequest->ExeLength =
|
||||
(USHORT)GetConsoleInputExeNameW(0, (PWCHAR)ReadConsoleRequest->StaticBuffer);
|
||||
// 2- Get the exe name (GetConsoleInputExeNameW returns 1 in case of success).
|
||||
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);
|
||||
}
|
||||
GetCurrentExeName((PWCHAR)ReadConsoleRequest->StaticBuffer,
|
||||
sizeof(ReadConsoleRequest->StaticBuffer));
|
||||
|
||||
/*** For DEBUGGING purposes ***/
|
||||
{
|
||||
|
|
|
@ -200,7 +200,7 @@ DllMain(HANDLE hDll,
|
|||
}
|
||||
|
||||
/* Initialize Console Support */
|
||||
if (!BasepInitConsole())
|
||||
if (!ConDllInitialize(dwReason, SessionDir))
|
||||
{
|
||||
DPRINT1("Failed to set up console\n");
|
||||
return FALSE;
|
||||
|
|
|
@ -726,7 +726,7 @@ BasePushProcessParameters(IN ULONG ParameterFlags,
|
|||
ProcessParameters->StandardError = StartupInfo->hStdError;
|
||||
}
|
||||
|
||||
/* Use Special Flags for BasepInitConsole in Kernel32 */
|
||||
/* Use Special Flags for ConDllInitialize in Kernel32 */
|
||||
if (CreationFlags & DETACHED_PROCESS)
|
||||
{
|
||||
ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
|
||||
|
|
|
@ -10,26 +10,35 @@
|
|||
|
||||
/* CONSTANTS ******************************************************************/
|
||||
|
||||
#define HANDLE_DETACHED_PROCESS (HANDLE)-2
|
||||
#define HANDLE_CREATE_NEW_CONSOLE (HANDLE)-3
|
||||
#define HANDLE_CREATE_NO_WINDOW (HANDLE)-4
|
||||
#define HANDLE_DETACHED_PROCESS (HANDLE)-1
|
||||
#define HANDLE_CREATE_NEW_CONSOLE (HANDLE)-2
|
||||
#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 ********************************************************/
|
||||
|
||||
BOOL WINAPI
|
||||
BasepInitConsole(VOID);
|
||||
BOOLEAN
|
||||
WINAPI
|
||||
ConDllInitialize(IN ULONG Reason,
|
||||
IN PWSTR SessionDir);
|
||||
|
||||
VOID WINAPI
|
||||
VOID
|
||||
WINAPI
|
||||
BasepUninitConsole(VOID);
|
||||
|
||||
VOID WINAPI
|
||||
InitConsoleCtrlHandling(VOID);
|
||||
VOID
|
||||
InitializeCtrlHandling(VOID);
|
||||
|
||||
DWORD WINAPI
|
||||
DWORD
|
||||
WINAPI
|
||||
ConsoleControlDispatcher(IN LPVOID lpThreadParameter);
|
||||
|
||||
DWORD WINAPI
|
||||
DWORD
|
||||
WINAPI
|
||||
PropDialogHandler(IN LPVOID lpThreadParameter);
|
||||
|
||||
HANDLE WINAPI
|
||||
|
@ -59,9 +68,32 @@ GetConsoleInputWaitHandle(VOID);
|
|||
HANDLE
|
||||
TranslateStdHandle(HANDLE hHandle);
|
||||
|
||||
#define SetTEBLangID(p) (p)
|
||||
|
||||
VOID
|
||||
InitConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
IN PUNICODE_STRING ImagePathName);
|
||||
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);
|
||||
|
||||
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
|
||||
IntCheckForConsoleFileName(IN LPCWSTR pszName,
|
||||
|
@ -73,7 +105,4 @@ OpenConsoleW(LPCWSTR wsName,
|
|||
BOOL bInheritHandle,
|
||||
DWORD dwShareMode);
|
||||
|
||||
BOOL WINAPI
|
||||
SetConsoleInputExeNameW(LPCWSTR lpInputExeName);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -119,6 +119,13 @@ typedef enum _CONSRV_API_NUMBER
|
|||
//
|
||||
typedef struct _CONSOLE_PROPERTIES
|
||||
{
|
||||
INT IconIndex;
|
||||
HICON hIcon;
|
||||
HICON hIconSm;
|
||||
DWORD dwHotKey;
|
||||
DWORD dwStartupFlags;
|
||||
|
||||
// NT_CONSOLE_PROPS
|
||||
WORD wFillAttribute;
|
||||
WORD wPopupFillAttribute;
|
||||
|
||||
|
@ -134,62 +141,60 @@ typedef struct _CONSOLE_PROPERTIES
|
|||
DWORD nFont;
|
||||
DWORD nInputBufferSize;
|
||||
COORD dwFontSize;
|
||||
UINT uFontFamily;
|
||||
UINT uFontWeight;
|
||||
UINT uFontFamily;
|
||||
UINT uFontWeight;
|
||||
WCHAR FaceName[LF_FACESIZE];
|
||||
UINT uCursorSize;
|
||||
BOOL bFullScreen;
|
||||
BOOL bQuickEdit;
|
||||
BOOL bInsertMode;
|
||||
BOOL bAutoPosition;
|
||||
UINT uHistoryBufferSize;
|
||||
UINT uNumberOfHistoryBuffers;
|
||||
BOOL bHistoryNoDup;
|
||||
UINT uCursorSize;
|
||||
BOOL bFullScreen;
|
||||
BOOL bQuickEdit;
|
||||
BOOL bInsertMode;
|
||||
BOOL bAutoPosition;
|
||||
UINT uHistoryBufferSize;
|
||||
UINT uNumberOfHistoryBuffers;
|
||||
BOOL bHistoryNoDup;
|
||||
COLORREF ColorTable[16];
|
||||
|
||||
//NT_FE_CONSOLE_PROPS
|
||||
// NT_FE_CONSOLE_PROPS
|
||||
UINT uCodePage;
|
||||
} 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
|
||||
{
|
||||
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 InputWaitHandle;
|
||||
HANDLE InputHandle;
|
||||
HANDLE OutputHandle;
|
||||
HANDLE ErrorHandle;
|
||||
HANDLE Event1;
|
||||
HANDLE Event2;
|
||||
/* Adapted from CONSOLE_ALLOCCONSOLE */
|
||||
HANDLE Events[2];
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
#if defined(_M_IX86)
|
||||
|
@ -259,25 +264,31 @@ typedef struct _CONSOLE_ALLOCCONSOLE
|
|||
{
|
||||
PCONSOLE_START_INFO ConsoleStartInfo;
|
||||
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
HANDLE OutputHandle;
|
||||
HANDLE ErrorHandle;
|
||||
HANDLE InputWaitHandle;
|
||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||
LPTHREAD_START_ROUTINE PropDispatcher;
|
||||
ULONG TitleLength;
|
||||
PWCHAR ConsoleTitle; // Console title or full path to the startup shortcut
|
||||
ULONG DesktopLength;
|
||||
PWCHAR Desktop;
|
||||
ULONG AppNameLength;
|
||||
PWCHAR AppName; // Full path of the launched app
|
||||
ULONG CurDirLength;
|
||||
PWCHAR CurDir;
|
||||
|
||||
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||
LPTHREAD_START_ROUTINE PropRoutine;
|
||||
} CONSOLE_ALLOCCONSOLE, *PCONSOLE_ALLOCCONSOLE;
|
||||
|
||||
typedef struct _CONSOLE_ATTACHCONSOLE
|
||||
{
|
||||
DWORD ProcessId; // If ProcessId == ATTACH_PARENT_PROCESS == -1, then attach the current process to its parent process console.
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
HANDLE OutputHandle;
|
||||
HANDLE ErrorHandle;
|
||||
HANDLE InputWaitHandle;
|
||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||
LPTHREAD_START_ROUTINE PropDispatcher;
|
||||
/*
|
||||
* If ProcessId == ATTACH_PARENT_PROCESS == -1, then attach
|
||||
* the current process to its parent process console.
|
||||
*/
|
||||
DWORD ProcessId;
|
||||
|
||||
PCONSOLE_START_INFO ConsoleStartInfo;
|
||||
|
||||
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||
LPTHREAD_START_ROUTINE PropRoutine;
|
||||
} CONSOLE_ATTACHCONSOLE, *PCONSOLE_ATTACHCONSOLE;
|
||||
|
||||
typedef struct _CONSOLE_FREECONSOLE
|
||||
|
|
|
@ -76,35 +76,6 @@ RemoveConsole(IN PCONSOLE Console)
|
|||
|
||||
/* 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
|
||||
ConDrvPause(PCONSOLE Console)
|
||||
{
|
||||
|
@ -194,9 +165,6 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
|
|||
TEXTMODE_BUFFER_INFO ScreenBufferInfo;
|
||||
PCONSOLE Console;
|
||||
PCONSOLE_SCREEN_BUFFER NewBuffer;
|
||||
#if 0
|
||||
WCHAR DefaultTitle[128];
|
||||
#endif
|
||||
|
||||
if (NewConsole == NULL || ConsoleInfo == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
@ -272,28 +240,6 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
|
|||
Console->ActiveBuffer = NewBuffer;
|
||||
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");
|
||||
|
||||
/* All went right, so add the console to the list */
|
||||
|
@ -460,9 +406,6 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
|
|||
|
||||
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
|
||||
|
||||
ConsoleFreeUnicodeString(&Console->OriginalTitle);
|
||||
ConsoleFreeUnicodeString(&Console->Title);
|
||||
|
||||
DPRINT("ConDrvDeleteConsole - Unlocking\n");
|
||||
LeaveCriticalSection(&Console->Lock);
|
||||
DPRINT("ConDrvDeleteConsole - Destroying lock\n");
|
||||
|
@ -566,111 +509,6 @@ ConDrvSetConsoleMode(IN PCONSOLE Console,
|
|||
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
|
||||
ConDrvGetConsoleCP(IN PCONSOLE Console,
|
||||
OUT PUINT CodePage,
|
||||
|
|
|
@ -108,11 +108,6 @@ DummyReleaseScreenBuffer(IN OUT PTERMINAL This,
|
|||
{
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
DummyChangeTitle(IN OUT PTERMINAL This)
|
||||
{
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
DummyGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
|
||||
PCOORD pSize)
|
||||
|
@ -148,7 +143,6 @@ static TERMINAL_VTBL DummyVtbl =
|
|||
DummyResizeTerminal,
|
||||
DummySetActiveScreenBuffer,
|
||||
DummyReleaseScreenBuffer,
|
||||
DummyChangeTitle,
|
||||
DummyGetLargestConsoleWindowSize,
|
||||
DummySetPalette,
|
||||
DummyShowMouseCursor,
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
|
||||
#include <ndk/psfuncs.h>
|
||||
|
||||
/* This is for COM usage */
|
||||
#define COBJMACROS
|
||||
#include <shlobj.h>
|
||||
|
||||
|
||||
#include <alias.h>
|
||||
#include <history.h>
|
||||
#include "procinit.h"
|
||||
|
@ -209,6 +214,35 @@ ConSrvValidateConsole(OUT PCONSRV_CONSOLE* Console,
|
|||
|
||||
/* 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
|
||||
ConioPause(PCONSRV_CONSOLE Console, UINT Flags)
|
||||
{
|
||||
|
@ -317,10 +351,157 @@ ConSrvInitTerminal(IN OUT PTERMINAL Terminal,
|
|||
NTSTATUS NTAPI
|
||||
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
|
||||
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||
OUT PCONSRV_CONSOLE* NewConsole,
|
||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
|
||||
IN ULONG ConsoleLeaderProcessId)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
@ -331,7 +512,7 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
|||
|
||||
TERMINAL Terminal; /* The ConSrv terminal for this console */
|
||||
|
||||
if (NewConsole == NULL || ConsoleStartInfo == NULL)
|
||||
if (NewConsole == NULL || ConsoleInitInfo == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
*NewConsole = NULL;
|
||||
|
@ -344,15 +525,15 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
|||
ConSrvGetDefaultSettings(&ConsoleInfo, ConsoleLeaderProcessId);
|
||||
|
||||
/* 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);
|
||||
wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length);
|
||||
ConsoleInfo.ConsoleTitle[Length] = L'\0';
|
||||
wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleInitInfo->ConsoleTitle, Length);
|
||||
ConsoleInfo.ConsoleTitle[Length] = L'\0'; // NULL-terminate it.
|
||||
|
||||
/* 3. Initialize the ConSrv terminal */
|
||||
Status = ConSrvInitTerminal(&Terminal,
|
||||
&ConsoleInfo,
|
||||
ConsoleStartInfo,
|
||||
ConsoleInitInfo,
|
||||
ConsoleLeaderProcessId);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -361,10 +542,25 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
|||
}
|
||||
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.
|
||||
*/
|
||||
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,
|
||||
|
@ -379,17 +575,17 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
|||
* (and which was transmitted via the ConsoleStartInfo structure).
|
||||
* 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 ***/
|
||||
|
||||
/* 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 */
|
||||
InitializeListHead(&Console->ProcessList);
|
||||
Console->NotifiedLastCloseProcess = NULL;
|
||||
|
@ -482,6 +703,10 @@ ConSrvDeleteConsole(PCONSRV_CONSOLE Console)
|
|||
IntDeleteAllAliases(Console);
|
||||
HistoryDeleteBuffers(Console);
|
||||
|
||||
/* Free the console title */
|
||||
ConsoleFreeUnicodeString(&Console->OriginalTitle);
|
||||
ConsoleFreeUnicodeString(&Console->Title);
|
||||
|
||||
/* Now, call the driver. ConDrvDeregisterTerminal is called on-demand. */
|
||||
ConDrvDeleteConsole((PCONSOLE)Console);
|
||||
|
||||
|
@ -504,7 +729,7 @@ ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
|
|||
|
||||
DPRINT("ConSrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
|
||||
|
||||
if (ProcessData->CtrlDispatcher)
|
||||
if (ProcessData->CtrlRoutine)
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
|
@ -513,7 +738,7 @@ ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
|
|||
_SEH2_TRY
|
||||
{
|
||||
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
||||
ProcessData->CtrlDispatcher,
|
||||
ProcessData->CtrlRoutine,
|
||||
UlongToPtr(CtrlEvent), 0, NULL);
|
||||
if (NULL == Thread)
|
||||
{
|
||||
|
@ -522,7 +747,8 @@ ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
|
|||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -628,9 +854,6 @@ ConSrvConsoleProcessCtrlEvent(IN PCONSRV_CONSOLE Console,
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* PUBLIC SERVER APIS *********************************************************/
|
||||
|
||||
CSR_API(SrvAllocConsole)
|
||||
|
@ -639,6 +862,7 @@ CSR_API(SrvAllocConsole)
|
|||
PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
|
||||
PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process;
|
||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||
CONSOLE_INIT_INFO ConsoleInitInfo;
|
||||
|
||||
if (ProcessData->ConsoleHandle != NULL)
|
||||
{
|
||||
|
@ -646,33 +870,64 @@ CSR_API(SrvAllocConsole)
|
|||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->ConsoleStartInfo,
|
||||
1,
|
||||
sizeof(CONSOLE_START_INFO)))
|
||||
if ( !CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->ConsoleStartInfo,
|
||||
1,
|
||||
sizeof(CONSOLE_START_INFO)) ||
|
||||
!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->ConsoleTitle,
|
||||
AllocConsoleRequest->TitleLength,
|
||||
sizeof(BYTE)) ||
|
||||
!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->Desktop,
|
||||
AllocConsoleRequest->DesktopLength,
|
||||
sizeof(BYTE)) ||
|
||||
!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->CurDir,
|
||||
AllocConsoleRequest->CurDirLength,
|
||||
sizeof(BYTE)) ||
|
||||
!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->AppName,
|
||||
AllocConsoleRequest->AppNameLength,
|
||||
sizeof(BYTE)) )
|
||||
{
|
||||
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 */
|
||||
Status = ConSrvAllocateConsole(ProcessData,
|
||||
&AllocConsoleRequest->InputHandle,
|
||||
&AllocConsoleRequest->OutputHandle,
|
||||
&AllocConsoleRequest->ErrorHandle,
|
||||
AllocConsoleRequest->ConsoleStartInfo);
|
||||
&AllocConsoleRequest->ConsoleStartInfo->InputHandle,
|
||||
&AllocConsoleRequest->ConsoleStartInfo->OutputHandle,
|
||||
&AllocConsoleRequest->ConsoleStartInfo->ErrorHandle,
|
||||
&ConsoleInitInfo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Console allocation failed\n");
|
||||
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 */
|
||||
AllocConsoleRequest->ConsoleHandle = ProcessData->ConsoleHandle;
|
||||
AllocConsoleRequest->InputWaitHandle = ProcessData->InputWaitHandle;
|
||||
AllocConsoleRequest->ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
|
||||
AllocConsoleRequest->ConsoleStartInfo->InputWaitHandle = ProcessData->InputWaitHandle;
|
||||
|
||||
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
||||
ProcessData->PropDispatcher = AllocConsoleRequest->PropDispatcher;
|
||||
ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher;
|
||||
ProcessData->PropRoutine = AllocConsoleRequest->PropRoutine;
|
||||
ProcessData->CtrlRoutine = AllocConsoleRequest->CtrlRoutine;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -694,6 +949,14 @@ CSR_API(SrvAttachConsole)
|
|||
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 */
|
||||
if (ProcessId == ULongToHandle(ATTACH_PARENT_PROCESS))
|
||||
{
|
||||
|
@ -734,22 +997,26 @@ CSR_API(SrvAttachConsole)
|
|||
Status = ConSrvInheritConsole(TargetProcessData,
|
||||
SourceProcessData->ConsoleHandle,
|
||||
TRUE,
|
||||
&AttachConsoleRequest->InputHandle,
|
||||
&AttachConsoleRequest->OutputHandle,
|
||||
&AttachConsoleRequest->ErrorHandle);
|
||||
&AttachConsoleRequest->ConsoleStartInfo->InputHandle,
|
||||
&AttachConsoleRequest->ConsoleStartInfo->OutputHandle,
|
||||
&AttachConsoleRequest->ConsoleStartInfo->ErrorHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Console inheritance failed\n");
|
||||
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 */
|
||||
AttachConsoleRequest->ConsoleHandle = TargetProcessData->ConsoleHandle;
|
||||
AttachConsoleRequest->InputWaitHandle = TargetProcessData->InputWaitHandle;
|
||||
AttachConsoleRequest->ConsoleStartInfo->ConsoleHandle = TargetProcessData->ConsoleHandle;
|
||||
AttachConsoleRequest->ConsoleStartInfo->InputWaitHandle = TargetProcessData->InputWaitHandle;
|
||||
|
||||
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
||||
TargetProcessData->PropDispatcher = AttachConsoleRequest->PropDispatcher;
|
||||
TargetProcessData->CtrlDispatcher = AttachConsoleRequest->CtrlDispatcher;
|
||||
TargetProcessData->PropRoutine = AttachConsoleRequest->PropRoutine;
|
||||
TargetProcessData->CtrlRoutine = AttachConsoleRequest->CtrlRoutine;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
|
@ -761,7 +1028,15 @@ Quit:
|
|||
|
||||
CSR_API(SrvFreeConsole)
|
||||
{
|
||||
PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process;
|
||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||
|
||||
ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
|
||||
|
||||
/* Mark the process as not having a console anymore */
|
||||
ProcessData->ConsoleApp = FALSE;
|
||||
CsrProcess->Flags &= ~CsrProcessIsConsoleApp;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -865,16 +1140,12 @@ CSR_API(SrvSetConsoleMode)
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvGetConsoleTitle(IN PCONSOLE Console,
|
||||
IN BOOLEAN Unicode,
|
||||
IN OUT PVOID TitleBuffer,
|
||||
IN OUT PULONG BufLength);
|
||||
CSR_API(SrvGetConsoleTitle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
ULONG Length;
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID)&TitleRequest->Title,
|
||||
|
@ -891,26 +1162,52 @@ CSR_API(SrvGetConsoleTitle)
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = ConDrvGetConsoleTitle(Console,
|
||||
TitleRequest->Unicode,
|
||||
TitleRequest->Title,
|
||||
&TitleRequest->Length);
|
||||
/* Copy title of the console to the user title buffer */
|
||||
if (TitleRequest->Unicode)
|
||||
{
|
||||
if (TitleRequest->Length >= sizeof(WCHAR))
|
||||
{
|
||||
Length = min(TitleRequest->Length - sizeof(WCHAR), Console->Title.Length);
|
||||
RtlCopyMemory(TitleRequest->Title, Console->Title.Buffer, Length);
|
||||
((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);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvSetConsoleTitle(IN PCONSOLE Console,
|
||||
IN BOOLEAN Unicode,
|
||||
IN PVOID TitleBuffer,
|
||||
IN ULONG BufLength);
|
||||
CSR_API(SrvSetConsoleTitle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
|
||||
PWCHAR Buffer;
|
||||
ULONG Length;
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID)&TitleRequest->Title,
|
||||
TitleRequest->Length,
|
||||
|
@ -926,13 +1223,56 @@ CSR_API(SrvSetConsoleTitle)
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = ConDrvSetConsoleTitle(Console,
|
||||
TitleRequest->Unicode,
|
||||
TitleRequest->Title,
|
||||
TitleRequest->Length);
|
||||
// FIXME: Keep this call here, or put it in ConDrvSetConsoleTitle ??
|
||||
if (NT_SUCCESS(Status)) TermChangeTitle(Console);
|
||||
if (TitleRequest->Unicode)
|
||||
{
|
||||
/* Length is in bytes */
|
||||
Length = TitleRequest->Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the console input CP for the conversion */
|
||||
Length = MultiByteToWideChar(Console->InputCodePage, 0,
|
||||
TitleRequest->Title, TitleRequest->Length,
|
||||
NULL, 0);
|
||||
/* The returned Length was in number of wchars, convert it in bytes */
|
||||
Length *= sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/* Allocate a new buffer to hold the new title (NULL-terminated) */
|
||||
Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Length + sizeof(WCHAR));
|
||||
if (!Buffer)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/* Free the old title */
|
||||
ConsoleFreeUnicodeString(&Console->Title);
|
||||
|
||||
/* Copy title to console */
|
||||
Console->Title.Buffer = Buffer;
|
||||
Console->Title.Length = Length;
|
||||
Console->Title.MaximumLength = Console->Title.Length + sizeof(WCHAR);
|
||||
|
||||
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);
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -8,13 +8,27 @@
|
|||
|
||||
#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
|
||||
ConSrvInitConsoleSupport(VOID);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||
OUT struct _CONSRV_CONSOLE** /* PCONSRV_CONSOLE* */ NewConsole,
|
||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
|
||||
IN ULONG ConsoleLeaderProcessId);
|
||||
VOID NTAPI ConSrvDeleteConsole(struct _CONSRV_CONSOLE* /* PCONSRV_CONSOLE */ Console);
|
||||
|
||||
|
|
|
@ -51,10 +51,9 @@ typedef struct _CONSOLE_PROCESS_DATA
|
|||
{
|
||||
LIST_ENTRY ConsoleLink;
|
||||
PCSR_PROCESS Process; // Process owning this structure.
|
||||
HANDLE InputWaitHandle;
|
||||
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE ParentConsoleHandle;
|
||||
HANDLE InputWaitHandle;
|
||||
|
||||
BOOLEAN ConsoleApp; // TRUE if it is a CUI app, FALSE otherwise.
|
||||
|
||||
|
@ -62,8 +61,9 @@ typedef struct _CONSOLE_PROCESS_DATA
|
|||
ULONG HandleTableSize;
|
||||
struct _CONSOLE_IO_HANDLE* /* PCONSOLE_IO_HANDLE */ HandleTable; // Length-varying table
|
||||
|
||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||
LPTHREAD_START_ROUTINE PropDispatcher; // We hold the property dialog handler there, till all the GUI thingie moves out from CSRSS.
|
||||
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||
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;
|
||||
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
|||
}
|
||||
|
||||
/* Start the properties dialog */
|
||||
if (ProcessData->PropDispatcher)
|
||||
if (ProcessData->PropRoutine)
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
|
@ -381,7 +381,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
|||
_SEH2_TRY
|
||||
{
|
||||
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
||||
ProcessData->PropDispatcher,
|
||||
ProcessData->PropRoutine,
|
||||
(PVOID)hClientSection, 0, NULL);
|
||||
if (NULL == Thread)
|
||||
{
|
||||
|
@ -389,7 +389,8 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
|||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
|
||||
#include <consrv.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#include <shlobj.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -405,9 +402,7 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
PGUI_CONSOLE_DATA GuiData;
|
||||
GUI_CONSOLE_INFO TermInfo;
|
||||
|
||||
SIZE_T Length = 0;
|
||||
LPWSTR IconPath = NULL;
|
||||
INT IconIndex = 0;
|
||||
SIZE_T Length = 0;
|
||||
|
||||
if (This == NULL || Console == NULL || This->OldData == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
@ -422,10 +417,6 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
ConsoleInfo = GuiInitInfo->ConsoleInfo;
|
||||
ConsoleStartInfo = GuiInitInfo->ConsoleStartInfo;
|
||||
|
||||
IconPath = ConsoleStartInfo->IconPath;
|
||||
IconIndex = ConsoleStartInfo->IconIndex;
|
||||
|
||||
|
||||
/* Terminal data allocation */
|
||||
GuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(GUI_CONSOLE_DATA));
|
||||
if (!GuiData)
|
||||
|
@ -451,10 +442,10 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
/* 1. Load the default settings */
|
||||
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)
|
||||
{
|
||||
/* Load the terminal infos from the registry. */
|
||||
/* Load the terminal infos from the registry */
|
||||
GuiConsoleReadUserSettings(&TermInfo,
|
||||
ConsoleInfo->ConsoleTitle,
|
||||
GuiInitInfo->ProcessId);
|
||||
|
@ -500,29 +491,17 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
GuiData->GuiInfo.AutoPosition = TermInfo.AutoPosition;
|
||||
GuiData->GuiInfo.WindowOrigin = TermInfo.WindowOrigin;
|
||||
|
||||
/* Initialize the icon handles to their default values */
|
||||
GuiData->hIcon = ghDefaultIcon;
|
||||
GuiData->hIconSm = ghDefaultIconSm;
|
||||
/* Initialize the icon handles */
|
||||
if (ConsoleStartInfo->hIcon != NULL)
|
||||
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);
|
||||
|
||||
/* 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
|
||||
GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
|
||||
IN OUT PCONSOLE_INFO ConsoleInfo,
|
||||
IN OUT PVOID ExtraConsoleInfo,
|
||||
IN ULONG ProcessId)
|
||||
{
|
||||
PCONSOLE_START_INFO ConsoleStartInfo = ExtraConsoleInfo;
|
||||
PCONSOLE_INIT_INFO ConsoleInitInfo = ExtraConsoleInfo;
|
||||
PGUI_INIT_INFO GuiInitInfo;
|
||||
|
||||
if (FrontEnd == NULL || ConsoleInfo == NULL || ConsoleStartInfo == NULL)
|
||||
if (FrontEnd == NULL || ConsoleInfo == NULL || ConsoleInitInfo == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* Initialize GUI terminal emulator common functionalities */
|
||||
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.
|
||||
* 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...
|
||||
GuiInitInfo->ConsoleInfo = ConsoleInfo;
|
||||
GuiInitInfo->ConsoleStartInfo = ConsoleStartInfo;
|
||||
GuiInitInfo->ConsoleStartInfo = ConsoleInitInfo->ConsoleStartInfo;
|
||||
GuiInitInfo->ProcessId = ProcessId;
|
||||
|
||||
|
||||
/* Finally, initialize the frontend structure */
|
||||
FrontEnd->Vtbl = &GuiVtbl;
|
||||
FrontEnd->Data = NULL;
|
||||
|
|
|
@ -14,13 +14,6 @@
|
|||
#include "guisettings.h"
|
||||
#include "conwnd.h"
|
||||
|
||||
NTSTATUS GuiInitConsole(PCONSOLE Console,
|
||||
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
PCONSOLE_INFO ConsoleInfo,
|
||||
DWORD ProcessId,
|
||||
LPCWSTR IconPath,
|
||||
INT IconIndex);
|
||||
|
||||
VOID
|
||||
GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData);
|
||||
|
||||
|
|
|
@ -273,6 +273,8 @@ ConSrvTermInitTerminal(IN OUT PTERMINAL This,
|
|||
Console->FrontEndIFace = *FrontEnd;
|
||||
|
||||
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!! **/
|
||||
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);
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
ConSrvTermChangeTitle(IN OUT PTERMINAL This)
|
||||
{
|
||||
PFRONTEND FrontEnd = This->Data;
|
||||
FrontEnd->Vtbl->ChangeTitle(FrontEnd);
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
ConSrvTermGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
|
||||
PCOORD pSize)
|
||||
|
@ -743,7 +738,6 @@ static TERMINAL_VTBL ConSrvTermVtbl =
|
|||
ConSrvTermResizeTerminal,
|
||||
ConSrvTermSetActiveScreenBuffer,
|
||||
ConSrvTermReleaseScreenBuffer,
|
||||
ConSrvTermChangeTitle,
|
||||
ConSrvTermGetLargestConsoleWindowSize,
|
||||
ConSrvTermSetPalette,
|
||||
ConSrvTermShowMouseCursor,
|
||||
|
|
|
@ -470,15 +470,12 @@ ConSrvReleaseObject(IN PCONSOLE_IO_OBJECT Object,
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
PHANDLE pInputHandle,
|
||||
PHANDLE pOutputHandle,
|
||||
PHANDLE pErrorHandle,
|
||||
PCONSOLE_START_INFO ConsoleStartInfo)
|
||||
PCONSOLE_INIT_INFO ConsoleInitInfo)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
HANDLE ConsoleHandle;
|
||||
|
@ -499,7 +496,7 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
/* Initialize a new Console owned by this process */
|
||||
Status = ConSrvInitConsole(&ConsoleHandle,
|
||||
&Console,
|
||||
ConsoleStartInfo,
|
||||
ConsoleInitInfo,
|
||||
HandleToUlong(ProcessData->Process->ClientId.UniqueProcess));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
|
|
@ -251,7 +251,6 @@ typedef struct _TERMINAL_VTBL
|
|||
/*
|
||||
* External interface (functions corresponding to the Console API)
|
||||
*/
|
||||
VOID (NTAPI *ChangeTitle)(IN OUT PTERMINAL This);
|
||||
VOID (NTAPI *GetLargestConsoleWindowSize)(IN OUT PTERMINAL This,
|
||||
PCOORD pSize);
|
||||
BOOL (NTAPI *SetPalette)(IN OUT PTERMINAL This,
|
||||
|
@ -326,9 +325,6 @@ typedef struct _CONSOLE
|
|||
UINT OutputCodePage;
|
||||
|
||||
/****************************** 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 */
|
||||
BOOLEAN FixedSize; /* TRUE if the console is of fixed size */
|
||||
|
||||
|
|
|
@ -183,7 +183,9 @@ typedef struct _WINSRV_CONSOLE
|
|||
HANDLE ErrorHardwareEvent;
|
||||
|
||||
/****************************** 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 */
|
||||
|
||||
} WINSRV_CONSOLE; // , *PWINSRV_CONSOLE;
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
(Console)->TermIFace.Vtbl->SetActiveScreenBuffer(&(Console)->TermIFace)
|
||||
#define TermReleaseScreenBuffer(Console, ScreenBuffer) \
|
||||
(Console)->TermIFace.Vtbl->ReleaseScreenBuffer(&(Console)->TermIFace, (ScreenBuffer))
|
||||
#define TermChangeTitle(Console) \
|
||||
(Console)->TermIFace.Vtbl->ChangeTitle(&(Console)->TermIFace)
|
||||
#define TermGetLargestConsoleWindowSize(Console, pSize) \
|
||||
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize(&(Console)->TermIFace, (pSize))
|
||||
#define TermSetPalette(Console, PaletteHandle, PaletteUsage) \
|
||||
|
@ -45,6 +43,8 @@
|
|||
|
||||
#define TermRefreshInternalInfo(Console) \
|
||||
(Console)->FrontEndIFace.Vtbl->RefreshInternalInfo(&(Console)->FrontEndIFace)
|
||||
#define TermChangeTitle(Console) \
|
||||
(Console)->FrontEndIFace.Vtbl->ChangeTitle(&(Console)->FrontEndIFace)
|
||||
#define TermChangeIcon(Console, IconHandle) \
|
||||
(Console)->FrontEndIFace.Vtbl->ChangeIcon(&(Console)->FrontEndIFace, (IconHandle))
|
||||
#define TermGetConsoleWindowHandle(Console) \
|
||||
|
|
|
@ -354,8 +354,8 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
|||
RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
|
||||
TargetProcessData->Process = TargetProcess;
|
||||
TargetProcessData->InputWaitHandle = NULL;
|
||||
TargetProcessData->ConsoleHandle = TargetProcessData->ParentConsoleHandle = NULL;
|
||||
TargetProcessData->ConsoleApp = ((TargetProcess->Flags & CsrProcessIsConsoleApp) ? TRUE : FALSE);
|
||||
TargetProcessData->ConsoleHandle = NULL;
|
||||
TargetProcessData->ConsoleApp = FALSE;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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);
|
||||
PCONSRV_CONSOLE SourceConsole;
|
||||
|
@ -389,10 +389,9 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
|||
{
|
||||
/* Inherit the parent's handles table */
|
||||
Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
|
||||
if (NT_SUCCESS(Status))
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Temporary save the parent's console too */
|
||||
TargetProcessData->ParentConsoleHandle = SourceProcessData->ConsoleHandle;
|
||||
DPRINT1("Inheriting handles table failed\n");
|
||||
}
|
||||
|
||||
/* Unlock the parent's console */
|
||||
|
@ -416,28 +415,37 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
|||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PCONSRV_API_CONNECTINFO ConnectInfo = (PCONSRV_API_CONNECTINFO)ConnectionInfo;
|
||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||
CONSOLE_INIT_INFO ConsoleInitInfo;
|
||||
|
||||
if ( ConnectionInfo == 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",
|
||||
ConnectionInfo,
|
||||
ConnectionInfoLength,
|
||||
ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
|
||||
sizeof(CONSRV_API_CONNECTINFO));
|
||||
sizeof(*ConnectInfo));
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
DPRINT("ConnectInfo->IsConsoleApp = %s\n", ConnectInfo->IsConsoleApp ? "True" : "False");
|
||||
if (!ConnectInfo->IsConsoleApp) return STATUS_SUCCESS;
|
||||
|
||||
/* If we don't have a console, then create a new one... */
|
||||
if (!ConnectInfo->ConsoleHandle ||
|
||||
ConnectInfo->ConsoleHandle != ProcessData->ParentConsoleHandle)
|
||||
/* Initialize the console initialization info structure */
|
||||
ConsoleInitInfo.ConsoleStartInfo = &ConnectInfo->ConsoleStartInfo;
|
||||
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");
|
||||
|
||||
|
@ -454,10 +462,10 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
|||
|
||||
/* Initialize a new Console owned by the Console Leader Process */
|
||||
Status = ConSrvAllocateConsole(ProcessData,
|
||||
&ConnectInfo->InputHandle,
|
||||
&ConnectInfo->OutputHandle,
|
||||
&ConnectInfo->ErrorHandle,
|
||||
&ConnectInfo->ConsoleStartInfo);
|
||||
&ConnectInfo->ConsoleStartInfo.InputHandle,
|
||||
&ConnectInfo->ConsoleStartInfo.OutputHandle,
|
||||
&ConnectInfo->ConsoleStartInfo.ErrorHandle,
|
||||
&ConsoleInitInfo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Console allocation failed\n");
|
||||
|
@ -470,11 +478,11 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
|||
|
||||
/* Reuse our current console */
|
||||
Status = ConSrvInheritConsole(ProcessData,
|
||||
ConnectInfo->ConsoleHandle,
|
||||
ConnectInfo->ConsoleStartInfo.ConsoleHandle,
|
||||
FALSE,
|
||||
NULL, // &ConnectInfo->InputHandle,
|
||||
NULL, // &ConnectInfo->OutputHandle,
|
||||
NULL); // &ConnectInfo->ErrorHandle);
|
||||
NULL, // &ConnectInfo->ConsoleStartInfo.InputHandle,
|
||||
NULL, // &ConnectInfo->ConsoleStartInfo.OutputHandle,
|
||||
NULL); // &ConnectInfo->ConsoleStartInfo.ErrorHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
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 */
|
||||
ConnectInfo->ConsoleHandle = ProcessData->ConsoleHandle;
|
||||
ConnectInfo->InputWaitHandle = ProcessData->InputWaitHandle;
|
||||
ConnectInfo->ConsoleStartInfo.ConsoleHandle = ProcessData->ConsoleHandle;
|
||||
ConnectInfo->ConsoleStartInfo.InputWaitHandle = ProcessData->InputWaitHandle;
|
||||
|
||||
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
||||
ProcessData->PropDispatcher = ConnectInfo->ConsoleStartInfo.PropDispatcher;
|
||||
ProcessData->CtrlDispatcher = ConnectInfo->ConsoleStartInfo.CtrlDispatcher;
|
||||
ProcessData->PropRoutine = ConnectInfo->PropRoutine;
|
||||
ProcessData->CtrlRoutine = ConnectInfo->CtrlRoutine;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -508,6 +520,10 @@ ConSrvDisconnect(PCSR_PROCESS Process)
|
|||
{
|
||||
DPRINT("ConSrvDisconnect - calling ConSrvRemoveConsole\n");
|
||||
ConSrvRemoveConsole(ProcessData);
|
||||
|
||||
/* Mark the process as not having a console anymore */
|
||||
ProcessData->ConsoleApp = FALSE;
|
||||
Process->Flags &= ~CsrProcessIsConsoleApp;
|
||||
}
|
||||
|
||||
RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
|
|
@ -12,7 +12,7 @@ NTSTATUS ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
PHANDLE pInputHandle,
|
||||
PHANDLE pOutputHandle,
|
||||
PHANDLE pErrorHandle,
|
||||
PCONSOLE_START_INFO ConsoleStartInfo);
|
||||
PCONSOLE_INIT_INFO ConsoleInitInfo);
|
||||
NTSTATUS ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
HANDLE ConsoleHandle,
|
||||
BOOLEAN CreateNewHandlesTable,
|
||||
|
|
Loading…
Reference in a new issue