Author: hbelusca
Date: Sat Mar 30 18:44:56 2013
New Revision: 58615
URL:
http://svn.reactos.org/svn/reactos?rev=58615&view=rev
Log:
[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.
Added:
branches/ros-csrss/win32ss/user/consrv/console.h (with props)
Modified:
branches/ros-csrss/dll/cpl/console/console.c
branches/ros-csrss/win32ss/user/consrv/coninput.c
branches/ros-csrss/win32ss/user/consrv/conio.h
branches/ros-csrss/win32ss/user/consrv/conoutput.c
branches/ros-csrss/win32ss/user/consrv/console.c
branches/ros-csrss/win32ss/user/consrv/consrv.h
branches/ros-csrss/win32ss/user/consrv/guiconsole.c
branches/ros-csrss/win32ss/user/consrv/guisettings.c
branches/ros-csrss/win32ss/user/consrv/handle.c
branches/ros-csrss/win32ss/user/consrv/init.c
Modified: branches/ros-csrss/dll/cpl/console/console.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/dll/cpl/console/conso…
==============================================================================
--- branches/ros-csrss/dll/cpl/console/console.c [iso-8859-1] (original)
+++ branches/ros-csrss/dll/cpl/console/console.c [iso-8859-1] Sat Mar 30 18:44:56 2013
@@ -86,6 +86,8 @@
InitConsoleDefaults(PCONSOLE_PROPS pConInfo)
{
PGUI_CONSOLE_INFO GuiInfo = NULL;
+
+ /* FIXME: Get also the defaults from the registry */
/* Initialize the default properties */
pConInfo->ci.HistoryBufferSize = 50;
@@ -108,7 +110,8 @@
/* Adapted for holding GUI terminal information */
pConInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
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->FontSize = 0;
GuiInfo->FontWeight = FW_DONTCARE;
@@ -166,16 +169,35 @@
ApplyConsoleInfo(HWND hwndDlg,
PCONSOLE_PROPS pConInfo)
{
- INT_PTR res = 0;
-
- res = DialogBox(hApplet, MAKEINTRESOURCE(IDD_APPLYOPTIONS), hwndDlg, ApplyProc);
- if (res == IDCANCEL)
- {
- /* Don't destroy when user presses cancel */
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
- return TRUE;
- }
- else if (res == IDC_RADIO_APPLY_ALL || res == IDC_RADIO_APPLY_CURRENT)
+ BOOL SetParams = FALSE;
+ BOOL SaveParams = FALSE;
+
+ /*
+ * 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 */
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
+ // return TRUE;
+ }
+ }
+
+ // if (res == IDC_RADIO_APPLY_ALL || res == IDC_RADIO_APPLY_CURRENT)
+ if (SetParams)
{
HANDLE hSection;
PCONSOLE_PROPS pSharedInfo;
@@ -207,10 +229,15 @@
/* We are applying the chosen configuration */
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));
- /* Offsetize */
- pSharedInfo->TerminalInfo.TermInfo =
(PVOID)((ULONG_PTR)pSharedInfo->TerminalInfo.TermInfo - (ULONG_PTR)pSharedInfo);
+ pSharedInfo->TerminalInfo.TermInfo =
(PVOID)((ULONG_PTR)pConInfo->TerminalInfo.TermInfo - (ULONG_PTR)pConInfo);
/* Unmap it */
UnmapViewOfFile(pSharedInfo);
@@ -220,11 +247,10 @@
SendMessage(pConInfo->hConsoleWindow,
PM_APPLY_CONSOLE_INFO,
(WPARAM)hSection,
- (LPARAM)(res == IDC_RADIO_APPLY_ALL));
+ (LPARAM)SaveParams);
/* Close the section and return */
CloseHandle(hSection);
- return TRUE;
}
return TRUE;
Modified: branches/ros-csrss/win32ss/user/consrv/coninput.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/c…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/coninput.c [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/coninput.c [iso-8859-1] Sat Mar 30 18:44:56
2013
@@ -685,7 +685,6 @@
return STATUS_INVALID_PARAMETER;
}
- // if (Request->Data.ReadConsoleRequest.NrCharactersRead * sizeof(WCHAR) >
nNumberOfCharsToRead * CharSize)
if (ReadConsoleRequest->NrCharactersRead >
ReadConsoleRequest->NrCharactersToRead)
{
return STATUS_INVALID_PARAMETER;
@@ -808,7 +807,7 @@
PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FlushInputBufferRequest;
PLIST_ENTRY CurrentEntry;
PCONSOLE_INPUT_BUFFER InputBuffer;
- ConsoleInput* Input;
+ ConsoleInput* Event;
DPRINT("SrvFlushConsoleInputBuffer\n");
@@ -823,14 +822,12 @@
while (!IsListEmpty(&InputBuffer->InputEvents))
{
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
- Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
- /* Destroy the event */
- RtlFreeHeap(ConSrvHeap, 0, Input);
+ Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+ RtlFreeHeap(ConSrvHeap, 0, Event);
}
ResetEvent(InputBuffer->ActiveEvent);
ConSrvReleaseInputBuffer(InputBuffer, TRUE);
-
return STATUS_SUCCESS;
}
Modified: branches/ros-csrss/win32ss/user/consrv/conio.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/c…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/conio.h [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/conio.h [iso-8859-1] Sat Mar 30 18:44:56 2013
@@ -147,12 +147,27 @@
PVOID OldData; /* Reserved */
} 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
{
- 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;
-
- struct _CONSOLE *Prev, *Next; /* Next and Prev consoles in console wheel
*/
+ CONSOLE_STATE State; /* State of the console */
+
+ // 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" */
FRONTEND_IFACE TermIFace; /* Frontend-specific interface */
@@ -218,11 +233,6 @@
#define PAUSED_FROM_SELECTION 0x4
/* 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 ConioUnpause(PCONSOLE Console, UINT Flags);
ULONG FASTCALL ConSrvConsoleProcessCtrlEvent(PCONSOLE Console,
Modified: branches/ros-csrss/win32ss/user/consrv/conoutput.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/c…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/conoutput.c [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/conoutput.c [iso-8859-1] Sat Mar 30 18:44:56
2013
@@ -1278,15 +1278,18 @@
DPRINT("SrvCreateConsoleScreenBuffer\n");
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
+ // RtlEnterCriticalSection(&ProcessData->HandleTableLock);
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (!NT_SUCCESS(Status))
{
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
+ RtlEnterCriticalSection(&ProcessData->HandleTableLock);
+
+ /*
if (Console->ActiveBuffer)
{
ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize;
@@ -1298,6 +1301,23 @@
IsCursorVisible = Console->ActiveBuffer->CursorInfo.bVisible;
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,
@@ -1309,6 +1329,7 @@
CursorSize);
if (NT_SUCCESS(Status))
{
+ /* Insert the new handle inside the process handles table */
Status = ConSrvInsertObject(ProcessData,
&CreateScreenBufferRequest->OutputHandle,
&Buff->Header,
@@ -1317,10 +1338,11 @@
CreateScreenBufferRequest->ShareMode);
}
+ // ConSrvReleaseConsole(Console, TRUE);
+
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+
ConSrvReleaseConsole(Console, TRUE);
-
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-
return Status;
}
Modified: branches/ros-csrss/win32ss/user/consrv/console.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/c…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/console.c [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/console.c [iso-8859-1] Sat Mar 30 18:44:56
2013
@@ -21,11 +21,18 @@
#include "tuiconsole.h"
#endif
+#include "console.h"
+
#include <shlwapi.h>
#include <shlobj.h>
-//#define NDEBUG
+#define NDEBUG
#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+LIST_ENTRY ConsoleList; /* The list of all the allocated consoles */
+/*static*/ RTL_RESOURCE ListLock;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -44,26 +51,43 @@
DWORD Timeout)
{
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)
{
- Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
- ProcessData->CtrlDispatcher,
- UlongToPtr(Event), 0, NULL);
- if (NULL == Thread)
- {
- Status = GetLastError();
- DPRINT1("Failed thread creation (Error: 0x%x)\n", Status);
- }
- else
- {
- DPRINT("We succeeded at creating ProcessData->CtrlDispatcher remote
thread, ProcessId = %x, Process = 0x%p\n",
ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
- WaitForSingleObject(Thread, Timeout);
- CloseHandle(Thread);
- }
+ _SEH2_TRY
+ {
+ HANDLE Thread = NULL;
+
+ _SEH2_TRY
+ {
+ Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle,
NULL, 0,
+ ProcessData->CtrlDispatcher,
+ UlongToPtr(Event), 0, NULL);
+ if (NULL == Thread)
+ {
+ Status = GetLastError();
+ DPRINT1("Failed thread creation (Error: 0x%x)\n", Status);
+ }
+ else
+ {
+ DPRINT("ProcessData->CtrlDispatcher remote thread creation
succeeded, ProcessId = %x, Process = 0x%p\n",
ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
+ WaitForSingleObject(Thread, Timeout);
+ }
+ }
+ _SEH2_FINALLY
+ {
+ 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;
@@ -84,6 +108,10 @@
ULONG Status = ERROR_SUCCESS;
PLIST_ENTRY current_entry;
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
@@ -139,6 +167,18 @@
CsrDereferenceWait(&Console->WriteWaitQueue);
}
}
+}
+
+VOID WINAPI
+ConSrvInitConsoleSupport(VOID)
+{
+ DPRINT("CONSRV: ConSrvInitConsoleSupport()\n");
+
+ /* Initialize the console list and its lock */
+ InitializeListHead(&ConsoleList);
+ RtlInitializeResource(&ListLock);
+
+ /* Should call LoadKeyboardLayout */
}
static BOOL
@@ -346,6 +386,7 @@
/*
* Initialize the console
*/
+ Console->State = CONSOLE_INITIALIZING;
InitializeCriticalSection(&Console->Lock);
Console->ReferenceCount = 0;
InitializeListHead(&Console->ProcessList);
@@ -428,6 +469,9 @@
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 fail, try to start the GUI-mode terminal emulator.
@@ -480,14 +524,33 @@
RtlFreeUnicodeString(&Console->OriginalTitle);
ConioDeleteScreenBuffer(NewBuffer);
CloseHandle(Console->InputBuffer.ActiveEvent);
+ // LeaveCriticalSection(&Console->Lock);
DeleteCriticalSection(&Console->Lock);
RtlFreeHeap(ConSrvHeap, 0, Console);
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 */
ConioDrawConsole(Console);
+ DPRINT1("Console drawn\n");
/* Return the newly created console to the caller and a success code too */
*NewConsole = Console;
@@ -495,30 +558,100 @@
}
VOID WINAPI
-ConSrvInitConsoleSupport(VOID)
-{
- DPRINT("CONSRV: ConSrvInitConsoleSupport()\n");
-
- /* Should call LoadKeyboardLayout */
-}
-
-VOID WINAPI
ConSrvDeleteConsole(PCONSOLE Console)
{
- ConsoleInput *Event;
-
- DPRINT("ConSrvDeleteConsole\n");
-
- /* Drain input event queue */
- while (Console->InputBuffer.InputEvents.Flink !=
&Console->InputBuffer.InputEvents)
- {
- Event = (ConsoleInput *) Console->InputBuffer.InputEvents.Flink;
- Console->InputBuffer.InputEvents.Flink =
Console->InputBuffer.InputEvents.Flink->Flink;
- Console->InputBuffer.InputEvents.Flink->Flink->Blink =
&Console->InputBuffer.InputEvents;
+ PLIST_ENTRY CurrentEntry;
+ ConsoleInput* Event;
+
+ DPRINT1("ConSrvDeleteConsole\n");
+
+ /*
+ * 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))
+ {
+ /* Unlock the console list and return */
+ ConSrvUnlockConsoleList();
+ 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);
}
- ConioCleanupConsole(Console);
if (Console->LineBuffer)
RtlFreeHeap(ConSrvHeap, 0, Console->LineBuffer);
while (!IsListEmpty(&Console->HistoryBuffers))
@@ -532,12 +665,22 @@
CloseHandle(Console->InputBuffer.ActiveEvent);
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
- DeleteCriticalSection(&Console->Lock);
RtlFreeUnicodeString(&Console->OriginalTitle);
RtlFreeUnicodeString(&Console->Title);
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);
+ DPRINT1("ConSrvDeleteConsole - Console freed\n");
+
+ /* Unlock the console list and return */
+ ConSrvUnlockConsoleList();
}
@@ -545,56 +688,59 @@
CSR_API(SrvOpenConsole)
{
- NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status;
PCONSOLE_OPENCONSOLE OpenConsoleRequest =
&((PCONSOLE_API_MESSAGE)ApiMessage)->Data.OpenConsoleRequest;
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;
+ Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Can't get console\n");
+ return Status;
+ }
+
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- if (ProcessData->Console)
- {
- DWORD DesiredAccess = OpenConsoleRequest->Access;
- DWORD ShareMode = OpenConsoleRequest->ShareMode;
-
- PCONSOLE Console = ProcessData->Console;
- Object_t *Object;
-
- EnterCriticalSection(&Console->Lock);
-
- if (OpenConsoleRequest->HandleType == HANDLE_OUTPUT)
- {
- Object = &Console->ActiveBuffer->Header;
- }
- else // HANDLE_INPUT
- {
- Object = &Console->InputBuffer.Header;
- }
-
- if (((DesiredAccess & GENERIC_READ) && Object->ExclusiveRead !=
0) ||
- ((DesiredAccess & GENERIC_WRITE) && Object->ExclusiveWrite !=
0) ||
- (!(ShareMode & FILE_SHARE_READ) && Object->AccessRead !=
0) ||
- (!(ShareMode & FILE_SHARE_WRITE) && Object->AccessWrite !=
0))
- {
- DPRINT1("Sharing violation\n");
- Status = STATUS_SHARING_VIOLATION;
- }
- else
- {
- Status = ConSrvInsertObject(ProcessData,
- &OpenConsoleRequest->ConsoleHandle,
- Object,
- DesiredAccess,
- OpenConsoleRequest->Inheritable,
- ShareMode);
- }
-
- LeaveCriticalSection(&Console->Lock);
+ /*
+ * Open a handle to either the active screen buffer or the input buffer.
+ */
+ if (OpenConsoleRequest->HandleType == HANDLE_OUTPUT)
+ {
+ Object = &Console->ActiveBuffer->Header;
+ }
+ else // HANDLE_INPUT
+ {
+ Object = &Console->InputBuffer.Header;
+ }
+
+ if (((DesiredAccess & GENERIC_READ) && Object->ExclusiveRead != 0)
||
+ ((DesiredAccess & GENERIC_WRITE) && Object->ExclusiveWrite != 0)
||
+ (!(ShareMode & FILE_SHARE_READ) && Object->AccessRead != 0)
||
+ (!(ShareMode & FILE_SHARE_WRITE) && Object->AccessWrite != 0))
+ {
+ DPRINT1("Sharing violation\n");
+ Status = STATUS_SHARING_VIOLATION;
+ }
+ else
+ {
+ Status = ConSrvInsertObject(ProcessData,
+ &OpenConsoleRequest->ConsoleHandle,
+ Object,
+ DesiredAccess,
+ OpenConsoleRequest->Inheritable,
+ ShareMode);
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ ConSrvReleaseConsole(Console, TRUE);
return Status;
}
@@ -758,7 +904,6 @@
CSR_API(SrvFreeConsole)
{
- DPRINT1("SrvFreeConsole\n");
ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
return STATUS_SUCCESS;
}
@@ -798,7 +943,6 @@
}
ConSrvReleaseObject(Object, TRUE);
-
return Status;
}
@@ -831,7 +975,6 @@
}
ConSrvReleaseObject(Object, TRUE);
-
return Status;
}
Added: branches/ros-csrss/win32ss/user/consrv/console.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/c…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/console.h (added)
+++ branches/ros-csrss/win32ss/user/consrv/console.h [iso-8859-1] Sat Mar 30 18:44:56
2013
@@ -1,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 */
Propchange: branches/ros-csrss/win32ss/user/consrv/console.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/ros-csrss/win32ss/user/consrv/consrv.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/c…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/consrv.h [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/consrv.h [iso-8859-1] Sat Mar 30 18:44:56 2013
@@ -34,6 +34,9 @@
/* Public Win32K Headers */
#include <ntuser.h>
+/* PSEH for SEH Support */
+#include <pseh/pseh2.h>
+
/* CSRSS Header */
#include <csr/csrsrv.h>
@@ -91,6 +94,20 @@
LPTHREAD_START_ROUTINE CtrlDispatcher;
LPTHREAD_START_ROUTINE PropDispatcher; // We hold the property dialog handler there,
till all the GUI thingie moves out from CSRSS.
} 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 */
@@ -177,12 +194,12 @@
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
PHANDLE pErrorHandle);
-VOID FASTCALL ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData);
NTSTATUS FASTCALL ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData,
struct _CONSOLE** Console,
BOOL LockConsole);
VOID FASTCALL ConSrvReleaseConsole(struct _CONSOLE* Console,
- BOOL IsConsoleLocked);
+ BOOL WasConsoleLocked);
+VOID FASTCALL ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData);
NTSTATUS NTAPI ConSrvNewProcess(PCSR_PROCESS SourceProcess,
PCSR_PROCESS TargetProcess);
Modified: branches/ros-csrss/win32ss/user/consrv/guiconsole.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/g…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/guiconsole.c [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/guiconsole.c [iso-8859-1] Sat Mar 30 18:44:56
2013
@@ -10,6 +10,7 @@
#include "consrv.h"
#include "conio.h"
+#include "console.h"
#include "settings.h"
#include "guiconsole.h"
#include "guisettings.h"
@@ -212,6 +213,13 @@
GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
{
LRESULT Ret = TRUE;
+ PCONSOLE Console = GuiData->Console;
+
+ if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
+ {
+ Ret = FALSE;
+ goto Quit;
+ }
switch (wParam)
{
@@ -229,7 +237,6 @@
case ID_SYSTEM_EDIT_SELECTALL:
{
- PCONSOLE Console = GuiData->Console;
COORD bottomRight = { 0, 0 };
bottomRight.X = Console->ConsoleSize.X - 1;
@@ -255,15 +262,23 @@
break;
default:
- Ret = DefWindowProcW(GuiData->hWindow, WM_SYSCOMMAND, wParam, lParam);
- break;
- }
+ Ret = FALSE;
+ break;
+ }
+
+ LeaveCriticalSection(&Console->Lock);
+
+Quit:
+ if (!Ret)
+ Ret = DefWindowProcW(GuiData->hWindow, WM_SYSCOMMAND, wParam, lParam);
+
return Ret;
}
static PGUI_CONSOLE_DATA
GuiGetGuiData(HWND hWnd)
{
+ /* This function ensures that the console pointer is not NULL */
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)GetWindowLongPtrW(hWnd,
GWLP_USERDATA);
return ( ((GuiData == NULL) || (GuiData->hWindow == hWnd &&
GuiData->Console != NULL)) ? GuiData : NULL );
}
@@ -341,6 +356,8 @@
HFONT OldFont;
TEXTMETRICW Metrics;
SIZE CharSize;
+
+ DPRINT1("GuiConsoleHandleNcCreate\n");
if (NULL == GuiData)
{
@@ -424,12 +441,7 @@
SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
GuiConsoleCreateSysMenu(GuiData->hWindow);
- /* Move and resize the window to the user's values */
- GuiConsoleMoveWindow(GuiData);
- GuiData->WindowSizeLock = TRUE;
- GuiConsoleResizeWindow(GuiData);
- GuiData->WindowSizeLock = FALSE;
-
+ DPRINT1("GuiConsoleHandleNcCreate - setting start event\n");
SetEvent(GuiData->hGuiInitEvent);
return (BOOL)DefWindowProcW(GuiData->hWindow, WM_NCCREATE, 0, (LPARAM)Create);
@@ -525,8 +537,6 @@
HFONT OldFont;
Buff = Console->ActiveBuffer;
-
- /// LOCK /// EnterCriticalSection(&Buff->Header.Console->Lock);
TopLine = rc->top / GuiData->CharHeight + Buff->ShowY;
BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight
- 1 + Buff->ShowY;
@@ -618,57 +628,71 @@
}
}
- /// LOCK /// LeaveCriticalSection(&Buff->Header.Console->Lock);
-
SelectObject(hDC, OldFont);
}
static VOID
-GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData, HDC hDCPaint)
-{
+GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData)
+{
+ BOOL Success = TRUE;
PCONSOLE Console = GuiData->Console;
HDC hDC;
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);
if (hDC != NULL &&
ps.rcPaint.left < ps.rcPaint.right &&
ps.rcPaint.top < ps.rcPaint.bottom)
{
- if (Console->ActiveBuffer->Buffer != NULL)
- {
- EnterCriticalSection(&GuiData->Lock);
-
- GuiConsolePaint(Console,
- GuiData,
- hDC,
- &ps.rcPaint);
-
- if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
+ EnterCriticalSection(&GuiData->Lock);
+
+ GuiConsolePaint(Console,
+ GuiData,
+ hDC,
+ &ps.rcPaint);
+
+ if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
+ {
+ RECT rc;
+ SmallRectToRect(GuiData, &rc, &Console->Selection.srSelection);
+
+ /* invert the selection */
+ if (IntersectRect(&rc,
+ &ps.rcPaint,
+ &rc))
{
- RECT rc;
- SmallRectToRect(GuiData, &rc,
&Console->Selection.srSelection);
-
- /* invert the selection */
- if (IntersectRect(&rc,
- &ps.rcPaint,
- &rc))
- {
- PatBlt(hDC,
- rc.left,
- rc.top,
- rc.right - rc.left,
- rc.bottom - rc.top,
- DSTINVERT);
- }
+ PatBlt(hDC,
+ rc.left,
+ rc.top,
+ rc.right - rc.left,
+ rc.bottom - rc.top,
+ DSTINVERT);
}
-
- LeaveCriticalSection(&GuiData->Lock);
- }
+ }
+
+ LeaveCriticalSection(&GuiData->Lock);
}
EndPaint(GuiData->hWindow, &ps);
+
+Quit:
+ if (Success)
+ LeaveCriticalSection(&Console->Lock);
+ else
+ DefWindowProcW(GuiData->hWindow, WM_PAINT, 0, 0);
+
+ return;
}
static VOID
@@ -676,6 +700,8 @@
{
PCONSOLE Console = GuiData->Console;
MSG Message;
+
+ if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
Message.hwnd = GuiData->hWindow;
Message.message = msg;
@@ -689,6 +715,8 @@
}
ConioProcessKey(Console, &Message);
+
+ LeaveCriticalSection(&Console->Lock);
}
static VOID
@@ -705,6 +733,8 @@
PCONSOLE_SCREEN_BUFFER Buff;
SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL);
+
+ if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
Buff = Console->ActiveBuffer;
GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y);
@@ -782,14 +812,15 @@
GuiData->OldCursor.y = Buff->CursorPosition.Y;
}
}
+
+ LeaveCriticalSection(&Console->Lock);
}
static VOID
GuiConsoleHandleClose(PGUI_CONSOLE_DATA GuiData)
{
PCONSOLE Console = GuiData->Console;
-
- /// LOCK /// EnterCriticalSection(&Console->Lock);
+ if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
/*
* FIXME: Windows will wait up to 5 seconds for the thread to exit.
@@ -798,17 +829,23 @@
*/
ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT);
- /// LOCK /// LeaveCriticalSection(&Console->Lock);
-}
-
-static VOID
-GuiConsoleHandleNcDestroy(PGUI_CONSOLE_DATA GuiData)
-{
- KillTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER);
- GetSystemMenu(GuiData->hWindow, TRUE);
-
- SetWindowLongPtrW(GuiData->hWindow, GWLP_USERDATA, (DWORD_PTR)NULL);
- GuiData->hWindow = NULL;
+ LeaveCriticalSection(&Console->Lock);
+}
+
+static LRESULT
+GuiConsoleHandleNcDestroy(HWND hWnd)
+{
+ // PGUI_CONSOLE_DATA GuiData;
+
+ KillTimer(hWnd, CONGUI_UPDATE_TIMER);
+ 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
@@ -835,43 +872,85 @@
return Coord;
}
-static VOID
-GuiConsoleLeftMouseDown(PGUI_CONSOLE_DATA GuiData, LPARAM lParam)
-{
+static LRESULT
+GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT Ret = TRUE;
PCONSOLE Console = GuiData->Console;
- Console->Selection.dwSelectionAnchor = PointToCoord(GuiData, lParam);
- SetCapture(GuiData->hWindow);
- Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS |
CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
- GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor);
-}
-
-static VOID
-GuiConsoleLeftMouseUp(PGUI_CONSOLE_DATA GuiData, LPARAM lParam)
-{
- PCONSOLE Console = GuiData->Console;
- COORD c;
-
- if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return;
-
- c = PointToCoord(GuiData, lParam);
- Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN;
- GuiConsoleUpdateSelection(Console, &c);
- ReleaseCapture();
-}
-
-static VOID
-GuiConsoleMouseMove(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
-{
- PCONSOLE Console = GuiData->Console;
- COORD c;
-
- if (!(wParam & MK_LBUTTON)) return;
-
- if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return;
-
- c = PointToCoord(GuiData, lParam); /* TODO: Scroll buffer to bring c into view */
- GuiConsoleUpdateSelection(Console, &c);
+ if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
+ {
+ Ret = FALSE;
+ goto Quit;
+ }
+
+ switch (msg)
+ {
+ case WM_LBUTTONDOWN:
+ {
+ Console->Selection.dwSelectionAnchor = PointToCoord(GuiData, lParam);
+ SetCapture(GuiData->hWindow);
+ Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS |
CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
+ GuiConsoleUpdateSelection(Console,
&Console->Selection.dwSelectionAnchor);
+ break;
+ }
+
+ case WM_LBUTTONUP:
+ {
+ COORD c;
+
+ if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) break;
+
+ c = PointToCoord(GuiData, lParam);
+ Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN;
+ GuiConsoleUpdateSelection(Console, &c);
+ ReleaseCapture();
+
+ break;
+ }
+
+ case WM_RBUTTONDOWN:
+ {
+ if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY))
+ {
+ GuiConsolePaste(GuiData);
+ }
+ else
+ {
+ GuiConsoleCopy(GuiData);
+
+ /* Clear the selection */
+ GuiConsoleUpdateSelection(Console, NULL);
+ }
+
+ break;
+ }
+
+ case WM_MOUSEMOVE:
+ {
+ COORD c;
+
+ if (!(wParam & MK_LBUTTON)) break;
+ if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) break;
+
+ c = PointToCoord(GuiData, lParam); /* TODO: Scroll buffer to bring c into
view */
+ 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
@@ -983,29 +1062,13 @@
}
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
GuiConsoleGetMinMaxInfo(PGUI_CONSOLE_DATA GuiData, PMINMAXINFO minMaxInfo)
{
PCONSOLE Console = GuiData->Console;
DWORD windx, windy;
+ if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
+
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);
@@ -1020,12 +1083,16 @@
minMaxInfo->ptMaxTrackSize.x = windx;
minMaxInfo->ptMaxTrackSize.y = windy;
+
+ LeaveCriticalSection(&Console->Lock);
}
static VOID
GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam)
{
PCONSOLE Console = GuiData->Console;
+
+ if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
if ((GuiData->WindowSizeLock == FALSE) &&
(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam ==
SIZE_MINIMIZED))
@@ -1076,6 +1143,8 @@
GuiData->WindowSizeLock = FALSE;
}
+
+ LeaveCriticalSection(&Console->Lock);
}
/*
@@ -1107,8 +1176,7 @@
}
*/
-static
-LRESULT
+static LRESULT
GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam)
{
PCONSOLE Console = GuiData->Console;
@@ -1118,7 +1186,7 @@
int old_pos, Maximum;
PUSHORT pShowXY;
- if (GuiData == NULL) return FALSE;
+ if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return 0;
Buff = Console->ActiveBuffer;
@@ -1139,10 +1207,7 @@
sInfo.cbSize = sizeof(SCROLLINFO);
sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS;
- if (!GetScrollInfo(GuiData->hWindow, fnBar, &sInfo))
- {
- return FALSE;
- }
+ if (!GetScrollInfo(GuiData->hWindow, fnBar, &sInfo)) goto Quit;
old_pos = sInfo.nPos;
@@ -1209,6 +1274,8 @@
UpdateWindow(GuiData->hWindow);
}
+Quit:
+ LeaveCriticalSection(&Console->Lock);
return 0;
}
@@ -1217,14 +1284,21 @@
{
LRESULT Result = 0;
PGUI_CONSOLE_DATA GuiData = NULL;
+ PCONSOLE Console = NULL;
/*
- * If it's the first time we create a window
- * for the terminal, just initialize it.
+ * - If it's the first time we create a window for the terminal,
+ * just initialize it and return.
+ *
+ * - If we are destroying the window, just do it and return.
*/
if (msg == WM_NCCREATE)
{
return (LRESULT)GuiConsoleHandleNcCreate(hWnd, (LPCREATESTRUCTW)lParam);
+ }
+ else if (msg == WM_NCDESTROY)
+ {
+ return GuiConsoleHandleNcDestroy(hWnd);
}
/*
@@ -1235,24 +1309,20 @@
GuiData = GuiGetGuiData(hWnd);
if (GuiData == NULL) return 0;
- // TODO: If the console is about to be destroyed, leave the loop.
-
- /* Lock the console */
- EnterCriticalSection(&GuiData->Console->Lock);
-
- /* We have a console, start message dispatching. */
+ /*
+ * Each helper function which needs the console
+ * has to validate and lock it.
+ */
+
+ /* We have a console, start message dispatching */
switch (msg)
{
case WM_CLOSE:
GuiConsoleHandleClose(GuiData);
break;
- case WM_NCDESTROY:
- GuiConsoleHandleNcDestroy(GuiData);
- break;
-
case WM_PAINT:
- GuiConsoleHandlePaint(GuiData, (HDC)wParam);
+ GuiConsoleHandlePaint(GuiData);
break;
case WM_KEYDOWN:
@@ -1260,37 +1330,43 @@
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_CHAR:
+ {
GuiConsoleHandleKey(GuiData, msg, wParam, lParam);
break;
+ }
case WM_TIMER:
GuiConsoleHandleTimer(GuiData);
break;
+ case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
- GuiConsoleLeftMouseDown(GuiData, lParam);
- break;
-
case WM_LBUTTONUP:
- GuiConsoleLeftMouseUp(GuiData, lParam);
- break;
-
+ case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN:
- GuiConsoleRightMouseDown(GuiData);
- break;
-
- case WM_MOUSEMOVE:
- GuiConsoleMouseMove(GuiData, wParam, lParam);
- break;
+ 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;
+ }
case WM_SYSCOMMAND:
+ {
Result = GuiConsoleHandleSysMenuCommand(GuiData, wParam, lParam);
break;
+ }
case WM_HSCROLL:
case WM_VSCROLL:
+ {
Result = GuiConsoleHandleScroll(GuiData, msg, wParam);
break;
+ }
case WM_GETMINMAXINFO:
GuiConsoleGetMinMaxInfo(GuiData, (PMINMAXINFO)lParam);
@@ -1301,25 +1377,29 @@
break;
case PM_APPLY_CONSOLE_INFO:
- GuiApplyUserSettings(GuiData, (HANDLE)wParam, (BOOL)lParam);
- break;
+ {
+ Console = GuiData->Console; // Not NULL because checked in GuiGetGuiData.
+ if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
+ {
+ GuiApplyUserSettings(GuiData, (HANDLE)wParam, (BOOL)lParam);
+ LeaveCriticalSection(&Console->Lock);
+ }
+ break;
+ }
case PM_CONSOLE_BEEP:
DPRINT1("Beep !!\n");
Beep(800, 200);
break;
- case PM_CONSOLE_SET_TITLE:
- SetWindowText(GuiData->hWindow, GuiData->Console->Title.Buffer);
- break;
+ // case PM_CONSOLE_SET_TITLE:
+ // SetWindowText(GuiData->hWindow, GuiData->Console->Title.Buffer);
+ // break;
default:
- Result = DefWindowProcW(GuiData->hWindow, msg, wParam, lParam);
- break;
- }
-
- /* Unlock the console */
- LeaveCriticalSection(&GuiData->Console->Lock);
+ Result = DefWindowProcW(hWnd, msg, wParam, lParam);
+ break;
+ }
return Result;
}
@@ -1336,8 +1416,6 @@
HWND NewWindow;
LONG WindowCount;
MSG Msg;
- PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
- PCONSOLE Console = GuiData->Console;
switch (msg)
{
@@ -1349,6 +1427,9 @@
case PM_CREATE_CONSOLE:
{
+ PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
+ PCONSOLE Console = GuiData->Console;
+
NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
GUI_CONSOLE_WINDOW_CLASS,
Console->Title.Buffer,
@@ -1381,7 +1462,16 @@
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;
@@ -1389,16 +1479,20 @@
case PM_DESTROY_CONSOLE:
{
+ PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
+
/*
* Window creation is done using a PostMessage(), so it's possible
* that the window that we want to destroy doesn't exist yet.
* So first empty the message queue.
*/
+ /*
while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
- }
+ }*/
+ while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE)) ;
if (GuiData->hWindow != NULL) /* &&
DestroyWindow(GuiData->hWindow) */
{
@@ -1607,6 +1701,8 @@
Console->TermIFace.Data = NULL;
DeleteCriticalSection(&GuiData->Lock);
RtlFreeHeap(ConSrvHeap, 0, GuiData);
+
+ DPRINT1("Quit GuiCleanupConsole\n");
}
static VOID WINAPI
@@ -1835,7 +1931,8 @@
GuiChangeTitle(PCONSOLE Console)
{
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
@@ -1916,6 +2013,7 @@
{
PGUI_CONSOLE_DATA GuiData;
GUI_CONSOLE_INFO TermInfo;
+ SIZE_T Length = 0;
if (Console == NULL || ConsoleInfo == NULL)
return STATUS_INVALID_PARAMETER;
@@ -1984,7 +2082,9 @@
* Set up the GUI data
*/
+ Length = min(wcslen(TermInfo.FaceName) + 1, LF_FACESIZE); // wcsnlen
wcsncpy(GuiData->GuiInfo.FaceName, TermInfo.FaceName, LF_FACESIZE);
+ GuiData->GuiInfo.FaceName[Length] = L'\0';
GuiData->GuiInfo.FontFamily = TermInfo.FontFamily;
GuiData->GuiInfo.FontSize = TermInfo.FontSize;
GuiData->GuiInfo.FontWeight = TermInfo.FontWeight;
@@ -2034,6 +2134,7 @@
/* Wait until initialization has finished */
WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
+ DPRINT1("OK we created the console window\n");
CloseHandle(GuiData->hGuiInitEvent);
GuiData->hGuiInitEvent = NULL;
Modified: branches/ros-csrss/win32ss/user/consrv/guisettings.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/g…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/guisettings.c [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/guisettings.c [iso-8859-1] Sat Mar 30 18:44:56
2013
@@ -86,7 +86,9 @@
if (!wcscmp(szValueName, L"FaceName"))
{
+ SIZE_T Length = min(wcslen(szValue) + 1, LF_FACESIZE); // wcsnlen
wcsncpy(TermInfo->FaceName, szValue, LF_FACESIZE);
+ TermInfo->FaceName[Length] = L'\0';
RetVal = TRUE;
}
else if (!wcscmp(szValueName, L"FontFamily"))
@@ -150,7 +152,7 @@
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"FontSize", REG_DWORD, sizeof(DWORD),
&TermInfo->FontSize, 0);
SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD),
&TermInfo->FontWeight, FW_DONTCARE);
@@ -269,43 +271,59 @@
pSharedInfo->hConsoleWindow = GuiData->hWindow;
pSharedInfo->ShowDefaultParams = Defaults;
- /* Console information */
- pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize;
- pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
- pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup;
- pSharedInfo->ci.FullScreen = Console->FullScreen;
- pSharedInfo->ci.QuickEdit = Console->QuickEdit;
- pSharedInfo->ci.InsertMode = Console->InsertMode;
- pSharedInfo->ci.InputBufferSize = 0;
- pSharedInfo->ci.ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize;
- pSharedInfo->ci.ConsoleSize = Console->ConsoleSize;
- pSharedInfo->ci.CursorBlinkOn;
- pSharedInfo->ci.ForceCursorOff;
- pSharedInfo->ci.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
- pSharedInfo->ci.ScreenAttrib = Console->ActiveBuffer->ScreenDefaultAttrib;
- pSharedInfo->ci.PopupAttrib = Console->ActiveBuffer->PopupDefaultAttrib;
- pSharedInfo->ci.CodePage;
-
- /* GUI Information */
- pSharedInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
- GuiInfo = pSharedInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pSharedInfo +
1);
- wcsncpy(GuiInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
- GuiInfo->FontSize = (DWORD)GuiData->GuiInfo.FontSize;
- GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
- GuiInfo->UseRasterFonts = GuiData->GuiInfo.UseRasterFonts;
- /// GuiInfo->WindowPosition = GuiData->GuiInfo.WindowPosition;
- GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition;
- GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin;
- /* Offsetize */
- pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)GuiInfo -
(ULONG_PTR)pSharedInfo);
-
- /* Palette */
- memcpy(pSharedInfo->ci.Colors, Console->Colors, sizeof(Console->Colors));
-
- /* Title of the console, original one corresponding to the one set by the console
leader */
- Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) /
sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1,
- Console->OriginalTitle.Length / sizeof(WCHAR));
- wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
+ /*
+ * We fill-in the fields only if we display
+ * our properties, not the default ones.
+ */
+ if (!Defaults)
+ {
+ /* Console information */
+ pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize;
+ pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
+ pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup;
+ pSharedInfo->ci.FullScreen = Console->FullScreen;
+ pSharedInfo->ci.QuickEdit = Console->QuickEdit;
+ pSharedInfo->ci.InsertMode = Console->InsertMode;
+ pSharedInfo->ci.InputBufferSize = 0;
+ pSharedInfo->ci.ScreenBufferSize =
Console->ActiveBuffer->ScreenBufferSize;
+ pSharedInfo->ci.ConsoleSize = Console->ConsoleSize;
+ pSharedInfo->ci.CursorBlinkOn;
+ pSharedInfo->ci.ForceCursorOff;
+ pSharedInfo->ci.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
+ pSharedInfo->ci.ScreenAttrib =
Console->ActiveBuffer->ScreenDefaultAttrib;
+ pSharedInfo->ci.PopupAttrib =
Console->ActiveBuffer->PopupDefaultAttrib;
+ pSharedInfo->ci.CodePage;
+
+ /* GUI Information */
+ pSharedInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
+ 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);
+ GuiInfo->FaceName[Length] = L'\0';
+ GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily;
+ GuiInfo->FontSize = GuiData->GuiInfo.FontSize;
+ GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
+ GuiInfo->UseRasterFonts = GuiData->GuiInfo.UseRasterFonts;
+ /// GuiInfo->WindowPosition = GuiData->GuiInfo.WindowPosition;
+ GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition;
+ GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin;
+ /* Offsetize */
+ pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)GuiInfo -
(ULONG_PTR)pSharedInfo);
+
+ /* Palette */
+ memcpy(pSharedInfo->ci.Colors, Console->Colors,
sizeof(Console->Colors));
+
+ /* Title of the console, original one corresponding to the one set by the console
leader */
+ Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) /
sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1,
+ Console->OriginalTitle.Length / sizeof(WCHAR));
+ wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer,
Length);
+ }
+ else
+ {
+ Length = 0;
+ }
+
+ /* Null-terminate the title */
pSharedInfo->ci.ConsoleTitle[Length] = L'\0';
@@ -326,29 +344,46 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Error: Impossible to duplicate section handle for client ; Status =
%lu\n", Status);
- NtClose(hSection);
- return;
+ goto Quit;
}
/* Start the properties dialog */
if (ProcessData->PropDispatcher)
{
- HANDLE Thread;
-
- Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
- ProcessData->PropDispatcher,
- (PVOID)hClientSection, 0, NULL);
- if (NULL == Thread)
- {
- DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
- return;
- }
-
- DPRINT1("We succeeded at creating ProcessData->PropDispatcher remote
thread, ProcessId = %x, Process = 0x%p\n",
ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
- /// WaitForSingleObject(Thread, INFINITE);
- CloseHandle(Thread);
- }
-
+ _SEH2_TRY
+ {
+ HANDLE Thread = NULL;
+
+ _SEH2_TRY
+ {
+ Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle,
NULL, 0,
+ ProcessData->PropDispatcher,
+ (PVOID)hClientSection, 0, NULL);
+ if (NULL == Thread)
+ {
+ DPRINT1("Failed thread creation (Error: 0x%x)\n",
GetLastError());
+ }
+ else
+ {
+ DPRINT("ProcessData->PropDispatcher remote thread creation
succeeded, ProcessId = %x, Process = 0x%p\n",
ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
+ /// WaitForSingleObject(Thread, INFINITE);
+ }
+ }
+ _SEH2_FINALLY
+ {
+ 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 */
NtClose(hSection);
return;
@@ -369,8 +404,6 @@
PTERMINAL_INFO TermInfo = NULL;
PGUI_CONSOLE_INFO GuiInfo = NULL;
- /// LOCK /// EnterCriticalSection(&Console->Lock);
-
/* Get the console leader process, our client */
ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
CONSOLE_PROCESS_DATA,
@@ -406,51 +439,65 @@
return Status;
}
- /* Check that the section is well-sized */
- if ( (ViewSize < sizeof(CONSOLE_PROPS)) ||
- (pConInfo->TerminalInfo.Size != sizeof(GUI_CONSOLE_INFO)) ||
- (ViewSize < sizeof(CONSOLE_PROPS) + pConInfo->TerminalInfo.Size) )
- {
- DPRINT1("Error: section bad-sized: sizeof(Section) <
sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n");
- Status = STATUS_INVALID_VIEW_SIZE;
- goto Quit;
- }
-
- // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow
-
- /* Set the console informations */
- ConInfo = &pConInfo->ci;
- ConSrvApplyUserSettings(Console, ConInfo);
-
- /* Set the terminal informations - De-offsetization of the pointer */
- TermInfo = &pConInfo->TerminalInfo;
- GuiInfo = TermInfo->TermInfo = (PVOID)((ULONG_PTR)pConInfo +
(ULONG_PTR)TermInfo->TermInfo);
-
- // memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO));
-
- /* Move the window to the user's values */
- GuiData->GuiInfo.AutoPosition = GuiInfo->AutoPosition;
- GuiData->GuiInfo.WindowOrigin = GuiInfo->WindowOrigin;
- GuiConsoleMoveWindow(GuiData);
-
- InvalidateRect(GuiData->hWindow, NULL, TRUE);
-
-
- /*
- * Save settings if needed
- */
-
- // FIXME: Do it in the console properties applet ??
- if (SaveSettings)
- {
- DWORD ProcessId =
HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
- ConSrvWriteUserSettings(ConInfo, ProcessId);
- GuiConsoleWriteUserSettings(GuiInfo, ConInfo->ConsoleTitle, ProcessId);
- }
-
- Status = STATUS_SUCCESS;
-
- /// LOCK /// LeaveCriticalSection(&Console->Lock);
+ _SEH2_TRY
+ {
+ /* Check that the section is well-sized */
+ if ( (ViewSize < sizeof(CONSOLE_PROPS)) ||
+ (pConInfo->TerminalInfo.Size != sizeof(GUI_CONSOLE_INFO)) ||
+ (ViewSize < sizeof(CONSOLE_PROPS) + pConInfo->TerminalInfo.Size) )
+ {
+ DPRINT1("Error: section bad-sized: sizeof(Section) <
sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n");
+ Status = STATUS_INVALID_VIEW_SIZE;
+ _SEH2_YIELD(goto Quit);
+ }
+
+ // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow
+
+ /* Retrieve terminal informations */
+ ConInfo = &pConInfo->ci;
+ TermInfo = &pConInfo->TerminalInfo;
+ 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));
+
+ /* Move the window to the user's values */
+ GuiData->GuiInfo.AutoPosition = GuiInfo->AutoPosition;
+ GuiData->GuiInfo.WindowOrigin = GuiInfo->WindowOrigin;
+ GuiConsoleMoveWindow(GuiData);
+
+ InvalidateRect(GuiData->hWindow, NULL, TRUE);
+ }
+
+ /*
+ * Save settings if needed
+ */
+ // FIXME: Do it in the console properties applet ??
+ if (SaveSettings)
+ {
+ DWORD ProcessId =
HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
+ ConSrvWriteUserSettings(ConInfo, ProcessId);
+ GuiConsoleWriteUserSettings(GuiInfo, ConInfo->ConsoleTitle, ProcessId);
+ }
+
+ Status = STATUS_SUCCESS;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ DPRINT1("GuiApplyUserSettings - Caught an exception, Status = %08X\n",
Status);
+ }
+ _SEH2_END;
Quit:
/* Finally, close the section and return */
Modified: branches/ros-csrss/win32ss/user/consrv/handle.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/h…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/handle.c [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/handle.c [iso-8859-1] Sat Mar 30 18:44:56 2013
@@ -10,8 +10,9 @@
#include "consrv.h"
#include "conio.h"
-
-//#define NDEBUG
+#include "console.h"
+
+#define NDEBUG
#include <debug.h>
@@ -22,7 +23,7 @@
{
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_WRITE) Object->AccessWrite += Change;
@@ -236,8 +237,6 @@
static VOID
ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData)
{
- DPRINT1("ConSrvFreeHandlesTable\n");
-
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (ProcessData->HandleTable != NULL)
@@ -267,12 +266,13 @@
BOOL Inheritable,
DWORD ShareMode)
{
-#define IO_HANDLES_INCREMENT 2*3
+#define IO_HANDLES_INCREMENT 2 * 3
ULONG i;
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++)
{
@@ -289,7 +289,7 @@
IO_HANDLES_INCREMENT) * sizeof(CONSOLE_IO_HANDLE));
if (Block == NULL)
{
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_UNSUCCESSFUL;
}
RtlCopyMemory(Block,
@@ -307,7 +307,7 @@
ConSrvCreateHandleEntry(&ProcessData->HandleTable[i]);
*Handle = ULongToHandle((i << 2) | 0x3);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
@@ -329,11 +329,9 @@
return STATUS_INVALID_HANDLE;
}
- DPRINT1("ConSrvRemoveObject - Process 0x%p, Release 0x%p\n",
ProcessData->Process, &ProcessData->HandleTable[h]);
ConSrvCloseHandleEntry(&ProcessData->HandleTable[h]);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-
return STATUS_SUCCESS;
}
@@ -376,16 +374,24 @@
return STATUS_INVALID_HANDLE;
}
- _InterlockedIncrement(&ObjectEntry->Console->ReferenceCount);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- if (LockConsole) EnterCriticalSection(&ObjectEntry->Console->Lock);
-
- /* Return the objects to the caller */
- *Object = ObjectEntry;
- if (Entry) *Entry = HandleEntry;
-
- return STATUS_SUCCESS;
+ if (ConSrvValidateConsole(ObjectEntry->Console, CONSOLE_RUNNING, LockConsole))
+ {
+ _InterlockedIncrement(&ObjectEntry->Console->ReferenceCount);
+
+ /* Return the objects to the caller */
+ *Object = ObjectEntry;
+ if (Entry) *Entry = HandleEntry;
+
+ // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ // RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ return STATUS_INVALID_HANDLE;
+ }
}
VOID
@@ -464,6 +470,13 @@
PHANDLE pErrorHandle)
{
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 */
ProcessData->Console = Console;
@@ -479,7 +492,7 @@
{
DPRINT1("Failed to initialize the handles table\n");
ProcessData->Console = NULL;
- return Status;
+ goto Quit;
}
}
@@ -494,7 +507,7 @@
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
ConSrvFreeHandlesTable(ProcessData); // NOTE: Always free the handles table.
ProcessData->Console = NULL;
- return Status;
+ goto Quit;
}
/* Insert the process into the processes list of the console */
@@ -506,29 +519,34 @@
/* Update the internal info of the terminal */
ConioRefreshInternalInfo(ProcessData->Console);
- return STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
+
+Quit:
+ /* Unlock the console and return */
+ LeaveCriticalSection(&Console->Lock);
+ return Status;
}
VOID
FASTCALL
ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
{
- PCONSOLE Console;
+ PCONSOLE Console = ProcessData->Console;
DPRINT1("ConSrvRemoveConsole\n");
- /* Close all console handles and free the handle table memory */
- ConSrvFreeHandlesTable(ProcessData);
-
- /* Detach process from console */
- Console = ProcessData->Console;
- if (Console != NULL)
- {
- DPRINT1("ConSrvRemoveConsole - Console->ReferenceCount = %lu - We are
going to decrement it !\n", Console->ReferenceCount);
+ 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);
+
+ /* Detach the process from the console */
ProcessData->Console = NULL;
-
- EnterCriticalSection(&Console->Lock);
- DPRINT1("ConSrvRemoveConsole - Locking OK\n");
/* Remove ourselves from the console's list of processes */
RemoveEntryList(&ProcessData->ConsoleLink);
@@ -537,10 +555,105 @@
ConioRefreshInternalInfo(Console);
/* Release the console */
+ DPRINT1("ConSrvRemoveConsole - Decrement Console->ReferenceCount =
%lu\n", Console->ReferenceCount);
ConSrvReleaseConsole(Console, TRUE);
//CloseHandle(ProcessData->ConsoleEvent);
//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
@@ -549,37 +662,53 @@
PCONSOLE* Console,
BOOL LockConsole)
{
+ NTSTATUS Status = STATUS_SUCCESS;
PCONSOLE ProcessConsole;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
ProcessConsole = ProcessData->Console;
- if (!ProcessConsole)
+ if (ConSrvValidateConsole(ProcessConsole, CONSOLE_RUNNING, LockConsole))
+ {
+ InterlockedIncrement(&ProcessConsole->ReferenceCount);
+ *Console = ProcessConsole;
+ }
+ else
{
*Console = NULL;
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_INVALID_HANDLE;
- }
-
- InterlockedIncrement(&ProcessConsole->ReferenceCount);
+ Status = STATUS_INVALID_HANDLE;
+ }
+
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-
- if (LockConsole) EnterCriticalSection(&ProcessConsole->Lock);
-
- *Console = ProcessConsole;
-
- return STATUS_SUCCESS;
+ return Status;
}
VOID FASTCALL
ConSrvReleaseConsole(PCONSOLE Console,
- BOOL IsConsoleLocked)
-{
- if (IsConsoleLocked) LeaveCriticalSection(&Console->Lock);
-
- /* Decrement reference count */
- if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
- ConSrvDeleteConsole(Console);
+ BOOL WasConsoleLocked)
+{
+ LONG RefCount = 0;
+
+ if (!Console) return;
+ // if (Console->ReferenceCount == 0) return; // This shouldn't happen
+ ASSERT(Console->ReferenceCount > 0);
+
+ /* The console must be locked */
+ // ASSERT(Console_locked);
+
+ /*
+ * Decrement the reference count. Save the new value too,
+ * because Console->ReferenceCount might be modified after
+ * the console gets unlocked but before we check whether we
+ * can destroy it.
+ */
+ RefCount = _InterlockedDecrement(&Console->ReferenceCount);
+
+ /* Unlock the console if needed */
+ if (WasConsoleLocked) LeaveCriticalSection(&Console->Lock);
+
+ /* Delete the console if needed */
+ if (RefCount <= 0) ConSrvDeleteConsole(Console);
}
NTSTATUS
@@ -745,8 +874,6 @@
* This function is called whenever a new process (GUI or CUI) is destroyed.
**************************************************************************/
- DPRINT1("ConSrvDisconnect\n");
-
if ( ProcessData->Console != NULL ||
ProcessData->HandleTable != NULL )
{
@@ -828,6 +955,7 @@
}
}
+ /* Insert the new handle inside the process handles table */
ApiMessage->Status = ConSrvInsertObject(ProcessData,
&DuplicateHandleRequest->ConsoleHandle, // Use the new handle value!
Entry->Object,
Modified: branches/ros-csrss/win32ss/user/consrv/init.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-csrss/win32ss/user/consrv/i…
==============================================================================
--- branches/ros-csrss/win32ss/user/consrv/init.c [iso-8859-1] (original)
+++ branches/ros-csrss/win32ss/user/consrv/init.c [iso-8859-1] Sat Mar 30 18:44:56 2013
@@ -10,6 +10,7 @@
#include "consrv.h"
#include "conio.h"
+#include "console.h"
#define NDEBUG
#include <debug.h>