Author: jmorlan
Date: Sun May 23 07:33:21 2010
New Revision: 47317
URL:
http://svn.reactos.org/svn/reactos?rev=47317&view=rev
Log:
[WIN32CSR]
- Simplify locking: having a lock for each screen buffer is overkill since most programs
only use one screen buffer at a time. (besides, almost all APIs were taking the console
lock anyway) Reduce to just having one lock for a console.
- Instead of keeping track of how many references a screen buffer has, keep track of
handles only. When all handles to a screen buffer are closed, it should be deleted even
if it's the active buffer (not yet implemented).
Modified:
trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
trunk/reactos/subsystems/win32/csrss/win32csr/conio.h
trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c
trunk/reactos/subsystems/win32/csrss/win32csr/handle.c
trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conio.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/conio.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/conio.c [iso-8859-1] Sun May 23 07:33:21
2010
@@ -53,9 +53,9 @@
return STATUS_INVALID_HANDLE;
}
- InterlockedIncrement(&ProcessConsole->Header.ReferenceCount);
+ InterlockedIncrement(&ProcessConsole->ReferenceCount);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- EnterCriticalSection(&(ProcessConsole->Header.Lock));
+ EnterCriticalSection(&(ProcessConsole->Lock));
*Console = ProcessConsole;
return STATUS_SUCCESS;
@@ -117,7 +117,8 @@
DPRINT("CsrInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX,
Buffer->MaxY);
Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC;
- Buffer->Header.ReferenceCount = 0;
+ Buffer->Header.Console = Console;
+ Buffer->Header.HandleCount = 0;
Buffer->ShowX = 0;
Buffer->ShowY = 0;
Buffer->VirtualY = 0;
@@ -126,7 +127,6 @@
{
return STATUS_INSUFFICIENT_RESOURCES;
}
- InitializeCriticalSection(&Buffer->Header.Lock);
ConioInitScreenBuffer(Console, Buffer);
/* initialize buffer to be empty with default attributes */
for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY;
Buffer->CurrentY++)
@@ -154,11 +154,12 @@
//FIXME
RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
- Console->Header.ReferenceCount = 0;
+ Console->ReferenceCount = 0;
Console->WaitingChars = 0;
Console->WaitingLines = 0;
Console->EchoCount = 0;
Console->Header.Type = CONIO_CONSOLE_MAGIC;
+ Console->Header.Console = Console;
Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT |
ENABLE_MOUSE_INPUT;
Console->EarlyReturn = FALSE;
Console->ActiveBuffer = NULL;
@@ -177,7 +178,7 @@
return STATUS_UNSUCCESSFUL;
}
Console->PrivateData = NULL;
- InitializeCriticalSection(&Console->Header.Lock);
+ InitializeCriticalSection(&Console->Lock);
GuiMode = DtbgIsDesktopVisible();
@@ -186,7 +187,7 @@
if (NULL == NewBuffer)
{
RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->ActiveEvent);
return STATUS_INSUFFICIENT_RESOURCES;
}
@@ -212,7 +213,7 @@
{
HeapFree(Win32CsrApiHeap,0, NewBuffer);
RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->ActiveEvent);
DPRINT1("GuiInitConsole: failed\n");
return Status;
@@ -224,15 +225,12 @@
{
ConioCleanupConsole(Console);
RtlFreeUnicodeString(&Console->Title);
- DeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->ActiveEvent);
HeapFree(Win32CsrApiHeap, 0, NewBuffer);
DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
return Status;
}
-
- /* add a reference count because the buffer is tied to the console */
- InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount);
/* copy buffer contents to screen */
ConioDrawConsole(Console);
@@ -308,7 +306,7 @@
Request->Data.AllocConsoleRequest.Console = Console;
/* Add a reference count because the process is tied to the console */
- Console->Header.ReferenceCount++;
+ _InterlockedIncrement(&Console->ReferenceCount);
if (NewConsole || !ProcessData->bInheritHandles)
{
@@ -836,15 +834,16 @@
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) -
sizeof(PORT_MESSAGE);
return STATUS_INVALID_PARAMETER;
}
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
-
- Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
- Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
-
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
+
+ Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+ Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+
+ Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ Console = Buff->Header.Console;
if(Request->Data.WriteConsoleRequest.Unicode)
{
@@ -872,7 +871,6 @@
if (Buffer)
{
- Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (NT_SUCCESS(Status))
{
Status = ConioWriteConsole(Console, Buff, Buffer,
@@ -881,14 +879,13 @@
{
Written = Request->Data.WriteConsoleRequest.NrCharactersToWrite;
}
- ConioUnlockScreenBuffer(Buff);
}
if (Request->Data.WriteConsoleRequest.Unicode)
{
RtlFreeHeap(GetProcessHeap(), 0, Buffer);
}
}
- ConioUnlockConsole(Console);
+ ConioUnlockScreenBuffer(Buff);
Request->Data.WriteConsoleRequest.NrCharactersWritten = Written;
@@ -899,7 +896,6 @@
ConioDeleteScreenBuffer(Object_t *Object)
{
PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
- DeleteCriticalSection(&Buffer->Header.Lock);
HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
HeapFree(Win32CsrApiHeap, 0, Buffer);
}
@@ -933,15 +929,12 @@
}
ConioCleanupConsole(Console);
- if (0 ==
InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
- {
- ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
- }
+ ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
Console->ActiveBuffer = NULL;
CloseHandle(Console->ActiveEvent);
- DeleteCriticalSection(&Console->Header.Lock);
+ DeleteCriticalSection(&Console->Lock);
RtlFreeUnicodeString(&Console->Title);
IntDeleteAllAliases(Console->Aliases);
HeapFree(Win32CsrApiHeap, 0, Console);
@@ -1280,17 +1273,12 @@
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.ScreenBufferInfoRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
pInfo = &Request->Data.ScreenBufferInfoRequest.Info;
pInfo->dwSize.X = Buff->MaxX;
pInfo->dwSize.Y = Buff->MaxY;
@@ -1304,7 +1292,6 @@
pInfo->dwMaximumWindowSize.X = Buff->MaxX;
pInfo->dwMaximumWindowSize.Y = Buff->MaxY;
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
@@ -1319,21 +1306,15 @@
DPRINT("CsrSetCursor\n");
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
NewCursorX = Request->Data.SetCursorRequest.Position.X;
NewCursorY = Request->Data.SetCursorRequest.Position.Y;
@@ -1341,7 +1322,6 @@
NewCursorY < 0 || NewCursorY >= Buff->MaxY)
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_INVALID_PARAMETER;
}
OldCursorX = Buff->CurrentX;
@@ -1353,13 +1333,11 @@
if (! ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_UNSUCCESSFUL;
}
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
@@ -1415,11 +1393,15 @@
return STATUS_INVALID_PARAMETER;
}
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
+ Status = ConioLockScreenBuffer(ProcessData,
+
Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
+ &Buff,
+ GENERIC_WRITE);
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
if (NT_SUCCESS(Status))
{
+ Console = Buff->Header.Console;
if(Request->Data.WriteConsoleOutputCharRequest.Unicode)
{
Length = WideCharToMultiByte(Console->OutputCodePage, 0,
@@ -1446,10 +1428,6 @@
if (String)
{
- Status = ConioLockScreenBuffer(ProcessData,
-
Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle,
- &Buff,
- GENERIC_WRITE);
if (NT_SUCCESS(Status))
{
X = Request->Data.WriteConsoleOutputCharRequest.Coord.X;
@@ -1481,14 +1459,13 @@
Request->Data.WriteConsoleOutputCharRequest.EndCoord.X = X;
Request->Data.WriteConsoleOutputCharRequest.EndCoord.Y = (Y +
Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
- ConioUnlockScreenBuffer(Buff);
}
if (Request->Data.WriteConsoleRequest.Unicode)
{
RtlFreeHeap(GetProcessHeap(), 0, tmpString);
}
}
- ConioUnlockConsole(Console);
+ ConioUnlockScreenBuffer(Buff);
}
Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten = Written;
return Status;
@@ -1509,18 +1486,12 @@
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.FillOutputRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
X = Request->Data.FillOutputRequest.Position.X;
Y = (Request->Data.FillOutputRequest.Position.Y + Buff->VirtualY) %
Buff->MaxY;
@@ -1554,7 +1525,6 @@
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
Length = Request->Data.FillOutputRequest.Length;
Request->Data.FillOutputRequest.NrCharactersWritten = Length;
return STATUS_SUCCESS;
@@ -1661,13 +1631,8 @@
return STATUS_INVALID_PARAMETER;
}
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
- Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
+ Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+ Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle,
@@ -1675,9 +1640,9 @@
GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X;
Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->VirtualY) %
Buff->MaxY;
@@ -1706,8 +1671,6 @@
ConioDrawRegion(Console, &UpdateRect);
}
- ConioUnlockConsole(Console);
-
Request->Data.WriteConsoleOutputAttribRequest.EndCoord.X = X;
Request->Data.WriteConsoleOutputAttribRequest.EndCoord.Y = (Y + Buff->MaxY -
Buff->VirtualY) % Buff->MaxY;
@@ -1728,20 +1691,14 @@
DPRINT("CsrFillOutputAttrib\n");
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.FillOutputAttribRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
X = Request->Data.FillOutputAttribRequest.Coord.X;
Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->VirtualY) %
Buff->MaxY;
@@ -1771,7 +1728,6 @@
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
@@ -1812,18 +1768,12 @@
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.SetCursorInfoRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
Size = Request->Data.SetCursorInfoRequest.Info.dwSize;
Visible = Request->Data.SetCursorInfoRequest.Info.bVisible;
@@ -1845,13 +1795,11 @@
if (! ConioSetCursorInfo(Console, Buff))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_UNSUCCESSFUL;
}
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
@@ -1864,18 +1812,12 @@
DPRINT("CsrSetTextAttrib\n");
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.SetCursorRequest.ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
Buff->DefaultAttrib = Request->Data.SetAttribRequest.Attrib;
if (Buff == Console->ActiveBuffer)
@@ -1883,13 +1825,11 @@
if (! ConioUpdateScreenInfo(Console, Buff))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_UNSUCCESSFUL;
}
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
@@ -1904,9 +1844,9 @@
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = Win32CsrGetObject(ProcessData,
- Request->Data.SetConsoleModeRequest.ConsoleHandle,
- (Object_t **) &Console, GENERIC_WRITE);
+ Status = Win32CsrLockObject(ProcessData,
+ Request->Data.SetConsoleModeRequest.ConsoleHandle,
+ (Object_t **) &Console, GENERIC_WRITE, 0);
if (! NT_SUCCESS(Status))
{
return Status;
@@ -1926,7 +1866,7 @@
Status = STATUS_INVALID_HANDLE;
}
- Win32CsrReleaseObjectByPointer((Object_t *)Console);
+ Win32CsrUnlockObject((Object_t *)Console);
return Status;
}
@@ -1941,8 +1881,8 @@
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
- Status = Win32CsrGetObject(ProcessData,
Request->Data.GetConsoleModeRequest.ConsoleHandle,
- (Object_t **) &Console, GENERIC_READ);
+ Status = Win32CsrLockObject(ProcessData,
Request->Data.GetConsoleModeRequest.ConsoleHandle,
+ (Object_t **) &Console, GENERIC_READ, 0);
if (! NT_SUCCESS(Status))
{
return Status;
@@ -1962,7 +1902,7 @@
Status = STATUS_INVALID_HANDLE;
}
- Win32CsrReleaseObjectByPointer((Object_t *)Console);
+ Win32CsrUnlockObject((Object_t *)Console);
return Status;
}
@@ -2039,43 +1979,33 @@
DPRINT("CsrSetScreenBuffer\n");
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.SetScreenBufferRequest.OutputHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
if (Buff == Console->ActiveBuffer)
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
- /* drop reference to old buffer, maybe delete */
- if (! InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
+ /* If old buffer has no handles, it's now unreferenced */
+ if (Console->ActiveBuffer->Header.HandleCount == 0)
{
ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
}
/* tie console to new buffer */
Console->ActiveBuffer = Buff;
- /* inc ref count on new buffer */
- InterlockedIncrement(&Buff->Header.ReferenceCount);
/* Redraw the console */
ConioDrawConsole(Console);
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
@@ -2181,12 +2111,6 @@
DPRINT("CsrWriteConsoleOutput\n");
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData,
@@ -2195,9 +2119,9 @@
GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
PSize = BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO);
@@ -2208,7 +2132,6 @@
((ULONG_PTR)ProcessData->CsrSectionViewBase +
ProcessData->CsrSectionViewSize)))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_ACCESS_VIOLATION;
}
WriteRegion.left = Request->Data.WriteConsoleOutputRequest.WriteRegion.Left;
@@ -2226,7 +2149,6 @@
if (! ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
/* It is okay to have a WriteRegion completely outside the screen buffer.
No data is written then. */
@@ -2257,7 +2179,6 @@
ConioDrawRegion(Console, &WriteRegion);
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
Request->Data.WriteConsoleOutputRequest.WriteRegion.Right = WriteRegion.left + SizeX
- 1;
Request->Data.WriteConsoleOutputRequest.WriteRegion.Bottom = WriteRegion.top + SizeY
- 1;
@@ -2327,20 +2248,14 @@
DestinationOrigin =
Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin;
Fill = Request->Data.ScrollConsoleScreenBufferRequest.Fill;
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Status = ConioLockScreenBuffer(ProcessData, ConsoleHandle, &Buff, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
ScrollRectangle.left =
Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Left;
ScrollRectangle.top =
Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle.Top;
@@ -2352,7 +2267,6 @@
if (! ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle))
{
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
@@ -2374,7 +2288,6 @@
ClipRectangle.bottom =
Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle.Bottom;
if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle,
&ScreenBuffer))
{
- ConioUnlockConsole(Console);
ConioUnlockScreenBuffer(Buff);
return STATUS_SUCCESS;
}
@@ -2408,7 +2321,6 @@
}
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
@@ -2432,18 +2344,12 @@
CharSize = (Request->Data.ReadConsoleOutputCharRequest.Unicode ? sizeof(WCHAR) :
sizeof(CHAR));
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle, &Buff, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
- return Status;
- }
+ return Status;
+ }
+ Console = Buff->Header.Console;
Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X;
Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + Buff->VirtualY)
% Buff->MaxY;
@@ -2479,7 +2385,6 @@
Request->Data.ReadConsoleOutputCharRequest.EndCoord.Y = (Ypos - Buff->VirtualY +
Buff->MaxY) % Buff->MaxY;
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
Request->Data.ReadConsoleOutputCharRequest.CharsRead = (DWORD)((ULONG_PTR)ReadBuffer
- (ULONG_PTR)Request->Data.ReadConsoleOutputCharRequest.String) / CharSize;
if (Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize +
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) > sizeof(CSR_API_MESSAGE))
@@ -3131,22 +3036,15 @@
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) -
sizeof(PORT_MESSAGE);
- Status = ConioConsoleFromProcessData(ProcessData, &Console);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
Status = ConioLockScreenBuffer(ProcessData,
Request->Data.SetScreenBufferSize.OutputHandle, &Buff, GENERIC_WRITE);
if (!NT_SUCCESS(Status))
{
- ConioUnlockConsole(Console);
return Status;
}
+ Console = Buff->Header.Console;
Status = ConioResizeBuffer(Console, Buff,
Request->Data.SetScreenBufferSize.Size);
ConioUnlockScreenBuffer(Buff);
- ConioUnlockConsole(Console);
return Status;
}
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conio.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/conio.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/conio.h [iso-8859-1] Sun May 23 07:33:21
2010
@@ -69,6 +69,8 @@
typedef struct tagCSRSS_CONSOLE
{
Object_t Header; /* Object header */
+ LONG ReferenceCount;
+ CRITICAL_SECTION Lock;
PCSRSS_CONSOLE Prev, Next; /* Next and Prev consoles in console wheel */
HANDLE ActiveEvent;
LIST_ENTRY InputEvents; /* List head for input event queue */
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/guiconsole.c [iso-8859-1] Sun May 23
07:33:21 2010
@@ -872,7 +872,7 @@
Buff = Console->ActiveBuffer;
- EnterCriticalSection(&Buff->Header.Lock);
+ EnterCriticalSection(&Buff->Header.Console->Lock);
TopLine = rc->top / GuiData->CharHeight + Buff->ShowY;
BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight
- 1 + Buff->ShowY;
@@ -971,7 +971,7 @@
}
}
- LeaveCriticalSection(&Buff->Header.Lock);
+ LeaveCriticalSection(&Buff->Header.Console->Lock);
SelectObject(hDC,
OldFont);
@@ -1327,7 +1327,7 @@
GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
- EnterCriticalSection(&Console->Header.Lock);
+ EnterCriticalSection(&Console->Lock);
current_entry = Console->ProcessList.Flink;
while (current_entry != &Console->ProcessList)
@@ -1341,7 +1341,7 @@
ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current);
}
- LeaveCriticalSection(&Console->Header.Lock);
+ LeaveCriticalSection(&Console->Lock);
}
static VOID FASTCALL
@@ -1809,7 +1809,7 @@
COORD BufSize;
BOOL SizeChanged = FALSE;
- EnterCriticalSection(&ActiveBuffer->Header.Lock);
+ EnterCriticalSection(&Console->Lock);
/* apply text / background color */
GuiData->ScreenText = pConInfo->ScreenText;
@@ -1844,7 +1844,7 @@
GuiData->WindowSizeLock = FALSE;
}
- LeaveCriticalSection(&ActiveBuffer->Header.Lock);
+ LeaveCriticalSection(&Console->Lock);
InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
}
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/handle.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/handle.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/handle.c [iso-8859-1] Sun May 23
07:33:21 2010
@@ -16,13 +16,6 @@
/* FUNCTIONS *****************************************************************/
-static unsigned ObjectDefinitionsCount = 2;
-static CSRSS_OBJECT_DEFINITION ObjectDefinitions[] =
-{
- { CONIO_CONSOLE_MAGIC, ConioDeleteConsole },
- { CONIO_SCREEN_BUFFER_MAGIC, ConioDeleteScreenBuffer },
-};
-
static
BOOL
CsrIsConsoleHandle(HANDLE Handle)
@@ -30,58 +23,40 @@
return ((ULONG_PTR)Handle & 0x10000003) == 0x3;
}
-NTSTATUS
-FASTCALL
-Win32CsrGetObject(
- PCSRSS_PROCESS_DATA ProcessData,
- HANDLE Handle,
- Object_t **Object,
- DWORD Access )
-{
- ULONG_PTR h = (ULONG_PTR)Handle >> 2;
-
- DPRINT("CsrGetObject, Object: %x, %x, %x\n",
- Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
-
- RtlEnterCriticalSection(&ProcessData->HandleTableLock);
- if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
- || (*Object = ProcessData->HandleTable[h].Object) == NULL
- || ~ProcessData->HandleTable[h].Access & Access)
- {
- DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- return STATUS_INVALID_HANDLE;
- }
- _InterlockedIncrement(&(*Object)->ReferenceCount);
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
- // DbgPrint( "CsrGetObject returning\n" );
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-FASTCALL
-Win32CsrReleaseObjectByPointer(
- Object_t *Object)
-{
- unsigned DefIndex;
-
- /* dec ref count */
- if (_InterlockedDecrement(&Object->ReferenceCount) == 0)
- {
- for (DefIndex = 0; DefIndex < ObjectDefinitionsCount; DefIndex++)
- {
- if (Object->Type == ObjectDefinitions[DefIndex].Type)
- {
- (ObjectDefinitions[DefIndex].CsrCleanupObjectProc)(Object);
- return STATUS_SUCCESS;
- }
- }
-
- DPRINT1("CSR: Error: releasing unknown object type 0x%x",
Object->Type);
- }
-
- return STATUS_SUCCESS;
+static VOID
+Win32CsrCreateHandleEntry(
+ PCSRSS_HANDLE Entry,
+ Object_t *Object,
+ DWORD Access,
+ BOOL Inheritable)
+{
+ Entry->Object = Object;
+ Entry->Access = Access;
+ Entry->Inheritable = Inheritable;
+ _InterlockedIncrement(&Object->HandleCount);
+}
+
+static VOID
+Win32CsrCloseHandleEntry(
+ PCSRSS_HANDLE Entry)
+{
+ Object_t *Object = Entry->Object;
+ if (Object != NULL)
+ {
+ Entry->Object = NULL;
+ /* If the last handle to a screen buffer is closed, delete it */
+ if (_InterlockedDecrement(&Object->HandleCount) == 0
+ && Object->Type == CONIO_SCREEN_BUFFER_MAGIC)
+ {
+ PCSRSS_CONSOLE Console = Object->Console;
+ EnterCriticalSection(&Console->Lock);
+ /* TODO: Should delete even the active buffer, but we're not yet ready
+ * to deal with the case where this results in no buffers left. */
+ if (Object != &Console->ActiveBuffer->Header)
+ ConioDeleteScreenBuffer(Object);
+ LeaveCriticalSection(&Console->Lock);
+ }
+ }
}
NTSTATUS
@@ -100,10 +75,9 @@
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
- ProcessData->HandleTable[h].Object = NULL;
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-
- return Win32CsrReleaseObjectByPointer(Object);
+ Win32CsrCloseHandleEntry(&ProcessData->HandleTable[h]);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+ return STATUS_SUCCESS;
}
NTSTATUS
@@ -114,22 +88,25 @@
DWORD Access,
LONG Type)
{
- NTSTATUS Status;
-
- Status = Win32CsrGetObject(ProcessData, Handle, Object, Access);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
-
- if ((*Object)->Type != Type)
- {
- Win32CsrReleaseObjectByPointer(*Object);
+ ULONG_PTR h = (ULONG_PTR)Handle >> 2;
+
+ DPRINT("CsrGetObject, Object: %x, %x, %x\n",
+ Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
+
+ RtlEnterCriticalSection(&ProcessData->HandleTableLock);
+ if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
+ || (*Object = ProcessData->HandleTable[h].Object) == NULL
+ || ~ProcessData->HandleTable[h].Access & Access
+ || (Type != 0 && (*Object)->Type != Type))
+ {
+ DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
-
- EnterCriticalSection(&((*Object)->Lock));
-
+ _InterlockedIncrement(&(*Object)->Console->ReferenceCount);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
+
+ EnterCriticalSection(&((*Object)->Console->Lock));
return STATUS_SUCCESS;
}
@@ -137,8 +114,11 @@
FASTCALL
Win32CsrUnlockObject(Object_t *Object)
{
- LeaveCriticalSection(&(Object->Lock));
- Win32CsrReleaseObjectByPointer(Object);
+ PCSRSS_CONSOLE Console = Object->Console;
+ LeaveCriticalSection(&Console->Lock);
+ /* dec ref count */
+ if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
+ ConioDeleteConsole(&Console->Header);
}
NTSTATUS
@@ -153,27 +133,24 @@
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
for (i = 0; i < ProcessData->HandleTableSize; i++)
- {
- if (ProcessData->HandleTable[i].Object != NULL)
- Win32CsrReleaseObjectByPointer(ProcessData->HandleTable[i].Object);
- }
+ Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
ProcessData->HandleTableSize = 0;
RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable);
ProcessData->HandleTable = NULL;
Console = ProcessData->Console;
- ProcessData->Console = NULL;
- RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
-
if (Console != NULL)
{
- EnterCriticalSection(&Console->Header.Lock);
+ ProcessData->Console = NULL;
+ EnterCriticalSection(&Console->Lock);
RemoveEntryList(&ProcessData->ProcessEntry);
- LeaveCriticalSection(&Console->Header.Lock);
- Win32CsrReleaseObjectByPointer(&Console->Header);
+ LeaveCriticalSection(&Console->Lock);
+ if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
+ ConioDeleteConsole(&Console->Header);
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
-
+ RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_PARAMETER;
}
@@ -215,11 +192,8 @@
ProcessData->HandleTable = Block;
ProcessData->HandleTableSize += 64;
}
- ProcessData->HandleTable[i].Object = Object;
- ProcessData->HandleTable[i].Access = Access;
- ProcessData->HandleTable[i].Inheritable = Inheritable;
+ Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i], Object, Access,
Inheritable);
*Handle = UlongToHandle((i << 2) | 0x3);
- _InterlockedIncrement( &Object->ReferenceCount );
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return(STATUS_SUCCESS);
}
@@ -256,8 +230,10 @@
if (SourceProcessData->HandleTable[i].Object != NULL &&
SourceProcessData->HandleTable[i].Inheritable)
{
- TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
- _InterlockedIncrement(
&SourceProcessData->HandleTable[i].Object->ReferenceCount );
+ Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i],
+ SourceProcessData->HandleTable[i].Object,
+ SourceProcessData->HandleTable[i].Access,
+
SourceProcessData->HandleTable[i].Inheritable);
}
}
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
@@ -385,9 +361,7 @@
if (NT_SUCCESS(Request->Status)
&& Request->Data.DuplicateHandleRequest.Options &
DUPLICATE_CLOSE_SOURCE)
{
- /* Close the original handle. This cannot drop the count to 0, since a new handle
now exists */
- _InterlockedDecrement(&Entry->Object->ReferenceCount);
- Entry->Object = NULL;
+ Win32CsrCloseHandleEntry(Entry);
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h [iso-8859-1] Sun May 23
07:33:21 2010
@@ -17,8 +17,8 @@
typedef struct Object_tt
{
LONG Type;
- LONG ReferenceCount;
- CRITICAL_SECTION Lock;
+ struct tagCSRSS_CONSOLE *Console;
+ LONG HandleCount;
} Object_t;
typedef struct _CSRSS_HANDLE
@@ -48,11 +48,6 @@
DWORD Access,
long Type);
VOID FASTCALL Win32CsrUnlockObject(Object_t *Object);
-NTSTATUS FASTCALL Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData,
- HANDLE Handle,
- Object_t **Object,
- DWORD Access);
-NTSTATUS FASTCALL Win32CsrReleaseObjectByPointer(Object_t *Object);
NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Object);
NTSTATUS WINAPI Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData);