From: Rose Hellsing <rose@pinkro.se> Implement client-side LPC port connection. The function connects to a named server port, waits for the server to accept/reject the connection, and returns a handle to the client port on success. NtSecureConnectPort is implemented as a wrapper around NtConnectPort with a FIXME for SID verification. --- dlls/ntdll/tests/port.c | 2 +- dlls/ntdll/unix/sync.c | 100 ++++++++++++++++++++++++++++++++++++---- dlls/wow64/sync.c | 23 ++++++--- 3 files changed, 109 insertions(+), 16 deletions(-) diff --git a/dlls/ntdll/tests/port.c b/dlls/ntdll/tests/port.c index 80c60d09683..0b7cd92d739 100644 --- a/dlls/ntdll/tests/port.c +++ b/dlls/ntdll/tests/port.c @@ -239,7 +239,7 @@ 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); diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index 1ffa0577573..8e1f9f76d7d 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -3137,23 +3137,105 @@ NTSTATUS WINAPI NtConnectPort( HANDLE *handle, UNICODE_STRING *name, SECURITY_QU LPC_SECTION_WRITE *write, LPC_SECTION_READ *read, ULONG *max_len, void *info, ULONG *info_len ) { - FIXME( "(%p,%s,%p,%p,%p,%p,%p,%p),stub!\n", handle, debugstr_us(name), qos, - write, read, max_len, info, info_len ); - if (info && info_len) TRACE("msg = %s\n", debugstr_an( info, *info_len )); - return STATUS_NOT_IMPLEMENTED; -} + unsigned int ret; + data_size_t len; + struct object_attributes *objattr; + OBJECT_ATTRIBUTES attr; + ULONG in_len = (info && info_len) ? *info_len : 0; + HANDLE port_handle; + + TRACE( "(%p,%s,%p,%p,%p,%p,%p,%p)\n", handle, debugstr_us(name), qos, write, read, max_len, info, info_len ); + + if (write) + FIXME( "LPC_SECTION_WRITE not supported\n" ); + if (read) + FIXME( "LPC_SECTION_READ not supported\n" ); + + *handle = 0; + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = name; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = qos; + + if ((ret = alloc_object_attributes( &attr, &objattr, &len ))) + return ret; + + SERVER_START_REQ( connect_lpc_port ) + { + req->access = PORT_ALL_ACCESS; + req->info_size = in_len; + wine_server_add_data( req, objattr, len ); + if (in_len) wine_server_add_data( req, info, in_len ); + if (!(ret = wine_server_call( req ))) + { + port_handle = wine_server_ptr_handle( reply->handle ); + if (info_len) + *info_len = reply->info_size; + } + } + SERVER_END_REQ; + free( objattr ); + + if (ret) return ret; + + /* Wait for the connection to be accepted/rejected by the server */ + for (;;) + { + unsigned int connect_status; + + SERVER_START_REQ( get_lpc_connect_status ) + { + req->handle = wine_server_obj_handle( port_handle ); + ret = wine_server_call( req ); + connect_status = reply->status; + } + SERVER_END_REQ; + + if (ret) + { + NtClose( port_handle ); + return ret; + } + + if (connect_status != STATUS_PENDING) + { + if (connect_status == STATUS_SUCCESS) + { + *handle = port_handle; + return STATUS_SUCCESS; + } + else + { + NtClose( port_handle ); + return connect_status; + } + } + + ret = NtWaitForSingleObject( port_handle, FALSE, NULL ); + if (ret) + { + NtClose( port_handle ); + return ret; + } + } +} /*********************************************************************** - * NtSecureConnectPort (NTDLL.@) + * NtReplyWaitReceivePort (NTDLL.@) */ NTSTATUS WINAPI NtSecureConnectPort( HANDLE *handle, UNICODE_STRING *name, SECURITY_QUALITY_OF_SERVICE *qos, LPC_SECTION_WRITE *write, PSID sid, LPC_SECTION_READ *read, ULONG *max_len, void *info, ULONG *info_len ) { - FIXME( "(%p,%s,%p,%p,%p,%p,%p,%p,%p),stub!\n", handle, debugstr_us(name), qos, - write, sid, read, max_len, info, info_len ); - return STATUS_NOT_IMPLEMENTED; + TRACE( "(%p,%s,%p,%p,%p,%p,%p,%p,%p)\n", handle, debugstr_us(name), qos, write, sid, read, max_len, info, info_len ); + + if (sid) + FIXME( "SID verification not implemented\n" ); + + return NtConnectPort( handle, name, qos, write, read, max_len, info, info_len ); } diff --git a/dlls/wow64/sync.c b/dlls/wow64/sync.c index 2f0a617b70c..f1ddfe5853d 100644 --- a/dlls/wow64/sync.c +++ b/dlls/wow64/sync.c @@ -205,9 +205,15 @@ 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; + + unicode_str_32to64( &name, name32 ); + + status = NtConnectPort( &handle, &name, qos, write, read, max_len, info, info_len ); + put_handle( handle_ptr, handle ); + return status; } @@ -1395,9 +1401,14 @@ NTSTATUS WINAPI wow64_NtSecureConnectPort( UINT *args ) void *info = get_ptr( &args ); ULONG *info_len = get_ptr( &args ); - FIXME( "%p %p %p %p %p %p %p %p %p: stub\n", - handle_ptr, name32, qos, write, sid, read, max_len, info, info_len ); - return STATUS_NOT_IMPLEMENTED; + UNICODE_STRING name; + HANDLE handle = 0; + NTSTATUS status; + + status = NtSecureConnectPort( &handle, unicode_str_32to64( &name, name32 ), + qos, write, sid, read, max_len, info, info_len ); + put_handle( handle_ptr, handle ); + return status; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10611