- Implement access masks and optional inheritability for console handles. Currently, only CsrDuplicateHandle actually checks the access mask.

- CreateFileW: Pass CONIN$/CONOUT$ opens to OpenConsoleW.
- DuplicateConsoleHandle: Remove ProcessId from request structure, since console handles can only be duplicated in the calling process.
                          Don't check low bits of handle (Windows ignores them), but do check options and (if DUPLICATE_SAME_ACCESS is not specified) access mode. 
- OpenConsoleW: Make wsName parameter const; allow any combination of GENERIC_READ and GENERIC_WRITE, don't require both.
- CreateConsoleScreenBuffer: Add parameter checks; return INVALID_HANDLE_VALUE (not FALSE) on failure.
- Remove remnants of unnecessary handle in Get/SetConsoleTitle.
- CsrDuplicateHandle: Implement DUPLICATE_CLOSE_SOURCE and DUPLICATE_SAME_ACCESS options.

svn path=/trunk/; revision=34685
This commit is contained in:
Jeffrey Morlan 2008-07-22 17:37:13 +00:00
parent b026106358
commit 0cc9f32797
11 changed files with 162 additions and 103 deletions

View file

@ -99,12 +99,21 @@ HANDLE STDCALL CreateFileW (LPCWSTR lpFileName,
HANDLE FileHandle; HANDLE FileHandle;
NTSTATUS Status; NTSTATUS Status;
ULONG FileAttributes, Flags = 0; ULONG FileAttributes, Flags = 0;
CSR_API_MESSAGE Request;
PVOID EaBuffer = NULL; PVOID EaBuffer = NULL;
ULONG EaLength = 0; ULONG EaLength = 0;
TRACE("CreateFileW(lpFileName %S)\n",lpFileName); TRACE("CreateFileW(lpFileName %S)\n",lpFileName);
/* check for console input/output */
if (0 == _wcsicmp(L"CONOUT$", lpFileName)
|| 0 == _wcsicmp(L"CONIN$", lpFileName))
{
return OpenConsoleW(lpFileName,
dwDesiredAccess,
lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE,
dwCreationDisposition);
}
/* validate & translate the creation disposition */ /* validate & translate the creation disposition */
switch (dwCreationDisposition) switch (dwCreationDisposition)
{ {
@ -187,44 +196,6 @@ HANDLE STDCALL CreateFileW (LPCWSTR lpFileName,
/* FILE_FLAG_POSIX_SEMANTICS is handled later */ /* FILE_FLAG_POSIX_SEMANTICS is handled later */
/* check for console output */
if (0 == _wcsicmp(L"CONOUT$", lpFileName))
{
/* FIXME: Send required access rights to Csrss */
Status = CsrClientCallServer(&Request,
NULL,
MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE),
sizeof(CSR_API_MESSAGE));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
{
SetLastErrorByStatus(Status);
return INVALID_HANDLE_VALUE;
}
else
{
return Request.Data.GetOutputHandleRequest.OutputHandle;
}
}
/* check for console input */
if (0 == _wcsicmp(L"CONIN$", lpFileName))
{
/* FIXME: Send required access rights to Csrss */
Status = CsrClientCallServer(&Request,
NULL,
MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE),
sizeof(CSR_API_MESSAGE));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
{
SetLastErrorByStatus(Status);
return INVALID_HANDLE_VALUE;
}
else
{
return Request.Data.GetInputHandleRequest.InputHandle;
}
}
/* validate & translate the filename */ /* validate & translate the filename */
if (!RtlDosPathNameToNtPathName_U (lpFileName, if (!RtlDosPathNameToNtPathName_U (lpFileName,
&NtPathU, &NtPathU,

View file

@ -66,7 +66,7 @@ BOOL STDCALL CloseConsoleHandle(HANDLE Handle);
HANDLE STDCALL HANDLE STDCALL
GetConsoleInputWaitHandle (VOID); GetConsoleInputWaitHandle (VOID);
HANDLE STDCALL OpenConsoleW (LPWSTR wsName, HANDLE STDCALL OpenConsoleW (LPCWSTR wsName,
DWORD dwDesiredAccess, DWORD dwDesiredAccess,
BOOL bInheritHandle, BOOL bInheritHandle,
DWORD dwCreationDistribution); DWORD dwCreationDistribution);

View file

@ -264,7 +264,9 @@ DuplicateConsoleHandle (HANDLE hConsole,
ULONG CsrRequest; ULONG CsrRequest;
NTSTATUS Status; NTSTATUS Status;
if (IsConsoleHandle (hConsole) == FALSE) if (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)
|| (!(dwOptions & DUPLICATE_SAME_ACCESS)
&& dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)))
{ {
SetLastError (ERROR_INVALID_PARAMETER); SetLastError (ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
@ -272,7 +274,9 @@ DuplicateConsoleHandle (HANDLE hConsole,
CsrRequest = MAKE_CSR_API(DUPLICATE_HANDLE, CSR_NATIVE); CsrRequest = MAKE_CSR_API(DUPLICATE_HANDLE, CSR_NATIVE);
Request.Data.DuplicateHandleRequest.Handle = hConsole; Request.Data.DuplicateHandleRequest.Handle = hConsole;
Request.Data.DuplicateHandleRequest.ProcessId = GetTeb()->Cid.UniqueProcess; Request.Data.DuplicateHandleRequest.Access = dwDesiredAccess;
Request.Data.DuplicateHandleRequest.Inheritable = bInheritHandle;
Request.Data.DuplicateHandleRequest.Options = dwOptions;
Status = CsrClientCallServer(&Request, Status = CsrClientCallServer(&Request,
NULL, NULL,
CsrRequest, CsrRequest,
@ -899,7 +903,7 @@ InvalidateConsoleDIBits (DWORD Unknown0,
* @unimplemented * @unimplemented
*/ */
HANDLE STDCALL HANDLE STDCALL
OpenConsoleW (LPWSTR wsName, OpenConsoleW (LPCWSTR wsName,
DWORD dwDesiredAccess, DWORD dwDesiredAccess,
BOOL bInheritHandle, BOOL bInheritHandle,
DWORD dwCreationDistribution) DWORD dwCreationDistribution)
@ -909,25 +913,22 @@ OpenConsoleW (LPWSTR wsName,
{ {
CSR_API_MESSAGE Request; ULONG CsrRequest; CSR_API_MESSAGE Request; ULONG CsrRequest;
PHANDLE phConsole = NULL;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
if(0 == _wcsicmp(wsName, L"CONIN$")) if(0 == _wcsicmp(wsName, L"CONIN$"))
{ {
CsrRequest = MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE); CsrRequest = MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE);
phConsole = & Request.Data.GetInputHandleRequest.InputHandle;
} }
else if (0 == _wcsicmp(wsName, L"CONOUT$")) else if (0 == _wcsicmp(wsName, L"CONOUT$"))
{ {
CsrRequest = MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE); CsrRequest = MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE);
phConsole = & Request.Data.GetOutputHandleRequest.OutputHandle;
} }
else else
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return(INVALID_HANDLE_VALUE); return(INVALID_HANDLE_VALUE);
} }
if ((GENERIC_READ|GENERIC_WRITE) != dwDesiredAccess) if (dwDesiredAccess & ~(GENERIC_READ|GENERIC_WRITE))
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return(INVALID_HANDLE_VALUE); return(INVALID_HANDLE_VALUE);
@ -937,6 +938,9 @@ OpenConsoleW (LPWSTR wsName,
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return(INVALID_HANDLE_VALUE); return(INVALID_HANDLE_VALUE);
} }
/* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */
Request.Data.GetInputHandleRequest.Access = dwDesiredAccess;
Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle;
Status = CsrClientCallServer(& Request, Status = CsrClientCallServer(& Request,
NULL, NULL,
CsrRequest, CsrRequest,
@ -946,7 +950,7 @@ OpenConsoleW (LPWSTR wsName,
SetLastErrorByStatus(Status); SetLastErrorByStatus(Status);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
return(*phConsole); return Request.Data.GetInputHandleRequest.InputHandle;
} }
@ -3476,17 +3480,29 @@ CreateConsoleScreenBuffer(
LPVOID lpScreenBufferData LPVOID lpScreenBufferData
) )
{ {
// FIXME: don't ignore access, share mode, and security
CSR_API_MESSAGE Request; ULONG CsrRequest; CSR_API_MESSAGE Request; ULONG CsrRequest;
NTSTATUS Status; NTSTATUS Status;
if (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)
|| dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)
|| dwFlags != CONSOLE_TEXTMODE_BUFFER)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
Request.Data.CreateScreenBufferRequest.Access = dwDesiredAccess;
Request.Data.CreateScreenBufferRequest.ShareMode = dwShareMode;
Request.Data.CreateScreenBufferRequest.Inheritable =
lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE;
CsrRequest = MAKE_CSR_API(CREATE_SCREEN_BUFFER, CSR_CONSOLE); CsrRequest = MAKE_CSR_API(CREATE_SCREEN_BUFFER, CSR_CONSOLE);
Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) ); Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) ) if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
{ {
SetLastErrorByStatus ( Status ); SetLastErrorByStatus ( Status );
return FALSE; return INVALID_HANDLE_VALUE;
} }
return Request.Data.CreateScreenBufferRequest.OutputHandle; return Request.Data.CreateScreenBufferRequest.OutputHandle;
} }

View file

@ -180,7 +180,9 @@ typedef struct
typedef struct typedef struct
{ {
/* may want to add some parameters here someday */ DWORD Access;
DWORD ShareMode;
BOOL Inheritable;
HANDLE OutputHandle; /* handle to newly created screen buffer */ HANDLE OutputHandle; /* handle to newly created screen buffer */
} CSRSS_CREATE_SCREEN_BUFFER, *PCSRSS_CREATE_SCREEN_BUFFER; } CSRSS_CREATE_SCREEN_BUFFER, *PCSRSS_CREATE_SCREEN_BUFFER;
@ -197,14 +199,12 @@ typedef struct
typedef struct typedef struct
{ {
HANDLE Console;
DWORD Length; DWORD Length;
WCHAR Title[0]; WCHAR Title[0];
} CSRSS_SET_TITLE, *PCSRSS_SET_TITLE; } CSRSS_SET_TITLE, *PCSRSS_SET_TITLE;
typedef struct typedef struct
{ {
HANDLE ConsoleHandle;
DWORD Length; DWORD Length;
WCHAR Title[0]; WCHAR Title[0];
} CSRSS_GET_TITLE, *PCSRSS_GET_TITLE; } CSRSS_GET_TITLE, *PCSRSS_GET_TITLE;
@ -312,11 +312,15 @@ typedef struct
typedef struct typedef struct
{ {
DWORD Access;
BOOL Inheritable;
HANDLE InputHandle; HANDLE InputHandle;
} CSRSS_GET_INPUT_HANDLE, *PCSRSS_GET_INPUT_HANDLE; } CSRSS_GET_INPUT_HANDLE, *PCSRSS_GET_INPUT_HANDLE;
typedef struct typedef struct
{ {
DWORD Access;
BOOL Inheritable;
HANDLE OutputHandle; HANDLE OutputHandle;
} CSRSS_GET_OUTPUT_HANDLE, *PCSRSS_GET_OUTPUT_HANDLE; } CSRSS_GET_OUTPUT_HANDLE, *PCSRSS_GET_OUTPUT_HANDLE;
@ -333,7 +337,9 @@ typedef struct
typedef struct typedef struct
{ {
HANDLE Handle; HANDLE Handle;
HANDLE ProcessId; DWORD Access;
BOOL Inheritable;
DWORD Options;
} CSRSS_DUPLICATE_HANDLE, *PCSRSS_DUPLICATE_HANDLE; } CSRSS_DUPLICATE_HANDLE, *PCSRSS_DUPLICATE_HANDLE;
#define CONSOLE_HARDWARE_STATE_GET 0 #define CONSOLE_HARDWARE_STATE_GET 0

View file

@ -61,7 +61,7 @@ CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object ) NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object, DWORD Access )
{ {
ULONG h = (ULONG)Handle >> 2; ULONG h = (ULONG)Handle >> 2;
DPRINT("CsrGetObject, Object: %x, %x, %x\n", Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0); DPRINT("CsrGetObject, Object: %x, %x, %x\n", Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
@ -72,7 +72,8 @@ NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, O
} }
RtlEnterCriticalSection(&ProcessData->HandleTableLock); RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
|| (*Object = ProcessData->HandleTable[h]) == NULL) || (*Object = ProcessData->HandleTable[h].Object) == NULL
|| ~ProcessData->HandleTable[h].Access & Access)
{ {
DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle); DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock); RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
@ -127,18 +128,22 @@ CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
} }
RtlEnterCriticalSection(&ProcessData->HandleTableLock); RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
|| (Object = ProcessData->HandleTable[h]) == NULL) || (Object = ProcessData->HandleTable[h].Object) == NULL)
{ {
RtlLeaveCriticalSection(&ProcessData->HandleTableLock); RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE; return STATUS_INVALID_HANDLE;
} }
ProcessData->HandleTable[h] = NULL; ProcessData->HandleTable[h].Object = NULL;
RtlLeaveCriticalSection(&ProcessData->HandleTableLock); RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return CsrReleaseObjectByPointer(Object); return CsrReleaseObjectByPointer(Object);
} }
NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object ) NTSTATUS STDCALL CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData,
PHANDLE Handle,
Object_t *Object,
DWORD Access,
BOOL Inheritable)
{ {
ULONG i; ULONG i;
PVOID* Block; PVOID* Block;
@ -152,7 +157,7 @@ NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handl
for (i = 0; i < ProcessData->HandleTableSize; i++) for (i = 0; i < ProcessData->HandleTableSize; i++)
{ {
if (ProcessData->HandleTable[i] == NULL) if (ProcessData->HandleTable[i].Object == NULL)
{ {
break; break;
} }
@ -161,7 +166,7 @@ NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handl
{ {
Block = RtlAllocateHeap(CsrssApiHeap, Block = RtlAllocateHeap(CsrssApiHeap,
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
(ProcessData->HandleTableSize + 64) * sizeof(HANDLE)); (ProcessData->HandleTableSize + 64) * sizeof(CSRSS_HANDLE));
if (Block == NULL) if (Block == NULL)
{ {
RtlLeaveCriticalSection(&ProcessData->HandleTableLock); RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
@ -169,12 +174,14 @@ NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handl
} }
RtlCopyMemory(Block, RtlCopyMemory(Block,
ProcessData->HandleTable, ProcessData->HandleTable,
ProcessData->HandleTableSize * sizeof(HANDLE)); ProcessData->HandleTableSize * sizeof(CSRSS_HANDLE));
Block = _InterlockedExchangePointer((volatile void*)&ProcessData->HandleTable, Block); Block = _InterlockedExchangePointer((volatile void*)&ProcessData->HandleTable, Block);
RtlFreeHeap( CsrssApiHeap, 0, Block ); RtlFreeHeap( CsrssApiHeap, 0, Block );
ProcessData->HandleTableSize += 64; ProcessData->HandleTableSize += 64;
} }
ProcessData->HandleTable[i] = Object; ProcessData->HandleTable[i].Object = Object;
ProcessData->HandleTable[i].Access = Access;
ProcessData->HandleTable[i].Inheritable = Inheritable;
*Handle = (HANDLE)((i << 2) | 0x3); *Handle = (HANDLE)((i << 2) | 0x3);
_InterlockedIncrement( &Object->ReferenceCount ); _InterlockedIncrement( &Object->ReferenceCount );
RtlLeaveCriticalSection(&ProcessData->HandleTableLock); RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
@ -199,7 +206,7 @@ NTSTATUS STDCALL CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData,
TargetProcessData->HandleTable = RtlAllocateHeap(CsrssApiHeap, TargetProcessData->HandleTable = RtlAllocateHeap(CsrssApiHeap,
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
SourceProcessData->HandleTableSize * sizeof(HANDLE)); SourceProcessData->HandleTableSize * sizeof(CSRSS_HANDLE));
if (TargetProcessData->HandleTable == NULL) if (TargetProcessData->HandleTable == NULL)
{ {
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock); RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
@ -208,10 +215,11 @@ NTSTATUS STDCALL CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData,
TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize; TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize;
for (i = 0; i < SourceProcessData->HandleTableSize; i++) for (i = 0; i < SourceProcessData->HandleTableSize; i++)
{ {
if (SourceProcessData->HandleTable[i]) if (SourceProcessData->HandleTable[i].Object != NULL
&& SourceProcessData->HandleTable[i].Inheritable)
{ {
TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i]; TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
_InterlockedIncrement( &SourceProcessData->HandleTable[i]->ReferenceCount ); _InterlockedIncrement( &SourceProcessData->HandleTable[i].Object->ReferenceCount );
} }
} }
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock); RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
@ -226,12 +234,13 @@ NTSTATUS STDCALL CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize) if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
|| ProcessData->HandleTable[h].Object == NULL)
{ {
return STATUS_INVALID_HANDLE; return STATUS_INVALID_HANDLE;
} }
return ProcessData->HandleTable[h] ? STATUS_SUCCESS : STATUS_INVALID_HANDLE; return STATUS_SUCCESS;
} }
/* EOF */ /* EOF */

