Module: wine Branch: master Commit: c411d95e204abd8dedd1415894a8343fb3b16cd4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c411d95e204abd8dedd1415894...
Author: Rob Shearman rob@codeweavers.com Date: Mon Jun 25 14:23:45 2007 +0100
rpcrt4: Close the connection if a protocol error or certain other kinds of errors occur, instead of returning it to the connection pool.
---
dlls/rpcrt4/rpc_message.c | 40 +++++++++++++++++++++++++++++++++------- 1 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c index dd37f33..cd25520 100644 --- a/dlls/rpcrt4/rpc_message.c +++ b/dlls/rpcrt4/rpc_message.c @@ -952,6 +952,23 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) return status; }
+/* is this status something that the server can't recover from? */ +static inline BOOL is_hard_error(RPC_STATUS status) +{ + switch (status) + { + case 0: /* user-defined fault */ + case ERROR_ACCESS_DENIED: + case ERROR_INVALID_PARAMETER: + case RPC_S_PROTOCOL_ERROR: + case RPC_S_CALL_FAILED: + case RPC_S_CALL_FAILED_DNE: + return TRUE; + default: + return FALSE; + } +} + /*********************************************************************** * I_RpcReceive [RPCRT4.@] */ @@ -999,31 +1016,40 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) goto fail; }
- status = RPC_S_PROTOCOL_ERROR; - switch (hdr->common.ptype) { case PKT_RESPONSE: - if (bind->server) goto fail; + if (bind->server) { + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } break; case PKT_REQUEST: - if (!bind->server) goto fail; + if (!bind->server) { + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } break; case PKT_FAULT: pMsg->RpcFlags |= WINE_RPCFLAG_EXCEPTION; ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status); status = hdr->fault.status; /* FIXME: do translation from nca error codes */ - goto fail; + if (is_hard_error(status)) + goto fail; + break; default: WARN("bad packet type %d\n", hdr->common.ptype); + status = RPC_S_PROTOCOL_ERROR; goto fail; }
/* success */ - status = RPC_S_OK; + RPCRT4_CloseBinding(bind, conn); + RPCRT4_FreeHeader(hdr); + return status;
fail: RPCRT4_FreeHeader(hdr); - RPCRT4_CloseBinding(bind, conn); + RPCRT4_DestroyConnection(conn); return status; }