mirror of
https://github.com/reactos/reactos.git
synced 2024-10-28 00:58:20 +00:00
[CONSOLE.DLL]
- Fix passing and retrieving gui terminal front-end information. - Fix default (global) console parameters saving. [CONSRV] - PSEH2-protect calls to CreateRemoteThread when 1. calling console app. control handlers and 2. retrieving console settings from console.dll. - Introduce a new way of locking consoles when being used, and store them in a list. svn path=/branches/ros-csrss/; revision=58615
This commit is contained in:
parent
1e1a59fb22
commit
01729482ae
|
@ -87,6 +87,8 @@ InitConsoleDefaults(PCONSOLE_PROPS pConInfo)
|
||||||
{
|
{
|
||||||
PGUI_CONSOLE_INFO GuiInfo = NULL;
|
PGUI_CONSOLE_INFO GuiInfo = NULL;
|
||||||
|
|
||||||
|
/* FIXME: Get also the defaults from the registry */
|
||||||
|
|
||||||
/* Initialize the default properties */
|
/* Initialize the default properties */
|
||||||
pConInfo->ci.HistoryBufferSize = 50;
|
pConInfo->ci.HistoryBufferSize = 50;
|
||||||
pConInfo->ci.NumberOfHistoryBuffers = 4;
|
pConInfo->ci.NumberOfHistoryBuffers = 4;
|
||||||
|
@ -108,7 +110,8 @@ InitConsoleDefaults(PCONSOLE_PROPS pConInfo)
|
||||||
/* Adapted for holding GUI terminal information */
|
/* Adapted for holding GUI terminal information */
|
||||||
pConInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
|
pConInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
|
||||||
GuiInfo = pConInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pConInfo + 1);
|
GuiInfo = pConInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pConInfo + 1);
|
||||||
GuiInfo->FaceName[0] = L'\0';
|
wcsncpy(GuiInfo->FaceName, L"Fixedsys", LF_FACESIZE); // HACK: !!
|
||||||
|
// GuiInfo->FaceName[0] = L'\0';
|
||||||
GuiInfo->FontFamily = FF_DONTCARE;
|
GuiInfo->FontFamily = FF_DONTCARE;
|
||||||
GuiInfo->FontSize = 0;
|
GuiInfo->FontSize = 0;
|
||||||
GuiInfo->FontWeight = FW_DONTCARE;
|
GuiInfo->FontWeight = FW_DONTCARE;
|
||||||
|
@ -166,16 +169,35 @@ BOOL
|
||||||
ApplyConsoleInfo(HWND hwndDlg,
|
ApplyConsoleInfo(HWND hwndDlg,
|
||||||
PCONSOLE_PROPS pConInfo)
|
PCONSOLE_PROPS pConInfo)
|
||||||
{
|
{
|
||||||
INT_PTR res = 0;
|
BOOL SetParams = FALSE;
|
||||||
|
BOOL SaveParams = FALSE;
|
||||||
|
|
||||||
res = DialogBox(hApplet, MAKEINTRESOURCE(IDD_APPLYOPTIONS), hwndDlg, ApplyProc);
|
/*
|
||||||
if (res == IDCANCEL)
|
* If we are setting the default parameters, just save them,
|
||||||
|
* otherwise display the save-confirmation dialog.
|
||||||
|
*/
|
||||||
|
if (pConInfo->ShowDefaultParams)
|
||||||
|
{
|
||||||
|
SetParams = TRUE;
|
||||||
|
SaveParams = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
INT_PTR res = DialogBox(hApplet, MAKEINTRESOURCE(IDD_APPLYOPTIONS), hwndDlg, ApplyProc);
|
||||||
|
|
||||||
|
SetParams = (res != IDCANCEL);
|
||||||
|
SaveParams = (res == IDC_RADIO_APPLY_ALL);
|
||||||
|
|
||||||
|
if (SetParams == FALSE)
|
||||||
{
|
{
|
||||||
/* Don't destroy when user presses cancel */
|
/* Don't destroy when user presses cancel */
|
||||||
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
|
||||||
return TRUE;
|
// return TRUE;
|
||||||
}
|
}
|
||||||
else if (res == IDC_RADIO_APPLY_ALL || res == IDC_RADIO_APPLY_CURRENT)
|
}
|
||||||
|
|
||||||
|
// if (res == IDC_RADIO_APPLY_ALL || res == IDC_RADIO_APPLY_CURRENT)
|
||||||
|
if (SetParams)
|
||||||
{
|
{
|
||||||
HANDLE hSection;
|
HANDLE hSection;
|
||||||
PCONSOLE_PROPS pSharedInfo;
|
PCONSOLE_PROPS pSharedInfo;
|
||||||
|
@ -207,10 +229,15 @@ ApplyConsoleInfo(HWND hwndDlg,
|
||||||
/* We are applying the chosen configuration */
|
/* We are applying the chosen configuration */
|
||||||
pConInfo->AppliedConfig = TRUE;
|
pConInfo->AppliedConfig = TRUE;
|
||||||
|
|
||||||
/* Copy the console info into the section */
|
/*
|
||||||
|
* Copy the console information into the section and
|
||||||
|
* offsetize the address of terminal-specific information.
|
||||||
|
* Do not perform the offsetization in pConInfo as it is
|
||||||
|
* likely to be reused later on. Instead, do it in pSharedInfo
|
||||||
|
* after having copied all the data.
|
||||||
|
*/
|
||||||
RtlCopyMemory(pSharedInfo, pConInfo, sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO));
|
RtlCopyMemory(pSharedInfo, pConInfo, sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO));
|
||||||
/* Offsetize */
|
pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)pConInfo->TerminalInfo.TermInfo - (ULONG_PTR)pConInfo);
|
||||||
pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)pSharedInfo->TerminalInfo.TermInfo - (ULONG_PTR)pSharedInfo);
|
|
||||||
|
|
||||||
/* Unmap it */
|
/* Unmap it */
|
||||||
UnmapViewOfFile(pSharedInfo);
|
UnmapViewOfFile(pSharedInfo);
|
||||||
|
@ -220,11 +247,10 @@ ApplyConsoleInfo(HWND hwndDlg,
|
||||||
SendMessage(pConInfo->hConsoleWindow,
|
SendMessage(pConInfo->hConsoleWindow,
|
||||||
PM_APPLY_CONSOLE_INFO,
|
PM_APPLY_CONSOLE_INFO,
|
||||||
(WPARAM)hSection,
|
(WPARAM)hSection,
|
||||||
(LPARAM)(res == IDC_RADIO_APPLY_ALL));
|
(LPARAM)SaveParams);
|
||||||
|
|
||||||
/* Close the section and return */
|
/* Close the section and return */
|
||||||
CloseHandle(hSection);
|
CloseHandle(hSection);
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -685,7 +685,6 @@ CSR_API(SrvReadConsole)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (Request->Data.ReadConsoleRequest.NrCharactersRead * sizeof(WCHAR) > nNumberOfCharsToRead * CharSize)
|
|
||||||
if (ReadConsoleRequest->NrCharactersRead > ReadConsoleRequest->NrCharactersToRead)
|
if (ReadConsoleRequest->NrCharactersRead > ReadConsoleRequest->NrCharactersToRead)
|
||||||
{
|
{
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -808,7 +807,7 @@ CSR_API(SrvFlushConsoleInputBuffer)
|
||||||
PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FlushInputBufferRequest;
|
PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FlushInputBufferRequest;
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PCONSOLE_INPUT_BUFFER InputBuffer;
|
PCONSOLE_INPUT_BUFFER InputBuffer;
|
||||||
ConsoleInput* Input;
|
ConsoleInput* Event;
|
||||||
|
|
||||||
DPRINT("SrvFlushConsoleInputBuffer\n");
|
DPRINT("SrvFlushConsoleInputBuffer\n");
|
||||||
|
|
||||||
|
@ -823,14 +822,12 @@ CSR_API(SrvFlushConsoleInputBuffer)
|
||||||
while (!IsListEmpty(&InputBuffer->InputEvents))
|
while (!IsListEmpty(&InputBuffer->InputEvents))
|
||||||
{
|
{
|
||||||
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
|
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
|
||||||
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
||||||
/* Destroy the event */
|
RtlFreeHeap(ConSrvHeap, 0, Event);
|
||||||
RtlFreeHeap(ConSrvHeap, 0, Input);
|
|
||||||
}
|
}
|
||||||
ResetEvent(InputBuffer->ActiveEvent);
|
ResetEvent(InputBuffer->ActiveEvent);
|
||||||
|
|
||||||
ConSrvReleaseInputBuffer(InputBuffer, TRUE);
|
ConSrvReleaseInputBuffer(InputBuffer, TRUE);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,12 +147,27 @@ typedef struct _FRONTEND_IFACE
|
||||||
PVOID OldData; /* Reserved */
|
PVOID OldData; /* Reserved */
|
||||||
} FRONTEND_IFACE, *PFRONTEND_IFACE;
|
} FRONTEND_IFACE, *PFRONTEND_IFACE;
|
||||||
|
|
||||||
|
#if 0 // Temporarily put in consrv.h
|
||||||
|
/*
|
||||||
|
* WARNING: Change the state of the console ONLY when the console is locked !
|
||||||
|
*/
|
||||||
|
typedef enum _CONSOLE_STATE
|
||||||
|
{
|
||||||
|
CONSOLE_INITIALIZING, /* Console is initializing */
|
||||||
|
CONSOLE_RUNNING , /* Console running */
|
||||||
|
CONSOLE_TERMINATING , /* Console about to be destroyed (but still not) */
|
||||||
|
CONSOLE_IN_DESTRUCTION /* Console in destruction */
|
||||||
|
} CONSOLE_STATE, *PCONSOLE_STATE;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _CONSOLE
|
typedef struct _CONSOLE
|
||||||
{
|
{
|
||||||
LONG ReferenceCount; /* Is incremented each time a handle to a screen-buffer or the input buffer of this console gets referenced, or the console gets locked */
|
LONG ReferenceCount; /* Is incremented each time a handle to something in the console (a screen-buffer or the input buffer of this console) gets referenced */
|
||||||
CRITICAL_SECTION Lock;
|
CRITICAL_SECTION Lock;
|
||||||
|
CONSOLE_STATE State; /* State of the console */
|
||||||
|
|
||||||
struct _CONSOLE *Prev, *Next; /* Next and Prev consoles in console wheel */
|
// struct _CONSOLE *Prev, *Next; /* Next and Prev consoles in console wheel */
|
||||||
|
LIST_ENTRY Entry; /* Entry in the list of consoles */
|
||||||
LIST_ENTRY ProcessList; /* List of processes owning the console. The first one is the so-called "Console Leader Process" */
|
LIST_ENTRY ProcessList; /* List of processes owning the console. The first one is the so-called "Console Leader Process" */
|
||||||
|
|
||||||
FRONTEND_IFACE TermIFace; /* Frontend-specific interface */
|
FRONTEND_IFACE TermIFace; /* Frontend-specific interface */
|
||||||
|
@ -218,11 +233,6 @@ typedef struct _CONSOLE
|
||||||
#define PAUSED_FROM_SELECTION 0x4
|
#define PAUSED_FROM_SELECTION 0x4
|
||||||
|
|
||||||
/* console.c */
|
/* console.c */
|
||||||
VOID WINAPI ConSrvDeleteConsole(PCONSOLE Console);
|
|
||||||
VOID WINAPI ConSrvInitConsoleSupport(VOID);
|
|
||||||
NTSTATUS WINAPI ConSrvInitConsole(OUT PCONSOLE* NewConsole,
|
|
||||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
|
||||||
IN PCSR_PROCESS ConsoleLeaderProcess);
|
|
||||||
VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags);
|
VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags);
|
||||||
VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags);
|
VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags);
|
||||||
ULONG FASTCALL ConSrvConsoleProcessCtrlEvent(PCONSOLE Console,
|
ULONG FASTCALL ConSrvConsoleProcessCtrlEvent(PCONSOLE Console,
|
||||||
|
|
|
@ -1278,15 +1278,18 @@ CSR_API(SrvCreateConsoleScreenBuffer)
|
||||||
|
|
||||||
DPRINT("SrvCreateConsoleScreenBuffer\n");
|
DPRINT("SrvCreateConsoleScreenBuffer\n");
|
||||||
|
|
||||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
// RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
|
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
// RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
|
/*
|
||||||
if (Console->ActiveBuffer)
|
if (Console->ActiveBuffer)
|
||||||
{
|
{
|
||||||
ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize;
|
ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize;
|
||||||
|
@ -1299,6 +1302,23 @@ CSR_API(SrvCreateConsoleScreenBuffer)
|
||||||
IsCursorVisible = Console->ActiveBuffer->CursorInfo.bVisible;
|
IsCursorVisible = Console->ActiveBuffer->CursorInfo.bVisible;
|
||||||
CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
|
CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This is Windows' behaviour
|
||||||
|
{
|
||||||
|
ScreenBufferSize = Console->ConsoleSize; // Use the current console size
|
||||||
|
if (ScreenBufferSize.X == 0) ScreenBufferSize.X = 1;
|
||||||
|
if (ScreenBufferSize.Y == 0) ScreenBufferSize.Y = 1;
|
||||||
|
|
||||||
|
if (Console->ActiveBuffer)
|
||||||
|
{
|
||||||
|
ScreenAttrib = Console->ActiveBuffer->ScreenDefaultAttrib;
|
||||||
|
PopupAttrib = Console->ActiveBuffer->PopupDefaultAttrib;
|
||||||
|
|
||||||
|
IsCursorVisible = Console->ActiveBuffer->CursorInfo.bVisible;
|
||||||
|
CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Status = ConSrvCreateScreenBuffer(Console,
|
Status = ConSrvCreateScreenBuffer(Console,
|
||||||
&Buff,
|
&Buff,
|
||||||
|
@ -1309,6 +1329,7 @@ CSR_API(SrvCreateConsoleScreenBuffer)
|
||||||
CursorSize);
|
CursorSize);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* Insert the new handle inside the process handles table */
|
||||||
Status = ConSrvInsertObject(ProcessData,
|
Status = ConSrvInsertObject(ProcessData,
|
||||||
&CreateScreenBufferRequest->OutputHandle,
|
&CreateScreenBufferRequest->OutputHandle,
|
||||||
&Buff->Header,
|
&Buff->Header,
|
||||||
|
@ -1317,10 +1338,11 @@ CSR_API(SrvCreateConsoleScreenBuffer)
|
||||||
CreateScreenBufferRequest->ShareMode);
|
CreateScreenBufferRequest->ShareMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConSrvReleaseConsole(Console, TRUE);
|
// ConSrvReleaseConsole(Console, TRUE);
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
|
ConSrvReleaseConsole(Console, TRUE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,19 @@
|
||||||
#include "tuiconsole.h"
|
#include "tuiconsole.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "console.h"
|
||||||
|
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
LIST_ENTRY ConsoleList; /* The list of all the allocated consoles */
|
||||||
|
/*static*/ RTL_RESOURCE ListLock;
|
||||||
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
@ -44,11 +51,16 @@ ConSrvConsoleCtrlEventTimeout(DWORD Event,
|
||||||
DWORD Timeout)
|
DWORD Timeout)
|
||||||
{
|
{
|
||||||
ULONG Status = ERROR_SUCCESS;
|
ULONG Status = ERROR_SUCCESS;
|
||||||
HANDLE Thread;
|
|
||||||
|
|
||||||
DPRINT("ConSrvConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
|
DPRINT("ConSrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
|
||||||
|
|
||||||
if (ProcessData->CtrlDispatcher)
|
if (ProcessData->CtrlDispatcher)
|
||||||
|
{
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
HANDLE Thread = NULL;
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
||||||
ProcessData->CtrlDispatcher,
|
ProcessData->CtrlDispatcher,
|
||||||
|
@ -60,10 +72,22 @@ ConSrvConsoleCtrlEventTimeout(DWORD Event,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT("We succeeded at creating ProcessData->CtrlDispatcher remote thread, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
DPRINT("ProcessData->CtrlDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
||||||
WaitForSingleObject(Thread, Timeout);
|
WaitForSingleObject(Thread, Timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_FINALLY
|
||||||
|
{
|
||||||
CloseHandle(Thread);
|
CloseHandle(Thread);
|
||||||
}
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = RtlNtStatusToDosError(_SEH2_GetExceptionCode());
|
||||||
|
DPRINT1("ConSrvConsoleCtrlEventTimeout - Caught an exception, Status = %08X\n", Status);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -85,6 +109,10 @@ ConSrvConsoleProcessCtrlEvent(PCONSOLE Console,
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCONSOLE_PROCESS_DATA current;
|
PCONSOLE_PROCESS_DATA current;
|
||||||
|
|
||||||
|
/* If the console is already being destroyed, just return */
|
||||||
|
if (!ConSrvValidateConsole(Console, CONSOLE_RUNNING, FALSE))
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop through the process list, from the most recent process
|
* Loop through the process list, from the most recent process
|
||||||
* (the active one) to the oldest one (the first created, i.e.
|
* (the active one) to the oldest one (the first created, i.e.
|
||||||
|
@ -141,6 +169,18 @@ ConioUnpause(PCONSOLE Console, UINT Flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID WINAPI
|
||||||
|
ConSrvInitConsoleSupport(VOID)
|
||||||
|
{
|
||||||
|
DPRINT("CONSRV: ConSrvInitConsoleSupport()\n");
|
||||||
|
|
||||||
|
/* Initialize the console list and its lock */
|
||||||
|
InitializeListHead(&ConsoleList);
|
||||||
|
RtlInitializeResource(&ListLock);
|
||||||
|
|
||||||
|
/* Should call LoadKeyboardLayout */
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
LoadShellLinkConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
LoadShellLinkConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||||
IN OUT PCONSOLE_INFO ConsoleInfo,
|
IN OUT PCONSOLE_INFO ConsoleInfo,
|
||||||
|
@ -346,6 +386,7 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
|
||||||
/*
|
/*
|
||||||
* Initialize the console
|
* Initialize the console
|
||||||
*/
|
*/
|
||||||
|
Console->State = CONSOLE_INITIALIZING;
|
||||||
InitializeCriticalSection(&Console->Lock);
|
InitializeCriticalSection(&Console->Lock);
|
||||||
Console->ReferenceCount = 0;
|
Console->ReferenceCount = 0;
|
||||||
InitializeListHead(&Console->ProcessList);
|
InitializeListHead(&Console->ProcessList);
|
||||||
|
@ -428,6 +469,9 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
|
||||||
RtlCreateUnicodeString(&Console->Title, ConsoleInfo.ConsoleTitle);
|
RtlCreateUnicodeString(&Console->Title, ConsoleInfo.ConsoleTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lock the console until its initialization is finished */
|
||||||
|
// EnterCriticalSection(&Console->Lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are not in GUI-mode, start the text-mode terminal emulator.
|
* If we are not in GUI-mode, start the text-mode terminal emulator.
|
||||||
* If we fail, try to start the GUI-mode terminal emulator.
|
* If we fail, try to start the GUI-mode terminal emulator.
|
||||||
|
@ -480,45 +524,134 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
|
||||||
RtlFreeUnicodeString(&Console->OriginalTitle);
|
RtlFreeUnicodeString(&Console->OriginalTitle);
|
||||||
ConioDeleteScreenBuffer(NewBuffer);
|
ConioDeleteScreenBuffer(NewBuffer);
|
||||||
CloseHandle(Console->InputBuffer.ActiveEvent);
|
CloseHandle(Console->InputBuffer.ActiveEvent);
|
||||||
|
// LeaveCriticalSection(&Console->Lock);
|
||||||
DeleteCriticalSection(&Console->Lock);
|
DeleteCriticalSection(&Console->Lock);
|
||||||
RtlFreeHeap(ConSrvHeap, 0, Console);
|
RtlFreeHeap(ConSrvHeap, 0, Console);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT1("Terminal initialized\n");
|
||||||
|
|
||||||
|
/* All went right, so add the console to the list */
|
||||||
|
ConSrvLockConsoleListExclusive();
|
||||||
|
DPRINT1("Insert in the list\n");
|
||||||
|
InsertTailList(&ConsoleList, &Console->Entry);
|
||||||
|
|
||||||
|
/* The initialization is finished */
|
||||||
|
DPRINT1("Change state\n");
|
||||||
|
Console->State = CONSOLE_RUNNING;
|
||||||
|
|
||||||
|
/* Unlock the console */
|
||||||
|
// LeaveCriticalSection(&Console->Lock);
|
||||||
|
|
||||||
|
/* Unlock the console list */
|
||||||
|
ConSrvUnlockConsoleList();
|
||||||
|
|
||||||
/* Copy buffer contents to screen */
|
/* Copy buffer contents to screen */
|
||||||
ConioDrawConsole(Console);
|
ConioDrawConsole(Console);
|
||||||
|
DPRINT1("Console drawn\n");
|
||||||
|
|
||||||
/* Return the newly created console to the caller and a success code too */
|
/* Return the newly created console to the caller and a success code too */
|
||||||
*NewConsole = Console;
|
*NewConsole = Console;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID WINAPI
|
|
||||||
ConSrvInitConsoleSupport(VOID)
|
|
||||||
{
|
|
||||||
DPRINT("CONSRV: ConSrvInitConsoleSupport()\n");
|
|
||||||
|
|
||||||
/* Should call LoadKeyboardLayout */
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID WINAPI
|
VOID WINAPI
|
||||||
ConSrvDeleteConsole(PCONSOLE Console)
|
ConSrvDeleteConsole(PCONSOLE Console)
|
||||||
{
|
{
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
ConsoleInput* Event;
|
ConsoleInput* Event;
|
||||||
|
|
||||||
DPRINT("ConSrvDeleteConsole\n");
|
DPRINT1("ConSrvDeleteConsole\n");
|
||||||
|
|
||||||
/* Drain input event queue */
|
/*
|
||||||
while (Console->InputBuffer.InputEvents.Flink != &Console->InputBuffer.InputEvents)
|
* Forbid validation of any console by other threads
|
||||||
|
* during the deletion of this console.
|
||||||
|
*/
|
||||||
|
ConSrvLockConsoleListExclusive();
|
||||||
|
|
||||||
|
/* Check the existence of the console, and if it's ok, continue */
|
||||||
|
if (!ConSrvValidatePointer(Console))
|
||||||
{
|
{
|
||||||
Event = (ConsoleInput *) Console->InputBuffer.InputEvents.Flink;
|
/* Unlock the console list and return */
|
||||||
Console->InputBuffer.InputEvents.Flink = Console->InputBuffer.InputEvents.Flink->Flink;
|
ConSrvUnlockConsoleList();
|
||||||
Console->InputBuffer.InputEvents.Flink->Flink->Blink = &Console->InputBuffer.InputEvents;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the console is already being destroyed
|
||||||
|
* (thus not running), just return.
|
||||||
|
*/
|
||||||
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
|
||||||
|
{
|
||||||
|
/* Unlock the console list and return */
|
||||||
|
ConSrvUnlockConsoleList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are about to be destroyed. Signal it to other people
|
||||||
|
* so that they can terminate what they are doing, and that
|
||||||
|
* they cannot longer validate the console.
|
||||||
|
*/
|
||||||
|
Console->State = CONSOLE_TERMINATING;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allow other threads to finish their job: basically, unlock
|
||||||
|
* all other calls to EnterCriticalSection(&Console->Lock); by
|
||||||
|
* ConSrvValidateConsole(Unsafe) functions so that they just see
|
||||||
|
* that we are not in CONSOLE_RUNNING state anymore, or unlock
|
||||||
|
* other concurrent calls to ConSrvDeleteConsole so that they
|
||||||
|
* can see that we are in fact already deleting the console.
|
||||||
|
*/
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
|
ConSrvUnlockConsoleList();
|
||||||
|
|
||||||
|
/* FIXME: Send a terminate message to all the processes owning this console */
|
||||||
|
|
||||||
|
/* Cleanup the UI-oriented part */
|
||||||
|
ConioCleanupConsole(Console);
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Check that the console is in terminating state before continuing
|
||||||
|
* (the cleanup code must not change the state of the console...
|
||||||
|
* ...unless to cancel console deletion ?).
|
||||||
|
***/
|
||||||
|
|
||||||
|
ConSrvLockConsoleListExclusive();
|
||||||
|
|
||||||
|
/* Re-check the existence of the console, and if it's ok, continue */
|
||||||
|
if (!ConSrvValidatePointer(Console))
|
||||||
|
{
|
||||||
|
/* Unlock the console list and return */
|
||||||
|
ConSrvUnlockConsoleList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_TERMINATING, TRUE))
|
||||||
|
{
|
||||||
|
ConSrvUnlockConsoleList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We are in destruction */
|
||||||
|
Console->State = CONSOLE_IN_DESTRUCTION;
|
||||||
|
|
||||||
|
/* Remove the console from the list */
|
||||||
|
RemoveEntryList(&Console->Entry);
|
||||||
|
|
||||||
|
/* Reset the count to be sure */
|
||||||
|
Console->ReferenceCount = 0;
|
||||||
|
|
||||||
|
/* Discard all entries in the input event queue */
|
||||||
|
while (!IsListEmpty(&Console->InputBuffer.InputEvents))
|
||||||
|
{
|
||||||
|
CurrentEntry = RemoveHeadList(&Console->InputBuffer.InputEvents);
|
||||||
|
Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
||||||
RtlFreeHeap(ConSrvHeap, 0, Event);
|
RtlFreeHeap(ConSrvHeap, 0, Event);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConioCleanupConsole(Console);
|
|
||||||
if (Console->LineBuffer)
|
if (Console->LineBuffer)
|
||||||
RtlFreeHeap(ConSrvHeap, 0, Console->LineBuffer);
|
RtlFreeHeap(ConSrvHeap, 0, Console->LineBuffer);
|
||||||
while (!IsListEmpty(&Console->HistoryBuffers))
|
while (!IsListEmpty(&Console->HistoryBuffers))
|
||||||
|
@ -532,12 +665,22 @@ ConSrvDeleteConsole(PCONSOLE Console)
|
||||||
|
|
||||||
CloseHandle(Console->InputBuffer.ActiveEvent);
|
CloseHandle(Console->InputBuffer.ActiveEvent);
|
||||||
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
|
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
|
||||||
DeleteCriticalSection(&Console->Lock);
|
|
||||||
|
|
||||||
RtlFreeUnicodeString(&Console->OriginalTitle);
|
RtlFreeUnicodeString(&Console->OriginalTitle);
|
||||||
RtlFreeUnicodeString(&Console->Title);
|
RtlFreeUnicodeString(&Console->Title);
|
||||||
IntDeleteAllAliases(Console->Aliases);
|
IntDeleteAllAliases(Console->Aliases);
|
||||||
|
|
||||||
|
DPRINT1("ConSrvDeleteConsole - Unlocking\n");
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
|
DPRINT1("ConSrvDeleteConsole - Destroying lock\n");
|
||||||
|
DeleteCriticalSection(&Console->Lock);
|
||||||
|
DPRINT1("ConSrvDeleteConsole - Lock destroyed ; freeing console\n");
|
||||||
|
|
||||||
RtlFreeHeap(ConSrvHeap, 0, Console);
|
RtlFreeHeap(ConSrvHeap, 0, Console);
|
||||||
|
DPRINT1("ConSrvDeleteConsole - Console freed\n");
|
||||||
|
|
||||||
|
/* Unlock the console list and return */
|
||||||
|
ConSrvUnlockConsoleList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -545,24 +688,29 @@ ConSrvDeleteConsole(PCONSOLE Console)
|
||||||
|
|
||||||
CSR_API(SrvOpenConsole)
|
CSR_API(SrvOpenConsole)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status;
|
||||||
PCONSOLE_OPENCONSOLE OpenConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.OpenConsoleRequest;
|
PCONSOLE_OPENCONSOLE OpenConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.OpenConsoleRequest;
|
||||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
|
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
|
||||||
|
PCONSOLE Console;
|
||||||
|
|
||||||
|
DWORD DesiredAccess = OpenConsoleRequest->Access;
|
||||||
|
DWORD ShareMode = OpenConsoleRequest->ShareMode;
|
||||||
|
Object_t *Object;
|
||||||
|
|
||||||
OpenConsoleRequest->ConsoleHandle = INVALID_HANDLE_VALUE;
|
OpenConsoleRequest->ConsoleHandle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Can't get console\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
if (ProcessData->Console)
|
/*
|
||||||
{
|
* Open a handle to either the active screen buffer or the input buffer.
|
||||||
DWORD DesiredAccess = OpenConsoleRequest->Access;
|
*/
|
||||||
DWORD ShareMode = OpenConsoleRequest->ShareMode;
|
|
||||||
|
|
||||||
PCONSOLE Console = ProcessData->Console;
|
|
||||||
Object_t *Object;
|
|
||||||
|
|
||||||
EnterCriticalSection(&Console->Lock);
|
|
||||||
|
|
||||||
if (OpenConsoleRequest->HandleType == HANDLE_OUTPUT)
|
if (OpenConsoleRequest->HandleType == HANDLE_OUTPUT)
|
||||||
{
|
{
|
||||||
Object = &Console->ActiveBuffer->Header;
|
Object = &Console->ActiveBuffer->Header;
|
||||||
|
@ -590,11 +738,9 @@ CSR_API(SrvOpenConsole)
|
||||||
ShareMode);
|
ShareMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&Console->Lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
|
ConSrvReleaseConsole(Console, TRUE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,7 +904,6 @@ Quit:
|
||||||
|
|
||||||
CSR_API(SrvFreeConsole)
|
CSR_API(SrvFreeConsole)
|
||||||
{
|
{
|
||||||
DPRINT1("SrvFreeConsole\n");
|
|
||||||
ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
|
ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -798,7 +943,6 @@ CSR_API(SrvSetConsoleMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
ConSrvReleaseObject(Object, TRUE);
|
ConSrvReleaseObject(Object, TRUE);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,7 +975,6 @@ CSR_API(SrvGetConsoleMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
ConSrvReleaseObject(Object, TRUE);
|
ConSrvReleaseObject(Object, TRUE);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
52
win32ss/user/consrv/console.h
Normal file
52
win32ss/user/consrv/console.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Console Server DLL
|
||||||
|
* FILE: win32ss/user/consrv/console.h
|
||||||
|
* PURPOSE: Consoles Management
|
||||||
|
* PROGRAMMERS: Hermes Belusca-Maito
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ConSrvLockConsoleListExclusive() \
|
||||||
|
RtlAcquireResourceExclusive(&ListLock, TRUE)
|
||||||
|
|
||||||
|
#define ConSrvLockConsoleListShared() \
|
||||||
|
RtlAcquireResourceShared(&ListLock, TRUE)
|
||||||
|
|
||||||
|
#define ConSrvUnlockConsoleList() \
|
||||||
|
RtlReleaseResource(&ListLock)
|
||||||
|
|
||||||
|
extern LIST_ENTRY ConsoleList;
|
||||||
|
extern RTL_RESOURCE ListLock;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
* WARNING: Change the state of the console ONLY when the console is locked !
|
||||||
|
*/
|
||||||
|
typedef enum _CONSOLE_STATE
|
||||||
|
{
|
||||||
|
CONSOLE_INITIALIZING, /* Console is initializing */
|
||||||
|
CONSOLE_RUNNING , /* Console running */
|
||||||
|
CONSOLE_TERMINATING , /* Console about to be destroyed (but still not) */
|
||||||
|
CONSOLE_IN_DESTRUCTION /* Console in destruction */
|
||||||
|
} CONSOLE_STATE, *PCONSOLE_STATE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
VOID WINAPI ConSrvInitConsoleSupport(VOID);
|
||||||
|
NTSTATUS WINAPI ConSrvInitConsole(OUT PCONSOLE* NewConsole,
|
||||||
|
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||||
|
IN PCSR_PROCESS ConsoleLeaderProcess);
|
||||||
|
VOID WINAPI ConSrvDeleteConsole(PCONSOLE Console);
|
||||||
|
BOOL FASTCALL ConSrvValidatePointer(PCONSOLE Console);
|
||||||
|
BOOL FASTCALL ConSrvValidateConsoleState(PCONSOLE Console,
|
||||||
|
CONSOLE_STATE ExpectedState);
|
||||||
|
BOOL FASTCALL ConSrvValidateConsoleUnsafe(PCONSOLE Console,
|
||||||
|
CONSOLE_STATE ExpectedState,
|
||||||
|
BOOL LockConsole);
|
||||||
|
BOOL FASTCALL ConSrvValidateConsole(PCONSOLE Console,
|
||||||
|
CONSOLE_STATE ExpectedState,
|
||||||
|
BOOL LockConsole);
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -34,6 +34,9 @@
|
||||||
/* Public Win32K Headers */
|
/* Public Win32K Headers */
|
||||||
#include <ntuser.h>
|
#include <ntuser.h>
|
||||||
|
|
||||||
|
/* PSEH for SEH Support */
|
||||||
|
#include <pseh/pseh2.h>
|
||||||
|
|
||||||
/* CSRSS Header */
|
/* CSRSS Header */
|
||||||
#include <csr/csrsrv.h>
|
#include <csr/csrsrv.h>
|
||||||
|
|
||||||
|
@ -93,6 +96,20 @@ typedef struct _CONSOLE_PROCESS_DATA
|
||||||
} CONSOLE_PROCESS_DATA, *PCONSOLE_PROCESS_DATA;
|
} CONSOLE_PROCESS_DATA, *PCONSOLE_PROCESS_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
#if 1 // Temporarily put there.
|
||||||
|
/*
|
||||||
|
* WARNING: Change the state of the console ONLY when the console is locked !
|
||||||
|
*/
|
||||||
|
typedef enum _CONSOLE_STATE
|
||||||
|
{
|
||||||
|
CONSOLE_INITIALIZING, /* Console is initializing */
|
||||||
|
CONSOLE_RUNNING , /* Console running */
|
||||||
|
CONSOLE_TERMINATING , /* Console about to be destroyed (but still not) */
|
||||||
|
CONSOLE_IN_DESTRUCTION /* Console in destruction */
|
||||||
|
} CONSOLE_STATE, *PCONSOLE_STATE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* alias.c */
|
/* alias.c */
|
||||||
CSR_API(SrvAddConsoleAlias);
|
CSR_API(SrvAddConsoleAlias);
|
||||||
CSR_API(SrvGetConsoleAlias);
|
CSR_API(SrvGetConsoleAlias);
|
||||||
|
@ -177,12 +194,12 @@ NTSTATUS FASTCALL ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
PHANDLE pInputHandle,
|
PHANDLE pInputHandle,
|
||||||
PHANDLE pOutputHandle,
|
PHANDLE pOutputHandle,
|
||||||
PHANDLE pErrorHandle);
|
PHANDLE pErrorHandle);
|
||||||
VOID FASTCALL ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData);
|
|
||||||
NTSTATUS FASTCALL ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
NTSTATUS FASTCALL ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
struct _CONSOLE** Console,
|
struct _CONSOLE** Console,
|
||||||
BOOL LockConsole);
|
BOOL LockConsole);
|
||||||
VOID FASTCALL ConSrvReleaseConsole(struct _CONSOLE* Console,
|
VOID FASTCALL ConSrvReleaseConsole(struct _CONSOLE* Console,
|
||||||
BOOL IsConsoleLocked);
|
BOOL WasConsoleLocked);
|
||||||
|
VOID FASTCALL ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData);
|
||||||
|
|
||||||
NTSTATUS NTAPI ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
NTSTATUS NTAPI ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
||||||
PCSR_PROCESS TargetProcess);
|
PCSR_PROCESS TargetProcess);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "consrv.h"
|
#include "consrv.h"
|
||||||
#include "conio.h"
|
#include "conio.h"
|
||||||
|
#include "console.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "guiconsole.h"
|
#include "guiconsole.h"
|
||||||
#include "guisettings.h"
|
#include "guisettings.h"
|
||||||
|
@ -212,6 +213,13 @@ static LRESULT
|
||||||
GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
|
GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LRESULT Ret = TRUE;
|
LRESULT Ret = TRUE;
|
||||||
|
PCONSOLE Console = GuiData->Console;
|
||||||
|
|
||||||
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
|
||||||
|
{
|
||||||
|
Ret = FALSE;
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
switch (wParam)
|
switch (wParam)
|
||||||
{
|
{
|
||||||
|
@ -229,7 +237,6 @@ GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM
|
||||||
|
|
||||||
case ID_SYSTEM_EDIT_SELECTALL:
|
case ID_SYSTEM_EDIT_SELECTALL:
|
||||||
{
|
{
|
||||||
PCONSOLE Console = GuiData->Console;
|
|
||||||
COORD bottomRight = { 0, 0 };
|
COORD bottomRight = { 0, 0 };
|
||||||
|
|
||||||
bottomRight.X = Console->ConsoleSize.X - 1;
|
bottomRight.X = Console->ConsoleSize.X - 1;
|
||||||
|
@ -255,15 +262,23 @@ GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Ret = DefWindowProcW(GuiData->hWindow, WM_SYSCOMMAND, wParam, lParam);
|
Ret = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
if (!Ret)
|
||||||
|
Ret = DefWindowProcW(GuiData->hWindow, WM_SYSCOMMAND, wParam, lParam);
|
||||||
|
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PGUI_CONSOLE_DATA
|
static PGUI_CONSOLE_DATA
|
||||||
GuiGetGuiData(HWND hWnd)
|
GuiGetGuiData(HWND hWnd)
|
||||||
{
|
{
|
||||||
|
/* This function ensures that the console pointer is not NULL */
|
||||||
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
|
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
|
||||||
return ( ((GuiData == NULL) || (GuiData->hWindow == hWnd && GuiData->Console != NULL)) ? GuiData : NULL );
|
return ( ((GuiData == NULL) || (GuiData->hWindow == hWnd && GuiData->Console != NULL)) ? GuiData : NULL );
|
||||||
}
|
}
|
||||||
|
@ -342,6 +357,8 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create)
|
||||||
TEXTMETRICW Metrics;
|
TEXTMETRICW Metrics;
|
||||||
SIZE CharSize;
|
SIZE CharSize;
|
||||||
|
|
||||||
|
DPRINT1("GuiConsoleHandleNcCreate\n");
|
||||||
|
|
||||||
if (NULL == GuiData)
|
if (NULL == GuiData)
|
||||||
{
|
{
|
||||||
DPRINT1("GuiConsoleNcCreate: No GUI data\n");
|
DPRINT1("GuiConsoleNcCreate: No GUI data\n");
|
||||||
|
@ -424,12 +441,7 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create)
|
||||||
SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
|
SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
|
||||||
GuiConsoleCreateSysMenu(GuiData->hWindow);
|
GuiConsoleCreateSysMenu(GuiData->hWindow);
|
||||||
|
|
||||||
/* Move and resize the window to the user's values */
|
DPRINT1("GuiConsoleHandleNcCreate - setting start event\n");
|
||||||
GuiConsoleMoveWindow(GuiData);
|
|
||||||
GuiData->WindowSizeLock = TRUE;
|
|
||||||
GuiConsoleResizeWindow(GuiData);
|
|
||||||
GuiData->WindowSizeLock = FALSE;
|
|
||||||
|
|
||||||
SetEvent(GuiData->hGuiInitEvent);
|
SetEvent(GuiData->hGuiInitEvent);
|
||||||
|
|
||||||
return (BOOL)DefWindowProcW(GuiData->hWindow, WM_NCCREATE, 0, (LPARAM)Create);
|
return (BOOL)DefWindowProcW(GuiData->hWindow, WM_NCCREATE, 0, (LPARAM)Create);
|
||||||
|
@ -526,8 +538,6 @@ GuiConsolePaint(PCONSOLE Console,
|
||||||
|
|
||||||
Buff = Console->ActiveBuffer;
|
Buff = Console->ActiveBuffer;
|
||||||
|
|
||||||
/// LOCK /// EnterCriticalSection(&Buff->Header.Console->Lock);
|
|
||||||
|
|
||||||
TopLine = rc->top / GuiData->CharHeight + Buff->ShowY;
|
TopLine = rc->top / GuiData->CharHeight + Buff->ShowY;
|
||||||
BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buff->ShowY;
|
BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buff->ShowY;
|
||||||
LeftChar = rc->left / GuiData->CharWidth + Buff->ShowX;
|
LeftChar = rc->left / GuiData->CharWidth + Buff->ShowX;
|
||||||
|
@ -618,26 +628,33 @@ GuiConsolePaint(PCONSOLE Console,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LOCK /// LeaveCriticalSection(&Buff->Header.Console->Lock);
|
|
||||||
|
|
||||||
SelectObject(hDC, OldFont);
|
SelectObject(hDC, OldFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData, HDC hDCPaint)
|
GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData)
|
||||||
{
|
{
|
||||||
|
BOOL Success = TRUE;
|
||||||
PCONSOLE Console = GuiData->Console;
|
PCONSOLE Console = GuiData->Console;
|
||||||
HDC hDC;
|
HDC hDC;
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
|
|
||||||
if (Console->ActiveBuffer == NULL) return;
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
|
||||||
|
{
|
||||||
|
Success = FALSE;
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Console->ActiveBuffer == NULL ||
|
||||||
|
Console->ActiveBuffer->Buffer == NULL)
|
||||||
|
{
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
hDC = BeginPaint(GuiData->hWindow, &ps);
|
hDC = BeginPaint(GuiData->hWindow, &ps);
|
||||||
if (hDC != NULL &&
|
if (hDC != NULL &&
|
||||||
ps.rcPaint.left < ps.rcPaint.right &&
|
ps.rcPaint.left < ps.rcPaint.right &&
|
||||||
ps.rcPaint.top < ps.rcPaint.bottom)
|
ps.rcPaint.top < ps.rcPaint.bottom)
|
||||||
{
|
|
||||||
if (Console->ActiveBuffer->Buffer != NULL)
|
|
||||||
{
|
{
|
||||||
EnterCriticalSection(&GuiData->Lock);
|
EnterCriticalSection(&GuiData->Lock);
|
||||||
|
|
||||||
|
@ -667,8 +684,15 @@ GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData, HDC hDCPaint)
|
||||||
|
|
||||||
LeaveCriticalSection(&GuiData->Lock);
|
LeaveCriticalSection(&GuiData->Lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
EndPaint(GuiData->hWindow, &ps);
|
EndPaint(GuiData->hWindow, &ps);
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
if (Success)
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
|
else
|
||||||
|
DefWindowProcW(GuiData->hWindow, WM_PAINT, 0, 0);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
|
@ -677,6 +701,8 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l
|
||||||
PCONSOLE Console = GuiData->Console;
|
PCONSOLE Console = GuiData->Console;
|
||||||
MSG Message;
|
MSG Message;
|
||||||
|
|
||||||
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
|
||||||
|
|
||||||
Message.hwnd = GuiData->hWindow;
|
Message.hwnd = GuiData->hWindow;
|
||||||
Message.message = msg;
|
Message.message = msg;
|
||||||
Message.wParam = wParam;
|
Message.wParam = wParam;
|
||||||
|
@ -689,6 +715,8 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l
|
||||||
}
|
}
|
||||||
|
|
||||||
ConioProcessKey(Console, &Message);
|
ConioProcessKey(Console, &Message);
|
||||||
|
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
|
@ -706,6 +734,8 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
||||||
|
|
||||||
SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL);
|
SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL);
|
||||||
|
|
||||||
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
|
||||||
|
|
||||||
Buff = Console->ActiveBuffer;
|
Buff = Console->ActiveBuffer;
|
||||||
GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||||
Buff->CursorBlinkOn = !Buff->CursorBlinkOn;
|
Buff->CursorBlinkOn = !Buff->CursorBlinkOn;
|
||||||
|
@ -782,14 +812,15 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData)
|
||||||
GuiData->OldCursor.y = Buff->CursorPosition.Y;
|
GuiData->OldCursor.y = Buff->CursorPosition.Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
GuiConsoleHandleClose(PGUI_CONSOLE_DATA GuiData)
|
GuiConsoleHandleClose(PGUI_CONSOLE_DATA GuiData)
|
||||||
{
|
{
|
||||||
PCONSOLE Console = GuiData->Console;
|
PCONSOLE Console = GuiData->Console;
|
||||||
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
|
||||||
/// LOCK /// EnterCriticalSection(&Console->Lock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: Windows will wait up to 5 seconds for the thread to exit.
|
* FIXME: Windows will wait up to 5 seconds for the thread to exit.
|
||||||
|
@ -798,17 +829,23 @@ GuiConsoleHandleClose(PGUI_CONSOLE_DATA GuiData)
|
||||||
*/
|
*/
|
||||||
ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT);
|
ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT);
|
||||||
|
|
||||||
/// LOCK /// LeaveCriticalSection(&Console->Lock);
|
LeaveCriticalSection(&Console->Lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static LRESULT
|
||||||
GuiConsoleHandleNcDestroy(PGUI_CONSOLE_DATA GuiData)
|
GuiConsoleHandleNcDestroy(HWND hWnd)
|
||||||
{
|
{
|
||||||
KillTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER);
|
// PGUI_CONSOLE_DATA GuiData;
|
||||||
GetSystemMenu(GuiData->hWindow, TRUE);
|
|
||||||
|
|
||||||
SetWindowLongPtrW(GuiData->hWindow, GWLP_USERDATA, (DWORD_PTR)NULL);
|
KillTimer(hWnd, CONGUI_UPDATE_TIMER);
|
||||||
GuiData->hWindow = NULL;
|
GetSystemMenu(hWnd, TRUE);
|
||||||
|
|
||||||
|
/* Free the GuiData registration */
|
||||||
|
SetWindowLongPtrW(hWnd, GWLP_USERDATA, (DWORD_PTR)NULL);
|
||||||
|
// GuiData->hWindow = NULL;
|
||||||
|
|
||||||
|
// return 0;
|
||||||
|
return DefWindowProcW(hWnd, WM_NCDESTROY, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static COORD
|
static COORD
|
||||||
|
@ -835,43 +872,85 @@ PointToCoord(PGUI_CONSOLE_DATA GuiData, LPARAM lParam)
|
||||||
return Coord;
|
return Coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static LRESULT
|
||||||
GuiConsoleLeftMouseDown(PGUI_CONSOLE_DATA GuiData, LPARAM lParam)
|
GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
LRESULT Ret = TRUE;
|
||||||
PCONSOLE Console = GuiData->Console;
|
PCONSOLE Console = GuiData->Console;
|
||||||
|
|
||||||
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
|
||||||
|
{
|
||||||
|
Ret = FALSE;
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
{
|
||||||
Console->Selection.dwSelectionAnchor = PointToCoord(GuiData, lParam);
|
Console->Selection.dwSelectionAnchor = PointToCoord(GuiData, lParam);
|
||||||
SetCapture(GuiData->hWindow);
|
SetCapture(GuiData->hWindow);
|
||||||
Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
|
Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
|
||||||
GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor);
|
GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
case WM_LBUTTONUP:
|
||||||
GuiConsoleLeftMouseUp(PGUI_CONSOLE_DATA GuiData, LPARAM lParam)
|
|
||||||
{
|
{
|
||||||
PCONSOLE Console = GuiData->Console;
|
|
||||||
COORD c;
|
COORD c;
|
||||||
|
|
||||||
if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return;
|
if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) break;
|
||||||
|
|
||||||
c = PointToCoord(GuiData, lParam);
|
c = PointToCoord(GuiData, lParam);
|
||||||
Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN;
|
Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN;
|
||||||
GuiConsoleUpdateSelection(Console, &c);
|
GuiConsoleUpdateSelection(Console, &c);
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
case WM_RBUTTONDOWN:
|
||||||
GuiConsoleMouseMove(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
|
{
|
||||||
|
if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY))
|
||||||
|
{
|
||||||
|
GuiConsolePaste(GuiData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GuiConsoleCopy(GuiData);
|
||||||
|
|
||||||
|
/* Clear the selection */
|
||||||
|
GuiConsoleUpdateSelection(Console, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
{
|
{
|
||||||
PCONSOLE Console = GuiData->Console;
|
|
||||||
COORD c;
|
COORD c;
|
||||||
|
|
||||||
if (!(wParam & MK_LBUTTON)) return;
|
if (!(wParam & MK_LBUTTON)) break;
|
||||||
|
if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) break;
|
||||||
if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return;
|
|
||||||
|
|
||||||
c = PointToCoord(GuiData, lParam); /* TODO: Scroll buffer to bring c into view */
|
c = PointToCoord(GuiData, lParam); /* TODO: Scroll buffer to bring c into view */
|
||||||
GuiConsoleUpdateSelection(Console, &c);
|
GuiConsoleUpdateSelection(Console, &c);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
Ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
if (!Ret)
|
||||||
|
Ret = DefWindowProcW(GuiData->hWindow, msg, wParam, lParam);
|
||||||
|
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
|
@ -982,30 +1061,14 @@ GuiConsolePaste(PGUI_CONSOLE_DATA GuiData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
|
||||||
GuiConsoleRightMouseDown(PGUI_CONSOLE_DATA GuiData)
|
|
||||||
{
|
|
||||||
PCONSOLE Console = GuiData->Console;
|
|
||||||
|
|
||||||
if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY))
|
|
||||||
{
|
|
||||||
GuiConsolePaste(GuiData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GuiConsoleCopy(GuiData);
|
|
||||||
|
|
||||||
/* Clear the selection */
|
|
||||||
GuiConsoleUpdateSelection(Console, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
GuiConsoleGetMinMaxInfo(PGUI_CONSOLE_DATA GuiData, PMINMAXINFO minMaxInfo)
|
GuiConsoleGetMinMaxInfo(PGUI_CONSOLE_DATA GuiData, PMINMAXINFO minMaxInfo)
|
||||||
{
|
{
|
||||||
PCONSOLE Console = GuiData->Console;
|
PCONSOLE Console = GuiData->Console;
|
||||||
DWORD windx, windy;
|
DWORD windx, windy;
|
||||||
|
|
||||||
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
|
||||||
|
|
||||||
windx = CONGUI_MIN_WIDTH * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
|
windx = CONGUI_MIN_WIDTH * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
|
||||||
windy = CONGUI_MIN_HEIGHT * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION);
|
windy = CONGUI_MIN_HEIGHT * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION);
|
||||||
|
|
||||||
|
@ -1020,6 +1083,8 @@ GuiConsoleGetMinMaxInfo(PGUI_CONSOLE_DATA GuiData, PMINMAXINFO minMaxInfo)
|
||||||
|
|
||||||
minMaxInfo->ptMaxTrackSize.x = windx;
|
minMaxInfo->ptMaxTrackSize.x = windx;
|
||||||
minMaxInfo->ptMaxTrackSize.y = windy;
|
minMaxInfo->ptMaxTrackSize.y = windy;
|
||||||
|
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
|
@ -1027,6 +1092,8 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
PCONSOLE Console = GuiData->Console;
|
PCONSOLE Console = GuiData->Console;
|
||||||
|
|
||||||
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
|
||||||
|
|
||||||
if ((GuiData->WindowSizeLock == FALSE) &&
|
if ((GuiData->WindowSizeLock == FALSE) &&
|
||||||
(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED))
|
(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED))
|
||||||
{
|
{
|
||||||
|
@ -1076,6 +1143,8 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
GuiData->WindowSizeLock = FALSE;
|
GuiData->WindowSizeLock = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1107,8 +1176,7 @@ GuiConsoleHandleScrollbarMenu(VOID)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static
|
static LRESULT
|
||||||
LRESULT
|
|
||||||
GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam)
|
GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam)
|
||||||
{
|
{
|
||||||
PCONSOLE Console = GuiData->Console;
|
PCONSOLE Console = GuiData->Console;
|
||||||
|
@ -1118,7 +1186,7 @@ GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam)
|
||||||
int old_pos, Maximum;
|
int old_pos, Maximum;
|
||||||
PUSHORT pShowXY;
|
PUSHORT pShowXY;
|
||||||
|
|
||||||
if (GuiData == NULL) return FALSE;
|
if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return 0;
|
||||||
|
|
||||||
Buff = Console->ActiveBuffer;
|
Buff = Console->ActiveBuffer;
|
||||||
|
|
||||||
|
@ -1139,10 +1207,7 @@ GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam)
|
||||||
sInfo.cbSize = sizeof(SCROLLINFO);
|
sInfo.cbSize = sizeof(SCROLLINFO);
|
||||||
sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS;
|
sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS;
|
||||||
|
|
||||||
if (!GetScrollInfo(GuiData->hWindow, fnBar, &sInfo))
|
if (!GetScrollInfo(GuiData->hWindow, fnBar, &sInfo)) goto Quit;
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
old_pos = sInfo.nPos;
|
old_pos = sInfo.nPos;
|
||||||
|
|
||||||
|
@ -1209,6 +1274,8 @@ GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam)
|
||||||
UpdateWindow(GuiData->hWindow);
|
UpdateWindow(GuiData->hWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1217,15 +1284,22 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LRESULT Result = 0;
|
LRESULT Result = 0;
|
||||||
PGUI_CONSOLE_DATA GuiData = NULL;
|
PGUI_CONSOLE_DATA GuiData = NULL;
|
||||||
|
PCONSOLE Console = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If it's the first time we create a window
|
* - If it's the first time we create a window for the terminal,
|
||||||
* for the terminal, just initialize it.
|
* just initialize it and return.
|
||||||
|
*
|
||||||
|
* - If we are destroying the window, just do it and return.
|
||||||
*/
|
*/
|
||||||
if (msg == WM_NCCREATE)
|
if (msg == WM_NCCREATE)
|
||||||
{
|
{
|
||||||
return (LRESULT)GuiConsoleHandleNcCreate(hWnd, (LPCREATESTRUCTW)lParam);
|
return (LRESULT)GuiConsoleHandleNcCreate(hWnd, (LPCREATESTRUCTW)lParam);
|
||||||
}
|
}
|
||||||
|
else if (msg == WM_NCDESTROY)
|
||||||
|
{
|
||||||
|
return GuiConsoleHandleNcDestroy(hWnd);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now the terminal window is initialized.
|
* Now the terminal window is initialized.
|
||||||
|
@ -1235,24 +1309,20 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
GuiData = GuiGetGuiData(hWnd);
|
GuiData = GuiGetGuiData(hWnd);
|
||||||
if (GuiData == NULL) return 0;
|
if (GuiData == NULL) return 0;
|
||||||
|
|
||||||
// TODO: If the console is about to be destroyed, leave the loop.
|
/*
|
||||||
|
* Each helper function which needs the console
|
||||||
|
* has to validate and lock it.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Lock the console */
|
/* We have a console, start message dispatching */
|
||||||
EnterCriticalSection(&GuiData->Console->Lock);
|
|
||||||
|
|
||||||
/* We have a console, start message dispatching. */
|
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
GuiConsoleHandleClose(GuiData);
|
GuiConsoleHandleClose(GuiData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_NCDESTROY:
|
|
||||||
GuiConsoleHandleNcDestroy(GuiData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
GuiConsoleHandlePaint(GuiData, (HDC)wParam);
|
GuiConsoleHandlePaint(GuiData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
|
@ -1260,37 +1330,43 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_SYSKEYDOWN:
|
case WM_SYSKEYDOWN:
|
||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
|
{
|
||||||
GuiConsoleHandleKey(GuiData, msg, wParam, lParam);
|
GuiConsoleHandleKey(GuiData, msg, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_TIMER:
|
case WM_TIMER:
|
||||||
GuiConsoleHandleTimer(GuiData);
|
GuiConsoleHandleTimer(GuiData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_LBUTTONDOWN:
|
|
||||||
GuiConsoleLeftMouseDown(GuiData, lParam);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_LBUTTONUP:
|
|
||||||
GuiConsoleLeftMouseUp(GuiData, lParam);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_RBUTTONDOWN:
|
|
||||||
GuiConsoleRightMouseDown(GuiData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
GuiConsoleMouseMove(GuiData, wParam, lParam);
|
case WM_LBUTTONDOWN:
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
case WM_LBUTTONDBLCLK:
|
||||||
|
case WM_RBUTTONDOWN:
|
||||||
|
case WM_RBUTTONUP:
|
||||||
|
case WM_RBUTTONDBLCLK:
|
||||||
|
case WM_MBUTTONDOWN:
|
||||||
|
case WM_MBUTTONUP:
|
||||||
|
case WM_MBUTTONDBLCLK:
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
{
|
||||||
|
Result = GuiConsoleHandleMouse(GuiData, msg, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_SYSCOMMAND:
|
case WM_SYSCOMMAND:
|
||||||
|
{
|
||||||
Result = GuiConsoleHandleSysMenuCommand(GuiData, wParam, lParam);
|
Result = GuiConsoleHandleSysMenuCommand(GuiData, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_HSCROLL:
|
case WM_HSCROLL:
|
||||||
case WM_VSCROLL:
|
case WM_VSCROLL:
|
||||||
|
{
|
||||||
Result = GuiConsoleHandleScroll(GuiData, msg, wParam);
|
Result = GuiConsoleHandleScroll(GuiData, msg, wParam);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_GETMINMAXINFO:
|
case WM_GETMINMAXINFO:
|
||||||
GuiConsoleGetMinMaxInfo(GuiData, (PMINMAXINFO)lParam);
|
GuiConsoleGetMinMaxInfo(GuiData, (PMINMAXINFO)lParam);
|
||||||
|
@ -1301,26 +1377,30 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PM_APPLY_CONSOLE_INFO:
|
case PM_APPLY_CONSOLE_INFO:
|
||||||
|
{
|
||||||
|
Console = GuiData->Console; // Not NULL because checked in GuiGetGuiData.
|
||||||
|
if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
|
||||||
|
{
|
||||||
GuiApplyUserSettings(GuiData, (HANDLE)wParam, (BOOL)lParam);
|
GuiApplyUserSettings(GuiData, (HANDLE)wParam, (BOOL)lParam);
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case PM_CONSOLE_BEEP:
|
case PM_CONSOLE_BEEP:
|
||||||
DPRINT1("Beep !!\n");
|
DPRINT1("Beep !!\n");
|
||||||
Beep(800, 200);
|
Beep(800, 200);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PM_CONSOLE_SET_TITLE:
|
// case PM_CONSOLE_SET_TITLE:
|
||||||
SetWindowText(GuiData->hWindow, GuiData->Console->Title.Buffer);
|
// SetWindowText(GuiData->hWindow, GuiData->Console->Title.Buffer);
|
||||||
break;
|
// break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Result = DefWindowProcW(GuiData->hWindow, msg, wParam, lParam);
|
Result = DefWindowProcW(hWnd, msg, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock the console */
|
|
||||||
LeaveCriticalSection(&GuiData->Console->Lock);
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1336,8 +1416,6 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
HWND NewWindow;
|
HWND NewWindow;
|
||||||
LONG WindowCount;
|
LONG WindowCount;
|
||||||
MSG Msg;
|
MSG Msg;
|
||||||
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
|
|
||||||
PCONSOLE Console = GuiData->Console;
|
|
||||||
|
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
|
@ -1349,6 +1427,9 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
case PM_CREATE_CONSOLE:
|
case PM_CREATE_CONSOLE:
|
||||||
{
|
{
|
||||||
|
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
|
||||||
|
PCONSOLE Console = GuiData->Console;
|
||||||
|
|
||||||
NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
|
NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
|
||||||
GUI_CONSOLE_WINDOW_CLASS,
|
GUI_CONSOLE_WINDOW_CLASS,
|
||||||
Console->Title.Buffer,
|
Console->Title.Buffer,
|
||||||
|
@ -1381,7 +1462,16 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
SendMessageW(GuiData->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)GuiData->hIconSm);
|
SendMessageW(GuiData->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)GuiData->hIconSm);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowWindow(NewWindow, (int)wParam);
|
/* Move and resize the window to the user's values */
|
||||||
|
/* CAN WE DEADLOCK ?? */
|
||||||
|
GuiConsoleMoveWindow(GuiData);
|
||||||
|
GuiData->WindowSizeLock = TRUE;
|
||||||
|
GuiConsoleResizeWindow(GuiData);
|
||||||
|
GuiData->WindowSizeLock = FALSE;
|
||||||
|
|
||||||
|
// ShowWindow(NewWindow, (int)wParam);
|
||||||
|
ShowWindowAsync(NewWindow, (int)wParam);
|
||||||
|
DPRINT1("Window showed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (LRESULT)NewWindow;
|
return (LRESULT)NewWindow;
|
||||||
|
@ -1389,16 +1479,20 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
case PM_DESTROY_CONSOLE:
|
case PM_DESTROY_CONSOLE:
|
||||||
{
|
{
|
||||||
|
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Window creation is done using a PostMessage(), so it's possible
|
* Window creation is done using a PostMessage(), so it's possible
|
||||||
* that the window that we want to destroy doesn't exist yet.
|
* that the window that we want to destroy doesn't exist yet.
|
||||||
* So first empty the message queue.
|
* So first empty the message queue.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
|
while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
|
||||||
{
|
{
|
||||||
TranslateMessage(&Msg);
|
TranslateMessage(&Msg);
|
||||||
DispatchMessageW(&Msg);
|
DispatchMessageW(&Msg);
|
||||||
}
|
}*/
|
||||||
|
while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE)) ;
|
||||||
|
|
||||||
if (GuiData->hWindow != NULL) /* && DestroyWindow(GuiData->hWindow) */
|
if (GuiData->hWindow != NULL) /* && DestroyWindow(GuiData->hWindow) */
|
||||||
{
|
{
|
||||||
|
@ -1607,6 +1701,8 @@ GuiCleanupConsole(PCONSOLE Console)
|
||||||
Console->TermIFace.Data = NULL;
|
Console->TermIFace.Data = NULL;
|
||||||
DeleteCriticalSection(&GuiData->Lock);
|
DeleteCriticalSection(&GuiData->Lock);
|
||||||
RtlFreeHeap(ConSrvHeap, 0, GuiData);
|
RtlFreeHeap(ConSrvHeap, 0, GuiData);
|
||||||
|
|
||||||
|
DPRINT1("Quit GuiCleanupConsole\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI
|
static VOID WINAPI
|
||||||
|
@ -1835,7 +1931,8 @@ static VOID WINAPI
|
||||||
GuiChangeTitle(PCONSOLE Console)
|
GuiChangeTitle(PCONSOLE Console)
|
||||||
{
|
{
|
||||||
PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data;
|
PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data;
|
||||||
PostMessageW(GuiData->hWindow, PM_CONSOLE_SET_TITLE, 0, 0);
|
// PostMessageW(GuiData->hWindow, PM_CONSOLE_SET_TITLE, 0, 0);
|
||||||
|
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
|
@ -1916,6 +2013,7 @@ GuiInitConsole(PCONSOLE Console,
|
||||||
{
|
{
|
||||||
PGUI_CONSOLE_DATA GuiData;
|
PGUI_CONSOLE_DATA GuiData;
|
||||||
GUI_CONSOLE_INFO TermInfo;
|
GUI_CONSOLE_INFO TermInfo;
|
||||||
|
SIZE_T Length = 0;
|
||||||
|
|
||||||
if (Console == NULL || ConsoleInfo == NULL)
|
if (Console == NULL || ConsoleInfo == NULL)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -1984,7 +2082,9 @@ GuiInitConsole(PCONSOLE Console,
|
||||||
* Set up the GUI data
|
* Set up the GUI data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Length = min(wcslen(TermInfo.FaceName) + 1, LF_FACESIZE); // wcsnlen
|
||||||
wcsncpy(GuiData->GuiInfo.FaceName, TermInfo.FaceName, LF_FACESIZE);
|
wcsncpy(GuiData->GuiInfo.FaceName, TermInfo.FaceName, LF_FACESIZE);
|
||||||
|
GuiData->GuiInfo.FaceName[Length] = L'\0';
|
||||||
GuiData->GuiInfo.FontFamily = TermInfo.FontFamily;
|
GuiData->GuiInfo.FontFamily = TermInfo.FontFamily;
|
||||||
GuiData->GuiInfo.FontSize = TermInfo.FontSize;
|
GuiData->GuiInfo.FontSize = TermInfo.FontSize;
|
||||||
GuiData->GuiInfo.FontWeight = TermInfo.FontWeight;
|
GuiData->GuiInfo.FontWeight = TermInfo.FontWeight;
|
||||||
|
@ -2034,6 +2134,7 @@ GuiInitConsole(PCONSOLE Console,
|
||||||
|
|
||||||
/* Wait until initialization has finished */
|
/* Wait until initialization has finished */
|
||||||
WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
|
WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
|
||||||
|
DPRINT1("OK we created the console window\n");
|
||||||
CloseHandle(GuiData->hGuiInitEvent);
|
CloseHandle(GuiData->hGuiInitEvent);
|
||||||
GuiData->hGuiInitEvent = NULL;
|
GuiData->hGuiInitEvent = NULL;
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,9 @@ GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
|
||||||
|
|
||||||
if (!wcscmp(szValueName, L"FaceName"))
|
if (!wcscmp(szValueName, L"FaceName"))
|
||||||
{
|
{
|
||||||
|
SIZE_T Length = min(wcslen(szValue) + 1, LF_FACESIZE); // wcsnlen
|
||||||
wcsncpy(TermInfo->FaceName, szValue, LF_FACESIZE);
|
wcsncpy(TermInfo->FaceName, szValue, LF_FACESIZE);
|
||||||
|
TermInfo->FaceName[Length] = L'\0';
|
||||||
RetVal = TRUE;
|
RetVal = TRUE;
|
||||||
}
|
}
|
||||||
else if (!wcscmp(szValueName, L"FontFamily"))
|
else if (!wcscmp(szValueName, L"FontFamily"))
|
||||||
|
@ -150,7 +152,7 @@ do {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetConsoleSetting(L"FaceName", REG_SZ, (wcslen(TermInfo->FaceName) + 1) * sizeof(WCHAR), TermInfo->FaceName, L'\0');
|
SetConsoleSetting(L"FaceName", REG_SZ, (wcslen(TermInfo->FaceName) + 1) * sizeof(WCHAR), TermInfo->FaceName, L'\0'); // wcsnlen
|
||||||
SetConsoleSetting(L"FontFamily", REG_DWORD, sizeof(DWORD), &TermInfo->FontFamily, FF_DONTCARE);
|
SetConsoleSetting(L"FontFamily", REG_DWORD, sizeof(DWORD), &TermInfo->FontFamily, FF_DONTCARE);
|
||||||
SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &TermInfo->FontSize, 0);
|
SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &TermInfo->FontSize, 0);
|
||||||
SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD), &TermInfo->FontWeight, FW_DONTCARE);
|
SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD), &TermInfo->FontWeight, FW_DONTCARE);
|
||||||
|
@ -269,6 +271,12 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
||||||
pSharedInfo->hConsoleWindow = GuiData->hWindow;
|
pSharedInfo->hConsoleWindow = GuiData->hWindow;
|
||||||
pSharedInfo->ShowDefaultParams = Defaults;
|
pSharedInfo->ShowDefaultParams = Defaults;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We fill-in the fields only if we display
|
||||||
|
* our properties, not the default ones.
|
||||||
|
*/
|
||||||
|
if (!Defaults)
|
||||||
|
{
|
||||||
/* Console information */
|
/* Console information */
|
||||||
pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize;
|
pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize;
|
||||||
pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
|
pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
|
||||||
|
@ -289,8 +297,11 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
||||||
/* GUI Information */
|
/* GUI Information */
|
||||||
pSharedInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
|
pSharedInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
|
||||||
GuiInfo = pSharedInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pSharedInfo + 1);
|
GuiInfo = pSharedInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pSharedInfo + 1);
|
||||||
|
Length = min(wcslen(GuiData->GuiInfo.FaceName) + 1, LF_FACESIZE); // wcsnlen
|
||||||
wcsncpy(GuiInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
|
wcsncpy(GuiInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
|
||||||
GuiInfo->FontSize = (DWORD)GuiData->GuiInfo.FontSize;
|
GuiInfo->FaceName[Length] = L'\0';
|
||||||
|
GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily;
|
||||||
|
GuiInfo->FontSize = GuiData->GuiInfo.FontSize;
|
||||||
GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
|
GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
|
||||||
GuiInfo->UseRasterFonts = GuiData->GuiInfo.UseRasterFonts;
|
GuiInfo->UseRasterFonts = GuiData->GuiInfo.UseRasterFonts;
|
||||||
/// GuiInfo->WindowPosition = GuiData->GuiInfo.WindowPosition;
|
/// GuiInfo->WindowPosition = GuiData->GuiInfo.WindowPosition;
|
||||||
|
@ -306,6 +317,13 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
||||||
Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) / sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1,
|
Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) / sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1,
|
||||||
Console->OriginalTitle.Length / sizeof(WCHAR));
|
Console->OriginalTitle.Length / sizeof(WCHAR));
|
||||||
wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
|
wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Null-terminate the title */
|
||||||
pSharedInfo->ci.ConsoleTitle[Length] = L'\0';
|
pSharedInfo->ci.ConsoleTitle[Length] = L'\0';
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,29 +344,46 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Error: Impossible to duplicate section handle for client ; Status = %lu\n", Status);
|
DPRINT1("Error: Impossible to duplicate section handle for client ; Status = %lu\n", Status);
|
||||||
NtClose(hSection);
|
goto Quit;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the properties dialog */
|
/* Start the properties dialog */
|
||||||
if (ProcessData->PropDispatcher)
|
if (ProcessData->PropDispatcher)
|
||||||
{
|
{
|
||||||
HANDLE Thread;
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
HANDLE Thread = NULL;
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
||||||
ProcessData->PropDispatcher,
|
ProcessData->PropDispatcher,
|
||||||
(PVOID)hClientSection, 0, NULL);
|
(PVOID)hClientSection, 0, NULL);
|
||||||
if (NULL == Thread)
|
if (NULL == Thread)
|
||||||
{
|
{
|
||||||
DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
|
DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
DPRINT1("We succeeded at creating ProcessData->PropDispatcher remote thread, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
{
|
||||||
|
DPRINT("ProcessData->PropDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
||||||
/// WaitForSingleObject(Thread, INFINITE);
|
/// WaitForSingleObject(Thread, INFINITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_FINALLY
|
||||||
|
{
|
||||||
CloseHandle(Thread);
|
CloseHandle(Thread);
|
||||||
}
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = %08X\n", Status);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
/* We have finished, close the section handle */
|
/* We have finished, close the section handle */
|
||||||
NtClose(hSection);
|
NtClose(hSection);
|
||||||
return;
|
return;
|
||||||
|
@ -369,8 +404,6 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
|
||||||
PTERMINAL_INFO TermInfo = NULL;
|
PTERMINAL_INFO TermInfo = NULL;
|
||||||
PGUI_CONSOLE_INFO GuiInfo = NULL;
|
PGUI_CONSOLE_INFO GuiInfo = NULL;
|
||||||
|
|
||||||
/// LOCK /// EnterCriticalSection(&Console->Lock);
|
|
||||||
|
|
||||||
/* Get the console leader process, our client */
|
/* Get the console leader process, our client */
|
||||||
ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
|
ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
|
||||||
CONSOLE_PROCESS_DATA,
|
CONSOLE_PROCESS_DATA,
|
||||||
|
@ -406,6 +439,8 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
/* Check that the section is well-sized */
|
/* Check that the section is well-sized */
|
||||||
if ( (ViewSize < sizeof(CONSOLE_PROPS)) ||
|
if ( (ViewSize < sizeof(CONSOLE_PROPS)) ||
|
||||||
(pConInfo->TerminalInfo.Size != sizeof(GUI_CONSOLE_INFO)) ||
|
(pConInfo->TerminalInfo.Size != sizeof(GUI_CONSOLE_INFO)) ||
|
||||||
|
@ -413,19 +448,27 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
|
||||||
{
|
{
|
||||||
DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n");
|
DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n");
|
||||||
Status = STATUS_INVALID_VIEW_SIZE;
|
Status = STATUS_INVALID_VIEW_SIZE;
|
||||||
goto Quit;
|
_SEH2_YIELD(goto Quit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow
|
// TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow
|
||||||
|
|
||||||
/* Set the console informations */
|
/* Retrieve terminal informations */
|
||||||
ConInfo = &pConInfo->ci;
|
ConInfo = &pConInfo->ci;
|
||||||
ConSrvApplyUserSettings(Console, ConInfo);
|
|
||||||
|
|
||||||
/* Set the terminal informations - De-offsetization of the pointer */
|
|
||||||
TermInfo = &pConInfo->TerminalInfo;
|
TermInfo = &pConInfo->TerminalInfo;
|
||||||
GuiInfo = TermInfo->TermInfo = (PVOID)((ULONG_PTR)pConInfo + (ULONG_PTR)TermInfo->TermInfo);
|
GuiInfo = TermInfo->TermInfo = (PVOID)((ULONG_PTR)pConInfo + (ULONG_PTR)TermInfo->TermInfo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we don't set the default parameters,
|
||||||
|
* apply them, otherwise just save them.
|
||||||
|
*/
|
||||||
|
if (pConInfo->ShowDefaultParams == FALSE)
|
||||||
|
{
|
||||||
|
/* Set the console informations */
|
||||||
|
ConSrvApplyUserSettings(Console, ConInfo);
|
||||||
|
|
||||||
|
/* Set the terminal informations */
|
||||||
|
|
||||||
// memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO));
|
// memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO));
|
||||||
|
|
||||||
/* Move the window to the user's values */
|
/* Move the window to the user's values */
|
||||||
|
@ -434,12 +477,11 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
|
||||||
GuiConsoleMoveWindow(GuiData);
|
GuiConsoleMoveWindow(GuiData);
|
||||||
|
|
||||||
InvalidateRect(GuiData->hWindow, NULL, TRUE);
|
InvalidateRect(GuiData->hWindow, NULL, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save settings if needed
|
* Save settings if needed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// FIXME: Do it in the console properties applet ??
|
// FIXME: Do it in the console properties applet ??
|
||||||
if (SaveSettings)
|
if (SaveSettings)
|
||||||
{
|
{
|
||||||
|
@ -449,8 +491,13 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
/// LOCK /// LeaveCriticalSection(&Console->Lock);
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
DPRINT1("GuiApplyUserSettings - Caught an exception, Status = %08X\n", Status);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
Quit:
|
Quit:
|
||||||
/* Finally, close the section and return */
|
/* Finally, close the section and return */
|
||||||
|
|
|
@ -10,8 +10,9 @@
|
||||||
|
|
||||||
#include "consrv.h"
|
#include "consrv.h"
|
||||||
#include "conio.h"
|
#include "conio.h"
|
||||||
|
#include "console.h"
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ AdjustHandleCounts(PCONSOLE_IO_HANDLE Entry, INT Change)
|
||||||
{
|
{
|
||||||
Object_t *Object = Entry->Object;
|
Object_t *Object = Entry->Object;
|
||||||
|
|
||||||
DPRINT1("AdjustHandleCounts(0x%p, %d), Object = 0x%p, Object->HandleCount = %d, Object->Type = %lu\n", Entry, Change, Object, Object->HandleCount, Object->Type);
|
DPRINT("AdjustHandleCounts(0x%p, %d), Object = 0x%p, Object->HandleCount = %d, Object->Type = %lu\n", Entry, Change, Object, Object->HandleCount, Object->Type);
|
||||||
|
|
||||||
if (Entry->Access & GENERIC_READ) Object->AccessRead += Change;
|
if (Entry->Access & GENERIC_READ) Object->AccessRead += Change;
|
||||||
if (Entry->Access & GENERIC_WRITE) Object->AccessWrite += Change;
|
if (Entry->Access & GENERIC_WRITE) Object->AccessWrite += Change;
|
||||||
|
@ -236,8 +237,6 @@ Quit:
|
||||||
static VOID
|
static VOID
|
||||||
ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
|
ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
|
||||||
{
|
{
|
||||||
DPRINT1("ConSrvFreeHandlesTable\n");
|
|
||||||
|
|
||||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
if (ProcessData->HandleTable != NULL)
|
if (ProcessData->HandleTable != NULL)
|
||||||
|
@ -272,7 +271,8 @@ ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PCONSOLE_IO_HANDLE Block;
|
PCONSOLE_IO_HANDLE Block;
|
||||||
|
|
||||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
// NOTE: Commented out because calling code always lock HandleTableLock before.
|
||||||
|
// RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
for (i = 0; i < ProcessData->HandleTableSize; i++)
|
||||||
{
|
{
|
||||||
|
@ -289,7 +289,7 @@ ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
IO_HANDLES_INCREMENT) * sizeof(CONSOLE_IO_HANDLE));
|
IO_HANDLES_INCREMENT) * sizeof(CONSOLE_IO_HANDLE));
|
||||||
if (Block == NULL)
|
if (Block == NULL)
|
||||||
{
|
{
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
// RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
RtlCopyMemory(Block,
|
RtlCopyMemory(Block,
|
||||||
|
@ -307,7 +307,7 @@ ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
ConSrvCreateHandleEntry(&ProcessData->HandleTable[i]);
|
ConSrvCreateHandleEntry(&ProcessData->HandleTable[i]);
|
||||||
*Handle = ULongToHandle((i << 2) | 0x3);
|
*Handle = ULongToHandle((i << 2) | 0x3);
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
// RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -329,11 +329,9 @@ ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("ConSrvRemoveObject - Process 0x%p, Release 0x%p\n", ProcessData->Process, &ProcessData->HandleTable[h]);
|
|
||||||
ConSrvCloseHandleEntry(&ProcessData->HandleTable[h]);
|
ConSrvCloseHandleEntry(&ProcessData->HandleTable[h]);
|
||||||
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,17 +374,25 @@ ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_InterlockedIncrement(&ObjectEntry->Console->ReferenceCount);
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
if (LockConsole) EnterCriticalSection(&ObjectEntry->Console->Lock);
|
if (ConSrvValidateConsole(ObjectEntry->Console, CONSOLE_RUNNING, LockConsole))
|
||||||
|
{
|
||||||
|
_InterlockedIncrement(&ObjectEntry->Console->ReferenceCount);
|
||||||
|
|
||||||
/* Return the objects to the caller */
|
/* Return the objects to the caller */
|
||||||
*Object = ObjectEntry;
|
*Object = ObjectEntry;
|
||||||
if (Entry) *Entry = HandleEntry;
|
if (Entry) *Entry = HandleEntry;
|
||||||
|
|
||||||
|
// RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
return STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
|
@ -465,6 +471,13 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* Validate and lock the console */
|
||||||
|
if (!ConSrvValidateConsole(Console, CONSOLE_RUNNING, TRUE))
|
||||||
|
{
|
||||||
|
// FIXME: Find another status code
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Inherit the console */
|
/* Inherit the console */
|
||||||
ProcessData->Console = Console;
|
ProcessData->Console = Console;
|
||||||
|
|
||||||
|
@ -479,7 +492,7 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to initialize the handles table\n");
|
DPRINT1("Failed to initialize the handles table\n");
|
||||||
ProcessData->Console = NULL;
|
ProcessData->Console = NULL;
|
||||||
return Status;
|
goto Quit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +507,7 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
|
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
|
||||||
ConSrvFreeHandlesTable(ProcessData); // NOTE: Always free the handles table.
|
ConSrvFreeHandlesTable(ProcessData); // NOTE: Always free the handles table.
|
||||||
ProcessData->Console = NULL;
|
ProcessData->Console = NULL;
|
||||||
return Status;
|
goto Quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert the process into the processes list of the console */
|
/* Insert the process into the processes list of the console */
|
||||||
|
@ -506,30 +519,35 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
/* Update the internal info of the terminal */
|
/* Update the internal info of the terminal */
|
||||||
ConioRefreshInternalInfo(ProcessData->Console);
|
ConioRefreshInternalInfo(ProcessData->Console);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
/* Unlock the console and return */
|
||||||
|
LeaveCriticalSection(&Console->Lock);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
|
ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
|
||||||
{
|
{
|
||||||
PCONSOLE Console;
|
PCONSOLE Console = ProcessData->Console;
|
||||||
|
|
||||||
DPRINT1("ConSrvRemoveConsole\n");
|
DPRINT1("ConSrvRemoveConsole\n");
|
||||||
|
|
||||||
/* Close all console handles and free the handle table memory */
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
|
||||||
|
/* Validate and lock the console */
|
||||||
|
if (ConSrvValidateConsole(Console, CONSOLE_RUNNING, TRUE))
|
||||||
|
{
|
||||||
|
DPRINT1("ConSrvRemoveConsole - Locking OK\n");
|
||||||
|
|
||||||
|
/* Close all console handles and free the handles table */
|
||||||
ConSrvFreeHandlesTable(ProcessData);
|
ConSrvFreeHandlesTable(ProcessData);
|
||||||
|
|
||||||
/* Detach process from console */
|
/* Detach the process from the console */
|
||||||
Console = ProcessData->Console;
|
|
||||||
if (Console != NULL)
|
|
||||||
{
|
|
||||||
DPRINT1("ConSrvRemoveConsole - Console->ReferenceCount = %lu - We are going to decrement it !\n", Console->ReferenceCount);
|
|
||||||
ProcessData->Console = NULL;
|
ProcessData->Console = NULL;
|
||||||
|
|
||||||
EnterCriticalSection(&Console->Lock);
|
|
||||||
DPRINT1("ConSrvRemoveConsole - Locking OK\n");
|
|
||||||
|
|
||||||
/* Remove ourselves from the console's list of processes */
|
/* Remove ourselves from the console's list of processes */
|
||||||
RemoveEntryList(&ProcessData->ConsoleLink);
|
RemoveEntryList(&ProcessData->ConsoleLink);
|
||||||
|
|
||||||
|
@ -537,10 +555,105 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
|
||||||
ConioRefreshInternalInfo(Console);
|
ConioRefreshInternalInfo(Console);
|
||||||
|
|
||||||
/* Release the console */
|
/* Release the console */
|
||||||
|
DPRINT1("ConSrvRemoveConsole - Decrement Console->ReferenceCount = %lu\n", Console->ReferenceCount);
|
||||||
ConSrvReleaseConsole(Console, TRUE);
|
ConSrvReleaseConsole(Console, TRUE);
|
||||||
//CloseHandle(ProcessData->ConsoleEvent);
|
//CloseHandle(ProcessData->ConsoleEvent);
|
||||||
//ProcessData->ConsoleEvent = NULL;
|
//ProcessData->ConsoleEvent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
ConSrvValidatePointer(PCONSOLE Console)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY ConsoleEntry;
|
||||||
|
PCONSOLE CurrentConsole = NULL;
|
||||||
|
|
||||||
|
if (!Console) return FALSE;
|
||||||
|
|
||||||
|
/* The console list must be locked */
|
||||||
|
// ASSERT(Console_list_locked);
|
||||||
|
|
||||||
|
ConsoleEntry = ConsoleList.Flink;
|
||||||
|
while (ConsoleEntry != &ConsoleList)
|
||||||
|
{
|
||||||
|
CurrentConsole = CONTAINING_RECORD(ConsoleEntry, CONSOLE, Entry);
|
||||||
|
ConsoleEntry = ConsoleEntry->Flink;
|
||||||
|
if (CurrentConsole == Console) return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
ConSrvValidateConsoleState(PCONSOLE Console,
|
||||||
|
CONSOLE_STATE ExpectedState)
|
||||||
|
{
|
||||||
|
// if (!Console) return FALSE;
|
||||||
|
|
||||||
|
/* The console must be locked */
|
||||||
|
// ASSERT(Console_locked);
|
||||||
|
|
||||||
|
return (Console->State == ExpectedState);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
ConSrvValidateConsoleUnsafe(PCONSOLE Console,
|
||||||
|
CONSOLE_STATE ExpectedState,
|
||||||
|
BOOL LockConsole)
|
||||||
|
{
|
||||||
|
if (!Console) return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock the console to forbid possible console's state changes
|
||||||
|
* (which must be done when the console is already locked).
|
||||||
|
* If we don't want to lock it, it's because the lock is already
|
||||||
|
* held. So there must be no problems.
|
||||||
|
*/
|
||||||
|
if (LockConsole) EnterCriticalSection(&Console->Lock);
|
||||||
|
|
||||||
|
// ASSERT(Console_locked);
|
||||||
|
|
||||||
|
/* Check whether the console's state is what we expect */
|
||||||
|
if (!ConSrvValidateConsoleState(Console, ExpectedState))
|
||||||
|
{
|
||||||
|
if (LockConsole) LeaveCriticalSection(&Console->Lock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
ConSrvValidateConsole(PCONSOLE Console,
|
||||||
|
CONSOLE_STATE ExpectedState,
|
||||||
|
BOOL LockConsole)
|
||||||
|
{
|
||||||
|
BOOL RetVal = FALSE;
|
||||||
|
|
||||||
|
if (!Console) return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forbid creation or deletion of consoles when
|
||||||
|
* checking for the existence of a console.
|
||||||
|
*/
|
||||||
|
ConSrvLockConsoleListShared();
|
||||||
|
|
||||||
|
if (ConSrvValidatePointer(Console))
|
||||||
|
{
|
||||||
|
RetVal = ConSrvValidateConsoleUnsafe(Console,
|
||||||
|
ExpectedState,
|
||||||
|
LockConsole);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock the console list and return */
|
||||||
|
ConSrvUnlockConsoleList();
|
||||||
|
return RetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -549,37 +662,53 @@ ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||||
PCONSOLE* Console,
|
PCONSOLE* Console,
|
||||||
BOOL LockConsole)
|
BOOL LockConsole)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PCONSOLE ProcessConsole;
|
PCONSOLE ProcessConsole;
|
||||||
|
|
||||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||||
ProcessConsole = ProcessData->Console;
|
ProcessConsole = ProcessData->Console;
|
||||||
|
|
||||||
if (!ProcessConsole)
|
if (ConSrvValidateConsole(ProcessConsole, CONSOLE_RUNNING, LockConsole))
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&ProcessConsole->ReferenceCount);
|
||||||
|
*Console = ProcessConsole;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
*Console = NULL;
|
*Console = NULL;
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
Status = STATUS_INVALID_HANDLE;
|
||||||
return STATUS_INVALID_HANDLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InterlockedIncrement(&ProcessConsole->ReferenceCount);
|
|
||||||
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
|
||||||
|
return Status;
|
||||||
if (LockConsole) EnterCriticalSection(&ProcessConsole->Lock);
|
|
||||||
|
|
||||||
*Console = ProcessConsole;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
ConSrvReleaseConsole(PCONSOLE Console,
|
ConSrvReleaseConsole(PCONSOLE Console,
|
||||||
BOOL IsConsoleLocked)
|
BOOL WasConsoleLocked)
|
||||||
{
|
{
|
||||||
if (IsConsoleLocked) LeaveCriticalSection(&Console->Lock);
|
LONG RefCount = 0;
|
||||||
|
|
||||||
/* Decrement reference count */
|
if (!Console) return;
|
||||||
if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
|
// if (Console->ReferenceCount == 0) return; // This shouldn't happen
|
||||||
ConSrvDeleteConsole(Console);
|
ASSERT(Console->ReferenceCount > 0);
|
||||||
|
|
||||||
|
/* The console must be locked */
|
||||||
|
// ASSERT(Console_locked);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrement the reference count. Save the new value too,
|
||||||
|
* because Console->ReferenceCount might be modified after
|
||||||
|
* the console gets unlocked but before we check whether we
|
||||||
|
* can destroy it.
|
||||||
|
*/
|
||||||
|
RefCount = _InterlockedDecrement(&Console->ReferenceCount);
|
||||||
|
|
||||||
|
/* Unlock the console if needed */
|
||||||
|
if (WasConsoleLocked) LeaveCriticalSection(&Console->Lock);
|
||||||
|
|
||||||
|
/* Delete the console if needed */
|
||||||
|
if (RefCount <= 0) ConSrvDeleteConsole(Console);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -745,8 +874,6 @@ ConSrvDisconnect(PCSR_PROCESS Process)
|
||||||
* This function is called whenever a new process (GUI or CUI) is destroyed.
|
* This function is called whenever a new process (GUI or CUI) is destroyed.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
DPRINT1("ConSrvDisconnect\n");
|
|
||||||
|
|
||||||
if ( ProcessData->Console != NULL ||
|
if ( ProcessData->Console != NULL ||
|
||||||
ProcessData->HandleTable != NULL )
|
ProcessData->HandleTable != NULL )
|
||||||
{
|
{
|
||||||
|
@ -828,6 +955,7 @@ CSR_API(SrvDuplicateHandle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Insert the new handle inside the process handles table */
|
||||||
ApiMessage->Status = ConSrvInsertObject(ProcessData,
|
ApiMessage->Status = ConSrvInsertObject(ProcessData,
|
||||||
&DuplicateHandleRequest->ConsoleHandle, // Use the new handle value!
|
&DuplicateHandleRequest->ConsoleHandle, // Use the new handle value!
|
||||||
Entry->Object,
|
Entry->Object,
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "consrv.h"
|
#include "consrv.h"
|
||||||
#include "conio.h"
|
#include "conio.h"
|
||||||
|
#include "console.h"
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
Loading…
Reference in a new issue