View file

@ -158,9 +158,9 @@ NTSTATUS STDCALL CsrFreeProcessData(HANDLE Pid)
{ {
for (c = 0; c < pProcessData->HandleTableSize; c++) for (c = 0; c < pProcessData->HandleTableSize; c++)
{ {
if (pProcessData->HandleTable[c]) if (pProcessData->HandleTable[c].Object)
{ {
CsrReleaseObjectByPointer(pProcessData->HandleTable[c]); CsrReleaseObjectByPointer(pProcessData->HandleTable[c].Object);
} }
} }
RtlFreeHeap(CsrssApiHeap, 0, pProcessData->HandleTable); RtlFreeHeap(CsrssApiHeap, 0, pProcessData->HandleTable);
@ -337,7 +337,9 @@ CSR_API(CsrGetInputHandle)
{ {
Request->Status = CsrInsertObject(ProcessData, Request->Status = CsrInsertObject(ProcessData,
&Request->Data.GetInputHandleRequest.InputHandle, &Request->Data.GetInputHandleRequest.InputHandle,
(Object_t *)ProcessData->Console); (Object_t *)ProcessData->Console,
Request->Data.GetInputHandleRequest.Access,
Request->Data.GetInputHandleRequest.Inheritable);
} }
else else
{ {
@ -363,7 +365,9 @@ CSR_API(CsrGetOutputHandle)
RtlEnterCriticalSection(&ProcessDataLock); RtlEnterCriticalSection(&ProcessDataLock);
Request->Status = CsrInsertObject(ProcessData, Request->Status = CsrInsertObject(ProcessData,
&Request->Data.GetOutputHandleRequest.OutputHandle, &Request->Data.GetOutputHandleRequest.OutputHandle,
&(ProcessData->Console->ActiveBuffer->Header)); &ProcessData->Console->ActiveBuffer->Header,
Request->Data.GetOutputHandleRequest.Access,
Request->Data.GetOutputHandleRequest.Inheritable);
RtlLeaveCriticalSection(&ProcessDataLock); RtlLeaveCriticalSection(&ProcessDataLock);
} }
else else
@ -407,31 +411,63 @@ CSR_API(CsrVerifyHandle)
CSR_API(CsrDuplicateHandle) CSR_API(CsrDuplicateHandle)
{ {
Object_t *Object; ULONG Index;
PCSRSS_HANDLE Entry;
DWORD DesiredAccess;
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
ProcessData = CsrGetProcessData(Request->Data.DuplicateHandleRequest.ProcessId); if (NULL == ProcessData)
if (NULL == ProcessData || ProcessData->Terminated)
{ {
DPRINT1("Invalid source process %d\n", Request->Data.DuplicateHandleRequest.ProcessId); DPRINT1("Invalid source process\n");
Request->Status = STATUS_INVALID_PARAMETER; Request->Status = STATUS_INVALID_PARAMETER;
return Request->Status; return Request->Status;
} }
Request->Status = CsrGetObject(ProcessData, Request->Data.DuplicateHandleRequest.Handle, &Object); Index = (ULONG)Request->Data.DuplicateHandleRequest.Handle >> 2;
if (! NT_SUCCESS(Request->Status)) RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (Index >= ProcessData->HandleTableSize
|| (Entry = &ProcessData->HandleTable[Index])->Object == NULL)
{ {
DPRINT("CsrGetObject failed, status=%x\n", Request->Status); DPRINT1("Couldn't dup invalid handle %p\n", Request->Data.DuplicateHandleRequest.Handle);
Request->Status = STATUS_INVALID_HANDLE;
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Request->Status;
}
if (Request->Data.DuplicateHandleRequest.Options & DUPLICATE_SAME_ACCESS)
{
DesiredAccess = Entry->Access;
} }
else else
{ {
DesiredAccess = Request->Data.DuplicateHandleRequest.Access;
/* Make sure the source handle has all the desired flags */
if (~Entry->Access & DesiredAccess)
{
DPRINT1("Handle %p only has access %X; requested %X\n",
Request->Data.DuplicateHandleRequest.Handle, Entry->Access, DesiredAccess);
Request->Status = STATUS_INVALID_PARAMETER;
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Request->Status;
}
}
Request->Status = CsrInsertObject(ProcessData, Request->Status = CsrInsertObject(ProcessData,
&Request->Data.DuplicateHandleRequest.Handle, &Request->Data.DuplicateHandleRequest.Handle,
Object); Entry->Object,
CsrReleaseObjectByPointer(Object); DesiredAccess,
Request->Data.DuplicateHandleRequest.Inheritable);
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;
} }
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Request->Status; return Request->Status;
} }

View file

@ -32,6 +32,13 @@ typedef struct ConsoleInput_t
typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE; typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE;
typedef struct _CSRSS_HANDLE
{
Object_t *Object;
DWORD Access;
BOOL Inheritable;
} CSRSS_HANDLE, *PCSRSS_HANDLE;
typedef struct _CSRSS_PROCESS_DATA typedef struct _CSRSS_PROCESS_DATA
{ {
PCSRSS_CONSOLE Console; PCSRSS_CONSOLE Console;
@ -39,7 +46,7 @@ typedef struct _CSRSS_PROCESS_DATA
BOOL bInheritHandles; BOOL bInheritHandles;
RTL_CRITICAL_SECTION HandleTableLock; RTL_CRITICAL_SECTION HandleTableLock;
ULONG HandleTableSize; ULONG HandleTableSize;
Object_t ** HandleTable; PCSRSS_HANDLE HandleTable;
HANDLE ProcessId; HANDLE ProcessId;
HANDLE Process; HANDLE Process;
ULONG ShutdownLevel; ULONG ShutdownLevel;
@ -125,9 +132,9 @@ NTSTATUS STDCALL CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Contex
/* api/handle.c */ /* api/handle.c */
NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions); NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions);
NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object ); NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, BOOL Inheritable );
NTSTATUS STDCALL CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, PCSRSS_PROCESS_DATA TargetProcessData); NTSTATUS STDCALL CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, PCSRSS_PROCESS_DATA TargetProcessData);
NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object ); NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object, DWORD Access );
BOOL STDCALL CsrServerInitialization (int,char**,char**); BOOL STDCALL CsrServerInitialization (int,char**,char**);
NTSTATUS STDCALL CsrReleaseObjectByPointer(Object_t *Object); NTSTATUS STDCALL CsrReleaseObjectByPointer(Object_t *Object);
NTSTATUS STDCALL CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); NTSTATUS STDCALL CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );

