- 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. Modified: trunk/reactos/include/subsys/csrss/csrss.h Modified: trunk/reactos/subsys/csrss/api/handle.c Modified: trunk/reactos/subsys/csrss/api/process.c Modified: trunk/reactos/subsys/csrss/include/api.h Modified: trunk/reactos/subsys/csrss/win32csr/conio.c _____
Modified: trunk/reactos/include/subsys/csrss/csrss.h --- trunk/reactos/include/subsys/csrss/csrss.h 2005-07-31 21:02:05 UTC (rev 16923) +++ trunk/reactos/include/subsys/csrss/csrss.h 2005-07-31 21:23:40 UTC (rev 16924) @@ -33,6 +33,7 @@
{ HANDLE NewProcessId; ULONG Flags; + BOOL bInheritHandles; } CSRSS_CREATE_PROCESS, *PCSRSS_CREATE_PROCESS;
typedef struct _____
Modified: trunk/reactos/subsys/csrss/api/handle.c --- trunk/reactos/subsys/csrss/api/handle.c 2005-07-31 21:02:05 UTC (rev 16923) +++ trunk/reactos/subsys/csrss/api/handle.c 2005-07-31 21:23:40 UTC (rev 16924) @@ -72,7 +72,7 @@
} 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 @@ 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; _____
Modified: trunk/reactos/subsys/csrss/api/process.c --- trunk/reactos/subsys/csrss/api/process.c 2005-07-31 21:02:05 UTC (rev 16923) +++ trunk/reactos/subsys/csrss/api/process.c 2005-07-31 21:23:40 UTC (rev 16924) @@ -192,6 +192,7 @@
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 @@ 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; _____
Modified: trunk/reactos/subsys/csrss/include/api.h --- trunk/reactos/subsys/csrss/include/api.h 2005-07-31 21:02:05 UTC (rev 16923) +++ trunk/reactos/subsys/csrss/include/api.h 2005-07-31 21:23:40 UTC (rev 16924) @@ -35,6 +35,8 @@
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 @@ /* 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); _____
Modified: trunk/reactos/subsys/csrss/win32csr/conio.c --- trunk/reactos/subsys/csrss/win32csr/conio.c 2005-07-31 21:02:05 UTC (rev 16923) +++ trunk/reactos/subsys/csrss/win32csr/conio.c 2005-07-31 21:23:40 UTC (rev 16924) @@ -212,7 +212,7 @@
} 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 @@ { PCSRSS_CONSOLE Console; NTSTATUS Status; + BOOLEAN NewConsole = FALSE;
DPRINT("CsrAllocConsole\n");
@@ -255,9 +256,11 @@ }
/* 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,29 +293,33 @@ /* 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; + /* 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; + } } - 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; - }
/* Duplicate the Event */ if (!DuplicateHandle(GetCurrentProcess(), @@ -324,14 +331,16 @@ 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 @@ }
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 @@ HeapFree(Win32CsrApiHeap, 0, Event); }
- if (0 == --Console->ActiveBuffer->Header.ReferenceCount) + if (0 == InterlockedDecrement(&Console->ActiveBuffer->Header.ReferenceCount)) { ConioDeleteScreenBuffer((Object_t *) Console->ActiveBuffer); }