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/win3... ============================================================================== --- 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/win3... ============================================================================== --- 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/win3... ============================================================================== --- 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/win3... ============================================================================== --- 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/win3... ============================================================================== --- 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);