View file

@ -24,10 +24,13 @@
typedef NTSTATUS (STDCALL *CSRSS_INSERT_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData, typedef NTSTATUS (STDCALL *CSRSS_INSERT_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData,
PHANDLE Handle, PHANDLE Handle,
Object_t *Object); Object_t *Object,
DWORD Access,
BOOL Inheritable);
typedef NTSTATUS (STDCALL *CSRSS_GET_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData, typedef NTSTATUS (STDCALL *CSRSS_GET_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Handle, HANDLE Handle,
Object_t **Object); Object_t **Object,
DWORD Access);
typedef NTSTATUS (STDCALL *CSRSS_RELEASE_OBJECT_BY_POINTER_PROC)(Object_t *Object); typedef NTSTATUS (STDCALL *CSRSS_RELEASE_OBJECT_BY_POINTER_PROC)(Object_t *Object);
typedef NTSTATUS (STDCALL *CSRSS_RELEASE_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData, typedef NTSTATUS (STDCALL *CSRSS_RELEASE_OBJECT_PROC)(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Object ); HANDLE Object );

View file

@ -18,7 +18,9 @@ extern HINSTANCE Win32CsrDllHandle;
NTSTATUS FASTCALL Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData, NTSTATUS FASTCALL Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData,
PHANDLE Handle, PHANDLE Handle,
Object_t *Object); Object_t *Object,
DWORD Access,
BOOL Inheritable);
NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Handle, HANDLE Handle,
Object_t **Object, Object_t **Object,

