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/csrsrv/api/wapi.c?rev=55638&r1=55637&r2=55638&view=diff
==============================================================================
--- 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/csrsrv/init.c?rev=55638&r1=55637&r2=55638&view=diff
==============================================================================
--- 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/include/api.h?rev=55638&r1=55637&r2=55638&view=diff
==============================================================================
--- 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


Reply via email to