- 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);
}