[WIN32CSR] Implement FILE_SHARE_* flags for console handles. Fixes some more winetests.

svn path=/trunk/; revision=47319
This commit is contained in:
Jeffrey Morlan 2010-05-23 09:10:02 +00:00
parent 85b0f2bc12
commit 0b077c2961
6 changed files with 89 additions and 74 deletions

View file

@ -1022,6 +1022,7 @@ OpenConsoleW(LPCWSTR wsName,
/* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */ /* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */
Request.Data.GetInputHandleRequest.Access = dwDesiredAccess; Request.Data.GetInputHandleRequest.Access = dwDesiredAccess;
Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle; Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle;
Request.Data.GetInputHandleRequest.ShareMode = dwShareMode;
Status = CsrClientCallServer(&Request, Status = CsrClientCallServer(&Request,
NULL, NULL,
@ -1033,7 +1034,7 @@ OpenConsoleW(LPCWSTR wsName,
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
return Request.Data.GetInputHandleRequest.InputHandle; return Request.Data.GetInputHandleRequest.Handle;
} }

View file

@ -320,15 +320,10 @@ typedef struct
{ {
DWORD Access; DWORD Access;
BOOL Inheritable; BOOL Inheritable;
HANDLE InputHandle; HANDLE Handle;
} CSRSS_GET_INPUT_HANDLE, *PCSRSS_GET_INPUT_HANDLE; DWORD ShareMode;
} CSRSS_GET_INPUT_HANDLE, *PCSRSS_GET_INPUT_HANDLE,
typedef struct CSRSS_GET_OUTPUT_HANDLE, *PCSRSS_GET_OUTPUT_HANDLE;
{
DWORD Access;
BOOL Inheritable;
HANDLE OutputHandle;
} CSRSS_GET_OUTPUT_HANDLE, *PCSRSS_GET_OUTPUT_HANDLE;
typedef struct typedef struct
{ {

View file

@ -317,7 +317,8 @@ CSR_API(CsrAllocConsole)
&Request->Data.AllocConsoleRequest.InputHandle, &Request->Data.AllocConsoleRequest.InputHandle,
&Console->Header, &Console->Header,
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
TRUE); TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (! NT_SUCCESS(Status)) if (! NT_SUCCESS(Status))
{ {
DPRINT1("Failed to insert object\n"); DPRINT1("Failed to insert object\n");
@ -331,7 +332,8 @@ CSR_API(CsrAllocConsole)
&Request->Data.AllocConsoleRequest.OutputHandle, &Request->Data.AllocConsoleRequest.OutputHandle,
&Console->ActiveBuffer->Header, &Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
TRUE); TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to insert object\n"); DPRINT1("Failed to insert object\n");
@ -1975,7 +1977,8 @@ CSR_API(CsrCreateScreenBuffer)
&Request->Data.CreateScreenBufferRequest.OutputHandle, &Request->Data.CreateScreenBufferRequest.OutputHandle,
&Buff->Header, &Buff->Header,
Request->Data.CreateScreenBufferRequest.Access, Request->Data.CreateScreenBufferRequest.Access,
Request->Data.CreateScreenBufferRequest.Inheritable); Request->Data.CreateScreenBufferRequest.Inheritable,
Request->Data.CreateScreenBufferRequest.ShareMode);
} }
} }
else else

View file

@ -24,8 +24,8 @@ static CSRSS_EXPORTED_FUNCS CsrExports;
static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] =
{ {
CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetInputHandle), CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetHandle),
CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetOutputHandle), CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetHandle),
CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle), CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle),
CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle), CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle),
CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle), CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle),

View file