View file

@ -320,7 +320,9 @@ CSR_API(CsrAllocConsole)
/* Insert the Objects */ /* Insert the Objects */
Status = Win32CsrInsertObject(ProcessData, Status = Win32CsrInsertObject(ProcessData,
&Request->Data.AllocConsoleRequest.InputHandle, &Request->Data.AllocConsoleRequest.InputHandle,
&Console->Header); &Console->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE);
if (! NT_SUCCESS(Status)) if (! NT_SUCCESS(Status))
{ {
DPRINT1("Failed to insert object\n"); DPRINT1("Failed to insert object\n");
@ -331,7 +333,9 @@ CSR_API(CsrAllocConsole)
Status = Win32CsrInsertObject(ProcessData, Status = Win32CsrInsertObject(ProcessData,
&Request->Data.AllocConsoleRequest.OutputHandle, &Request->Data.AllocConsoleRequest.OutputHandle,
&Console->ActiveBuffer->Header); &Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to insert object\n"); DPRINT1("Failed to insert object\n");
@ -2048,7 +2052,11 @@ CSR_API(CsrCreateScreenBuffer)
} }
else else
{ {
Request->Status = Win32CsrInsertObject(ProcessData, &Request->Data.CreateScreenBufferRequest.OutputHandle, &Buff->Header); Request->Status = Win32CsrInsertObject(ProcessData,
&Request->Data.CreateScreenBufferRequest.OutputHandle,
&Buff->Header,
Request->Data.CreateScreenBufferRequest.Access,
Request->Data.CreateScreenBufferRequest.Inheritable);
} }
} }
else else
@ -2182,7 +2190,6 @@ CSR_API(CsrGetTitle)
/* Copy title of the console to the user title buffer */ /* Copy title of the console to the user title buffer */
RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE)); RtlZeroMemory(&Request->Data.GetTitleRequest, sizeof(CSRSS_GET_TITLE));
Request->Data.GetTitleRequest.ConsoleHandle = Request->Data.GetTitleRequest.ConsoleHandle;
Request->Data.GetTitleRequest.Length = Console->Title.Length; Request->Data.GetTitleRequest.Length = Console->Title.Length;
memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer, memcpy (Request->Data.GetTitleRequest.Title, Console->Title.Buffer,
Console->Title.Length); Console->Title.Length);

View file

@ -96,9 +96,11 @@ DllMain(HANDLE hDll,
NTSTATUS FASTCALL NTSTATUS FASTCALL
Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData, Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData,
PHANDLE Handle, PHANDLE Handle,
Object_t *Object) Object_t *Object,
DWORD Access,
BOOL Inheritable)
{ {
return (CsrExports.CsrInsertObjectProc)(ProcessData, Handle, Object); return (CsrExports.CsrInsertObjectProc)(ProcessData, Handle, Object, Access, Inheritable);
} }
NTSTATUS FASTCALL NTSTATUS FASTCALL
@ -106,7 +108,7 @@ Win32CsrGetObject(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Handle, HANDLE Handle,
Object_t **Object) Object_t **Object)
{ {
return (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object); return (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, 0);
} }
NTSTATUS FASTCALL NTSTATUS FASTCALL
@ -117,7 +119,7 @@ Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData,
{ {
NTSTATUS Status; NTSTATUS Status;
Status = (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object); Status = (CsrExports.CsrGetObjectProc)(ProcessData, Handle, Object, 0);
if (! NT_SUCCESS(Status)) if (! NT_SUCCESS(Status))
{ {
return Status; return Status;