[KERNEL32/CONSRV]

- Code reorganization.
- In particular, move IsConsoleHandle macro to a place which it can be used by both kernel32 and consrv.

svn path=/branches/ros-csrss/; revision=58063
This commit is contained in:
Hermès Bélusca-Maïto 2012-12-30 21:02:12 +00:00
parent d6769b4364
commit c0399e88a6
6 changed files with 126 additions and 111 deletions

View file

@ -51,12 +51,16 @@ typedef struct tagCSRSS_CONSOLE
Object_t Header; /* Object header */
LONG ReferenceCount;
CRITICAL_SECTION Lock;
struct tagCSRSS_CONSOLE *Prev, *Next; /* Next and Prev consoles in console wheel */
struct tagCSRSS_CONSOLE *Prev, *Next; /* Next and Prev consoles in console wheel */
struct tagCSRSS_CONSOLE_VTBL *Vtbl; /* Using CUI or GUI consoles */
LIST_ENTRY ProcessList;
LIST_ENTRY InputEvents; /* List head for input event queue */
HANDLE ActiveEvent; /* Event set when an input event is added in its queue */
LIST_ENTRY ReadWaitQueue; /* List head for the queue of read wait blocks */
LIST_ENTRY InputEvents; /* List head for input event queue */
PWCHAR LineBuffer; /* current line being input, in line buffered mode */
WORD LineMaxSize; /* maximum size of line in characters (including CR+LF) */
WORD LineSize; /* current size of line */
@ -65,28 +69,30 @@ typedef struct tagCSRSS_CONSOLE
BOOLEAN LineUpPressed;
BOOLEAN LineInsertToggle; /* replace character over cursor instead of inserting */
ULONG LineWakeupMask; /* bitmap of which control characters will end line input */
struct tagALIAS_HEADER *Aliases;
LIST_ENTRY HistoryBuffers;
UINT HistoryBufferSize; /* size for newly created history buffers */
UINT NumberOfHistoryBuffers; /* maximum number of history buffers allowed */
BOOLEAN HistoryNoDup; /* remove old duplicate history entries */
LIST_ENTRY BufferList; /* List of all screen buffers for this console */
PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */
BYTE PauseFlags;
HANDLE UnpauseEvent;
LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */
WORD Mode; /* Console mode flags */
UNICODE_STRING Title; /* Title of console */
DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */
HWND hWindow;
COORD Size;
PVOID PrivateData;
UINT CodePage;
UINT OutputCodePage;
struct tagCSRSS_CONSOLE_VTBL *Vtbl;
LIST_ENTRY ProcessList;
struct tagALIAS_HEADER *Aliases;
CONSOLE_SELECTION_INFO Selection;
BYTE PauseFlags;
HANDLE UnpauseEvent;
LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */
CONSOLE_SELECTION_INFO Selection;
} CSRSS_CONSOLE, *PCSRSS_CONSOLE;
typedef struct tagCSRSS_CONSOLE_VTBL

View file

