From: Jacek Caban Subject: [PATCH 2/3] rpcrt4: Added support for binding argument in RpcMgmtIsServerListening. Message-Id: <562FC24C.4080502@codeweavers.com> Date: Tue, 27 Oct 2015 19:28:28 +0100 Based on patch by Andrew Eikum. Signed-off-by: Jacek Caban --- dlls/rpcrt4/rpc_binding.h | 2 ++ dlls/rpcrt4/rpc_server.c | 12 +++++++--- dlls/rpcrt4/rpc_transport.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/dlls/rpcrt4/rpc_binding.h b/dlls/rpcrt4/rpc_binding.h index 7b8eaf3..1d73ebf 100644 --- a/dlls/rpcrt4/rpc_binding.h +++ b/dlls/rpcrt4/rpc_binding.h @@ -104,6 +104,7 @@ struct connection_ops { int (*write)(RpcConnection *conn, const void *buffer, unsigned int len); int (*close)(RpcConnection *conn); void (*cancel_call)(RpcConnection *conn); + RPC_STATUS (*is_server_listening)(const char *endpoint); int (*wait_for_incoming_data)(RpcConnection *conn); size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint); RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint); @@ -162,6 +163,7 @@ RpcConnection *RPCRT4_GrabConnection( RpcConnection *conn ) DECLSPEC_HIDDEN; RPC_STATUS RPCRT4_ReleaseConnection(RpcConnection* Connection) DECLSPEC_HIDDEN; RPC_STATUS RPCRT4_OpenClientConnection(RpcConnection* Connection) DECLSPEC_HIDDEN; RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection) DECLSPEC_HIDDEN; +RPC_STATUS RPCRT4_IsServerListening(const char *protseq, const char *endpoint) DECLSPEC_HIDDEN; RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint) DECLSPEC_HIDDEN; RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid) DECLSPEC_HIDDEN; diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c index 1e22d03..9c3dea7 100644 --- a/dlls/rpcrt4/rpc_server.c +++ b/dlls/rpcrt4/rpc_server.c @@ -1676,9 +1676,15 @@ RPC_STATUS WINAPI RpcMgmtIsServerListening(RPC_BINDING_HANDLE Binding) TRACE("(%p)\n", Binding); - EnterCriticalSection(&listen_cs); - if (manual_listen_count > 0) status = RPC_S_OK; - LeaveCriticalSection(&listen_cs); + if (Binding) { + RpcBinding *rpc_binding = (RpcBinding*)Binding; + status = RPCRT4_IsServerListening(rpc_binding->Protseq, rpc_binding->Endpoint); + }else { + EnterCriticalSection(&listen_cs); + if (manual_listen_count > 0) status = RPC_S_OK; + LeaveCriticalSection(&listen_cs); + } + return status; } diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c index 932fa64..54cef07 100644 --- a/dlls/rpcrt4/rpc_transport.c +++ b/dlls/rpcrt4/rpc_transport.c @@ -398,6 +398,33 @@ static RPC_STATUS rpcrt4_ncacn_np_handoff(RpcConnection *old_conn, RpcConnection return status; } +static RPC_STATUS is_pipe_listening(const char *pipe_name) +{ + return WaitNamedPipeA(pipe_name, 1) ? RPC_S_OK : RPC_S_NOT_LISTENING; +} + +static RPC_STATUS rpcrt4_ncacn_np_is_server_listening(const char *endpoint) +{ + char *pipe_name; + RPC_STATUS status; + + pipe_name = ncacn_pipe_name(endpoint); + status = is_pipe_listening(pipe_name); + I_RpcFree(pipe_name); + return status; +} + +static RPC_STATUS rpcrt4_ncalrpc_np_is_server_listening(const char *endpoint) +{ + char *pipe_name; + RPC_STATUS status; + + pipe_name = ncalrpc_pipe_name(endpoint); + status = is_pipe_listening(pipe_name); + I_RpcFree(pipe_name); + return status; +} + static RPC_STATUS rpcrt4_ncalrpc_handoff(RpcConnection *old_conn, RpcConnection *new_conn) { RPC_STATUS status; @@ -1532,6 +1559,12 @@ static void rpcrt4_conn_tcp_cancel_call(RpcConnection *Connection) rpcrt4_sock_wait_cancel(tcpc); } +static RPC_STATUS rpcrt4_conn_tcp_is_server_listening(const char *endpoint) +{ + FIXME("\n"); + return RPC_S_ACCESS_DENIED; +} + static int rpcrt4_conn_tcp_wait_for_incoming_data(RpcConnection *Connection) { RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; @@ -3301,6 +3334,12 @@ static void rpcrt4_ncacn_http_cancel_call(RpcConnection *Connection) SetEvent(httpc->cancel_event); } +static RPC_STATUS rpcrt4_ncacn_http_is_server_listening(const char *endpoint) +{ + FIXME("\n"); + return RPC_S_ACCESS_DENIED; +} + static int rpcrt4_ncacn_http_wait_for_incoming_data(RpcConnection *Connection) { RpcConnection_http *httpc = (RpcConnection_http *) Connection; @@ -3342,6 +3381,7 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_np_write, rpcrt4_conn_np_close, rpcrt4_conn_np_cancel_call, + rpcrt4_ncacn_np_is_server_listening, rpcrt4_conn_np_wait_for_incoming_data, rpcrt4_ncacn_np_get_top_of_tower, rpcrt4_ncacn_np_parse_top_of_tower, @@ -3362,6 +3402,7 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_np_write, rpcrt4_conn_np_close, rpcrt4_conn_np_cancel_call, + rpcrt4_ncalrpc_np_is_server_listening, rpcrt4_conn_np_wait_for_incoming_data, rpcrt4_ncalrpc_get_top_of_tower, rpcrt4_ncalrpc_parse_top_of_tower, @@ -3382,6 +3423,7 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_tcp_write, rpcrt4_conn_tcp_close, rpcrt4_conn_tcp_cancel_call, + rpcrt4_conn_tcp_is_server_listening, rpcrt4_conn_tcp_wait_for_incoming_data, rpcrt4_ncacn_ip_tcp_get_top_of_tower, rpcrt4_ncacn_ip_tcp_parse_top_of_tower, @@ -3402,6 +3444,7 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_ncacn_http_write, rpcrt4_ncacn_http_close, rpcrt4_ncacn_http_cancel_call, + rpcrt4_ncacn_http_is_server_listening, rpcrt4_ncacn_http_wait_for_incoming_data, rpcrt4_ncacn_http_get_top_of_tower, rpcrt4_ncacn_http_parse_top_of_tower, @@ -3575,6 +3618,20 @@ RPC_STATUS RPCRT4_ReleaseConnection(RpcConnection* Connection) return RPC_S_OK; } +RPC_STATUS RPCRT4_IsServerListening(const char *protseq, const char *endpoint) +{ + const struct connection_ops *ops; + + ops = rpcrt4_get_conn_protseq_ops(protseq); + if (!ops) + { + FIXME("not supported for protseq %s\n", protseq); + return RPC_S_INVALID_BINDING; + } + + return ops->is_server_listening(endpoint); +} + RPC_STATUS RpcTransport_GetTopOfTower(unsigned char *tower_data, size_t *tower_size, const char *protseq,