From: Rose Hellsing <rose@pinkro.se> The LPC port implementation is now complete, so the tests pass without needing todo_wine markers. --- dlls/ntdll/tests/port.c | 198 +++++++++++----------------------------- dlls/ntdll/unix/sync.c | 2 +- dlls/wow64/struct32.h | 12 +++ dlls/wow64/sync.c | 178 ++++++++++++++++++++++++++++++------ 4 files changed, 219 insertions(+), 171 deletions(-) diff --git a/dlls/ntdll/tests/port.c b/dlls/ntdll/tests/port.c index 80c60d09683..626e839d95a 100644 --- a/dlls/ntdll/tests/port.c +++ b/dlls/ntdll/tests/port.c @@ -69,25 +69,6 @@ typedef struct _LPC_MESSAGE #endif -/* on Wow64 we have to use the 64-bit layout */ -typedef struct -{ - USHORT DataSize; - USHORT MessageSize; - USHORT MessageType; - USHORT VirtualRangesOffset; - ULONGLONG ClientId[2]; - ULONGLONG MessageId; - ULONGLONG SectionSize; - UCHAR Data[ANYSIZE_ARRAY]; -} LPC_MESSAGE64; - -union lpc_message -{ - LPC_MESSAGE msg; - LPC_MESSAGE64 msg64; -}; - /* Types of LPC messages */ #define UNUSED_MSG_TYPE 0 #define LPC_REQUEST 1 @@ -128,9 +109,6 @@ static NTSTATUS (WINAPI *pNtConnectPort)(PHANDLE,PUNICODE_STRING, PLPC_SECTION_WRITE,PLPC_SECTION_READ, PVOID,PVOID,PULONG); static NTSTATUS (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING,LPCWSTR); -static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); - -static BOOL is_wow64; static BOOL init_function_ptrs(void) { @@ -155,80 +133,50 @@ static BOOL init_function_ptrs(void) !pNtRequestPort || !pNtRegisterThreadTerminatePort || !pNtConnectPort || !pRtlInitUnicodeString) { - todo_wine win_skip("Needed port functions are not available\n"); + win_skip("Needed port functions are not available\n"); FreeLibrary(hntdll); return FALSE; } - - pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); - if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE; return TRUE; } -static void ProcessConnectionRequest(union lpc_message *LpcMessage, PHANDLE pAcceptPortHandle) +static void ProcessConnectionRequest(LPC_MESSAGE *LpcMessage, PHANDLE pAcceptPortHandle) { NTSTATUS status; - if (is_wow64) - { - ok(LpcMessage->msg64.MessageType == LPC_CONNECTION_REQUEST, - "Expected LPC_CONNECTION_REQUEST, got %d\n", LpcMessage->msg64.MessageType); - ok(!*LpcMessage->msg64.Data, "Expected empty string!\n"); - } - else - { - ok(LpcMessage->msg.MessageType == LPC_CONNECTION_REQUEST, - "Expected LPC_CONNECTION_REQUEST, got %d\n", LpcMessage->msg.MessageType); - ok(!*LpcMessage->msg.Data, "Expected empty string!\n"); - } + ok(LpcMessage->MessageType == LPC_CONNECTION_REQUEST, + "Expected LPC_CONNECTION_REQUEST, got %d\n", LpcMessage->MessageType); + ok(!*LpcMessage->Data, "Expected empty string!\n"); - status = pNtAcceptConnectPort(pAcceptPortHandle, 0, &LpcMessage->msg, 1, NULL, NULL); + status = pNtAcceptConnectPort(pAcceptPortHandle, 0, LpcMessage, 1, NULL, NULL); ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); status = pNtCompleteConnectPort(*pAcceptPortHandle); ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); } -static void ProcessLpcRequest(HANDLE PortHandle, union lpc_message *LpcMessage) +static void ProcessLpcRequest(HANDLE PortHandle, LPC_MESSAGE *LpcMessage) { NTSTATUS status; - if (is_wow64) - { - ok(LpcMessage->msg64.MessageType == LPC_REQUEST, - "Expected LPC_REQUEST, got %d\n", LpcMessage->msg64.MessageType); - ok(!strcmp((LPSTR)LpcMessage->msg64.Data, REQUEST2), - "Expected %s, got %s\n", REQUEST2, LpcMessage->msg64.Data); - strcpy((LPSTR)LpcMessage->msg64.Data, REPLY); - - status = pNtReplyPort(PortHandle, &LpcMessage->msg); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); - ok(LpcMessage->msg64.MessageType == LPC_REQUEST, - "Expected LPC_REQUEST, got %d\n", LpcMessage->msg64.MessageType); - ok(!strcmp((LPSTR)LpcMessage->msg64.Data, REPLY), - "Expected %s, got %s\n", REPLY, LpcMessage->msg64.Data); - } - else - { - ok(LpcMessage->msg.MessageType == LPC_REQUEST, - "Expected LPC_REQUEST, got %d\n", LpcMessage->msg.MessageType); - ok(!strcmp((LPSTR)LpcMessage->msg.Data, REQUEST2), - "Expected %s, got %s\n", REQUEST2, LpcMessage->msg.Data); - strcpy((LPSTR)LpcMessage->msg.Data, REPLY); - - status = pNtReplyPort(PortHandle, &LpcMessage->msg); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); - ok(LpcMessage->msg.MessageType == LPC_REQUEST, - "Expected LPC_REQUEST, got %d\n", LpcMessage->msg.MessageType); - ok(!strcmp((LPSTR)LpcMessage->msg.Data, REPLY), - "Expected %s, got %s\n", REPLY, LpcMessage->msg.Data); - } + ok(LpcMessage->MessageType == LPC_REQUEST, + "Expected LPC_REQUEST, got %d\n", LpcMessage->MessageType); + ok(!strcmp((LPSTR)LpcMessage->Data, REQUEST2), + "Expected %s, got %s\n", REQUEST2, LpcMessage->Data); + strcpy((LPSTR)LpcMessage->Data, REPLY); + + status = pNtReplyPort(PortHandle, LpcMessage); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); + ok(LpcMessage->MessageType == LPC_REQUEST, + "Expected LPC_REQUEST, got %d\n", LpcMessage->MessageType); + ok(!strcmp((LPSTR)LpcMessage->Data, REPLY), + "Expected %s, got %s\n", REPLY, LpcMessage->Data); } static DWORD WINAPI test_ports_client(LPVOID arg) { SECURITY_QUALITY_OF_SERVICE sqos; - union lpc_message *LpcMessage, *out; + LPC_MESSAGE *LpcMessage, *out; HANDLE PortHandle; ULONG len, size; NTSTATUS status; @@ -239,68 +187,37 @@ static DWORD WINAPI test_ports_client(LPVOID arg) sqos.EffectiveOnly = TRUE; status = pNtConnectPort(&PortHandle, &port, &sqos, 0, 0, &len, NULL, NULL); - todo_wine ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); if (status != STATUS_SUCCESS) return 1; status = pNtRegisterThreadTerminatePort(PortHandle); ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); - if (is_wow64) - { - size = FIELD_OFFSET(LPC_MESSAGE64, Data[MAX_MESSAGE_LEN]); - LpcMessage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); - out = HeapAlloc(GetProcessHeap(), 0, size); - - LpcMessage->msg64.DataSize = strlen(REQUEST1) + 1; - LpcMessage->msg64.MessageSize = FIELD_OFFSET(LPC_MESSAGE64, Data[LpcMessage->msg64.DataSize]); - strcpy((LPSTR)LpcMessage->msg64.Data, REQUEST1); - - status = pNtRequestPort(PortHandle, &LpcMessage->msg); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); - ok(LpcMessage->msg64.MessageType == 0, "Expected 0, got %d\n", LpcMessage->msg64.MessageType); - ok(!strcmp((LPSTR)LpcMessage->msg64.Data, REQUEST1), - "Expected %s, got %s\n", REQUEST1, LpcMessage->msg64.Data); - - /* Fill in the message */ - memset(LpcMessage, 0, size); - LpcMessage->msg64.DataSize = strlen(REQUEST2) + 1; - LpcMessage->msg64.MessageSize = FIELD_OFFSET(LPC_MESSAGE64, Data[LpcMessage->msg64.DataSize]); - strcpy((LPSTR)LpcMessage->msg64.Data, REQUEST2); - - /* Send the message and wait for the reply */ - status = pNtRequestWaitReplyPort(PortHandle, &LpcMessage->msg, &out->msg); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); - ok(!strcmp((LPSTR)out->msg64.Data, REPLY), "Expected %s, got %s\n", REPLY, out->msg64.Data); - ok(out->msg64.MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->msg64.MessageType); - } - else - { - size = FIELD_OFFSET(LPC_MESSAGE, Data[MAX_MESSAGE_LEN]); - LpcMessage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); - out = HeapAlloc(GetProcessHeap(), 0, size); - - LpcMessage->msg.DataSize = strlen(REQUEST1) + 1; - LpcMessage->msg.MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data[LpcMessage->msg.DataSize]); - strcpy((LPSTR)LpcMessage->msg.Data, REQUEST1); - - status = pNtRequestPort(PortHandle, &LpcMessage->msg); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); - ok(LpcMessage->msg.MessageType == 0, "Expected 0, got %d\n", LpcMessage->msg.MessageType); - ok(!strcmp((LPSTR)LpcMessage->msg.Data, REQUEST1), - "Expected %s, got %s\n", REQUEST1, LpcMessage->msg.Data); - - /* Fill in the message */ - memset(LpcMessage, 0, size); - LpcMessage->msg.DataSize = strlen(REQUEST2) + 1; - LpcMessage->msg.MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data[LpcMessage->msg.DataSize]); - strcpy((LPSTR)LpcMessage->msg.Data, REQUEST2); - - /* Send the message and wait for the reply */ - status = pNtRequestWaitReplyPort(PortHandle, &LpcMessage->msg, &out->msg); - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); - ok(!strcmp((LPSTR)out->msg.Data, REPLY), "Expected %s, got %s\n", REPLY, out->msg.Data); - ok(out->msg.MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->msg.MessageType); - } + size = FIELD_OFFSET(LPC_MESSAGE, Data[MAX_MESSAGE_LEN]); + LpcMessage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + out = HeapAlloc(GetProcessHeap(), 0, size); + + LpcMessage->DataSize = strlen(REQUEST1) + 1; + LpcMessage->MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data[LpcMessage->DataSize]); + strcpy((LPSTR)LpcMessage->Data, REQUEST1); + + status = pNtRequestPort(PortHandle, LpcMessage); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); + ok(LpcMessage->MessageType == 0, "Expected 0, got %d\n", LpcMessage->MessageType); + ok(!strcmp((LPSTR)LpcMessage->Data, REQUEST1), + "Expected %s, got %s\n", REQUEST1, LpcMessage->Data); + + /* Fill in the message */ + memset(LpcMessage, 0, size); + LpcMessage->DataSize = strlen(REQUEST2) + 1; + LpcMessage->MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data[LpcMessage->DataSize]); + strcpy((LPSTR)LpcMessage->Data, REQUEST2); + + /* Send the message and wait for the reply */ + status = pNtRequestWaitReplyPort(PortHandle, LpcMessage, out); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status); + ok(!strcmp((LPSTR)out->Data, REPLY), "Expected %s, got %s\n", REPLY, out->Data); + ok(out->MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->MessageType); HeapFree(GetProcessHeap(), 0, out); HeapFree(GetProcessHeap(), 0, LpcMessage); @@ -311,7 +228,7 @@ static DWORD WINAPI test_ports_client(LPVOID arg) static void test_ports_server( HANDLE PortHandle ) { HANDLE AcceptPortHandle; - union lpc_message *LpcMessage; + LPC_MESSAGE *LpcMessage; ULONG size; NTSTATUS status; BOOL done = FALSE; @@ -321,18 +238,15 @@ static void test_ports_server( HANDLE PortHandle ) while (TRUE) { - status = pNtReplyWaitReceivePort(PortHandle, NULL, NULL, &LpcMessage->msg); - todo_wine - { - ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld(%lx)\n", status, status); - } + status = pNtReplyWaitReceivePort(PortHandle, NULL, NULL, LpcMessage); + 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 (is_wow64 ? LpcMessage->msg64.MessageType : LpcMessage->msg.MessageType) + switch (LpcMessage->MessageType) { case LPC_CONNECTION_REQUEST: ProcessConnectionRequest(LpcMessage, &AcceptPortHandle); @@ -344,12 +258,8 @@ static void test_ports_server( HANDLE PortHandle ) break; case LPC_DATAGRAM: - if (is_wow64) - ok(!strcmp((LPSTR)LpcMessage->msg64.Data, REQUEST1), - "Expected %s, got %s\n", REQUEST1, LpcMessage->msg64.Data); - else - ok(!strcmp((LPSTR)LpcMessage->msg.Data, REQUEST1), - "Expected %s, got %s\n", REQUEST1, LpcMessage->msg.Data); + ok(!strcmp((LPSTR)LpcMessage->Data, REQUEST1), + "Expected %s, got %s\n", REQUEST1, LpcMessage->Data); break; case LPC_CLIENT_DIED: @@ -359,7 +269,7 @@ static void test_ports_server( HANDLE PortHandle ) default: ok(FALSE, "Unexpected message: %d\n", - is_wow64 ? LpcMessage->msg64.MessageType : LpcMessage->msg.MessageType); + LpcMessage->MessageType); break; } } @@ -384,7 +294,7 @@ START_TEST(port) status = pNtCreatePort(&port_handle, &obj, 100, 100, 0); if (status == STATUS_ACCESS_DENIED) skip("Not enough rights\n"); - else ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status); + else ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); if (status == STATUS_SUCCESS) { diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 48a564545d9..48d7bc6041a 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -3529,7 +3529,7 @@ NTSTATUS WINAPI NtReplyWaitReceivePortEx( HANDLE handle, ULONG *id, LPC_MESSAGE { /* Use a reasonable max size for LPC message data. * sizeof(msg->Data) is just 1 due to ANYSIZE_ARRAY. */ - wine_server_set_reply( req, msg->Data, 0x1000 ); + wine_server_set_reply( req, msg->Data, msg->DataSize ); } ret = wine_server_call( req ); if (!ret && msg) diff --git a/dlls/wow64/struct32.h b/dlls/wow64/struct32.h index de378c13cc2..6d1acf6736e 100644 --- a/dlls/wow64/struct32.h +++ b/dlls/wow64/struct32.h @@ -749,4 +749,16 @@ typedef struct LARGE_INTEGER TimeLimit; } QUOTA_LIMITS32; +typedef struct +{ + USHORT DataSize; + USHORT MessageSize; + USHORT MessageType; + USHORT VirtualRangesOffset; + CLIENT_ID32 ClientId; + ULONG MessageId; + ULONG SectionSize; + UCHAR Data[ANYSIZE_ARRAY]; +} LPC_MESSAGE32; + #endif /* __WOW64_STRUCT32_H */ diff --git a/dlls/wow64/sync.c b/dlls/wow64/sync.c index b083d63253e..e9d0ecf62a3 100644 --- a/dlls/wow64/sync.c +++ b/dlls/wow64/sync.c @@ -127,6 +127,34 @@ void put_section_image_info( SECTION_IMAGE_INFORMATION32 *info32, const SECTION_ info32->CheckSum = info->CheckSum; } +static void lpc_message_32to64( LPC_MESSAGE *msg64, const LPC_MESSAGE32 *msg32 ) +{ + msg64->DataSize = msg32->DataSize; + msg64->MessageSize = msg32->MessageSize; + msg64->MessageType = msg32->MessageType; + msg64->VirtualRangesOffset = msg32->VirtualRangesOffset; + msg64->ClientId.UniqueProcess = ULongToHandle( msg32->ClientId.UniqueProcess ); + msg64->ClientId.UniqueThread = ULongToHandle( msg32->ClientId.UniqueThread ); + msg64->MessageId = msg32->MessageId; + msg64->SectionSize = msg32->SectionSize; + if (msg32->DataSize) + memcpy( msg64->Data, msg32->Data, msg32->DataSize ); +} + +static void lpc_message_64to32( LPC_MESSAGE32 *msg32, const LPC_MESSAGE *msg64 ) +{ + msg32->DataSize = msg64->DataSize; + msg32->MessageSize = msg64->MessageSize; + msg32->MessageType = msg64->MessageType; + msg32->VirtualRangesOffset = msg64->VirtualRangesOffset; + msg32->ClientId.UniqueProcess = HandleToULong( msg64->ClientId.UniqueProcess ); + msg32->ClientId.UniqueThread = HandleToULong( msg64->ClientId.UniqueThread ); + msg32->MessageId = msg64->MessageId; + msg32->SectionSize = msg64->SectionSize; + if (msg64->DataSize) + memcpy( msg32->Data, msg64->Data, msg64->DataSize ); +} + /********************************************************************** * wow64_NtAcceptConnectPort @@ -135,13 +163,25 @@ NTSTATUS WINAPI wow64_NtAcceptConnectPort( UINT *args ) { ULONG *handle_ptr = get_ptr( &args ); ULONG id = get_ulong( &args ); - LPC_MESSAGE *msg = get_ptr( &args ); + LPC_MESSAGE32 *msg32 = get_ptr( &args ); BOOLEAN accept = get_ulong( &args ); LPC_SECTION_WRITE *write = get_ptr( &args ); LPC_SECTION_READ *read = get_ptr( &args ); - FIXME( "%p %lu %p %u %p %p: stub\n", handle_ptr, id, msg, accept, write, read ); - return STATUS_NOT_IMPLEMENTED; + HANDLE handle = 0; + LPC_MESSAGE *msg64; + NTSTATUS status; + + if (msg32) + { + msg64 = Wow64AllocateTemp( offsetof( LPC_MESSAGE, Data[msg32->DataSize] ) ); + lpc_message_32to64( msg64, msg32 ); + } + else msg64 = NULL; + + status = NtAcceptConnectPort( &handle, id, msg64, accept, write, read ); + put_handle( handle_ptr, handle ); + return status; } @@ -205,9 +245,14 @@ NTSTATUS WINAPI wow64_NtConnectPort( UINT *args ) void *info = get_ptr( &args ); ULONG *info_len = get_ptr( &args ); - FIXME( "%p %p %p %p %p %p %p %p: stub\n", - handle_ptr, name32, qos, write, read, max_len, info, info_len ); - return STATUS_NOT_IMPLEMENTED; + UNICODE_STRING name; + HANDLE handle = 0; + NTSTATUS status; + + status = NtConnectPort( &handle, unicode_str_32to64( &name, name32 ), + qos, write, read, max_len, info, info_len ); + put_handle( handle_ptr, handle ); + return status; } @@ -559,10 +604,25 @@ NTSTATUS WINAPI wow64_NtImpersonateClientOfPort( UINT *args ) NTSTATUS WINAPI wow64_NtListenPort( UINT *args ) { HANDLE handle = get_handle( &args ); - LPC_MESSAGE *msg = get_ptr( &args ); + LPC_MESSAGE32 *msg32 = get_ptr( &args ); - FIXME( "%p %p: stub\n", handle, msg ); - return STATUS_NOT_IMPLEMENTED; + LPC_MESSAGE *msg64; + NTSTATUS status; + + if (msg32) + { + /* Allocate a 64-bit message with enough space for data */ + msg64 = Wow64AllocateTemp( offsetof( LPC_MESSAGE, Data[0x1000] ) ); + memset( msg64, 0, sizeof(*msg64) ); + } + else msg64 = NULL; + + status = NtListenPort( handle, msg64 ); + + if (!status && msg32) + lpc_message_64to32( msg32, msg64 ); + + return status; } @@ -1314,10 +1374,20 @@ NTSTATUS WINAPI wow64_NtReadRequestData( UINT *args ) NTSTATUS WINAPI wow64_NtReplyPort( UINT *args ) { HANDLE handle = get_handle( &args ); - LPC_MESSAGE *reply = get_ptr( &args ); + LPC_MESSAGE32 *reply32 = get_ptr( &args ); - FIXME( "%p %p: stub\n", handle, reply ); - return STATUS_NOT_IMPLEMENTED; + LPC_MESSAGE *reply64; + NTSTATUS status; + + if (reply32) + { + reply64 = Wow64AllocateTemp( offsetof( LPC_MESSAGE, Data[reply32->DataSize] ) ); + lpc_message_32to64( reply64, reply32 ); + } + else reply64 = NULL; + + status = NtReplyPort( handle, reply64 ); + return status; } @@ -1328,11 +1398,16 @@ NTSTATUS WINAPI wow64_NtReplyWaitReceivePort( UINT *args ) { HANDLE handle = get_handle( &args ); ULONG *id = get_ptr( &args ); - LPC_MESSAGE *reply = get_ptr( &args ); - LPC_MESSAGE *msg = get_ptr( &args ); + LPC_MESSAGE32 *reply32 = get_ptr( &args ); + LPC_MESSAGE32 *msg32 = get_ptr( &args ); - FIXME( "%p %p %p %p: stub\n", handle, id, reply, msg ); - return STATUS_NOT_IMPLEMENTED; + return wow64_NtReplyWaitReceivePortEx( (UINT[]){ + HandleToULong( handle ), + PtrToUlong( id ), + PtrToUlong( reply32 ), + PtrToUlong( msg32 ), + 0 /* timeout = NULL */ + } ); } @@ -1343,12 +1418,34 @@ NTSTATUS WINAPI wow64_NtReplyWaitReceivePortEx( UINT *args ) { HANDLE handle = get_handle( &args ); ULONG *id = get_ptr( &args ); - LPC_MESSAGE *reply = get_ptr( &args ); - LPC_MESSAGE *msg = get_ptr( &args ); + LPC_MESSAGE32 *reply32 = get_ptr( &args ); + LPC_MESSAGE32 *msg32 = get_ptr( &args ); LARGE_INTEGER *timeout = get_ptr( &args ); - FIXME( "%p %p %p %p %p: stub\n", handle, id, reply, msg, timeout ); - return STATUS_NOT_IMPLEMENTED; + LPC_MESSAGE *reply64 = NULL; + LPC_MESSAGE *msg64 = NULL; + NTSTATUS status; + + if (reply32) + { + reply64 = Wow64AllocateTemp( offsetof( LPC_MESSAGE, Data[reply32->DataSize] ) ); + lpc_message_32to64( reply64, reply32 ); + } + + if (msg32) + { + msg64 = Wow64AllocateTemp( offsetof( LPC_MESSAGE, Data[0x1000] ) ); + memset( msg64, 0, sizeof(*msg64) ); + /* Set DataSize to indicate receive buffer capacity */ + msg64->DataSize = 0x1000; + } + + status = NtReplyWaitReceivePortEx( handle, id, reply64, msg64, timeout ); + + if (!status && msg32) + lpc_message_64to32( msg32, msg64 ); + + return status; } @@ -1358,9 +1455,18 @@ NTSTATUS WINAPI wow64_NtReplyWaitReceivePortEx( UINT *args ) NTSTATUS WINAPI wow64_NtRequestPort( UINT *args ) { HANDLE handle = get_handle( &args ); - LPC_MESSAGE *msg = get_ptr( &args ); + LPC_MESSAGE32 *msg32 = get_ptr( &args ); + + LPC_MESSAGE *msg64; - return NtRequestPort( handle, msg ); + if (msg32) + { + msg64 = Wow64AllocateTemp( offsetof( LPC_MESSAGE, Data[msg32->DataSize] ) ); + lpc_message_32to64( msg64, msg32 ); + } + else msg64 = NULL; + + return NtRequestPort( handle, msg64 ); } @@ -1370,11 +1476,31 @@ NTSTATUS WINAPI wow64_NtRequestPort( UINT *args ) NTSTATUS WINAPI wow64_NtRequestWaitReplyPort( UINT *args ) { HANDLE handle = get_handle( &args ); - LPC_MESSAGE *msg_in = get_ptr( &args ); - LPC_MESSAGE *msg_out = get_ptr( &args ); + LPC_MESSAGE32 *msg_in32 = get_ptr( &args ); + LPC_MESSAGE32 *msg_out32 = get_ptr( &args ); - FIXME( "%p %p %p: stub\n", handle, msg_in, msg_out ); - return STATUS_NOT_IMPLEMENTED; + LPC_MESSAGE *msg_in64 = NULL; + LPC_MESSAGE *msg_out64 = NULL; + NTSTATUS status; + + if (msg_in32) + { + msg_in64 = Wow64AllocateTemp( offsetof( LPC_MESSAGE, Data[msg_in32->DataSize] ) ); + lpc_message_32to64( msg_in64, msg_in32 ); + } + + if (msg_out32) + { + msg_out64 = Wow64AllocateTemp( offsetof( LPC_MESSAGE, Data[0x1000] ) ); + memset( msg_out64, 0, sizeof(*msg_out64) ); + } + + status = NtRequestWaitReplyPort( handle, msg_in64, msg_out64 ); + + if (!status && msg_out32) + lpc_message_64to32( msg_out32, msg_out64 ); + + return status; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10611