Author: jmorlan Date: Sun May 23 11:10:02 2010 New Revision: 47319
URL: http://svn.reactos.org/svn/reactos?rev=47319&view=rev Log: [WIN32CSR] Implement FILE_SHARE_* flags for console handles. Fixes some more winetests.
Modified: trunk/reactos/dll/win32/kernel32/misc/console.c trunk/reactos/include/reactos/subsys/csrss/csrss.h trunk/reactos/subsystems/win32/csrss/win32csr/conio.c trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c trunk/reactos/subsystems/win32/csrss/win32csr/handle.c trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h
Modified: trunk/reactos/dll/win32/kernel32/misc/console.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/con... ============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/misc/console.c [iso-8859-1] Sun May 23 11:10:02 2010 @@ -1022,6 +1022,7 @@ /* 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 @@ return INVALID_HANDLE_VALUE; }
- return Request.Data.GetInputHandleRequest.InputHandle; + return Request.Data.GetInputHandleRequest.Handle; }
Modified: trunk/reactos/include/reactos/subsys/csrss/csrss.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/subsys/csrs... ============================================================================== --- trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] Sun May 23 11:10:02 2010 @@ -320,15 +320,10 @@ { 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 {
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/conio.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/conio.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/conio.c [iso-8859-1] Sun May 23 11:10:02 2010 @@ -317,7 +317,8 @@ &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 @@ &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 @@ &Request->Data.CreateScreenBufferRequest.OutputHandle, &Buff->Header, Request->Data.CreateScreenBufferRequest.Access, - Request->Data.CreateScreenBufferRequest.Inheritable); + Request->Data.CreateScreenBufferRequest.Inheritable, + Request->Data.CreateScreenBufferRequest.ShareMode); } } else
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] Sun May 23 11:10:02 2010 @@ -24,8 +24,8 @@
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),
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/handle.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/handle.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/handle.c [iso-8859-1] Sun May 23 11:10:02 2010 @@ -23,17 +23,26 @@ 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) -{ - Entry->Object = Object; - Entry->Access = Access; - Entry->Inheritable = Inheritable; - _InterlockedIncrement(&Object->HandleCount); + PCSRSS_HANDLE Entry) +{ + Object_t *Object = Entry->Object; + EnterCriticalSection(&Object->Console->Lock); + AdjustHandleCounts(Entry, +1); + LeaveCriticalSection(&Object->Console->Lock); }
static VOID @@ -43,21 +52,21 @@ 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 @@ PHANDLE Handle, Object_t *Object, DWORD Access, - BOOL Inheritable) + BOOL Inheritable, + DWORD ShareMode) { ULONG i; PCSRSS_HANDLE Block; @@ -194,7 +204,11 @@ 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 @@ 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) -{ - Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE); - Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE); +CSR_API(CsrGetHandle) +{ + NTSTATUS Status = STATUS_SUCCESS; + + 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.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; -} - -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; + 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 Status; }
CSR_API(CsrCloseHandle) @@ -359,7 +371,8 @@ &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) {
Modified: trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win3... ============================================================================== --- trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/csrss/win32csr/win32csr.h [iso-8859-1] Sun May 23 11:10:02 2010 @@ -18,6 +18,8 @@ { LONG Type; struct tagCSRSS_CONSOLE *Console; + LONG AccessRead, AccessWrite; + LONG ExclusiveRead, ExclusiveWrite; LONG HandleCount; } Object_t;
@@ -26,6 +28,7 @@ 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 @@ 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 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);