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/csrs... ============================================================================== --- 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/csrs... ============================================================================== --- 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/incl... ============================================================================== --- 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