static void test_ports_server(void) { OBJECT_ATTRIBUTES obj; HANDLE PortHandle; HANDLE AcceptPortHandle; PLPC_MESSAGE LpcMessage; ULONG size; NTSTATUS status; BOOL done = FALSE; pRtlInitUnicodeString(&port, PORTNAME); memset(&obj, 0, sizeof(OBJECT_ATTRIBUTES)); obj.Length = sizeof(OBJECT_ATTRIBUTES); obj.ObjectName = &port; status = pNtCreatePort(&PortHandle, &obj, 100, 100, 0); todo_wine { ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status); } size = FIELD_OFFSET(LPC_MESSAGE, Data) + MAX_MESSAGE_LEN; LpcMessage = HeapAlloc(GetProcessHeap(), 0, size); memset(LpcMessage, 0, size); while (TRUE) { status = pNtReplyWaitReceivePort(PortHandle, NULL, NULL, LpcMessage); todo_wine { ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld(%lx)\n", status, status); } /* STATUS_INVALID_HANDLE: win2k without admin rights will perform an * endless loop here */ if ((status == STATUS_NOT_IMPLEMENTED) || (status == STATUS_INVALID_HANDLE)) return; switch (LpcMessage->MessageType) { case LPC_CONNECTION_REQUEST: ProcessConnectionRequest(LpcMessage, &AcceptPortHandle); break; case LPC_REQUEST: ProcessLpcRequest(PortHandle, LpcMessage); done = TRUE; break; case LPC_DATAGRAM: ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST1), "Expected %s, got %s\n", REQUEST1, LpcMessage->Data); break; case LPC_CLIENT_DIED: ok(done, "Expected LPC request to be completed!\n"); return; default: ok(FALSE, "Unexpected message: %d\n", LpcMessage->MessageType); break; } } }
/********************************************************************** * ApiPortListener/1 * * DESCRIPTION * The thread to process messages from the \POSIX+\ApiPort * LPC port. Mostly used by PSXDLL.DLL. */ VOID STDCALL ApiPortListener (PVOID pArg) { ULONG ulIndex = (ULONG) pArg; NTSTATUS Status; LPC_TYPE RequestType; ULONG PortIdentifier; PSX_MAX_MESSAGE Request; PPSX_MAX_MESSAGE Reply = NULL; BOOL NullReply = FALSE; debug_print (L"PSXSS: ->%s pArg=%d", __FUNCTION__, ulIndex); while (TRUE) { Reply = NULL; NullReply = FALSE; while (!NullReply) { Status = NtReplyWaitReceivePort ( Server.Port[ulIndex].hObject, 0, (PLPC_MESSAGE) Reply, (PLPC_MESSAGE) & Request ); if (!NT_SUCCESS(Status)) { break; } RequestType = PORT_MESSAGE_TYPE(Request); switch (RequestType) { case LPC_CONNECTION_REQUEST: ProcessConnectionRequest ((PLPC_MAX_MESSAGE) & Request); NullReply = TRUE; continue; case LPC_CLIENT_DIED: case LPC_PORT_CLOSED: case LPC_DEBUG_EVENT: case LPC_ERROR_EVENT: case LPC_EXCEPTION: NullReply = TRUE; continue; default: if (RequestType != LPC_REQUEST) { NullReply = TRUE; continue; } } Reply = & Request; Reply->PsxHeader.Status = ProcessRequest (& Request); NullReply = FALSE; } if ((STATUS_INVALID_HANDLE == Status) || (STATUS_OBJECT_TYPE_MISMATCH == Status)) { break; } } #ifdef __PSXSS_ON_W32__ TerminateThread(GetCurrentThread(),Status); #else NtTerminateThread(NtCurrentThread(),Status); #endif }