@ -23,17 +23,26 @@ CsrIsConsoleHandle(HANDLE Handle)
return ((ULONG_PTR)Handle & 0x10000003) == 0x3; return ((ULONG_PTR)Handle & 0x10000003) == 0x3;
} }
static INT
AdjustHandleCounts(PCSRSS_HANDLE Entry, INT Change)
{
Object_t *Object = Entry->Object;
if (Entry->Access & GENERIC_READ) Object->AccessRead += Change;
if (Entry->Access & GENERIC_WRITE) Object->AccessWrite += Change;
if (!(Entry->ShareMode & FILE_SHARE_READ)) Object->ExclusiveRead += Change;
if (!(Entry->ShareMode & FILE_SHARE_WRITE)) Object->ExclusiveWrite += Change;
Object->HandleCount += Change;
return Object->HandleCount;
}
static VOID static VOID
Win32CsrCreateHandleEntry( Win32CsrCreateHandleEntry(
PCSRSS_HANDLE Entry, PCSRSS_HANDLE Entry)
Object_t *Object,
DWORD Access,
BOOL Inheritable)
{ {
Entry->Object = Object; Object_t *Object = Entry->Object;
Entry->Access = Access; EnterCriticalSection(&Object->Console->Lock);
Entry->Inheritable = Inheritable; AdjustHandleCounts(Entry, +1);
_InterlockedIncrement(&Object->HandleCount); LeaveCriticalSection(&Object->Console->Lock);
} }
static VOID static VOID
@ -43,21 +52,21 @@ Win32CsrCloseHandleEntry(
Object_t *Object = Entry->Object; Object_t *Object = Entry->Object;
if (Object != NULL) if (Object != NULL)
{ {
Entry->Object = NULL; PCSRSS_CONSOLE Console = Object->Console;
EnterCriticalSection(&Console->Lock);
/* If the last handle to a screen buffer is closed, delete it */ /* If the last handle to a screen buffer is closed, delete it */
if (_InterlockedDecrement(&Object->HandleCount) == 0 if (AdjustHandleCounts(Entry, -1) == 0
&& Object->Type == CONIO_SCREEN_BUFFER_MAGIC) && Object->Type == CONIO_SCREEN_BUFFER_MAGIC)
{ {
PCSRSS_CONSOLE Console = Object->Console;
PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER)Object; PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER)Object;
EnterCriticalSection(&Console->Lock);
/* ...unless it's the only buffer left. Windows allows deletion /* ...unless it's the only buffer left. Windows allows deletion
* even of the last buffer, but having to deal with a lack of * even of the last buffer, but having to deal with a lack of
* any active buffer might be error-prone. */ * any active buffer might be error-prone. */
if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink) if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink)
ConioDeleteScreenBuffer(Buffer); ConioDeleteScreenBuffer(Buffer);
LeaveCriticalSection(&Console->Lock);
} }
LeaveCriticalSection(&Console->Lock);
Entry->Object = NULL;
} }
} }
@ -163,7 +172,8 @@ Win32CsrInsertObject(
PHANDLE Handle, PHANDLE Handle,
Object_t *Object, Object_t *Object,
DWORD Access, DWORD Access,
BOOL Inheritable) BOOL Inheritable,
DWORD ShareMode)
{ {
ULONG i; ULONG i;
PCSRSS_HANDLE Block; PCSRSS_HANDLE Block;
@ -194,7 +204,11 @@ Win32CsrInsertObject(
ProcessData->HandleTable = Block; ProcessData->HandleTable = Block;
ProcessData->HandleTableSize += 64; ProcessData->HandleTableSize += 64;
} }
Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i], Object, Access, Inheritable); 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); *Handle = UlongToHandle((i << 2) | 0x3);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock); RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -232,62 +246,60 @@ Win32CsrDuplicateHandleTable(
if (SourceProcessData->HandleTable[i].Object != NULL && if (SourceProcessData->HandleTable[i].Object != NULL &&
SourceProcessData->HandleTable[i].Inheritable) SourceProcessData->HandleTable[i].Inheritable)
{ {
Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i], TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
SourceProcessData->HandleTable[i].Object, Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]);
SourceProcessData->HandleTable[i].Access,
SourceProcessData->HandleTable[i].Inheritable);
} }
} }
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock); RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
CSR_API(CsrGetInputHandle) CSR_API(CsrGetHandle)
{ {
NTSTATUS Status = STATUS_SUCCESS;
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);
Request->Data.GetInputHandleRequest.Handle = INVALID_HANDLE_VALUE;
RtlEnterCriticalSection(&ProcessData->HandleTableLock); RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (ProcessData->Console) if (ProcessData->Console)
{ {
Request->Status = Win32CsrInsertObject(ProcessData, DWORD DesiredAccess = Request->Data.GetInputHandleRequest.Access;
&Request->Data.GetInputHandleRequest.InputHandle, DWORD ShareMode = Request->Data.GetInputHandleRequest.ShareMode;
&ProcessData->Console->Header,
Request->Data.GetInputHandleRequest.Access, PCSRSS_CONSOLE Console = ProcessData->Console;
Request->Data.GetInputHandleRequest.Inheritable); Object_t *Object;
EnterCriticalSection(&Console->Lock);
if (Request->Type == GET_OUTPUT_HANDLE)
Object = &Console->ActiveBuffer->Header;
else
Object = &Console->Header;
if (((DesiredAccess & GENERIC_READ) && Object->ExclusiveRead != 0) ||
((DesiredAccess & GENERIC_WRITE) && Object->ExclusiveWrite != 0) ||
(!(ShareMode & FILE_SHARE_READ) && Object->AccessRead != 0) ||
(!(ShareMode & FILE_SHARE_WRITE) && Object->AccessWrite != 0))
{
DPRINT1("Sharing violation\n");
Status = STATUS_SHARING_VIOLATION;
} }
else else
{ {
Request->Data.GetInputHandleRequest.InputHandle = INVALID_HANDLE_VALUE; Status = Win32CsrInsertObject(ProcessData,
Request->Status = STATUS_SUCCESS; &Request->Data.GetInputHandleRequest.Handle,
Object,
DesiredAccess,
Request->Data.GetInputHandleRequest.Inheritable,
ShareMode);
}
LeaveCriticalSection(&Console->Lock);
} }
RtlLeaveCriticalSection(&ProcessData->HandleTableLock); RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Request->Status; return Status;
}
CSR_API(CsrGetOutputHandle)
{
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (ProcessData->Console)
{
Request->Status = Win32CsrInsertObject(ProcessData,
&Request->Data.GetOutputHandleRequest.OutputHandle,
&ProcessData->Console->ActiveBuffer->Header,
Request->Data.GetOutputHandleRequest.Access,
Request->Data.GetOutputHandleRequest.Inheritable);
}
else
{
Request->Data.GetOutputHandleRequest.OutputHandle = INVALID_HANDLE_VALUE;
Request->Status = STATUS_SUCCESS;
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Request->Status;
} }
CSR_API(CsrCloseHandle) CSR_API(CsrCloseHandle)
@ -359,7 +371,8 @@ CSR_API(CsrDuplicateHandle)
&Request->Data.DuplicateHandleRequest.Handle, &Request->Data.DuplicateHandleRequest.Handle,
Entry->Object, Entry->Object,
DesiredAccess, DesiredAccess,
Request->Data.DuplicateHandleRequest.Inheritable); Request->Data.DuplicateHandleRequest.Inheritable,
Entry->ShareMode);
if (NT_SUCCESS(Request->Status) if (NT_SUCCESS(Request->Status)
&& Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE) && Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE)
{ {

View file

@ -18,6 +18,8 @@ typedef struct Object_tt
{ {
LONG Type; LONG Type;
struct tagCSRSS_CONSOLE *Console; struct tagCSRSS_CONSOLE *Console;
LONG AccessRead, AccessWrite;
LONG ExclusiveRead, ExclusiveWrite;
LONG HandleCount; LONG HandleCount;
} Object_t; } Object_t;
@ -26,6 +28,7 @@ typedef struct _CSRSS_HANDLE
Object_t *Object; Object_t *Object;
DWORD Access; DWORD Access;
BOOL Inheritable; BOOL Inheritable;
DWORD ShareMode;
} CSRSS_HANDLE, *PCSRSS_HANDLE; } CSRSS_HANDLE, *PCSRSS_HANDLE;
typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object); typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object);
@ -41,7 +44,8 @@ NTSTATUS FASTCALL Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData,
PHANDLE Handle, PHANDLE Handle,
Object_t *Object, Object_t *Object,
DWORD Access, DWORD Access,
BOOL Inheritable); BOOL Inheritable,
DWORD ShareMode);
NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData,
HANDLE Handle, HANDLE Handle,
Object_t **Object, Object_t **Object,
@ -53,8 +57,7 @@ NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData,
NTSTATUS WINAPI Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData); NTSTATUS WINAPI Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData);
NTSTATUS WINAPI Win32CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, NTSTATUS WINAPI Win32CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData,
PCSRSS_PROCESS_DATA TargetProcessData); PCSRSS_PROCESS_DATA TargetProcessData);
CSR_API(CsrGetInputHandle); CSR_API(CsrGetHandle);
CSR_API(CsrGetOutputHandle);
CSR_API(CsrCloseHandle); CSR_API(CsrCloseHandle);
CSR_API(CsrVerifyHandle); CSR_API(CsrVerifyHandle);
CSR_API(CsrDuplicateHandle); CSR_API(CsrDuplicateHandle);