Module: wine Branch: master Commit: 01290cdc1f79e2ad53ef02acc109f132521e3f66 URL: http://source.winehq.org/git/wine.git/?a=commit;h=01290cdc1f79e2ad53ef02acc1...
Author: Christoph von Wittich Christoph@ApiViewer.de Date: Wed Oct 12 17:14:11 2016 +0200
rpcrt4: Implement RpcBindingServerFromClient and populate NetworkAddr for each transport.
Add more thorough testing for this function.
Signed-off-by: Colin Finck mail@colinfinck.de Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/rpcrt4/rpc_binding.c | 22 ++++++++++++++++++---- dlls/rpcrt4/rpc_transport.c | 34 ++++++++++++++++++++++++++++++++-- dlls/rpcrt4/tests/server.c | 33 ++++++++++++++++++++++----------- 3 files changed, 72 insertions(+), 17 deletions(-)
diff --git a/dlls/rpcrt4/rpc_binding.c b/dlls/rpcrt4/rpc_binding.c index 7212a18..07eddbe 100644 --- a/dlls/rpcrt4/rpc_binding.c +++ b/dlls/rpcrt4/rpc_binding.c @@ -1636,11 +1636,25 @@ RpcBindingInqAuthClientExW( RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE * /*********************************************************************** * RpcBindingServerFromClient (RPCRT4.@) */ - -RPC_STATUS RPC_ENTRY RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE *ServerBinding) +RPCRTAPI RPC_STATUS RPC_ENTRY +RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE* ServerBinding) { - FIXME("%p %p: stub\n", ClientBinding, ServerBinding); - return RPC_S_INVALID_BINDING; + RpcBinding* bind = ClientBinding; + RpcBinding* NewBinding; + + if (!bind) + bind = I_RpcGetCurrentCallHandle(); + + if (!bind->server) + return RPC_S_INVALID_BINDING; + + RPCRT4_AllocBinding(&NewBinding, TRUE); + NewBinding->Protseq = RPCRT4_strdupA(bind->Protseq); + NewBinding->NetworkAddr = RPCRT4_strdupA(bind->NetworkAddr); + + *ServerBinding = NewBinding; + + return RPC_S_OK; }
/*********************************************************************** diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c index b2fbf9b..4ba17a0 100644 --- a/dlls/rpcrt4/rpc_transport.c +++ b/dlls/rpcrt4/rpc_transport.c @@ -388,6 +388,7 @@ static void rpcrt4_conn_np_handoff(RpcConnection_np *old_npc, RpcConnection_np *
static RPC_STATUS rpcrt4_ncacn_np_handoff(RpcConnection *old_conn, RpcConnection *new_conn) { + DWORD len = MAX_COMPUTERNAME_LENGTH + 1; RPC_STATUS status; LPSTR pname;
@@ -397,6 +398,16 @@ static RPC_STATUS rpcrt4_ncacn_np_handoff(RpcConnection *old_conn, RpcConnection status = rpcrt4_conn_create_pipe(old_conn, pname); I_RpcFree(pname);
+ /* Store the local computer name as the NetworkAddr for ncacn_np as long as + * we don't support named pipes over the network. */ + FIXME("Using local computer name as NetworkAddr\n"); + new_conn->NetworkAddr = HeapAlloc(GetProcessHeap(), 0, len); + if (!GetComputerNameA(new_conn->NetworkAddr, &len)) + { + ERR("Failed to retrieve the computer name, error %u\n", GetLastError()); + return RPC_S_OUT_OF_RESOURCES; + } + return status; }
@@ -429,6 +440,7 @@ static RPC_STATUS rpcrt4_ncalrpc_np_is_server_listening(const char *endpoint)
static RPC_STATUS rpcrt4_ncalrpc_handoff(RpcConnection *old_conn, RpcConnection *new_conn) { + DWORD len = MAX_COMPUTERNAME_LENGTH + 1; RPC_STATUS status; LPSTR pname;
@@ -439,7 +451,15 @@ static RPC_STATUS rpcrt4_ncalrpc_handoff(RpcConnection *old_conn, RpcConnection pname = ncalrpc_pipe_name(old_conn->Endpoint); status = rpcrt4_conn_create_pipe(old_conn, pname); I_RpcFree(pname); - + + /* Store the local computer name as the NetworkAddr for ncalrpc. */ + new_conn->NetworkAddr = HeapAlloc(GetProcessHeap(), 0, len); + if (!GetComputerNameA(new_conn->NetworkAddr, &len)) + { + ERR("Failed to retrieve the computer name, error %u\n", GetLastError()); + return RPC_S_OUT_OF_RESOURCES; + } + return status; }
@@ -1479,10 +1499,20 @@ static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection ERR("Failed to accept a TCP connection: error %d\n", ret); return RPC_S_OUT_OF_RESOURCES; } + nonblocking = 1; ioctlsocket(ret, FIONBIO, &nonblocking); client->sock = ret; - TRACE("Accepted a new TCP connection\n"); + + client->common.NetworkAddr = HeapAlloc(GetProcessHeap(), 0, INET6_ADDRSTRLEN); + ret = getnameinfo((struct sockaddr*)&address, addrsize, client->common.NetworkAddr, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST); + if (ret != 0) + { + ERR("Failed to retrieve the IP address, error %d\n", ret); + return RPC_S_OUT_OF_RESOURCES; + } + + TRACE("Accepted a new TCP connection from %s\n", client->common.NetworkAddr); return RPC_S_OK; }
diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index f9a5a96..ee28703 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -745,29 +745,40 @@ void __cdecl s_context_handle_test(void) binding = NULL; status = RpcBindingServerFromClient(NULL, &binding);
- todo_wine - { - ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status); - ok(binding != NULL, "binding is NULL\n"); - } + ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status); + ok(binding != NULL, "binding is NULL\n");
if (status == RPC_S_OK && binding != NULL) { unsigned char* string_binding = NULL; - unsigned char* computer_name = NULL; + unsigned char* object_uuid = NULL; + unsigned char* protseq = NULL; + unsigned char* network_address = NULL; + unsigned char* endpoint = NULL; + unsigned char* network_options = NULL;
status = RpcBindingToStringBindingA(binding, &string_binding); - ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status); ok(string_binding != NULL, "string_binding is NULL\n");
- status = RpcStringBindingParseA(string_binding, NULL, NULL, &computer_name, NULL, NULL); - + status = RpcStringBindingParseA(string_binding, &object_uuid, &protseq, &network_address, &endpoint, &network_options); ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status); - ok(computer_name != NULL, "computer_name is NULL\n"); + ok(protseq != NULL && *protseq != '\0', "protseq is %s\n", protseq); + ok(network_address != NULL && *network_address != '\0', "network_address is %s\n", network_address); + + todo_wine + { + ok(object_uuid != NULL && *object_uuid == '\0', "object_uuid is %s\n", object_uuid); + ok(endpoint != NULL && *endpoint == '\0', "endpoint is %s\n", endpoint); + ok(network_options != NULL && *network_options == '\0', "network_options is %s\n", network_options); + }
RpcStringFreeA(&string_binding); - RpcStringFreeA(&computer_name); + RpcStringFreeA(&object_uuid); + RpcStringFreeA(&protseq); + RpcStringFreeA(&network_address); + RpcStringFreeA(&endpoint); + RpcStringFreeA(&network_options); RpcBindingFree(&binding); } }