Rob Shearman : rpcrt4: Call RPCRT4_Send directly from PKT_RECEIVE handler in server.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jul 5 13:31:25 CDT 2007


Module: wine
Branch: master
Commit: 234b8cbe0afa9c146348e22c9f6153c0b936f440
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=234b8cbe0afa9c146348e22c9f6153c0b936f440

Author: Rob Shearman <rob at codeweavers.com>
Date:   Thu Jul  5 12:47:42 2007 +0100

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(-)

diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c
index 3fc8e0f..bfd5aec 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->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 || bind->server) return RPC_S_INVALID_BINDING;
 
-    if (!bind->Endpoint || !bind->Endpoint[0])
-    {
-      TRACE("automatically resolving partially bound binding\n");
-      status = RpcEpResolveBinding(bind, cif);
-      if (status != RPC_S_OK) return status;
-    }
+  cif = pMsg->RpcInterfaceInformation;
+  if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */
 
-    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 103bc66..8815d8d 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 0cb41c1..0000000
--- 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 20c1afa..4b9a93d 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);




More information about the wine-cvs mailing list