Christoph von Wittich : rpcrt4: Implement RpcBindingServerFromClient and populate NetworkAddr for each transport.
Alexandre Julliard
julliard at winehq.org
Wed Oct 19 20:47:57 CDT 2016
Module: wine
Branch: master
Commit: 01290cdc1f79e2ad53ef02acc109f132521e3f66
URL: http://source.winehq.org/git/wine.git/?a=commit;h=01290cdc1f79e2ad53ef02acc109f132521e3f66
Author: Christoph von Wittich <Christoph at 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 at colinfinck.de>
Signed-off-by: Alexandre Julliard <julliard at 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);
}
}
More information about the wine-cvs
mailing list