Commit 234b8cbe authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

rpcrt4: Call RPCRT4_Send directly from PKT_RECEIVE handler in server.

Remove the WINE_RPCFLAG_EXCEPTION hack to pass exception information to I_RpcSend.
parent 9c77d7ac
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include "wine/debug.h" #include "wine/debug.h"
#include "rpc_binding.h" #include "rpc_binding.h"
#include "rpc_misc.h"
#include "rpc_defs.h" #include "rpc_defs.h"
#include "rpc_message.h" #include "rpc_message.h"
#include "ncastatus.h" #include "ncastatus.h"
...@@ -141,7 +140,7 @@ static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation, ...@@ -141,7 +140,7 @@ static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation,
return header; return header;
} }
static RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation,
unsigned long BufferLength) unsigned long BufferLength)
{ {
RpcPktHdr *header; RpcPktHdr *header;
...@@ -964,62 +963,42 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) ...@@ -964,62 +963,42 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcBinding* bind = (RpcBinding*)pMsg->Handle;
RpcConnection* conn; RpcConnection* conn;
RPC_CLIENT_INTERFACE* cif = NULL; RPC_CLIENT_INTERFACE* cif = NULL;
RPC_SERVER_INTERFACE* sif = NULL;
RPC_STATUS status; RPC_STATUS status;
RpcPktHdr *hdr; RpcPktHdr *hdr;
TRACE("(%p)\n", pMsg); 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; /* ? */
if (!bind->Endpoint || !bind->Endpoint[0]) cif = pMsg->RpcInterfaceInformation;
{ if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */
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, if (!bind->Endpoint || !bind->Endpoint[0])
&cif->InterfaceId); {
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 (status != RPC_S_OK) return status;
if (bind->server) { hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation,
if (pMsg->RpcFlags & WINE_RPCFLAG_EXCEPTION) { pMsg->BufferLength, pMsg->ProcNum,
hdr = RPCRT4_BuildFaultHeader(pMsg->DataRepresentation, &bind->ObjectUuid);
RPC2NCA_STATUS(*(RPC_STATUS *)pMsg->Buffer)); if (!hdr)
} else { {
hdr = RPCRT4_BuildResponseHeader(pMsg->DataRepresentation, RPCRT4_CloseBinding(bind, conn);
pMsg->BufferLength); return ERROR_OUTOFMEMORY;
}
} else {
hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation,
pMsg->BufferLength, pMsg->ProcNum,
&bind->ObjectUuid);
hdr->common.call_id = conn->NextCallId++;
} }
hdr->common.call_id = conn->NextCallId++;
status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength); status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength);
RPCRT4_FreeHeader(hdr); RPCRT4_FreeHeader(hdr);
/* success */ /* save the connection, so the response can be read from it */
if (!bind->server) { pMsg->ReservedForRuntime = conn;
/* save the connection, so the response can be read from it */
pMsg->ReservedForRuntime = conn;
return status;
}
RPCRT4_CloseBinding(bind, conn);
return status; return status;
} }
...@@ -1101,7 +1080,6 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) ...@@ -1101,7 +1080,6 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
} }
break; break;
case PKT_FAULT: case PKT_FAULT:
pMsg->RpcFlags |= WINE_RPCFLAG_EXCEPTION;
ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status); ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status);
status = NCA2RPC_STATUS(hdr->fault.status); status = NCA2RPC_STATUS(hdr->fault.status);
if (is_hard_error(status)) if (is_hard_error(status))
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
typedef unsigned int NCA_STATUS; typedef unsigned int NCA_STATUS;
RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS 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_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_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); 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);
......
/*
* 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 */
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "wine/exception.h" #include "wine/exception.h"
#include "rpc_server.h" #include "rpc_server.h"
#include "rpc_misc.h"
#include "rpc_message.h" #include "rpc_message.h"
#include "rpc_defs.h" #include "rpc_defs.h"
#include "ncastatus.h" #include "ncastatus.h"
...@@ -171,6 +170,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA ...@@ -171,6 +170,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
RpcPktHdr *response; RpcPktHdr *response;
void *buf = msg->Buffer; void *buf = msg->Buffer;
RPC_STATUS status; RPC_STATUS status;
BOOL exception;
switch (hdr->common.ptype) { switch (hdr->common.ptype) {
case PKT_BIND: case PKT_BIND:
...@@ -272,23 +272,32 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA ...@@ -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]), MAKELONG( MAKEWORD(hdr->common.drep[0], hdr->common.drep[1]),
MAKEWORD(hdr->common.drep[2], hdr->common.drep[3])); MAKEWORD(hdr->common.drep[2], hdr->common.drep[3]));
exception = FALSE;
/* dispatch */ /* dispatch */
__TRY { __TRY {
if (func) func(msg); if (func) func(msg);
} __EXCEPT(rpc_filter) { } __EXCEPT(rpc_filter) {
if (msg->Buffer != buf) I_RpcFreeBuffer(msg); exception = TRUE;
/* 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);
if (GetExceptionCode() == STATUS_ACCESS_VIOLATION) if (GetExceptionCode() == STATUS_ACCESS_VIOLATION)
*(RPC_STATUS*)msg->Buffer = ERROR_NOACCESS; status = ERROR_NOACCESS;
else else
*(RPC_STATUS*)msg->Buffer = GetExceptionCode(); status = GetExceptionCode();
response = RPCRT4_BuildFaultHeader(msg->DataRepresentation,
RPC2NCA_STATUS(status));
} __ENDTRY } __ENDTRY
if (!exception)
response = RPCRT4_BuildResponseHeader(msg->DataRepresentation,
msg->BufferLength);
/* send response packet */ /* 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; msg->RpcInterfaceInformation = NULL;
RPCRT4_release_server_interface(sif); RPCRT4_release_server_interface(sif);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment