From 0b077c296117dcc04cbf7c6280eddc253dc35f2c Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 23 May 2010 09:10:02 +0000 Subject: [PATCH] [WIN32CSR] Implement FILE_SHARE_* flags for console handles. Fixes some more winetests. svn path=/trunk/; revision=47319 --- reactos/dll/win32/kernel32/misc/console.c | 3 +- reactos/include/reactos/subsys/csrss/csrss.h | 13 +- .../subsystems/win32/csrss/win32csr/conio.c | 9 +- .../subsystems/win32/csrss/win32csr/dllmain.c | 4 +- .../subsystems/win32/csrss/win32csr/handle.c | 123 ++++++++++-------- .../win32/csrss/win32csr/win32csr.h | 9 +- 6 files changed, 88 insertions(+), 73 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/console.c b/reactos/dll/win32/kernel32/misc/console.c index 594b8ac2abb..419f4373a42 100644 --- a/reactos/dll/win32/kernel32/misc/console.c +++ b/reactos/dll/win32/kernel32/misc/console.c @@ -1022,6 +1022,7 @@ OpenConsoleW(LPCWSTR wsName, /* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */ Request.Data.GetInputHandleRequest.Access = dwDesiredAccess; Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle; + Request.Data.GetInputHandleRequest.ShareMode = dwShareMode; Status = CsrClientCallServer(&Request, NULL, @@ -1033,7 +1034,7 @@ OpenConsoleW(LPCWSTR wsName, return INVALID_HANDLE_VALUE; } - return Request.Data.GetInputHandleRequest.InputHandle; + return Request.Data.GetInputHandleRequest.Handle; } diff --git a/reactos/include/reactos/subsys/csrss/csrss.h b/reactos/include/reactos/subsys/csrss/csrss.h index 0119bad99a3..9e87a4d6b81 100644 --- a/reactos/include/reactos/subsys/csrss/csrss.h +++ b/reactos/include/reactos/subsys/csrss/csrss.h @@ -320,15 +320,10 @@ typedef struct { DWORD Access; BOOL Inheritable; - HANDLE InputHandle; -} CSRSS_GET_INPUT_HANDLE, *PCSRSS_GET_INPUT_HANDLE; - -typedef struct -{ - DWORD Access; - BOOL Inheritable; - HANDLE OutputHandle; -} CSRSS_GET_OUTPUT_HANDLE, *PCSRSS_GET_OUTPUT_HANDLE; + HANDLE Handle; + DWORD ShareMode; +} CSRSS_GET_INPUT_HANDLE, *PCSRSS_GET_INPUT_HANDLE, + CSRSS_GET_OUTPUT_HANDLE, *PCSRSS_GET_OUTPUT_HANDLE; typedef struct { diff --git a/reactos/subsystems/win32/csrss/win32csr/conio.c b/reactos/subsystems/win32/csrss/win32csr/conio.c index 92d68554a53..ee89dad553f 100644 --- a/reactos/subsystems/win32/csrss/win32csr/conio.c +++ b/reactos/subsystems/win32/csrss/win32csr/conio.c @@ -317,7 +317,8 @@ CSR_API(CsrAllocConsole) &Request->Data.AllocConsoleRequest.InputHandle, &Console->Header, GENERIC_READ | GENERIC_WRITE, - TRUE); + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); if (! NT_SUCCESS(Status)) { DPRINT1("Failed to insert object\n"); @@ -331,7 +332,8 @@ CSR_API(CsrAllocConsole) &Request->Data.AllocConsoleRequest.OutputHandle, &Console->ActiveBuffer->Header, GENERIC_READ | GENERIC_WRITE, - TRUE); + TRUE, + FILE_SHARE_READ | FILE_SHARE_WRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to insert object\n"); @@ -1975,7 +1977,8 @@ CSR_API(CsrCreateScreenBuffer) &Request->Data.CreateScreenBufferRequest.OutputHandle, &Buff->Header, Request->Data.CreateScreenBufferRequest.Access, - Request->Data.CreateScreenBufferRequest.Inheritable); + Request->Data.CreateScreenBufferRequest.Inheritable, + Request->Data.CreateScreenBufferRequest.ShareMode); } } else diff --git a/reactos/subsystems/win32/csrss/win32csr/dllmain.c b/reactos/subsystems/win32/csrss/win32csr/dllmain.c index a8fdd418161..bd0409c55ca 100644 --- a/reactos/subsystems/win32/csrss/win32csr/dllmain.c +++ b/reactos/subsystems/win32/csrss/win32csr/dllmain.c @@ -24,8 +24,8 @@ static CSRSS_EXPORTED_FUNCS CsrExports; static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = { - CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetInputHandle), - CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetOutputHandle), + CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetHandle), + CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetHandle), CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle), CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle), CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle), diff --git a/reactos/subsystems/win32/csrss/win32csr/handle.c b/reactos/subsystems/win32/csrss/win32csr/handle.c index e7b28b1977b..87f5c6348a4 100644 --- a/reactos/subsystems/win32/csrss/win32csr/handle.c +++ b/reactos/subsystems/win32/csrss/win32csr/handle.c @@ -23,17 +23,26 @@ CsrIsConsoleHandle(HANDLE Handle) 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 Win32CsrCreateHandleEntry( - PCSRSS_HANDLE Entry, - Object_t *Object, - DWORD Access, - BOOL Inheritable) + PCSRSS_HANDLE Entry) { - Entry->Object = Object; - Entry->Access = Access; - Entry->Inheritable = Inheritable; - _InterlockedIncrement(&Object->HandleCount); + Object_t *Object = Entry->Object; + EnterCriticalSection(&Object->Console->Lock); + AdjustHandleCounts(Entry, +1); + LeaveCriticalSection(&Object->Console->Lock); } static VOID @@ -43,21 +52,21 @@ Win32CsrCloseHandleEntry( Object_t *Object = Entry->Object; 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 (_InterlockedDecrement(&Object->HandleCount) == 0 + if (AdjustHandleCounts(Entry, -1) == 0 && Object->Type == CONIO_SCREEN_BUFFER_MAGIC) { - PCSRSS_CONSOLE Console = Object->Console; PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER)Object; - EnterCriticalSection(&Console->Lock); /* ...unless it's the only buffer left. Windows allows deletion * even of the last buffer, but having to deal with a lack of * any active buffer might be error-prone. */ if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink) ConioDeleteScreenBuffer(Buffer); - LeaveCriticalSection(&Console->Lock); } + LeaveCriticalSection(&Console->Lock); + Entry->Object = NULL; } } @@ -163,7 +172,8 @@ Win32CsrInsertObject( PHANDLE Handle, Object_t *Object, DWORD Access, - BOOL Inheritable) + BOOL Inheritable, + DWORD ShareMode) { ULONG i; PCSRSS_HANDLE Block; @@ -194,7 +204,11 @@ Win32CsrInsertObject( ProcessData->HandleTable = Block; 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); RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return(STATUS_SUCCESS); @@ -232,62 +246,60 @@ Win32CsrDuplicateHandleTable( if (SourceProcessData->HandleTable[i].Object != NULL && SourceProcessData->HandleTable[i].Inheritable) { - Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i], - SourceProcessData->HandleTable[i].Object, - SourceProcessData->HandleTable[i].Access, - SourceProcessData->HandleTable[i].Inheritable); + TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i]; + Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]); } } RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock); return(STATUS_SUCCESS); } -CSR_API(CsrGetInputHandle) +CSR_API(CsrGetHandle) { - 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.GetInputHandleRequest.InputHandle, - &ProcessData->Console->Header, - Request->Data.GetInputHandleRequest.Access, - Request->Data.GetInputHandleRequest.Inheritable); - } - else - { - Request->Data.GetInputHandleRequest.InputHandle = INVALID_HANDLE_VALUE; - Request->Status = STATUS_SUCCESS; - } - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - - return Request->Status; -} + NTSTATUS Status = STATUS_SUCCESS; -CSR_API(CsrGetOutputHandle) -{ Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); + Request->Data.GetInputHandleRequest.Handle = INVALID_HANDLE_VALUE; + 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; + DWORD DesiredAccess = Request->Data.GetInputHandleRequest.Access; + DWORD ShareMode = Request->Data.GetInputHandleRequest.ShareMode; + + PCSRSS_CONSOLE Console = ProcessData->Console; + 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 + { + Status = Win32CsrInsertObject(ProcessData, + &Request->Data.GetInputHandleRequest.Handle, + Object, + DesiredAccess, + Request->Data.GetInputHandleRequest.Inheritable, + ShareMode); + } + LeaveCriticalSection(&Console->Lock); } RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Request->Status; + return Status; } CSR_API(CsrCloseHandle) @@ -359,7 +371,8 @@ CSR_API(CsrDuplicateHandle) &Request->Data.DuplicateHandleRequest.Handle, Entry->Object, DesiredAccess, - Request->Data.DuplicateHandleRequest.Inheritable); + Request->Data.DuplicateHandleRequest.Inheritable, + Entry->ShareMode); if (NT_SUCCESS(Request->Status) && Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE) { diff --git a/reactos/subsystems/win32/csrss/win32csr/win32csr.h b/reactos/subsystems/win32/csrss/win32csr/win32csr.h index 0bb444003f0..111c27db80a 100644 --- a/reactos/subsystems/win32/csrss/win32csr/win32csr.h +++ b/reactos/subsystems/win32/csrss/win32csr/win32csr.h @@ -18,6 +18,8 @@ typedef struct Object_tt { LONG Type; struct tagCSRSS_CONSOLE *Console; + LONG AccessRead, AccessWrite; + LONG ExclusiveRead, ExclusiveWrite; LONG HandleCount; } Object_t; @@ -26,6 +28,7 @@ typedef struct _CSRSS_HANDLE Object_t *Object; DWORD Access; BOOL Inheritable; + DWORD ShareMode; } CSRSS_HANDLE, *PCSRSS_HANDLE; typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object); @@ -41,7 +44,8 @@ NTSTATUS FASTCALL Win32CsrInsertObject(PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object, DWORD Access, - BOOL Inheritable); + BOOL Inheritable, + DWORD ShareMode); NTSTATUS FASTCALL Win32CsrLockObject(PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object, @@ -53,8 +57,7 @@ NTSTATUS FASTCALL Win32CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, NTSTATUS WINAPI Win32CsrReleaseConsole(PCSRSS_PROCESS_DATA ProcessData); NTSTATUS WINAPI Win32CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, PCSRSS_PROCESS_DATA TargetProcessData); -CSR_API(CsrGetInputHandle); -CSR_API(CsrGetOutputHandle); +CSR_API(CsrGetHandle); CSR_API(CsrCloseHandle); CSR_API(CsrVerifyHandle); CSR_API(CsrDuplicateHandle); -- 2.17.1