NTSTATUS PhSvcApiRequestThreadStart( _In_ PVOID Parameter ) { PH_AUTO_POOL autoPool; NTSTATUS status; PHSVC_THREAD_CONTEXT threadContext; HANDLE portHandle; PVOID portContext; SIZE_T messageSize; PPORT_MESSAGE receiveMessage; PPORT_MESSAGE replyMessage; CSHORT messageType; PPHSVC_CLIENT client; PPHSVC_API_PAYLOAD payload; PhInitializeAutoPool(&autoPool); threadContext.CurrentClient = NULL; threadContext.OldClient = NULL; TlsSetValue(PhSvcApiThreadContextTlsIndex, &threadContext); portHandle = PhSvcApiPortHandle; messageSize = PhIsExecutingInWow64() ? sizeof(PHSVC_API_MSG64) : sizeof(PHSVC_API_MSG); receiveMessage = PhAllocate(messageSize); replyMessage = NULL; while (TRUE) { status = NtReplyWaitReceivePort( portHandle, &portContext, replyMessage, receiveMessage ); portHandle = PhSvcApiPortHandle; replyMessage = NULL; if (!NT_SUCCESS(status)) { // Client probably died. continue; } messageType = receiveMessage->u2.s2.Type; if (messageType == LPC_CONNECTION_REQUEST) { PhSvcHandleConnectionRequest(receiveMessage); continue; } if (!portContext) continue; client = portContext; threadContext.CurrentClient = client; PhWaitForEvent(&client->ReadyEvent, NULL); if (messageType == LPC_REQUEST) { if (PhIsExecutingInWow64()) payload = &((PPHSVC_API_MSG64)receiveMessage)->p; else payload = &((PPHSVC_API_MSG)receiveMessage)->p; PhSvcDispatchApiCall(client, payload, &portHandle); replyMessage = receiveMessage; } else if (messageType == LPC_PORT_CLOSED) { PhDereferenceObject(client); if (_InterlockedDecrement(&PhSvcApiNumberOfClients) == 0) { NtSetEvent(PhSvcTimeoutStandbyEventHandle, NULL); } } assert(!threadContext.OldClient); PhDrainAutoPool(&autoPool); } PhDeleteAutoPool(&autoPool); }
NTSTATUS PhSvcApiRequestThreadStart( __in PVOID Parameter ) { NTSTATUS status; PHSVC_THREAD_CONTEXT threadContext; HANDLE portHandle; PVOID portContext; PHSVC_API_MSG receiveMessage; PPHSVC_API_MSG replyMessage; CSHORT messageType; PPHSVC_CLIENT client; threadContext.CurrentClient = NULL; threadContext.OldClient = NULL; TlsSetValue(PhSvcApiThreadContextTlsIndex, &threadContext); portHandle = PhSvcApiPortHandle; replyMessage = NULL; while (TRUE) { status = NtReplyWaitReceivePort( portHandle, &portContext, (PPORT_MESSAGE)replyMessage, (PPORT_MESSAGE)&receiveMessage ); portHandle = PhSvcApiPortHandle; replyMessage = NULL; if (!NT_SUCCESS(status)) { // Client probably died. continue; } messageType = receiveMessage.h.u2.s2.Type; if (messageType == LPC_CONNECTION_REQUEST) { PhSvcHandleConnectionRequest(&receiveMessage); continue; } if (!portContext) continue; client = (PPHSVC_CLIENT)portContext; threadContext.CurrentClient = client; if (messageType == LPC_REQUEST) { PhSvcDispatchApiCall(client, &receiveMessage, &replyMessage, &portHandle); } else if (messageType == LPC_PORT_CLOSED) { PhDereferenceObject(client); if (_InterlockedDecrement(&PhSvcApiNumberOfClients) == 0) { NtSetEvent(PhSvcTimeoutStandbyEventHandle, NULL); } } assert(!threadContext.OldClient); } }