+ DPRINT("CSR: %s called", __FUNCTION__);
+
+ NewCount = 0;
+ for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++)
+ {
+ NewCount++;
+ }
+
+ New = RtlAllocateHeap(CsrssApiHeap, 0,
+ (ApiDefinitionsCount + NewCount)
+ * sizeof(CSRSS_API_DEFINITION));
+ if (NULL == New)
+ {
+ DPRINT1("Unable to allocate memory\n");
+ return STATUS_NO_MEMORY;
+ }
+ if (0 != ApiDefinitionsCount)
+ {
+ RtlCopyMemory(New, ApiDefinitions,
+ ApiDefinitionsCount * sizeof(CSRSS_API_DEFINITION));
+ RtlFreeHeap(CsrssApiHeap, 0, ApiDefinitions);
+ }
+ RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions,
+ NewCount * sizeof(CSRSS_API_DEFINITION));
+ ApiDefinitions = New;
+ ApiDefinitionsCount += NewCount;
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+FASTCALL
+CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
+ PCSR_API_MESSAGE Request)
+{
+ BOOL Found = FALSE;
+ unsigned DefIndex;
+ ULONG Type;
+
+ DPRINT("CSR: Calling handler for type: %x.\n", Request->Type);
+ Type = Request->Type & 0xFFFF; /* FIXME: USE MACRO */
+ DPRINT("CSR: API Number: %x ServerID: %x\n",Type, Request->Type >> 16);
+
+ /* FIXME: Extract DefIndex instead of looping */
+ for (DefIndex = 0; ! Found && DefIndex < ApiDefinitionsCount; DefIndex++)
+ {
+ if (ApiDefinitions[DefIndex].Type == Type)
+ {
+ if (Request->Header.u1.s1.DataLength < ApiDefinitions[DefIndex].MinRequestSize)
+ {
+ DPRINT1("Request type %d min request size %d actual %d\n",
+ Type, ApiDefinitions[DefIndex].MinRequestSize,
+ Request->Header.u1.s1.DataLength);
+ Request->Status = STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ (ApiDefinitions[DefIndex].Handler)(ProcessData, Request);
+ Found = TRUE;
+ }
+ }
+ }
+ if (! Found)
+ {
+ DPRINT1("CSR: Unknown request type 0x%x\n", Request->Type);
+ Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
+ Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
+ Request->Status = STATUS_INVALID_SYSTEM_SERVICE;
+ }
+}
+
+static
+VOID
+STDCALL
+ClientConnectionThread(HANDLE ServerPort)
+{
+ NTSTATUS Status;
+ BYTE RawRequest[LPC_MAX_DATA_LENGTH];
+ PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest;
+ PCSR_API_MESSAGE Reply;
+ PCSRSS_PROCESS_DATA ProcessData;
+
+ DPRINT("CSR: %s called", __FUNCTION__);
+
+ /* Reply must be NULL at the first call to NtReplyWaitReceivePort */
+ Reply = NULL;
+
+ /* Loop and reply/wait for a new message */
+ for (;;)
+ {
+ /* Send the reply and wait for a new request */
+ Status = NtReplyWaitReceivePort(ServerPort,
+ 0,
+ &Reply->Header,
+ &Request->Header);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSR: NtReplyWaitReceivePort failed\n");
+ break;
+ }
+
+ /* If the connection was closed, handle that */
+ if (Request->Header.u2.s2.Type == LPC_PORT_CLOSED)
+ {
+ CsrFreeProcessData( Request->Header.ClientId.UniqueProcess );
+ break;
+ }
+
+ DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n",
+ Request->Type,
+ Request->Header.ClientId.UniqueProcess);
+
+ /* Get the Process Data */
+ ProcessData = CsrGetProcessData(Request->Header.ClientId.UniqueProcess);
+ if (ProcessData == NULL)
+ {
+ DPRINT1("CSR: Message %d: Unable to find data for process 0x%x\n",
+ Request->Header.u2.s2.Type,
+ Request->Header.ClientId.UniqueProcess);
+ break;
+ }
+
+ /* Call the Handler */
+ CsrApiCallHandler(ProcessData, Request);
+
+ /* Send back the reply */
+ Reply = Request;
+ }
+
+ /* Close the port and exit the thread */
+ NtClose(ServerPort);
+ RtlExitUserThread(STATUS_SUCCESS);