mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
- Implemented CsrDuplicateHandleTable.
- Duplicate the handle table in CsrCreateProcess if the caller wants to inherit all handles. - Don't allocate new handles in CsrAllocConsole if the caller wants to reuse a console and if the parent handles were inherited. - Do only allow to reuse the console from parent. svn path=/trunk/; revision=16924
This commit is contained in:
parent
22332a5bae
commit
d20bf6a780
5 changed files with 94 additions and 34 deletions
|
@ -33,6 +33,7 @@ typedef struct
|
|||
{
|
||||
HANDLE NewProcessId;
|
||||
ULONG Flags;
|
||||
BOOL bInheritHandles;
|
||||
} CSRSS_CREATE_PROCESS, *PCSRSS_CREATE_PROCESS;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -72,7 +72,7 @@ NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, O
|
|||
}
|
||||
if (!CsrIsConsoleHandle(Handle) || ProcessData->HandleTableSize <= h)
|
||||
{
|
||||
DPRINT1("CsrGetObject returning invalid handle\n");
|
||||
DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle);
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
*Object = ProcessData->HandleTable[h];
|
||||
|
@ -177,6 +177,43 @@ NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handl
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData,
|
||||
PCSRSS_PROCESS_DATA TargetProcessData)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
if (SourceProcessData == NULL ||
|
||||
TargetProcessData == NULL ||
|
||||
TargetProcessData->HandleTableSize)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RtlEnterCriticalSection(&SourceProcessData->HandleTableLock);
|
||||
|
||||
/* we are called from CreateProcessData, it isn't necessary to lock the target process data */
|
||||
|
||||
TargetProcessData->HandleTable = RtlAllocateHeap(CsrssApiHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
SourceProcessData->HandleTableSize * sizeof(HANDLE));
|
||||
if (TargetProcessData->HandleTable == NULL)
|
||||
{
|
||||
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize;
|
||||
for (i = 0; i < SourceProcessData->HandleTableSize; i++)
|
||||
{
|
||||
if (SourceProcessData->HandleTable[i])
|
||||
{
|
||||
TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
|
||||
InterlockedIncrement( &SourceProcessData->HandleTable[i]->ReferenceCount );
|
||||
}
|
||||
}
|
||||
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle )
|
||||
{
|
||||
ULONG h = (((ULONG)Handle) >> 2) - 1;
|
||||
|
|
|
@ -192,6 +192,7 @@ NTSTATUS STDCALL CsrFreeProcessData(HANDLE Pid)
|
|||
CSR_API(CsrCreateProcess)
|
||||
{
|
||||
PCSRSS_PROCESS_DATA NewProcessData;
|
||||
NTSTATUS Status;
|
||||
|
||||
Request->Header.DataSize = sizeof(CSR_API_MESSAGE) - LPC_MESSAGE_BASE_SIZE;
|
||||
Request->Header.MessageSize = sizeof(CSR_API_MESSAGE);
|
||||
|
@ -203,6 +204,16 @@ CSR_API(CsrCreateProcess)
|
|||
return(STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
if (!(Request->Data.CreateProcessRequest.Flags & (CREATE_NEW_CONSOLE|DETACHED_PROCESS)))
|
||||
{
|
||||
NewProcessData->ParentConsole = ProcessData->Console;
|
||||
NewProcessData->bInheritHandles = Request->Data.CreateProcessRequest.bInheritHandles;
|
||||
if (Request->Data.CreateProcessRequest.bInheritHandles)
|
||||
{
|
||||
Status = CsrDuplicateHandleTable(ProcessData, NewProcessData);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set default shutdown parameters */
|
||||
NewProcessData->ShutdownLevel = 0x280;
|
||||
NewProcessData->ShutdownFlags = 0;
|
||||
|
|
|
@ -35,6 +35,8 @@ typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE;
|
|||
typedef struct _CSRSS_PROCESS_DATA
|
||||
{
|
||||
PCSRSS_CONSOLE Console;
|
||||
PCSRSS_CONSOLE ParentConsole;
|
||||
BOOL bInheritHandles;
|
||||
RTL_CRITICAL_SECTION HandleTableLock;
|
||||
ULONG HandleTableSize;
|
||||
Object_t ** HandleTable;
|
||||
|
@ -116,6 +118,7 @@ NTSTATUS STDCALL CsrFreeProcessData( HANDLE Pid );
|
|||
/* api/handle.c */
|
||||
NTSTATUS FASTCALL CsrRegisterObjectDefinitions(PCSRSS_OBJECT_DEFINITION NewDefinitions);
|
||||
NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handle, Object_t *Object );
|
||||
NTSTATUS STDCALL CsrDuplicateHandleTable(PCSRSS_PROCESS_DATA SourceProcessData, PCSRSS_PROCESS_DATA TargetProcessData);
|
||||
NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object );
|
||||
BOOL STDCALL CsrServerInitialization (ULONG ArgumentCount, PWSTR *ArgumentArray);
|
||||
NTSTATUS STDCALL CsrReleaseObjectByPointer(Object_t *Object);
|
||||
|
|
|
@ -212,7 +212,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
|
|||
}
|
||||
Console->ActiveBuffer = NewBuffer;
|
||||
/* add a reference count because the buffer is tied to the console */
|
||||
Console->ActiveBuffer->Header.ReferenceCount++;
|
||||
InterlockedIncrement(&Console->ActiveBuffer->Header.ReferenceCount);
|
||||
/* make console active, and insert into console list */
|
||||
/* copy buffer contents to screen */
|
||||
ConioDrawConsole(Console);
|
||||
|
@ -225,6 +225,7 @@ CSR_API(CsrAllocConsole)
|
|||
{
|
||||
PCSRSS_CONSOLE Console;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN NewConsole = FALSE;
|
||||
|
||||
DPRINT("CsrAllocConsole\n");
|
||||
|
||||
|
@ -255,9 +256,11 @@ CSR_API(CsrAllocConsole)
|
|||
}
|
||||
|
||||
/* If we already have one, then don't create a new one... */
|
||||
if (!Request->Data.AllocConsoleRequest.Console)
|
||||
if (!Request->Data.AllocConsoleRequest.Console ||
|
||||
Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole)
|
||||
{
|
||||
/* Allocate a console structure */
|
||||
NewConsole = TRUE;
|
||||
Console = HeapAlloc(Win32CsrApiHeap, 0, sizeof(CSRSS_CONSOLE));
|
||||
if (NULL == Console)
|
||||
{
|
||||
|
@ -290,28 +293,32 @@ CSR_API(CsrAllocConsole)
|
|||
/* Add a reference count because the process is tied to the console */
|
||||
Console->Header.ReferenceCount++;
|
||||
|
||||
/* Insert the Objects */
|
||||
Status = Win32CsrInsertObject(ProcessData,
|
||||
&Request->Data.AllocConsoleRequest.InputHandle,
|
||||
&Console->Header);
|
||||
if (! NT_SUCCESS(Status))
|
||||
if (NewConsole || !ProcessData->bInheritHandles)
|
||||
{
|
||||
DPRINT1("Failed to insert object\n");
|
||||
ConioDeleteConsole((Object_t *) Console);
|
||||
ProcessData->Console = 0;
|
||||
return Request->Status = Status;
|
||||
}
|
||||
Status = Win32CsrInsertObject(ProcessData,
|
||||
&Request->Data.AllocConsoleRequest.OutputHandle,
|
||||
&Console->ActiveBuffer->Header);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to insert object\n");
|
||||
Console->Header.ReferenceCount--;
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
Request->Data.AllocConsoleRequest.InputHandle);
|
||||
ProcessData->Console = 0;
|
||||
return Request->Status = Status;
|
||||
/* Insert the Objects */
|
||||
Status = Win32CsrInsertObject(ProcessData,
|
||||
&Request->Data.AllocConsoleRequest.InputHandle,
|
||||
&Console->Header);
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to insert object\n");
|
||||
ConioDeleteConsole((Object_t *) Console);
|
||||
ProcessData->Console = 0;
|
||||
return Request->Status = Status;
|
||||
}
|
||||
|
||||
Status = Win32CsrInsertObject(ProcessData,
|
||||
&Request->Data.AllocConsoleRequest.OutputHandle,
|
||||
&Console->ActiveBuffer->Header);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to insert object\n");
|
||||
ConioDeleteConsole((Object_t *) Console);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
Request->Data.AllocConsoleRequest.InputHandle);
|
||||
ProcessData->Console = 0;
|
||||
return Request->Status = Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Duplicate the Event */
|
||||
|
@ -324,14 +331,16 @@ CSR_API(CsrAllocConsole)
|
|||
0))
|
||||
{
|
||||
DPRINT1("DuplicateHandle() failed: %d\n", GetLastError);
|
||||
Console->Header.ReferenceCount--;
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
Request->Data.AllocConsoleRequest.OutputHandle);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
Request->Data.AllocConsoleRequest.InputHandle);
|
||||
ConioDeleteConsole((Object_t *) Console);
|
||||
if (NewConsole || !ProcessData->bInheritHandles)
|
||||
{
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
Request->Data.AllocConsoleRequest.OutputHandle);
|
||||
Win32CsrReleaseObject(ProcessData,
|
||||
Request->Data.AllocConsoleRequest.InputHandle);
|
||||
}
|
||||
ProcessData->Console = 0;
|
||||
Request->Status = Status;
|
||||
return Status;
|
||||
return Request->Status = Status;
|
||||
}
|
||||
|
||||
/* Set the Ctrl Dispatcher */
|
||||
|
@ -358,9 +367,8 @@ CSR_API(CsrFreeConsole)
|
|||
}
|
||||
|
||||
Console = ProcessData->Console;
|
||||
Console->Header.ReferenceCount--;
|
||||
ProcessData->Console = NULL;
|
||||
if (0 == Console->Header.ReferenceCount)
|
||||
if (0 == InterlockedDecrement(&Console->Header.ReferenceCount))
|
||||
{
|
||||
ConioDeleteConsole((Object_t *) Console);
|
||||
}
|
||||
|
@ -1002,7 +1010,7 @@ ConioDeleteConsole(Object_t *Object)
|
|||
HeapFree(Win32CsrApiHeap, 0, Event);
|
||||
}
|
||||
|
||||
if (0 == --Console->ActiveBuffer->Header.ReferenceCount)
|
||||
if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount))
|
||||
{
|
||||
ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue