Author: ion
Date: Thu Feb 16 16:40:15 2012
New Revision: 55638
URL:
http://svn.reactos.org/svn/reactos?rev=55638&view=rev
Log:
[CSRSRV]: Improve ClientConnectionThread a bit to make it look a bit more like CSRSRV2 and
add some extra functionality.
[CSRSRV]: Port from CSRSRV2 and use CsrApiPortInitialize instead of CsrpCreateListenPort.
This will set appropriate SDs and also wait for all threads to be ready.
Modified:
trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c
trunk/reactos/subsystems/win32/csrss/csrsrv/init.c
trunk/reactos/subsystems/win32/csrss/include/api.h
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csr…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c [iso-8859-1] Thu Feb 16
16:40:15 2012
@@ -19,6 +19,7 @@
static unsigned ApiDefinitionsCount = 0;
static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
+UNICODE_STRING CsrApiPortName;
/* FUNCTIONS *****************************************************************/
@@ -301,6 +302,129 @@
/* Return success */
return STATUS_SUCCESS;
+}
+
+/*++
+ * @name CsrApiPortInitialize
+ *
+ * The CsrApiPortInitialize routine initializes the LPC Port used for
+ * communications with the Client/Server Runtime (CSR) and initializes the
+ * static thread that will handle connection requests and APIs.
+ *
+ * @param None
+ *
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
+ * othwerwise.
+ *
+ * @remarks None.
+ *
+ *--*/
+NTSTATUS
+NTAPI
+CsrApiPortInitialize(VOID)
+{
+ ULONG Size;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
+ HANDLE hRequestEvent, hThread;
+ CLIENT_ID ClientId;
+ PLIST_ENTRY ListHead, NextEntry;
+ PCSR_THREAD ServerThread;
+
+ /* Calculate how much space we'll need for the Port Name */
+ Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR);
+
+ /* Create the buffer for it */
+ CsrApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
+ if (!CsrApiPortName.Buffer) return STATUS_NO_MEMORY;
+
+ /* Setup the rest of the empty string */
+ CsrApiPortName.Length = 0;
+ CsrApiPortName.MaximumLength = (USHORT)Size;
+ RtlAppendUnicodeStringToString(&CsrApiPortName, &CsrDirectoryName);
+ RtlAppendUnicodeToString(&CsrApiPortName, UNICODE_PATH_SEP);
+ RtlAppendUnicodeToString(&CsrApiPortName, CSR_PORT_NAME);
+ if (CsrDebug & 1)
+ {
+ DPRINT1("CSRSS: Creating %wZ port and associated threads\n",
&CsrApiPortName);
+ DPRINT1("CSRSS: sizeof( CONNECTINFO ) == %ld sizeof( API_MSG ) ==
%ld\n",
+ sizeof(CSR_CONNECTION_INFO), sizeof(CSR_API_MESSAGE));
+ }
+
+ /* FIXME: Create a Security Descriptor */
+
+ /* Initialize the Attributes */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &CsrApiPortName,
+ 0,
+ NULL,
+ NULL /* FIXME*/);
+
+ /* Create the Port Object */
+ Status = NtCreatePort(&hApiPort, //&CsrApiPort,
+ &ObjectAttributes,
+ sizeof(CSR_CONNECTION_INFO),
+ sizeof(CSR_API_MESSAGE),
+ 16 * PAGE_SIZE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Create the event the Port Thread will use */
+ Status = NtCreateEvent(&hRequestEvent,
+ EVENT_ALL_ACCESS,
+ NULL,
+ SynchronizationEvent,
+ FALSE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Create the Request Thread */
+ Status = RtlCreateUserThread(NtCurrentProcess(),
+ NULL,
+ TRUE,
+ 0,
+ 0,
+ 0,
+
(PVOID)ClientConnectionThread,//CsrApiRequestThread,
+ (PVOID)hRequestEvent,
+ &hThread,
+ &ClientId);
+ if (NT_SUCCESS(Status))
+ {
+ /* Add this as a static thread to CSRSRV */
+ CsrAddStaticServerThread(hThread, &ClientId,
CsrThreadIsServerThread);
+
+ /* Get the Thread List Pointers */
+ ListHead = &CsrRootProcess->ThreadList;
+ NextEntry = ListHead->Flink;
+
+ /* Start looping the list */
+ while (NextEntry != ListHead)
+ {
+ /* Get the Thread */
+ ServerThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
+
+ /* Start it up */
+ Status = NtResumeThread(ServerThread->ThreadHandle, NULL);
+
+ /* Is this a Server Thread? */
+ if (ServerThread->Flags & CsrThreadIsServerThread)
+ {
+ /* If so, then wait for it to initialize */
+ Status = NtWaitForSingleObject(hRequestEvent, FALSE, NULL);
+ ASSERT(NT_SUCCESS(Status));
+ }
+
+ /* Next thread */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* We don't need this anymore */
+ NtClose(hRequestEvent);
+ }
+ }
+ }
+
+ /* Return */
+ return Status;
}
PBASE_STATIC_SERVER_DATA BaseStaticServerData;
@@ -685,8 +809,7 @@
}
NTSTATUS WINAPI
-CsrpHandleConnectionRequest (PPORT_MESSAGE Request,
- IN HANDLE hApiListenPort)
+CsrpHandleConnectionRequest (PPORT_MESSAGE Request)
{
NTSTATUS Status;
HANDLE ServerPort = NULL, ServerThread = NULL;
@@ -780,7 +903,7 @@
0,
0,
(PTHREAD_START_ROUTINE)ClientConnectionThread,
- ServerPort,
+ NULL,
& ServerThread,
&ClientId);
if (!NT_SUCCESS(Status))
@@ -849,74 +972,130 @@
VOID
WINAPI
-ClientConnectionThread(HANDLE ServerPort)
+ClientConnectionThread(IN PVOID Parameter)
{
+ PTEB Teb = NtCurrentTeb();
+ LARGE_INTEGER TimeOut;
NTSTATUS Status;
BYTE RawRequest[LPC_MAX_DATA_LENGTH];
PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest;
PCSR_API_MESSAGE Reply;
PCSR_PROCESS ProcessData;
PCSR_THREAD ServerThread;
+ ULONG MessageType;
DPRINT("CSR: %s called\n", __FUNCTION__);
+
+ /* Setup LPC loop port and message */
+ Reply = NULL;
+// ReplyPort = CsrApiPort;
/* Connect to user32 */
while (!CsrConnectToUser())
{
+ /* Set up the timeout for the connect (30 seconds) */
+ TimeOut.QuadPart = -30 * 1000 * 1000 * 10;
+
/* Keep trying until we get a response */
- NtCurrentTeb()->Win32ClientInfo[0] = 0;
- //NtDelayExecution(FALSE, &TimeOut);
- }
-
- /* Reply must be NULL at the first call to NtReplyWaitReceivePort */
- ServerThread = NtCurrentTeb()->CsrClientThread;
- Reply = NULL;
-
- /* Loop and reply/wait for a new message */
- for (;;)
- {
+ Teb->Win32ClientInfo[0] = 0;
+ NtDelayExecution(FALSE, &TimeOut);
+ }
+
+ /* Get our thread */
+ ServerThread = Teb->CsrClientThread;
+
+ /* If we got an event... */
+ if (Parameter)
+ {
+ /* Set it, to let stuff waiting on us load */
+ Status = NtSetEvent((HANDLE)Parameter, NULL);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Increase the Thread Counts */
+ //_InterlockedIncrement(&CsrpStaticThreadCount);
+ //_InterlockedIncrement(&CsrpDynamicThreadTotal);
+ }
+
+ /* Now start the loop */
+ while (TRUE)
+ {
+ /* Make sure the real CID is set */
+ Teb->RealClientId = Teb->ClientId;
+
+ /* Debug check */
+ if (Teb->CountOfOwnedCriticalSections)
+ {
+ DPRINT1("CSRSRV: FATAL ERROR. CsrThread is Idle while holding %lu
critical sections\n",
+ Teb->CountOfOwnedCriticalSections);
+ DPRINT1("CSRSRV: Last Receive Message %lx ReplyMessage %lx\n",
+ &Request, Reply);
+ DbgBreakPoint();
+ }
+
/* Send the reply and wait for a new request */
Status = NtReplyWaitReceivePort(hApiPort,
0,
&Reply->Header,
&Request->Header);
- /* Client died, continue */
- if (Status == STATUS_INVALID_CID)
- {
- Reply = NULL;
- continue;
- }
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtReplyWaitReceivePort failed: %lx\n", Status);
- break;
- }
+ /* Check if we didn't get success */
+ if (Status != STATUS_SUCCESS)
+ {
+ /* Was it a failure or another success code? */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Check for specific status cases */
+ if ((Status != STATUS_INVALID_CID) &&
+ (Status != STATUS_UNSUCCESSFUL))// &&
+// ((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort)))
+ {
+ /* Notify the debugger */
+ DPRINT1("CSRSS: ReceivePort failed - Status == %X\n",
Status);
+ //DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n",
ReplyPort, CsrApiPort);
+ }
+
+ /* We failed big time, so start out fresh */
+ Reply = NULL;
+ //ReplyPort = CsrApiPort;
+ continue;
+ }
+ else
+ {
+ /* A bizare "success" code, just try again */
+ DPRINT1("NtReplyWaitReceivePort returned \"success\"
status 0x%x\n", Status);
+ continue;
+ }
+ }
+
+ /* Use whatever Client ID we got */
+ Teb->RealClientId = Request->Header.ClientId;
+
+ /* Get the Message Type */
+ MessageType = Request->Header.u2.s2.Type;
/* If the connection was closed, handle that */
- if (Request->Header.u2.s2.Type == LPC_PORT_CLOSED)
+ if (MessageType == LPC_PORT_CLOSED)
{
DPRINT("Port died, oh well\n");
CsrFreeProcessData( Request->Header.ClientId.UniqueProcess );
break;
}
- if (Request->Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
- {
- CsrpHandleConnectionRequest((PPORT_MESSAGE)Request, ServerPort);
+ if (MessageType == LPC_CONNECTION_REQUEST)
+ {
+ CsrpHandleConnectionRequest((PPORT_MESSAGE)Request);
Reply = NULL;
continue;
}
- if (Request->Header.u2.s2.Type == LPC_CLIENT_DIED)
+ if (MessageType == LPC_CLIENT_DIED)
{
DPRINT("Client died, oh well\n");
Reply = NULL;
continue;
}
- if ((Request->Header.u2.s2.Type != LPC_ERROR_EVENT) &&
- (Request->Header.u2.s2.Type != LPC_REQUEST))
+ if ((MessageType != LPC_ERROR_EVENT) &&
+ (MessageType != LPC_REQUEST))
{
DPRINT1("CSR: received message %d\n",
Request->Header.u2.s2.Type);
Reply = NULL;
@@ -932,7 +1111,7 @@
if (ProcessData == NULL)
{
DPRINT1("Message %d: Unable to find data for process 0x%x\n",
- Request->Header.u2.s2.Type,
+ MessageType,
Request->Header.ClientId.UniqueProcess);
break;
}
@@ -944,7 +1123,7 @@
}
/* Check if we got a hard error */
- if (Request->Header.u2.s2.Type == LPC_ERROR_EVENT)
+ if (MessageType == LPC_ERROR_EVENT)
{
/* Call the Handler */
CsrHandleHardError(ProcessData, (PHARDERROR_MSG)Request);
@@ -972,7 +1151,9 @@
// NtClose(ServerPort);
DPRINT("CSR: %s done\n", __FUNCTION__);
- RtlExitUserThread(STATUS_SUCCESS);
+ /* We're out of the loop for some reason, terminate! */
+ NtTerminateThread(NtCurrentThread(), Status);
+ //return Status;
}
/*++
Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csr…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/init.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/init.c [iso-8859-1] Thu Feb 16 16:40:15
2012
@@ -175,57 +175,6 @@
CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS, CsrSetShutdownParameters),
{ 0, 0, NULL }
};
-
-static NTSTATUS WINAPI
-CsrpCreateListenPort (IN LPWSTR Name,
- IN OUT PHANDLE Port,
- IN PTHREAD_START_ROUTINE ListenThread)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- OBJECT_ATTRIBUTES PortAttributes;
- UNICODE_STRING PortName;
- HANDLE ServerThread;
- CLIENT_ID ClientId;
-
- DPRINT("CSR: %s called\n", __FUNCTION__);
-
- RtlInitUnicodeString (& PortName, Name);
- InitializeObjectAttributes (& PortAttributes,
- & PortName,
- 0,
- NULL,
- NULL);
- Status = NtCreatePort ( Port,
- & PortAttributes,
- sizeof(SB_CONNECTION_INFO),
- sizeof(SB_API_MSG),
- 32 * sizeof(SB_API_MSG));
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
- __FUNCTION__, Status);
- return Status;
- }
- Status = RtlCreateUserThread(NtCurrentProcess(),
- NULL,
- TRUE,
- 0,
- 0,
- 0,
- (PTHREAD_START_ROUTINE) ListenThread,
- *Port,
- &ServerThread,
- &ClientId);
-
- if (ListenThread == (PVOID)ClientConnectionThread)
- {
- CsrAddStaticServerThread(ServerThread, &ClientId, 0);
- }
-
- NtResumeThread(ServerThread, NULL);
- NtClose(ServerThread);
- return Status;
-}
/* === INIT ROUTINES === */
@@ -1150,10 +1099,13 @@
DPRINT1("CSRSRV failed in %s with status %lx\n",
"CsrApiRegisterDefinitions", Status);
}
- Status = CsrpCreateListenPort(L"\\Windows\\ApiPort", &hApiPort,
(PTHREAD_START_ROUTINE)ClientConnectionThread);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV failed in %s with status %lx\n",
"CsrpCreateApiPort", Status);
+ /* Now initialize our API Port */
+ Status = CsrApiPortInitialize();
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
+ __FUNCTION__, Status);
+ return Status;
}
Status = CsrpInitWin32Csr();
Modified: trunk/reactos/subsystems/win32/csrss/include/api.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/include/api.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/include/api.h [iso-8859-1] Thu Feb 16 16:40:15
2012
@@ -235,6 +235,12 @@
extern LIST_ENTRY CsrThreadHashTable[256];
extern PCSR_PROCESS CsrRootProcess;
extern RTL_CRITICAL_SECTION ProcessDataLock, CsrWaitListsLock;
+extern UNICODE_STRING CsrDirectoryName;
+extern ULONG CsrDebug;
+
+NTSTATUS
+NTAPI
+CsrApiPortInitialize(VOID);
BOOLEAN
NTAPI