Robert Shearman : rpcrt4: Implement explicit generic binding handles.

Alexandre Julliard julliard at wine.codeweavers.com
Thu May 25 04:16:11 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 4e85273086f05d69656b844a3354ebcf8e6866b6
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=4e85273086f05d69656b844a3354ebcf8e6866b6

Author: Robert Shearman <rob at codeweavers.com>
Date:   Wed May 24 23:03:54 2006 +0100

rpcrt4: Implement explicit generic binding handles.

---

 dlls/rpcrt4/ndr_stubless.c |   79 ++++++++++++++++++++++++++++++++++++++++++--
 include/rpcndr.h           |   17 ++++++++-
 2 files changed, 90 insertions(+), 6 deletions(-)

diff --git a/dlls/rpcrt4/ndr_stubless.c b/dlls/rpcrt4/ndr_stubless.c
index 03541c5..1f1e2e1 100644
--- a/dlls/rpcrt4/ndr_stubless.c
+++ b/dlls/rpcrt4/ndr_stubless.c
@@ -394,9 +394,23 @@ static PFORMAT_STRING client_get_handle(
                 return pFormat + sizeof(NDR_EHD_PRIMITIVE);
             }
         case RPC_FC_BIND_GENERIC: /* explicit generic */
-            FIXME("RPC_FC_BIND_GENERIC\n");
-            RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */
-            return pFormat + sizeof(NDR_EHD_GENERIC);
+            {
+                NDR_EHD_GENERIC * pDesc = (NDR_EHD_GENERIC *)pFormat;
+                void *pObject = NULL;
+                void *pArg;
+                const GENERIC_BINDING_ROUTINE_PAIR *pGenPair;
+
+                TRACE("Explicit generic binding handle #%d\n", pDesc->binding_routine_pair_index);
+
+                if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR)
+                    pArg = *(void **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset);
+                else
+                    pArg = (void *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset);
+                memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf);
+                pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index];
+                *phBinding = pGenPair->pfnBind(pObject);
+                return pFormat + sizeof(NDR_EHD_GENERIC);
+            }
         case RPC_FC_BIND_CONTEXT: /* explicit context */
             {
                 NDR_EHD_CONTEXT * pDesc = (NDR_EHD_CONTEXT *)pFormat;
@@ -451,6 +465,57 @@ static PFORMAT_STRING client_get_handle(
     return pFormat;
 }
 
+static void client_free_handle(
+    PMIDL_STUB_MESSAGE pStubMsg, const NDR_PROC_HEADER *pProcHeader,
+    PFORMAT_STRING pFormat, handle_t hBinding)
+{
+    /* binding */
+    switch (pProcHeader->handle_type)
+    {
+    /* explicit binding: parse additional section */
+    case RPC_FC_BIND_EXPLICIT:
+        switch (*pFormat) /* handle_type */
+        {
+        case RPC_FC_BIND_GENERIC: /* explicit generic */
+            {
+                NDR_EHD_GENERIC * pDesc = (NDR_EHD_GENERIC *)pFormat;
+                void *pObject = NULL;
+                void *pArg;
+                const GENERIC_BINDING_ROUTINE_PAIR *pGenPair;
+
+                TRACE("Explicit generic binding handle #%d\n", pDesc->binding_routine_pair_index);
+
+                if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR)
+                    pArg = *(void **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset);
+                else
+                    pArg = (void *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset);
+                memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf);
+                pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index];
+                pGenPair->pfnUnbind(pObject, hBinding);
+                break;
+            }
+        case RPC_FC_BIND_CONTEXT: /* explicit context */
+        case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */
+            break;
+        default:
+            ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type);
+            RpcRaiseException(RPC_X_BAD_STUB_DATA);
+        }
+        break;
+    case RPC_FC_BIND_GENERIC: /* implicit generic */
+        FIXME("RPC_FC_BIND_GENERIC\n");
+        RpcRaiseException(RPC_X_BAD_STUB_DATA); /* FIXME: remove when implemented */
+        break;
+    case RPC_FC_CALLBACK_HANDLE: /* implicit callback */
+    case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */
+    case RPC_FC_AUTO_HANDLE: /* implicit auto handle */
+        break;
+    default:
+        ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type);
+        RpcRaiseException(RPC_X_BAD_STUB_DATA);
+    }
+}
+
 /* the return type should be CLIENT_CALL_RETURN, but this is incompatible
  * with the way gcc returns structures. "void *" should be the largest type
  * that MIDL should allow you to return anyway */
@@ -480,6 +545,7 @@ LONG_PTR WINAPIV NdrClientCall2(PMIDL_ST
     LONG_PTR RetVal = 0;
     /* the pointer to the object when in OLE mode */
     void * This = NULL;
+    PFORMAT_STRING pHandleFormat;
 
     TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat);
 
@@ -524,10 +590,12 @@ #else
 # warning Stack not retrieved for your CPU architecture
 #endif
 
+    pHandleFormat = pFormat;
+
     /* we only need a handle if this isn't an object method */
     if (!(pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT))
     {
-        pFormat = client_get_handle(&stubMsg, pProcHeader, pFormat, &hBinding);
+        pFormat = client_get_handle(&stubMsg, pProcHeader, pHandleFormat, &hBinding);
         if (!pFormat) return 0;
     }
 
@@ -890,7 +958,10 @@ #endif
     if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
         NdrProxyFreeBuffer(This, &stubMsg);
     else
+    {
         NdrFreeBuffer(&stubMsg);
+        client_free_handle(&stubMsg, pProcHeader, pHandleFormat, hBinding);
+    }
 
     TRACE("RetVal = 0x%lx\n", RetVal);
 
diff --git a/include/rpcndr.h b/include/rpcndr.h
index 18dce08..6f43bb4 100644
--- a/include/rpcndr.h
+++ b/include/rpcndr.h
@@ -227,9 +227,22 @@ typedef struct _MIDL_STUB_MESSAGE
 } MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE;
 #include <poppack.h>
 
-typedef struct _GENERIC_BINDING_ROUTINE_PAIR GENERIC_BINDING_ROUTINE_PAIR, *PGENERIC_BINDING_ROUTINE_PAIR;
+typedef void * (__RPC_API * GENERIC_BINDING_ROUTINE)(void *);
+typedef void (__RPC_API * GENERIC_UNBIND_ROUTINE)(void *, unsigned char *);
 
-typedef struct __GENERIC_BINDING_INFO GENERIC_BINDING_INFO, *PGENERIC_BINDING_INFO;
+typedef struct _GENERIC_BINDING_ROUTINE_PAIR
+{
+  GENERIC_BINDING_ROUTINE pfnBind;
+  GENERIC_UNBIND_ROUTINE pfnUnbind;
+} GENERIC_BINDING_ROUTINE_PAIR, *PGENERIC_BINDING_ROUTINE_PAIR;
+
+typedef struct __GENERIC_BINDING_INFO
+{
+  void *pObj;
+  unsigned int Size;
+  GENERIC_BINDING_ROUTINE pfnBind;
+  GENERIC_UNBIND_ROUTINE pfnUnbind;
+} GENERIC_BINDING_INFO, *PGENERIC_BINDING_INFO;
 
 typedef void (__RPC_USER *XMIT_HELPER_ROUTINE)(PMIDL_STUB_MESSAGE);
 




More information about the wine-cvs mailing list