mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 04:37:15 +00:00
[WIN32CSR] Implement FILE_SHARE_* flags for console handles. Fixes some more winetests.
svn path=/trunk/; revision=47319
This commit is contained in:
parent
85b0f2bc12
commit
0b077c2961
6 changed files with 89 additions and 74 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue