[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

@ -61,9 +61,6 @@
#define FIELD_OFFSET(type,fld) ((LONG)&(((type *)0)->fld)) #define FIELD_OFFSET(type,fld) ((LONG)&(((type *)0)->fld))
#endif #endif
#define IsConsoleHandle(h) \
(((((ULONG_PTR)h) & 0x10000003) == 0x3) ? TRUE : FALSE)
#define HANDLE_DETACHED_PROCESS (HANDLE)-2 #define HANDLE_DETACHED_PROCESS (HANDLE)-2
#define HANDLE_CREATE_NEW_CONSOLE (HANDLE)-3 #define HANDLE_CREATE_NEW_CONSOLE (HANDLE)-3
#define HANDLE_CREATE_NO_WINDOW (HANDLE)-4 #define HANDLE_CREATE_NO_WINDOW (HANDLE)-4
@ -194,12 +191,12 @@ BOOL WINAPI VerifyConsoleIoHandle(HANDLE Handle);
BOOL WINAPI CloseConsoleHandle(HANDLE Handle); BOOL WINAPI CloseConsoleHandle(HANDLE Handle);
HANDLE WINAPI HANDLE WINAPI
GetConsoleInputWaitHandle (VOID); GetConsoleInputWaitHandle(VOID);
HANDLE WINAPI OpenConsoleW (LPCWSTR wsName, HANDLE WINAPI OpenConsoleW(LPCWSTR wsName,
DWORD dwDesiredAccess, DWORD dwDesiredAccess,
BOOL bInheritHandle, BOOL bInheritHandle,
DWORD dwShareMode); DWORD dwShareMode);
BOOL WINAPI SetConsoleInputExeNameW(LPCWSTR lpInputExeName); BOOL WINAPI SetConsoleInputExeNameW(LPCWSTR lpInputExeName);

View file

@ -39,6 +39,7 @@
#include <csr/csr.h> #include <csr/csr.h>
#include <win/base.h> #include <win/base.h>
#include <win/basemsg.h> #include <win/basemsg.h>
#include <win/console.h>
#include <win/conmsg.h> #include <win/conmsg.h>
#include <win/winmsg.h> #include <win/winmsg.h>

View file

@ -11,23 +11,8 @@
#pragma once #pragma once
#define ConsoleGetPerProcessData(pcsrprocess) \ #define IsConsoleHandle(h) \
((PCONSOLE_PROCESS_DATA)((pcsrprocess)->ServerData[CONSRV_SERVERDLL_INDEX])) (((ULONG_PTR)(h) & 0x3) == 0x3)
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;
#endif // _CONSOLE_H #endif // _CONSOLE_H

View file

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

View file

@ -36,7 +36,7 @@ extern HANDLE ConSrvHeap;
// extern PBASE_STATIC_SERVER_DATA BaseStaticServerData; // extern PBASE_STATIC_SERVER_DATA BaseStaticServerData;
/* Common things to input/output/console objects */
typedef struct Object_tt typedef struct Object_tt
{ {
LONG Type; LONG Type;
@ -49,13 +49,30 @@ typedef struct Object_tt
typedef struct _CSRSS_HANDLE typedef struct _CSRSS_HANDLE
{ {
Object_t *Object; Object_t *Object; /* The object on which the handle points to */
DWORD Access; DWORD Access;
BOOL Inheritable; BOOL Inheritable;
DWORD ShareMode; DWORD ShareMode;
} CSRSS_HANDLE, *PCSRSS_HANDLE; } 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 */ /* alias.c */
CSR_API(SrvAddConsoleAlias); CSR_API(SrvAddConsoleAlias);

View file

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