From 234b8cbe0afa9c146348e22c9f6153c0b936f440 Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Thu, 5 Jul 2007 12:47:42 +0100 Subject: [PATCH] rpcrt4: Call RPCRT4_Send directly from PKT_RECEIVE handler in server. Remove the WINE_RPCFLAG_EXCEPTION hack to pass exception information to I_RpcSend. --- dlls/rpcrt4/rpc_message.c | 64 +++++++++++++-------------------------- dlls/rpcrt4/rpc_message.h | 1 + dlls/rpcrt4/rpc_misc.h | 28 ----------------- dlls/rpcrt4/rpc_server.c | 27 +++++++++++------ 4 files changed, 40 insertions(+), 80 deletions(-) delete mode 100644 dlls/rpcrt4/rpc_misc.h diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c index 3fc8e0f5ca..bfd5aece88 100644 --- a/dlls/rpcrt4/rpc_message.c +++ b/dlls/rpcrt4/rpc_message.c @@ -35,7 +35,6 @@ #include "wine/debug.h" #include "rpc_binding.h" -#include "rpc_misc.h" #include "rpc_defs.h" #include "rpc_message.h" #include "ncastatus.h" @@ -141,7 +140,7 @@ static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation, return header; } -static RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, +RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength) { RpcPktHdr *header; @@ -964,62 +963,42 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcConnection* conn; RPC_CLIENT_INTERFACE* cif = NULL; - RPC_SERVER_INTERFACE* sif = NULL; RPC_STATUS status; RpcPktHdr *hdr; TRACE("(%p)\n", pMsg); - if (!bind) return RPC_S_INVALID_BINDING; + if (!bind || bind->server) return RPC_S_INVALID_BINDING; - if (bind->server) { - sif = pMsg->RpcInterfaceInformation; - if (!sif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ - status = RPCRT4_OpenBinding(bind, &conn, &sif->TransferSyntax, - &sif->InterfaceId); - } else { - cif = pMsg->RpcInterfaceInformation; - if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ + cif = pMsg->RpcInterfaceInformation; + if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ - if (!bind->Endpoint || !bind->Endpoint[0]) - { - TRACE("automatically resolving partially bound binding\n"); - status = RpcEpResolveBinding(bind, cif); - if (status != RPC_S_OK) return status; - } - - status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, - &cif->InterfaceId); + if (!bind->Endpoint || !bind->Endpoint[0]) + { + TRACE("automatically resolving partially bound binding\n"); + status = RpcEpResolveBinding(bind, cif); + if (status != RPC_S_OK) return status; } + status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, + &cif->InterfaceId); if (status != RPC_S_OK) return status; - if (bind->server) { - if (pMsg->RpcFlags & WINE_RPCFLAG_EXCEPTION) { - hdr = RPCRT4_BuildFaultHeader(pMsg->DataRepresentation, - RPC2NCA_STATUS(*(RPC_STATUS *)pMsg->Buffer)); - } else { - hdr = RPCRT4_BuildResponseHeader(pMsg->DataRepresentation, - pMsg->BufferLength); - } - } else { - hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation, - pMsg->BufferLength, pMsg->ProcNum, - &bind->ObjectUuid); - hdr->common.call_id = conn->NextCallId++; + hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation, + pMsg->BufferLength, pMsg->ProcNum, + &bind->ObjectUuid); + if (!hdr) + { + RPCRT4_CloseBinding(bind, conn); + return ERROR_OUTOFMEMORY; } + hdr->common.call_id = conn->NextCallId++; status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength); RPCRT4_FreeHeader(hdr); - /* success */ - if (!bind->server) { - /* save the connection, so the response can be read from it */ - pMsg->ReservedForRuntime = conn; - return status; - } - RPCRT4_CloseBinding(bind, conn); - + /* save the connection, so the response can be read from it */ + pMsg->ReservedForRuntime = conn; return status; } @@ -1101,7 +1080,6 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) } break; case PKT_FAULT: - pMsg->RpcFlags |= WINE_RPCFLAG_EXCEPTION; ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status); status = NCA2RPC_STATUS(hdr->fault.status); if (is_hard_error(status)) diff --git a/dlls/rpcrt4/rpc_message.h b/dlls/rpcrt4/rpc_message.h index 103bc668b6..8815d8d2de 100644 --- a/dlls/rpcrt4/rpc_message.h +++ b/dlls/rpcrt4/rpc_message.h @@ -27,6 +27,7 @@ typedef unsigned int NCA_STATUS; RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS Status); +RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength); RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId); RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor); RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId); diff --git a/dlls/rpcrt4/rpc_misc.h b/dlls/rpcrt4/rpc_misc.h deleted file mode 100644 index 0cb41c1b7b..0000000000 --- a/dlls/rpcrt4/rpc_misc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * RPC definitions - * - * Copyright 2003 Ove Kåven, TransGaming Technologies - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#ifndef __WINE_RPC_MISC_H -#define __WINE_RPC_MISC_H - -/* flags for RPC_MESSAGE.RpcFlags */ -#define WINE_RPCFLAG_EXCEPTION 0x0001 - -#endif /* __WINE_RPC_MISC_H */ diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c index 20c1afacf1..4b9a93d2fe 100644 --- a/dlls/rpcrt4/rpc_server.c +++ b/dlls/rpcrt4/rpc_server.c @@ -42,7 +42,6 @@ #include "wine/exception.h" #include "rpc_server.h" -#include "rpc_misc.h" #include "rpc_message.h" #include "rpc_defs.h" #include "ncastatus.h" @@ -171,6 +170,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA RpcPktHdr *response; void *buf = msg->Buffer; RPC_STATUS status; + BOOL exception; switch (hdr->common.ptype) { case PKT_BIND: @@ -272,23 +272,32 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA MAKELONG( MAKEWORD(hdr->common.drep[0], hdr->common.drep[1]), MAKEWORD(hdr->common.drep[2], hdr->common.drep[3])); + exception = FALSE; + /* dispatch */ __TRY { if (func) func(msg); } __EXCEPT(rpc_filter) { - if (msg->Buffer != buf) I_RpcFreeBuffer(msg); - /* this will cause a failure packet to be sent in I_RpcSend */ - msg->RpcFlags |= WINE_RPCFLAG_EXCEPTION; - msg->BufferLength = sizeof(RPC_STATUS); - I_RpcGetBuffer(msg); + exception = TRUE; if (GetExceptionCode() == STATUS_ACCESS_VIOLATION) - *(RPC_STATUS*)msg->Buffer = ERROR_NOACCESS; + status = ERROR_NOACCESS; else - *(RPC_STATUS*)msg->Buffer = GetExceptionCode(); + status = GetExceptionCode(); + response = RPCRT4_BuildFaultHeader(msg->DataRepresentation, + RPC2NCA_STATUS(status)); } __ENDTRY + if (!exception) + response = RPCRT4_BuildResponseHeader(msg->DataRepresentation, + msg->BufferLength); + /* send response packet */ - I_RpcSend(msg); + if (response) { + status = RPCRT4_Send(conn, response, exception ? NULL : msg->Buffer, + exception ? 0 : msg->BufferLength); + RPCRT4_FreeHeader(response); + } else + ERR("out of memory\n"); msg->RpcInterfaceInformation = NULL; RPCRT4_release_server_interface(sif);