@ -36,7 +36,7 @@ extern HANDLE ConSrvHeap;
// extern PBASE_STATIC_SERVER_DATA BaseStaticServerData;
/* Common things to input/output/console objects */
typedef struct Object_tt
{
LONG Type;
@ -49,13 +49,30 @@ typedef struct Object_tt
typedef struct _CSRSS_HANDLE
{
Object_t *Object;
Object_t *Object; /* The object on which the handle points to */
DWORD Access;
BOOL Inheritable;
DWORD ShareMode;
} CSRSS_HANDLE, *PCSRSS_HANDLE;
#define ConsoleGetPerProcessData(pcsrprocess) \
((PCONSOLE_PROCESS_DATA)((pcsrprocess)->ServerData[CONSRV_SERVERDLL_INDEX]))
typedef struct _CONSOLE_PROCESS_DATA
{
LIST_ENTRY ConsoleLink;
PCSR_PROCESS Process; // Parent process.
HANDLE ConsoleEvent;
/* PCSRSS_CONSOLE */ struct tagCSRSS_CONSOLE* Console;
/* PCSRSS_CONSOLE */ struct tagCSRSS_CONSOLE* ParentConsole;
BOOL bInheritHandles;
RTL_CRITICAL_SECTION HandleTableLock;
ULONG HandleTableSize;
/* PCSRSS_HANDLE */ struct _CSRSS_HANDLE* HandleTable; // Is it a length-varying table or length-fixed ??
LPTHREAD_START_ROUTINE CtrlDispatcher;
} CONSOLE_PROCESS_DATA, *PCONSOLE_PROCESS_DATA;
/* alias.c */
CSR_API(SrvAddConsoleAlias);

View file

@ -2,7 +2,7 @@
* LICENSE: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/consrv/handle.c
* PURPOSE: Handle functions
* PURPOSE: Console IO Handle functions
* PROGRAMMERS:
*/
@ -15,14 +15,7 @@
#include <debug.h>
/* FUNCTIONS *****************************************************************/
static
BOOL
CsrIsConsoleHandle(HANDLE Handle)
{
return ((ULONG_PTR)Handle & 0x10000003) == 0x3;
}
/* PRIVATE FUNCTIONS *********************************************************/
static INT
AdjustHandleCounts(PCSRSS_HANDLE Entry, INT Change)
@ -69,6 +62,57 @@ Win32CsrCloseHandleEntry(PCSRSS_HANDLE Entry)
}
}
/* FUNCTIONS *****************************************************************/
NTSTATUS
FASTCALL
Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
PHANDLE Handle,
Object_t *Object,
DWORD Access,
BOOL Inheritable,
DWORD ShareMode)
{
ULONG i;
PCSRSS_HANDLE Block;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
for (i = 0; i < ProcessData->HandleTableSize; i++)
{
if (ProcessData->HandleTable[i].Object == NULL)
{
break;
}
}
if (i >= ProcessData->HandleTableSize)
{
Block = RtlAllocateHeap(ConSrvHeap,
HEAP_ZERO_MEMORY,
(ProcessData->HandleTableSize + 64) * sizeof(CSRSS_HANDLE));
if (Block == NULL)
{
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return(STATUS_UNSUCCESSFUL);
}
RtlCopyMemory(Block,
ProcessData->HandleTable,
ProcessData->HandleTableSize * sizeof(CSRSS_HANDLE));
RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
ProcessData->HandleTable = Block;
ProcessData->HandleTableSize += 64;
}
ProcessData->HandleTable[i].Object = Object;
ProcessData->HandleTable[i].Access = Access;
ProcessData->HandleTable[i].Inheritable = Inheritable;
ProcessData->HandleTable[i].ShareMode = ShareMode;
Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i]);
*Handle = UlongToHandle((i << 2) | 0x3);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
NTSTATUS
FASTCALL
Win32CsrReleaseObject(PCONSOLE_PROCESS_DATA ProcessData,
@ -78,14 +122,17 @@ Win32CsrReleaseObject(PCONSOLE_PROCESS_DATA ProcessData,
Object_t *Object;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (h >= ProcessData->HandleTableSize
|| (Object = ProcessData->HandleTable[h].Object) == NULL)
if (h >= ProcessData->HandleTableSize ||
(Object = ProcessData->HandleTable[h].Object) == NULL)
{
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[h]);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
@ -103,15 +150,18 @@ Win32CsrLockObject(PCONSOLE_PROCESS_DATA ProcessData,
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))
if ( !IsConsoleHandle(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;
}
_InterlockedIncrement(&(*Object)->Console->ReferenceCount);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
@ -130,6 +180,8 @@ Win32CsrUnlockObject(Object_t *Object)
ConioDeleteConsole(&Console->Header);
}
NTSTATUS
NTAPI
ConsoleNewProcess(PCSR_PROCESS SourceProcess,
@ -238,54 +290,6 @@ Win32CsrReleaseConsole(PCSR_PROCESS Process)
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
}
NTSTATUS
FASTCALL
Win32CsrInsertObject(PCONSOLE_PROCESS_DATA ProcessData,
PHANDLE Handle,
Object_t *Object,
DWORD Access,
BOOL Inheritable,
DWORD ShareMode)
{
ULONG i;
PCSRSS_HANDLE Block;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
for (i = 0; i < ProcessData->HandleTableSize; i++)
{
if (ProcessData->HandleTable[i].Object == NULL)
{
break;
}
}
if (i >= ProcessData->HandleTableSize)
{
Block = RtlAllocateHeap(ConSrvHeap,
HEAP_ZERO_MEMORY,
(ProcessData->HandleTableSize + 64) * sizeof(CSRSS_HANDLE));
if (Block == NULL)
{
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return(STATUS_UNSUCCESSFUL);
}
RtlCopyMemory(Block,
ProcessData->HandleTable,
ProcessData->HandleTableSize * sizeof(CSRSS_HANDLE));
RtlFreeHeap(ConSrvHeap, 0, ProcessData->HandleTable);
ProcessData->HandleTable = Block;
ProcessData->HandleTableSize += 64;
}
ProcessData->HandleTable[i].Object = Object;
ProcessData->HandleTable[i].Access = Access;
ProcessData->HandleTable[i].Inheritable = Inheritable;
ProcessData->HandleTable[i].ShareMode = ShareMode;
Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i]);
*Handle = UlongToHandle((i << 2) | 0x3);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
CSR_API(SrvCloseHandle)
{
PCSRSS_CLOSE_HANDLE CloseHandleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CloseHandleRequest;
@ -299,16 +303,19 @@ CSR_API(SrvVerifyConsoleIoHandle)
NTSTATUS Status = STATUS_SUCCESS;
PCSRSS_VERIFY_HANDLE VerifyHandleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.VerifyHandleRequest;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
ULONG_PTR Index;
HANDLE Handle = VerifyHandleRequest->Handle;
ULONG_PTR Index = (ULONG_PTR)Handle >> 2;
Index = (ULONG_PTR)VerifyHandleRequest->Handle >> 2;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (Index >= ProcessData->HandleTableSize ||
if (!IsConsoleHandle(Handle) ||
Index >= ProcessData->HandleTableSize ||
ProcessData->HandleTable[Index].Object == NULL)
{
DPRINT("CsrVerifyObject failed\n");
Status = STATUS_INVALID_HANDLE;
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
@ -316,18 +323,20 @@ CSR_API(SrvVerifyConsoleIoHandle)
CSR_API(SrvDuplicateHandle)
{
ULONG_PTR Index;
PCSRSS_HANDLE Entry;
DWORD DesiredAccess;
PCSRSS_DUPLICATE_HANDLE DuplicateHandleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.DuplicateHandleRequest;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
HANDLE Handle = DuplicateHandleRequest->Handle;
ULONG_PTR Index = (ULONG_PTR)Handle >> 2;
Index = (ULONG_PTR)DuplicateHandleRequest->Handle >> 2;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (Index >= ProcessData->HandleTableSize
|| (Entry = &ProcessData->HandleTable[Index])->Object == NULL)
if ( /** !IsConsoleHandle(Handle) || **/
Index >= ProcessData->HandleTableSize ||
(Entry = &ProcessData->HandleTable[Index])->Object == NULL)
{
DPRINT1("Couldn't dup invalid handle %p\n", DuplicateHandleRequest->Handle);
DPRINT1("Couldn't duplicate invalid handle %p\n", Handle);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
@ -343,20 +352,20 @@ CSR_API(SrvDuplicateHandle)
if (~Entry->Access & DesiredAccess)
{
DPRINT1("Handle %p only has access %X; requested %X\n",
DuplicateHandleRequest->Handle, Entry->Access, DesiredAccess);
Handle, Entry->Access, DesiredAccess);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_PARAMETER;
}
}
ApiMessage->Status = Win32CsrInsertObject(ProcessData,
&DuplicateHandleRequest->Handle,
&DuplicateHandleRequest->Handle, // Use the new handle value!
Entry->Object,
DesiredAccess,
DuplicateHandleRequest->Inheritable,
Entry->ShareMode);
if (NT_SUCCESS(ApiMessage->Status)
&& DuplicateHandleRequest->Options & DUPLICATE_CLOSE_SOURCE)
if (NT_SUCCESS(ApiMessage->Status) &&
DuplicateHandleRequest->Options & DUPLICATE_CLOSE_SOURCE)
{
Win32CsrCloseHandleEntry(Entry);
}