[rpcrt4]
authorAleksey Bragin <aleksey@reactos.org>
Wed, 25 Nov 2009 19:36:10 +0000 (19:36 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Wed, 25 Nov 2009 19:36:10 +0000 (19:36 +0000)
- Revert rpcrt4 back to 1.1.31-partial. Fixes various RPC related regressions.

svn path=/trunk/; revision=44287

25 files changed:
reactos/dll/win32/rpcrt4/cproxy.c
reactos/dll/win32/rpcrt4/cpsf.c
reactos/dll/win32/rpcrt4/cpsf.h
reactos/dll/win32/rpcrt4/cstub.c
reactos/dll/win32/rpcrt4/epm_towers.h
reactos/dll/win32/rpcrt4/ndr_contexthandle.c
reactos/dll/win32/rpcrt4/ndr_misc.h
reactos/dll/win32/rpcrt4/ndr_ole.c
reactos/dll/win32/rpcrt4/ndr_stubless.c
reactos/dll/win32/rpcrt4/ndr_stubless.h
reactos/dll/win32/rpcrt4/rpc_assoc.c
reactos/dll/win32/rpcrt4/rpc_assoc.h
reactos/dll/win32/rpcrt4/rpc_async.c
reactos/dll/win32/rpcrt4/rpc_binding.c
reactos/dll/win32/rpcrt4/rpc_binding.h
reactos/dll/win32/rpcrt4/rpc_defs.h
reactos/dll/win32/rpcrt4/rpc_epmap.c
reactos/dll/win32/rpcrt4/rpc_message.c
reactos/dll/win32/rpcrt4/rpc_message.h
reactos/dll/win32/rpcrt4/rpc_server.c
reactos/dll/win32/rpcrt4/rpc_server.h
reactos/dll/win32/rpcrt4/rpc_transport.c
reactos/dll/win32/rpcrt4/rpcrt4.rbuild
reactos/dll/win32/rpcrt4/rpcrt4.spec
reactos/dll/win32/rpcrt4/rpcrt4_main.c

index 9ce555f..6c26d18 100644 (file)
@@ -2,7 +2,6 @@
  * COM proxy implementation
  *
  * Copyright 2001 Ove Kåven, TransGaming Technologies
- * Copyright 2009 Alexandre Julliard
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,9 +20,6 @@
  * TODO: Handle non-i386 architectures
  */
 
-#include "config.h"
-#include "wine/port.h"
-
 #include <stdarg.h>
 
 #define COBJMACROS
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
+struct StublessThunk;
+
 /* I don't know what MS's std proxy structure looks like,
    so this probably doesn't match, but that shouldn't matter */
 typedef struct {
   const IRpcProxyBufferVtbl *lpVtbl;
   LPVOID *PVtbl;
   LONG RefCount;
+  const MIDL_STUBLESS_PROXY_INFO *stubless;
   const IID* piid;
   LPUNKNOWN pUnkOuter;
-  IUnknown *base_object;  /* must be at offset 0x10 from PVtbl */
-  IRpcProxyBuffer *base_proxy;
   PCInterfaceName name;
   LPPSFACTORYBUFFER pPSFactory;
   LPRPCCHANNELBUFFER pChannel;
+  struct StublessThunk *thunks;
 } StdProxyImpl;
 
 static const IRpcProxyBufferVtbl StdProxy_Vtbl;
@@ -64,111 +62,66 @@ static const IRpcProxyBufferVtbl StdProxy_Vtbl;
 
 #include "pshpack1.h"
 
-struct thunk {
+struct StublessThunk {
   BYTE push;
   DWORD index;
-  BYTE jmp;
+  BYTE call;
   LONG handler;
+  BYTE ret;
+  WORD bytes;
+  BYTE pad[3];
 };
 
 #include "poppack.h"
 
-extern void call_stubless_func(void);
-__ASM_GLOBAL_FUNC(call_stubless_func,
-                  "pushl %esp\n\t"  /* pointer to index */
-                  __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
-                  "call " __ASM_NAME("ObjectStubless") __ASM_STDCALL(4) "\n\t"
-                  "popl %edx\n\t"  /* args size */
-                  __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
-                  "movl (%esp),%ecx\n\t"  /* return address */
-                  "addl %edx,%esp\n\t"
-                  "jmp *%ecx" );
-
-HRESULT WINAPI ObjectStubless(DWORD *args)
+/* adjust the stack size since we don't use Windows's method */
+#define STACK_ADJUST sizeof(DWORD)
+
+#define FILL_STUBLESS(x,idx,stk) \
+ x->push = 0x68; /* pushl [immediate] */ \
+ x->index = (idx); \
+ x->call = 0xe8; /* call [near] */ \
+ x->handler = (char*)ObjectStubless - (char*)&x->ret; \
+ x->ret = 0xc2; /* ret [immediate] */ \
+ x->bytes = stk; \
+ x->pad[0] = 0x8d; /* leal (%esi),%esi */ \
+ x->pad[1] = 0x76; \
+ x->pad[2] = 0x00;
+
+static HRESULT WINAPI ObjectStubless(DWORD index)
 {
-    DWORD index = args[0];
-    void **iface = (void **)args[2];
-    const void **vtbl = (const void **)*iface;
-    const MIDL_STUBLESS_PROXY_INFO *stubless = *(const MIDL_STUBLESS_PROXY_INFO **)(vtbl - 2);
-    const PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[index];
-
-    /* store bytes to remove from stack */
-    args[0] = *(const WORD*)(fs + 8);
-    TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, args[0], args[1]);
-
-    return NdrClientCall2(stubless->pStubDesc, fs, args + 2);
-}
+  char *args = (char*)(&index + 2);
+  LPVOID iface = *(LPVOID*)args;
 
-#define BLOCK_SIZE 1024
-#define MAX_BLOCKS 64  /* 64k methods should be enough for anybody */
-
-static const struct thunk *method_blocks[MAX_BLOCKS];
-
-static const struct thunk *allocate_block( unsigned int num )
-{
-    unsigned int i;
-    struct thunk *prev, *block;
+  ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
 
-    block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block),
-                          MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
-    if (!block) return NULL;
+  PFORMAT_STRING fs = This->stubless->ProcFormatString + This->stubless->FormatStringOffset[index];
+  unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST;
+  TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, bytes, *(DWORD*)(args+bytes));
 
-    for (i = 0; i < BLOCK_SIZE; i++)
-    {
-        block[i].push    = 0x68; /* pushl */
-        block[i].index   = BLOCK_SIZE * num + i + 3;
-        block[i].jmp     = 0xe9; /* jmp */
-        block[i].handler = (char *)call_stubless_func - (char *)(&block[i].handler + 1);
-    }
-    VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL );
-    prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL );
-    if (prev) /* someone beat us to it */
-    {
-        VirtualFree( block, 0, MEM_RELEASE );
-        block = prev;
-    }
-    return block;
-}
-
-static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num )
-{
-    const void **entry = (const void **)(vtbl + 1);
-    DWORD i, j;
-
-    if (num - 3 > BLOCK_SIZE * MAX_BLOCKS)
-    {
-        FIXME( "%u methods not supported\n", num );
-        return FALSE;
-    }
-    for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++)
-    {
-        const struct thunk *block = method_blocks[i];
-        if (!block && !(block = allocate_block( i ))) return FALSE;
-        for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++)
-            if (*entry == (LPVOID)-1) *entry = &block[j];
-    }
-    return TRUE;
+  return NdrClientCall2(This->stubless->pStubDesc, fs, args);
 }
 
 #else  /* __i386__ */
 
-static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num )
-{
-    ERR("stubless proxies are not supported on this architecture\n");
   return FALSE;
-}
+/* can't do that on this arch */
+struct StublessThunk { int dummy; };
+#define FILL_STUBLESS(x,idx,stk) \
ERR("stubless proxies are not supported on this architecture\n");
+#define STACK_ADJUST 0
 
 #endif  /* __i386__ */
 
-HRESULT StdProxy_Construct(REFIID riid,
-                           LPUNKNOWN pUnkOuter,
-                           const ProxyFileInfo *ProxyInfo,
-                           int Index,
-                           LPPSFACTORYBUFFER pPSFactory,
-                           LPRPCPROXYBUFFER *ppProxy,
-                           LPVOID *ppvObj)
+HRESULT WINAPI StdProxy_Construct(REFIID riid,
+                                 LPUNKNOWN pUnkOuter,
+                                 const ProxyFileInfo *ProxyInfo,
+                                 int Index,
+                                 LPPSFACTORYBUFFER pPSFactory,
+                                 LPRPCPROXYBUFFER *ppProxy,
+                                 LPVOID *ppvObj)
 {
   StdProxyImpl *This;
+  const MIDL_STUBLESS_PROXY_INFO *stubless = NULL;
   PCInterfaceName name = ProxyInfo->pNamesArray[Index];
   CInterfaceProxyVtbl *vtbl = ProxyInfo->pProxyVtblList[Index];
 
@@ -176,12 +129,14 @@ HRESULT StdProxy_Construct(REFIID riid,
 
   /* TableVersion = 2 means it is the stubless version of CInterfaceProxyVtbl */
   if (ProxyInfo->TableVersion > 1) {
-    ULONG count = ProxyInfo->pStubVtblList[Index]->header.DispatchTableCount;
+    stubless = *(const void **)vtbl;
     vtbl = (CInterfaceProxyVtbl *)((const void **)vtbl + 1);
-    TRACE("stubless vtbl %p: count=%d\n", vtbl->Vtbl, count );
-    fill_stubless_table( (IUnknownVtbl *)vtbl->Vtbl, count );
+    TRACE("stubless=%p\n", stubless);
   }
 
+  TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid));
+  TRACE("vtbl=%p\n", vtbl->Vtbl);
+
   if (!IsEqualGUID(vtbl->header.piid, riid)) {
     ERR("IID mismatch during proxy creation\n");
     return RPC_E_UNEXPECTED;
@@ -190,37 +145,51 @@ HRESULT StdProxy_Construct(REFIID riid,
   This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(StdProxyImpl));
   if (!This) return E_OUTOFMEMORY;
 
-  if (!pUnkOuter) pUnkOuter = (IUnknown *)This;
+  if (stubless) {
+    CInterfaceStubVtbl *svtbl = ProxyInfo->pStubVtblList[Index];
+    unsigned long i, count = svtbl->header.DispatchTableCount;
+    /* Maybe the original vtbl is just modified directly to point at
+     * ObjectStublessClientXXX thunks in real Windows, but I don't like it
+     */
+    TRACE("stubless thunks: count=%ld\n", count);
+    This->thunks = HeapAlloc(GetProcessHeap(),0,sizeof(struct StublessThunk)*count);
+    This->PVtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID)*count);
+    for (i=0; i<count; i++) {
+      struct StublessThunk *thunk = &This->thunks[i];
+      if (vtbl->Vtbl[i] == (LPVOID)-1) {
+        PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[i];
+        unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST;
+        TRACE("method %ld: stacksize=%d\n", i, bytes);
+        FILL_STUBLESS(thunk, i, bytes)
+        This->PVtbl[i] = thunk;
+      }
+      else {
+        memset(thunk, 0, sizeof(struct StublessThunk));
+        This->PVtbl[i] = vtbl->Vtbl[i];
+      }
+    }
+  }
+  else 
+    This->PVtbl = vtbl->Vtbl;
+
   This->lpVtbl = &StdProxy_Vtbl;
-  This->PVtbl = vtbl->Vtbl;
   /* one reference for the proxy */
   This->RefCount = 1;
+  This->stubless = stubless;
   This->piid = vtbl->header.piid;
-  This->base_object = NULL;
-  This->base_proxy = NULL;
   This->pUnkOuter = pUnkOuter;
   This->name = name;
   This->pPSFactory = pPSFactory;
   This->pChannel = NULL;
-
-  if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index])
-  {
-      HRESULT r = create_proxy( ProxyInfo->pDelegatedIIDs[Index], NULL,
-                                &This->base_proxy, (void **)&This->base_object );
-      if (FAILED(r))
-      {
-          HeapFree( GetProcessHeap(), 0, This );
-          return r;
-      }
-  }
-
   *ppProxy = (LPRPCPROXYBUFFER)&This->lpVtbl;
   *ppvObj = &This->PVtbl;
-  IUnknown_AddRef((IUnknown *)*ppvObj);
+  /* if there is no outer unknown then the caller will control the lifetime
+   * of the proxy object through the proxy buffer, so no need to increment the
+   * ref count of the proxy object */
+  if (pUnkOuter)
+    IUnknown_AddRef((IUnknown *)*ppvObj);
   IPSFactoryBuffer_AddRef(pPSFactory);
 
-  TRACE( "iid=%s this %p proxy %p obj %p vtbl %p base proxy %p base obj %p\n",
-         debugstr_guid(riid), This, *ppProxy, *ppvObj, This->PVtbl, This->base_proxy, This->base_object );
   return S_OK;
 }
 
@@ -231,10 +200,11 @@ static void StdProxy_Destruct(LPRPCPROXYBUFFER iface)
   if (This->pChannel)
     IRpcProxyBuffer_Disconnect(iface);
 
-  if (This->base_object) IUnknown_Release( This->base_object );
-  if (This->base_proxy) IRpcProxyBuffer_Release( This->base_proxy );
-
   IPSFactoryBuffer_Release(This->pPSFactory);
+  if (This->thunks) {
+    HeapFree(GetProcessHeap(),0,This->PVtbl);
+    HeapFree(GetProcessHeap(),0,This->thunks);
+  }
   HeapFree(GetProcessHeap(),0,This);
 }
 
@@ -289,7 +259,6 @@ static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface,
 
   This->pChannel = pChannel;
   IRpcChannelBuffer_AddRef(pChannel);
-  if (This->base_proxy) IRpcProxyBuffer_Connect( This->base_proxy, pChannel );
   return S_OK;
 }
 
@@ -298,8 +267,6 @@ static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface)
   ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
   TRACE("(%p)->Disconnect()\n",This);
 
-  if (This->base_proxy) IRpcProxyBuffer_Disconnect( This->base_proxy );
-
   IRpcChannelBuffer_Release(This->pChannel);
   This->pChannel = NULL;
 }
index ac1eccf..bece899 100644 (file)
@@ -145,41 +145,6 @@ static const IPSFactoryBufferVtbl CStdPSFactory_Vtbl =
   CStdPSFactory_CreateStub
 };
 
-
-static void init_psfactory( CStdPSFactoryBuffer *psfac, const ProxyFileInfo **file_list )
-{
-    DWORD i, j, k;
-
-    psfac->lpVtbl = &CStdPSFactory_Vtbl;
-    psfac->RefCount = 0;
-    psfac->pProxyFileList = file_list;
-    for (i = 0; file_list[i]; i++)
-    {
-        const PCInterfaceProxyVtblList *proxies = file_list[i]->pProxyVtblList;
-        const PCInterfaceStubVtblList *stubs = file_list[i]->pStubVtblList;
-
-        for (j = 0; j < file_list[i]->TableSize; j++)
-        {
-            /* FIXME: i think that different vtables should be copied for
-             * async interfaces */
-            void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl;
-            void **pRpcStubVtbl = (void **)&stubs[j]->Vtbl;
-
-            if (file_list[i]->pDelegatedIIDs && file_list[i]->pDelegatedIIDs[j])
-            {
-                void **vtbl = proxies[j]->Vtbl;
-                if (file_list[i]->TableVersion > 1) vtbl++;
-                fill_delegated_proxy_table( (IUnknownVtbl *)vtbl, stubs[j]->header.DispatchTableCount );
-                pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl;
-            }
-
-            for (k = 0; k < sizeof(IRpcStubBufferVtbl)/sizeof(void *); k++)
-                if (!pRpcStubVtbl[k]) pRpcStubVtbl[k] = pSrcRpcStubVtbl[k];
-        }
-    }
-}
-
-
 /***********************************************************************
  *           NdrDllGetClassObject [RPCRT4.@]
  */
@@ -193,8 +158,35 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
     pPSFactoryBuffer);
 
   *ppv = NULL;
-  if (!pPSFactoryBuffer->lpVtbl) init_psfactory( pPSFactoryBuffer, pProxyFileList );
+  if (!pPSFactoryBuffer->lpVtbl) {
+    const ProxyFileInfo **pProxyFileList2;
+    DWORD max_delegating_vtbl_size = 0;
+    pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl;
+    pPSFactoryBuffer->RefCount = 0;
+    pPSFactoryBuffer->pProxyFileList = pProxyFileList;
+    for (pProxyFileList2 = pProxyFileList; *pProxyFileList2; pProxyFileList2++) {
+      int i;
+      for (i = 0; i < (*pProxyFileList2)->TableSize; i++) {
+        /* FIXME: i think that different vtables should be copied for
+         * async interfaces */
+        void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl;
+        void **pRpcStubVtbl = (void **)&(*pProxyFileList2)->pStubVtblList[i]->Vtbl;
+        unsigned int j;
+
+        if ((*pProxyFileList2)->pDelegatedIIDs && (*pProxyFileList2)->pDelegatedIIDs[i]) {
+          pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl;
+          if ((*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount > max_delegating_vtbl_size)
+            max_delegating_vtbl_size = (*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount;
+        }
 
+        for (j = 0; j < sizeof(IRpcStubBufferVtbl)/sizeof(void *); j++)
+          if (!pRpcStubVtbl[j])
+            pRpcStubVtbl[j] = pSrcRpcStubVtbl[j];
+      }
+    }
+    if(max_delegating_vtbl_size > 0)
+      create_delegating_vtbl(max_delegating_vtbl_size);
+  }
   if (pclsid && IsEqualGUID(rclsid, pclsid))
     return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
   else {
@@ -215,7 +207,7 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
  */
 HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer)
 {
-  return pPSFactoryBuffer->RefCount != 0 ? S_FALSE : S_OK;
+  return !(pPSFactoryBuffer->RefCount);
 }
 
 
@@ -274,7 +266,7 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll,
   if (len && len < sizeof(module)) {
       TRACE("registering CLSID %s => %s\n", debugstr_w(clsid), debugstr_w(module));
       if (RegCreateKeyW(HKEY_CLASSES_ROOT, keyname, &key) == ERROR_SUCCESS) {
-          RegSetValueExW(key, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW));
+          RegSetValueExW(subkey, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW));
           if (RegCreateKeyW(key, inprocserverW, &subkey) == ERROR_SUCCESS) {
               RegSetValueExW(subkey, NULL, 0, REG_SZ, (LPBYTE)module, (strlenW(module)+1)*sizeof(WCHAR));
               RegSetValueExW(subkey, threadingmodelW, 0, REG_SZ, (const BYTE *)bothW, sizeof(bothW));
index 9cc046f..d8867d4 100644 (file)
 #ifndef __WINE_CPSF_H
 #define __WINE_CPSF_H
 
-HRESULT StdProxy_Construct(REFIID riid, LPUNKNOWN pUnkOuter, const ProxyFileInfo *ProxyInfo,
-                           int Index, LPPSFACTORYBUFFER pPSFactory, LPRPCPROXYBUFFER *ppProxy,
-                           LPVOID *ppvObj);
-
-HRESULT CStdStubBuffer_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name,
-                                 CInterfaceStubVtbl *vtbl, LPPSFACTORYBUFFER pPSFactory,
-                                 LPRPCSTUBBUFFER *ppStub);
-
-HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name,
-                                            CInterfaceStubVtbl *vtbl, REFIID delegating_iid,
-                                            LPPSFACTORYBUFFER pPSFactory, LPRPCSTUBBUFFER *ppStub);
+HRESULT WINAPI StdProxy_Construct(REFIID riid,
+                                 LPUNKNOWN pUnkOuter,
+                                 const ProxyFileInfo *ProxyInfo,
+                                 int Index,
+                                 LPPSFACTORYBUFFER pPSFactory,
+                                 LPRPCPROXYBUFFER *ppProxy,
+                                 LPVOID *ppvObj);
+
+HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
+                                       LPUNKNOWN pUnkServer,
+                                       PCInterfaceName name,
+                                       CInterfaceStubVtbl *vtbl,
+                                       LPPSFACTORYBUFFER pPSFactory,
+                                       LPRPCSTUBBUFFER *ppStub);
+
+HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid,
+                                                   LPUNKNOWN pUnkServer,
+                                                   PCInterfaceName name,
+                                                   CInterfaceStubVtbl *vtbl,
+                                                   REFIID delegating_iid,
+                                                   LPPSFACTORYBUFFER pPSFactory,
+                                                   LPRPCSTUBBUFFER *ppStub);
 
 const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface);
 
 const IRpcStubBufferVtbl CStdStubBuffer_Vtbl;
 const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl;
 
-BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num);
-HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv);
+void create_delegating_vtbl(DWORD num_methods);
+
 HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub);
 
 #endif  /* __WINE_CPSF_H */
index 95ac1d8..85411cd 100644 (file)
@@ -2,7 +2,6 @@
  * COM stub (CStdStubBuffer) implementation
  *
  * Copyright 2001 Ove Kåven, TransGaming Technologies
- * Copyright 2009 Alexandre Julliard
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -62,12 +61,12 @@ static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer
     return (cstdstubbuffer_delegating_t*)((char *)iface - FIELD_OFFSET(cstdstubbuffer_delegating_t, stub_buffer));
 }
 
-HRESULT CStdStubBuffer_Construct(REFIID riid,
-                                 LPUNKNOWN pUnkServer,
-                                 PCInterfaceName name,
-                                 CInterfaceStubVtbl *vtbl,
-                                 LPPSFACTORYBUFFER pPSFactory,
-                                 LPRPCSTUBBUFFER *ppStub)
+HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
+                                       LPUNKNOWN pUnkServer,
+                                       PCInterfaceName name,
+                                       CInterfaceStubVtbl *vtbl,
+                                       LPPSFACTORYBUFFER pPSFactory,
+                                       LPRPCSTUBBUFFER *ppStub)
 {
   CStdStubBuffer *This;
   IUnknown *pvServer;
@@ -114,16 +113,20 @@ typedef struct
 {
     DWORD ref;
     DWORD size;
+    void **methods;
     IUnknownVtbl vtbl;
     /* remaining entries in vtbl */
 } ref_counted_vtbl;
 
-static ref_counted_vtbl *current_vtbl;
+static struct
+{
+    ref_counted_vtbl *table;
+} current_vtbl;
 
 
 static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv)
 {
-    *ppv = pUnk;
+    *ppv = (void *)pUnk;
     return S_OK;
 }
 
@@ -158,137 +161,87 @@ typedef struct {
 } vtbl_method_t;
 #include "poppack.h"
 
-#define BLOCK_SIZE 1024
-#define MAX_BLOCKS 64  /* 64k methods should be enough for anybody */
-
-static const vtbl_method_t *method_blocks[MAX_BLOCKS];
-
-static const vtbl_method_t *allocate_block( unsigned int num )
+static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num)
 {
-    unsigned int i;
-    vtbl_method_t *prev, *block;
-
-    block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block),
-                          MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
-    if (!block) return NULL;
-
-    for (i = 0; i < BLOCK_SIZE; i++)
-    {
-        block[i].mov1 = 0x0424448b;
-        block[i].mov2 = 0x408b;
-        block[i].sixteen = 0x10;
-        block[i].mov3 = 0x04244489;
-        block[i].mov4 = 0x008b;
-        block[i].mov5 = 0x808b;
-        block[i].offset = (BLOCK_SIZE * num + i + 3) << 2;
-        block[i].jmp = 0xe0ff;
-        block[i].pad[0] = 0x8d;
-        block[i].pad[1] = 0x76;
-        block[i].pad[2] = 0x00;
-    }
-    VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL );
-    prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL );
-    if (prev) /* someone beat us to it */
-    {
-        VirtualFree( block, 0, MEM_RELEASE );
-        block = prev;
-    }
-    return block;
-}
+    vtbl_method_t *method;
+    void **entry;
+    DWORD i;
 
-static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num)
-{
-    const void **entry = (const void **)(vtbl + 1);
-    DWORD i, j;
-
-    if (num - 3 > BLOCK_SIZE * MAX_BLOCKS)
-    {
-        FIXME( "%u methods not supported\n", num );
-        return FALSE;
-    }
     vtbl->QueryInterface = delegating_QueryInterface;
     vtbl->AddRef = delegating_AddRef;
     vtbl->Release = delegating_Release;
-    for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++)
-    {
-        const vtbl_method_t *block = method_blocks[i];
-        if (!block && !(block = allocate_block( i ))) return FALSE;
-        for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++) *entry++ = &block[j];
-    }
-    return TRUE;
-}
 
-BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num)
-{
-    const void **entry = (const void **)(vtbl + 1);
-    DWORD i, j;
+    method = (vtbl_method_t*)methods;
+    entry = (void**)(vtbl + 1);
 
-    if (num - 3 > BLOCK_SIZE * MAX_BLOCKS)
-    {
-        FIXME( "%u methods not supported\n", num );
-        return FALSE;
-    }
-    vtbl->QueryInterface = IUnknown_QueryInterface_Proxy;
-    vtbl->AddRef = IUnknown_AddRef_Proxy;
-    vtbl->Release = IUnknown_Release_Proxy;
-    for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++)
+    for(i = 3; i < num; i++)
     {
-        const vtbl_method_t *block = method_blocks[i];
-        if (!block && !(block = allocate_block( i ))) return FALSE;
-        for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++)
-            if (!*entry) *entry = &block[j];
+        *entry = method;
+        method->mov1 = 0x0424448b;
+        method->mov2 = 0x408b;
+        method->sixteen = 0x10;
+        method->mov3 = 0x04244489;
+        method->mov4 = 0x008b;
+        method->mov5 = 0x808b;
+        method->offset = i << 2;
+        method->jmp = 0xe0ff;
+        method->pad[0] = 0x8d;
+        method->pad[1] = 0x76;
+        method->pad[2] = 0x00;
+
+        method++;
+        entry++;
     }
-    return TRUE;
 }
 
 #else  /* __i386__ */
 
-static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num)
+typedef struct {int dummy;} vtbl_method_t;
+static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num)
 {
     ERR("delegated stubs are not supported on this architecture\n");
-    return FALSE;
-}
-
-BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num)
-{
-    ERR("delegated proxies are not supported on this architecture\n");
-    return FALSE;
 }
 
 #endif  /* __i386__ */
 
-static IUnknownVtbl *get_delegating_vtbl(DWORD num_methods)
+void create_delegating_vtbl(DWORD num_methods)
 {
-    IUnknownVtbl *ret;
-
-    if (num_methods < 256) num_methods = 256;  /* avoid frequent reallocations */
+    TRACE("%d\n", num_methods);
+    if(num_methods <= 3)
+    {
+        ERR("should have more than %d methods\n", num_methods);
+        return;
+    }
 
     EnterCriticalSection(&delegating_vtbl_section);
-
-    if(!current_vtbl || num_methods > current_vtbl->size)
+    if(!current_vtbl.table || num_methods > current_vtbl.table->size)
     {
-        ref_counted_vtbl *table = HeapAlloc(GetProcessHeap(), 0,
-                                            FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*));
-        if (!table)
-        {
-            LeaveCriticalSection(&delegating_vtbl_section);
-            return NULL;
-        }
-
-        table->ref = 0;
-        table->size = num_methods;
-        fill_delegated_stub_table(&table->vtbl, num_methods);
-
-        if (current_vtbl && current_vtbl->ref == 0)
+        DWORD size;
+        DWORD old_protect;
+        if(current_vtbl.table && current_vtbl.table->ref == 0)
         {
             TRACE("freeing old table\n");
-            HeapFree(GetProcessHeap(), 0, current_vtbl);
+            VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE);
+            HeapFree(GetProcessHeap(), 0, current_vtbl.table);
         }
-        current_vtbl = table;
+        size = (num_methods - 3) * sizeof(vtbl_method_t);
+        current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*));
+        current_vtbl.table->ref = 0;
+        current_vtbl.table->size = num_methods;
+        current_vtbl.table->methods = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+        fill_table(&current_vtbl.table->vtbl, current_vtbl.table->methods, num_methods);
+        VirtualProtect(current_vtbl.table->methods, size, PAGE_EXECUTE_READ, &old_protect);
     }
+    LeaveCriticalSection(&delegating_vtbl_section);
+}
 
-    current_vtbl->ref++;
-    ret = &current_vtbl->vtbl;
+static IUnknownVtbl *get_delegating_vtbl(void)
+{
+    IUnknownVtbl *ret;
+
+    EnterCriticalSection(&delegating_vtbl_section);
+    current_vtbl.table->ref++;
+    ret = &current_vtbl.table->vtbl;
     LeaveCriticalSection(&delegating_vtbl_section);
     return ret;
 }
@@ -300,21 +253,22 @@ static void release_delegating_vtbl(IUnknownVtbl *vtbl)
     EnterCriticalSection(&delegating_vtbl_section);
     table->ref--;
     TRACE("ref now %d\n", table->ref);
-    if(table->ref == 0 && table != current_vtbl)
+    if(table->ref == 0 && table != current_vtbl.table)
     {
         TRACE("... and we're not current so free'ing\n");
+        VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE);
         HeapFree(GetProcessHeap(), 0, table);
     }
     LeaveCriticalSection(&delegating_vtbl_section);
 }
 
-HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid,
-                                            LPUNKNOWN pUnkServer,
-                                            PCInterfaceName name,
-                                            CInterfaceStubVtbl *vtbl,
-                                            REFIID delegating_iid,
-                                            LPPSFACTORYBUFFER pPSFactory,
-                                            LPRPCSTUBBUFFER *ppStub)
+HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid,
+                                                   LPUNKNOWN pUnkServer,
+                                                   PCInterfaceName name,
+                                                   CInterfaceStubVtbl *vtbl,
+                                                   REFIID delegating_iid,
+                                                   LPPSFACTORYBUFFER pPSFactory,
+                                                   LPRPCSTUBBUFFER *ppStub)
 {
     cstdstubbuffer_delegating_t *This;
     IUnknown *pvServer;
@@ -340,7 +294,7 @@ HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid,
         return E_OUTOFMEMORY;
     }
 
-    This->base_obj = get_delegating_vtbl( vtbl->header.DispatchTableCount );
+    This->base_obj = get_delegating_vtbl();
     r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub);
     if(FAILED(r))
     {
index 3eec37a..1afd3eb 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
 
-#include "epm.h"
+#include "epm_c.h"
 
 #define EPM_PROTOCOL_DNET_NSP          0x04
 #define EPM_PROTOCOL_OSI_TP4           0x05
index cab0fc5..15192a7 100644 (file)
@@ -59,7 +59,7 @@ static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
 
 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
 {
-    struct context_handle_entry *che = CContext;
+    struct context_handle_entry *che = (struct context_handle_entry*) CContext;
 
     if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
         return NULL;
@@ -111,7 +111,7 @@ void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
     }
     else
     {
-        ndr_context_handle *wire_data = pBuff;
+        ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
         wire_data->attributes = 0;
         wire_data->uuid = GUID_NULL;
     }
index b0150c3..c3beff4 100644 (file)
@@ -62,6 +62,6 @@ extern const NDR_BUFFERSIZE NdrBufferSizer[];
 extern const NDR_MEMORYSIZE NdrMemorySizer[];
 extern const NDR_FREE       NdrFreer[];
 
-ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat);
+unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat);
 
 #endif  /* __WINE_NDR_MISC_H */
index a4c23c2..a3264e7 100644 (file)
@@ -369,30 +369,6 @@ void WINAPI NdrOleFree(void *NodeToFree)
   COM_MemFree(NodeToFree);
 }
 
-/***********************************************************************
- * Helper function to create a proxy.
- * Probably similar to NdrpCreateProxy.
- */
-HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv)
-{
-    CLSID clsid;
-    IPSFactoryBuffer *psfac;
-    HRESULT r;
-
-    if(!LoadCOM()) return E_FAIL;
-
-    r = COM_GetPSClsid( iid, &clsid );
-    if(FAILED(r)) return r;
-
-    r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac );
-    if(FAILED(r)) return r;
-
-    r = IPSFactoryBuffer_CreateProxy(psfac, pUnkOuter, iid, pproxy, ppv);
-
-    IPSFactoryBuffer_Release(psfac);
-    return r;
-}
-
 /***********************************************************************
  * Helper function to create a stub.
  * This probably looks very much like NdrpCreateStub.
index 8cb5f2b..645a0ca 100644 (file)
@@ -173,7 +173,7 @@ static PFORMAT_STRING client_get_handle(
                 if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR)
                     pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                 else
-                    pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
+                    pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                 memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf);
                 pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index];
                 *phBinding = pGenPair->pfnBind(pObject);
@@ -256,7 +256,7 @@ static void client_free_handle(
                 if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR)
                     pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                 else
-                    pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
+                    pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
                 memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf);
                 pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index];
                 pGenPair->pfnUnbind(pObject, hBinding);
@@ -867,14 +867,9 @@ __declspec(naked) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigne
 LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size);
 __ASM_GLOBAL_FUNC(call_server_func,
     "pushl %ebp\n\t"
-    __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
-    __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
-    "movl %esp,%ebp\n\t"
-    __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+    "movl %esp, %ebp\n\t"
     "pushl %edi\n\t"            /* Save registers */
-    __ASM_CFI(".cfi_rel_offset %edi,-4\n\t")
     "pushl %esi\n\t"
-    __ASM_CFI(".cfi_rel_offset %esi,-8\n\t")
     "movl 16(%ebp), %eax\n\t"   /* Get stack size */
     "subl %eax, %esp\n\t"       /* Make room in stack for arguments */
     "andl $~15, %esp\n\t"      /* Make sure stack has 16-byte alignment for Mac OS X */
@@ -887,13 +882,9 @@ __ASM_GLOBAL_FUNC(call_server_func,
     "call *8(%ebp)\n\t"         /* Call function */
     "leal -8(%ebp), %esp\n\t"   /* Restore stack */
     "popl %esi\n\t"             /* Restore registers */
-    __ASM_CFI(".cfi_same_value %esi\n\t")
     "popl %edi\n\t"
-    __ASM_CFI(".cfi_same_value %edi\n\t")
     "popl %ebp\n\t"
-    __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
-    __ASM_CFI(".cfi_same_value %ebp\n\t")
-    "ret" )
+    "ret\n" )
 #else
 #warning call_server_func not implemented for your architecture
 LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size)
@@ -1531,339 +1522,3 @@ void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg)
     DWORD dwPhase;
     NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase);
 }
-
-struct async_call_data
-{
-    MIDL_STUB_MESSAGE *pStubMsg;
-    const NDR_PROC_HEADER *pProcHeader;
-    PFORMAT_STRING pHandleFormat;
-    PFORMAT_STRING pParamFormat;
-    RPC_BINDING_HANDLE hBinding;
-    /* size of stack */
-    unsigned short stack_size;
-    /* number of parameters. optional for client to give it to us */
-    unsigned char number_of_params;
-    /* correlation cache */
-    unsigned long NdrCorrCache[256];
-};
-
-LONG_PTR WINAPIV NdrAsyncClientCall(PMIDL_STUB_DESC pStubDesc,
-  PFORMAT_STRING pFormat, ...)
-{
-    /* pointer to start of stack where arguments start */
-    PRPC_MESSAGE pRpcMsg;
-    PMIDL_STUB_MESSAGE pStubMsg;
-    RPC_ASYNC_STATE *pAsync;
-    struct async_call_data *async_call_data;
-    /* procedure number */
-    unsigned short procedure_number;
-    /* cache of Oif_flags from v2 procedure header */
-    INTERPRETER_OPT_FLAGS Oif_flags = { 0 };
-    /* cache of extension flags from NDR_PROC_HEADER_EXTS */
-    INTERPRETER_OPT_FLAGS2 ext_flags = { 0 };
-    /* the type of pass we are currently doing */
-    int phase;
-    /* header for procedure string */
-    const NDR_PROC_HEADER * pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0];
-    /* -Oif or -Oicf generated format */
-    BOOL bV2Format = FALSE;
-
-    TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat);
-
-    /* Later NDR language versions probably won't be backwards compatible */
-    if (pStubDesc->Version > 0x50002)
-    {
-        FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version);
-        RpcRaiseException(RPC_X_WRONG_STUB_VERSION);
-    }
-
-    async_call_data = I_RpcAllocate(sizeof(*async_call_data) + sizeof(MIDL_STUB_MESSAGE) + sizeof(RPC_MESSAGE));
-    if (!async_call_data) RpcRaiseException(ERROR_OUTOFMEMORY);
-    async_call_data->number_of_params = ~0;
-    async_call_data->pProcHeader = pProcHeader;
-
-    async_call_data->pStubMsg = pStubMsg = (PMIDL_STUB_MESSAGE)(async_call_data + 1);
-    pRpcMsg = (PRPC_MESSAGE)(pStubMsg + 1);
-
-    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
-    {
-        const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0];
-        async_call_data->stack_size = pProcHeader->stack_size;
-        procedure_number = pProcHeader->proc_num;
-        pFormat += sizeof(NDR_PROC_HEADER_RPC);
-    }
-    else
-    {
-        async_call_data->stack_size = pProcHeader->stack_size;
-        procedure_number = pProcHeader->proc_num;
-        pFormat += sizeof(NDR_PROC_HEADER);
-    }
-    TRACE("stack size: 0x%x\n", async_call_data->stack_size);
-    TRACE("proc num: %d\n", procedure_number);
-
-    /* create the full pointer translation tables, if requested */
-    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
-        pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT);
-
-    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
-    {
-        ERR("objects not supported\n");
-        I_RpcFree(async_call_data);
-        RpcRaiseException(RPC_X_BAD_STUB_DATA);
-    }
-
-    NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDesc, procedure_number);
-
-    TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags);
-    TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion);
-
-    /* needed for conformance of top-level objects */
-#ifdef __i386__
-    pStubMsg->StackTop = I_RpcAllocate(async_call_data->stack_size);
-    /* FIXME: this may read one more DWORD than is necessary, but it shouldn't hurt */
-    memcpy(pStubMsg->StackTop, *(unsigned char **)(&pFormat+1), async_call_data->stack_size);
-#else
-# warning Stack not retrieved for your CPU architecture
-#endif
-
-    pAsync = *(RPC_ASYNC_STATE **)pStubMsg->StackTop;
-    pAsync->StubInfo = async_call_data;
-    async_call_data->pHandleFormat = pFormat;
-
-    pFormat = client_get_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, &async_call_data->hBinding);
-    if (!pFormat) return 0;
-
-    bV2Format = (pStubDesc->Version >= 0x20000);
-
-    if (bV2Format)
-    {
-        const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader =
-            (const NDR_PROC_PARTIAL_OIF_HEADER *)pFormat;
-
-        Oif_flags = pOIFHeader->Oi2Flags;
-        async_call_data->number_of_params = pOIFHeader->number_of_params;
-
-        pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER);
-    }
-
-    TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags);
-
-    if (Oif_flags.HasExtensions)
-    {
-        const NDR_PROC_HEADER_EXTS *pExtensions =
-            (const NDR_PROC_HEADER_EXTS *)pFormat;
-        ext_flags = pExtensions->Flags2;
-        pFormat += pExtensions->Size;
-    }
-
-    async_call_data->pParamFormat = pFormat;
-
-    pStubMsg->BufferLength = 0;
-
-    /* store the RPC flags away */
-    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
-        pRpcMsg->RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags;
-
-    /* use alternate memory allocation routines */
-    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC)
-        NdrRpcSmSetClientToOsf(pStubMsg);
-
-    if (Oif_flags.HasPipes)
-    {
-        FIXME("pipes not supported yet\n");
-        RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */
-        /* init pipes package */
-        /* NdrPipesInitialize(...) */
-    }
-    if (ext_flags.HasNewCorrDesc)
-    {
-        /* initialize extra correlation package */
-        NdrCorrelationInitialize(pStubMsg, async_call_data->NdrCorrCache, sizeof(async_call_data->NdrCorrCache), 0);
-    }
-
-    /* order of phases:
-     * 1. PROXY_CALCSIZE - calculate the buffer size
-     * 2. PROXY_GETBUFFER - allocate the buffer
-     * 3. PROXY_MARHSAL - marshal [in] params into the buffer
-     * 4. PROXY_SENDRECEIVE - send buffer
-     * Then in NdrpCompleteAsyncClientCall:
-     * 1. PROXY_SENDRECEIVE - receive buffer
-     * 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer
-     */
-    for (phase = PROXY_CALCSIZE; phase <= PROXY_SENDRECEIVE; phase++)
-    {
-        RPC_STATUS status;
-        TRACE("phase = %d\n", phase);
-        switch (phase)
-        {
-        case PROXY_GETBUFFER:
-            /* allocate the buffer */
-            if (Oif_flags.HasPipes)
-                /* NdrGetPipeBuffer(...) */
-                FIXME("pipes not supported yet\n");
-            else
-            {
-                if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
-#if 0
-                    NdrNsGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding);
-#else
-                    FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n");
-#endif
-                else
-                    NdrGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding);
-            }
-            pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
-            status = I_RpcAsyncSetHandle(pRpcMsg, pAsync);
-            if (status != RPC_S_OK)
-                RpcRaiseException(status);
-            break;
-        case PROXY_SENDRECEIVE:
-            pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
-            /* send the [in] params only */
-            if (Oif_flags.HasPipes)
-                /* NdrPipesSend(...) */
-                FIXME("pipes not supported yet\n");
-            else
-            {
-                if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
-#if 0
-                    NdrNsSend(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle);
-#else
-                    FIXME("using auto handle - call NdrNsSend when it gets implemented\n");
-#endif
-                else
-                {
-                    pStubMsg->RpcMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
-                    status = I_RpcSend(pStubMsg->RpcMsg);
-                    if (status != RPC_S_OK)
-                        RpcRaiseException(status);
-                }
-            }
-
-            break;
-        case PROXY_CALCSIZE:
-        case PROXY_MARSHAL:
-            if (bV2Format)
-                client_do_args(pStubMsg, pFormat, phase, pStubMsg->StackTop,
-                    async_call_data->number_of_params, NULL);
-            else
-                client_do_args_old_format(pStubMsg, pFormat, phase,
-                    pStubMsg->StackTop, async_call_data->stack_size, NULL,
-                    (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT), FALSE);
-            break;
-        default:
-            ERR("shouldn't reach here. phase %d\n", phase);
-            break;
-        }
-    }
-
-    TRACE("returning 0\n");
-    return 0;
-}
-
-RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply)
-{
-    /* pointer to start of stack where arguments start */
-    PMIDL_STUB_MESSAGE pStubMsg;
-    struct async_call_data *async_call_data;
-    /* the type of pass we are currently doing */
-    int phase;
-    /* header for procedure string */
-    const NDR_PROC_HEADER * pProcHeader;
-    /* -Oif or -Oicf generated format */
-    BOOL bV2Format;
-    RPC_STATUS status = RPC_S_OK;
-
-    if (!pAsync->StubInfo)
-        return RPC_S_INVALID_ASYNC_HANDLE;
-
-    async_call_data = pAsync->StubInfo;
-    pStubMsg = async_call_data->pStubMsg;
-    pProcHeader = async_call_data->pProcHeader;
-
-    bV2Format = (pStubMsg->StubDesc->Version >= 0x20000);
-
-    /* order of phases:
-     * 1. PROXY_CALCSIZE - calculate the buffer size
-     * 2. PROXY_GETBUFFER - allocate the buffer
-     * 3. PROXY_MARHSAL - marshal [in] params into the buffer
-     * 4. PROXY_SENDRECEIVE - send buffer
-     * Then in NdrpCompleteAsyncClientCall:
-     * 1. PROXY_SENDRECEIVE - receive buffer
-     * 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer
-     */
-    for (phase = PROXY_SENDRECEIVE; phase <= PROXY_UNMARSHAL; phase++)
-    {
-        switch (phase)
-        {
-        case PROXY_SENDRECEIVE:
-            pStubMsg->RpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
-            /* receive the [out] params */
-            if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
-#if 0
-                NdrNsReceive(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle);
-#else
-                FIXME("using auto handle - call NdrNsReceive when it gets implemented\n");
-#endif
-            else
-            {
-                status = I_RpcReceive(pStubMsg->RpcMsg);
-                if (status != RPC_S_OK)
-                    goto cleanup;
-                pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
-                pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
-                pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
-                pStubMsg->Buffer = pStubMsg->BufferStart;
-            }
-
-            /* convert strings, floating point values and endianess into our
-             * preferred format */
-#if 0
-            if ((pStubMsg->RpcMsg.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)
-                NdrConvert(pStubMsg, pFormat);
-#endif
-
-            break;
-        case PROXY_UNMARSHAL:
-            if (bV2Format)
-                client_do_args(pStubMsg, async_call_data->pParamFormat, phase, pStubMsg->StackTop,
-                    async_call_data->number_of_params, Reply);
-            else
-                client_do_args_old_format(pStubMsg, async_call_data->pParamFormat, phase,
-                    pStubMsg->StackTop, async_call_data->stack_size, Reply, FALSE, FALSE);
-            break;
-        default:
-            ERR("shouldn't reach here. phase %d\n", phase);
-            break;
-        }
-    }
-
-cleanup:
-    if (pStubMsg->fHasNewCorrDesc)
-    {
-        /* free extra correlation package */
-        NdrCorrelationFree(pStubMsg);
-    }
-
-    /* free the full pointer translation tables */
-    if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
-        NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);
-
-    /* free marshalling buffer */
-    NdrFreeBuffer(pStubMsg);
-    client_free_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, async_call_data->hBinding);
-
-    I_RpcFree(pStubMsg->StackTop);
-    I_RpcFree(async_call_data);
-
-    TRACE("-- 0x%x\n", status);
-    return status;
-}
-
-RPCRTAPI LONG RPC_ENTRY NdrAsyncStubCall(struct IRpcStubBuffer* pThis,
-    struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg,
-    DWORD * pdwStubPhase)
-{
-    FIXME("unimplemented, expect crash!\n");
-    return 0;
-}
index 87f603b..9a6fb44 100644 (file)
@@ -85,7 +85,7 @@ typedef struct _NDR_PROC_HEADER_RPC
      * RPCF_Asynchronous = 0x4000 - [async] MIDL attribute
      * Reserved = 0x8000
      */
-    unsigned int rpc_flags;
+    unsigned long rpc_flags;
     unsigned short proc_num;
     unsigned short stack_size;
 
@@ -240,4 +240,3 @@ void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg,
     PFORMAT_STRING pFormat, int phase, unsigned char *args,
     unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc,
     BOOL ignore_retval);
-RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply);
index 117301f..32e951a 100644 (file)
@@ -125,7 +125,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr,
 
 RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr,
                                          LPCSTR Endpoint, LPCWSTR NetworkOptions,
-                                         ULONG assoc_gid,
+                                         unsigned long assoc_gid,
                                          RpcAssoc **assoc_out)
 {
     RpcAssoc *assoc;
@@ -223,7 +223,7 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection *
     RPC_MESSAGE msg;
     RPC_STATUS status;
     unsigned char *auth_data = NULL;
-    ULONG auth_length;
+    unsigned long auth_length;
 
     TRACE("sending bind request to server\n");
 
@@ -394,7 +394,6 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
     if (status != RPC_S_OK)
         return status;
 
-    NewConnection->assoc = assoc;
     status = RPCRT4_OpenClientConnection(NewConnection);
     if (status != RPC_S_OK)
     {
@@ -417,7 +416,6 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
 void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection)
 {
     assert(!Connection->server);
-    Connection->async_state = NULL;
     EnterCriticalSection(&assoc->cs);
     if (!assoc->assoc_group_id) assoc->assoc_group_id = Connection->assoc_group_id;
     list_add_head(&assoc->free_connection_pool, &Connection->conn_pool_entry);
index 70fb664..1ce1f13 100644 (file)
@@ -34,7 +34,6 @@ typedef struct _RpcAssoc
 
     /* id of this association group */
     ULONG assoc_group_id;
-    UUID http_uuid;
 
     CRITICAL_SECTION cs;
 
@@ -50,7 +49,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endp
 RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, RpcConnection **Connection);
 void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection);
 ULONG RpcAssoc_Release(RpcAssoc *assoc);
-RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, ULONG assoc_gid, RpcAssoc **assoc_out);
+RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, unsigned long assoc_gid, RpcAssoc **assoc_out);
 RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext);
 RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext);
 RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine);
index 891fc5a..33fdc77 100644 (file)
 
 #include "rpc_binding.h"
 #include "rpc_message.h"
-#include "ndr_stubless.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(rpc);
 
 #define RPC_ASYNC_SIGNATURE 0x43595341
 
-static inline BOOL valid_async_handle(PRPC_ASYNC_STATE pAsync)
-{
-    return pAsync->Signature == RPC_ASYNC_SIGNATURE;
-}
-
 /***********************************************************************
  *           RpcAsyncInitializeHandle [RPCRT4.@]
  *
@@ -110,14 +104,8 @@ RPC_STATUS WINAPI RpcAsyncGetCallStatus(PRPC_ASYNC_STATE pAsync)
  */
 RPC_STATUS WINAPI RpcAsyncCompleteCall(PRPC_ASYNC_STATE pAsync, void *Reply)
 {
-    TRACE("(%p, %p)\n", pAsync, Reply);
-
-    if (!valid_async_handle(pAsync))
-        return RPC_S_INVALID_ASYNC_HANDLE;
-
-    /* FIXME: check completed */
-
-    return NdrpCompleteAsyncClientCall(pAsync, Reply);
+    FIXME("(%p, %p): stub\n", pAsync, Reply);
+    return RPC_S_INVALID_ASYNC_HANDLE;
 }
 
 /***********************************************************************
index 29e0709..696887c 100644 (file)
@@ -661,11 +661,11 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU
   return RPC_S_OK;
 
 fail:
-  if (ObjUuid) RpcStringFreeA(ObjUuid);
-  if (Protseq) RpcStringFreeA(Protseq);
-  if (NetworkAddr) RpcStringFreeA(NetworkAddr);
-  if (Endpoint) RpcStringFreeA(Endpoint);
-  if (Options) RpcStringFreeA(Options);
+  if (ObjUuid) RpcStringFreeA((unsigned char**)ObjUuid);
+  if (Protseq) RpcStringFreeA((unsigned char**)Protseq);
+  if (NetworkAddr) RpcStringFreeA((unsigned char**)NetworkAddr);
+  if (Endpoint) RpcStringFreeA((unsigned char**)Endpoint);
+  if (Options) RpcStringFreeA((unsigned char**)Options);
   return RPC_S_INVALID_STRING_BINDING;
 }
 
@@ -796,7 +796,7 @@ RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding )
 RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector )
 {
   RPC_STATUS status;
-  ULONG c;
+  unsigned long c;
 
   TRACE("(%p)\n", BindingVector);
   for (c=0; c<(*BindingVector)->Count; c++) {
@@ -812,7 +812,7 @@ RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector )
  */
 RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid )
 {
-  RpcBinding* bind = Binding;
+  RpcBinding* bind = (RpcBinding*)Binding;
 
   TRACE("(%p,%p) = %s\n", Binding, ObjectUuid, debugstr_guid(&bind->ObjectUuid));
   *ObjectUuid = bind->ObjectUuid;
@@ -824,7 +824,7 @@ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU
  */
 RPC_STATUS WINAPI RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid )
 {
-  RpcBinding* bind = Binding;
+  RpcBinding* bind = (RpcBinding*)Binding;
 
   TRACE("(%p,%s)\n", Binding, debugstr_guid(ObjectUuid));
   if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING;
@@ -856,11 +856,11 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BIND
   if (ret == RPC_S_OK)
     ret = RPCRT4_CompleteBindingA(bind, (char*)NetworkAddr, (char*)Endpoint, (char*)Options);
 
-  RpcStringFreeA(&Options);
-  RpcStringFreeA(&Endpoint);
-  RpcStringFreeA(&NetworkAddr);
-  RpcStringFreeA(&Protseq);
-  RpcStringFreeA(&ObjectUuid);
+  RpcStringFreeA((unsigned char**)&Options);
+  RpcStringFreeA((unsigned char**)&Endpoint);
+  RpcStringFreeA((unsigned char**)&NetworkAddr);
+  RpcStringFreeA((unsigned char**)&Protseq);
+  RpcStringFreeA((unsigned char**)&ObjectUuid);
 
   if (ret == RPC_S_OK) 
     *Binding = (RPC_BINDING_HANDLE)bind;
@@ -915,7 +915,7 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BIND
 RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CSTR *StringBinding )
 {
   RPC_STATUS ret;
-  RpcBinding* bind = Binding;
+  RpcBinding* bind = (RpcBinding*)Binding;
   RPC_CSTR ObjectUuid;
 
   TRACE("(%p,%p)\n", Binding, StringBinding);
@@ -946,7 +946,7 @@ RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, RPC_WS
   TRACE("(%p,%p)\n", Binding, StringBinding);
   ret = RpcBindingToStringBindingA(Binding, &str);
   *StringBinding = RPCRT4_strdupAtoW((char*)str);
-  RpcStringFreeA(&str);
+  RpcStringFreeA((unsigned char**)&str);
   return ret;
 }
 
@@ -969,7 +969,7 @@ RPC_STATUS WINAPI I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding, unsi
  */
 RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn)
 {
-  RpcBinding* bind = Binding;
+  RpcBinding* bind = (RpcBinding*)Binding;
 
   TRACE( "(%p,%p): stub\n", Binding, BlockingFn );
 
@@ -986,7 +986,7 @@ RPC_STATUS RPC_ENTRY RpcBindingCopy(
   RPC_BINDING_HANDLE* DestinationBinding)
 {
   RpcBinding *DestBinding;
-  RpcBinding *SrcBinding = SourceBinding;
+  RpcBinding *SrcBinding = (RpcBinding*)SourceBinding;
   RPC_STATUS status;
 
   TRACE("(%p, %p)\n", SourceBinding, DestinationBinding);
@@ -1501,7 +1501,7 @@ RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName,
                           RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr,
                           RPC_SECURITY_QOS *SecurityQos )
 {
-  RpcBinding* bind = Binding;
+  RpcBinding* bind = (RpcBinding*)Binding;
   SECURITY_STATUS r;
   CredHandle cred;
   TimeStamp exp;
@@ -1631,7 +1631,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName,
                           ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr,
                           RPC_SECURITY_QOS *SecurityQos )
 {
-  RpcBinding* bind = Binding;
+  RpcBinding* bind = (RpcBinding*)Binding;
   SECURITY_STATUS r;
   CredHandle cred;
   TimeStamp exp;
@@ -1640,7 +1640,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName,
   PSecPkgInfoW packages;
   ULONG cbMaxToken;
 
-  TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w(ServerPrincName),
+  TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w((const WCHAR*)ServerPrincName),
         AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos);
 
   if (SecurityQos)
@@ -1772,7 +1772,7 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
 RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnLevel,
                         ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr )
 {
-    TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w(ServerPrincName),
+    TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w((const WCHAR*)ServerPrincName),
           AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr);
     return RpcBindingSetAuthInfoExW(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, NULL);
 }
index 036b59a..5aa8307 100644 (file)
@@ -24,7 +24,6 @@
 #include "rpcndr.h"
 #include "security.h"
 #include "wine/list.h"
-#include "rpc_defs.h"
 
 
 typedef struct _RpcAuthInfo
@@ -67,7 +66,6 @@ typedef struct _RpcConnection
   TimeStamp exp;
   ULONG attr;
   RpcAuthInfo *AuthInfo;
-  ULONG auth_context_id;
   ULONG encryption_auth_len;
   ULONG signature_auth_len;
   RpcQualityOfService *QOS;
@@ -76,7 +74,6 @@ typedef struct _RpcConnection
   struct list conn_pool_entry;
   ULONG assoc_group_id; /* association group returned during binding */
   RPC_ASYNC_STATE *async_state;
-  struct _RpcAssoc *assoc; /* association this connection is part of */
 
   /* server-only */
   /* The active interface bound to server. */
@@ -99,7 +96,6 @@ struct connection_ops {
   int (*wait_for_incoming_data)(RpcConnection *conn);
   size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint);
   RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint);
-  RPC_STATUS (*receive_fragment)(RpcConnection *conn, RpcPktHdr **Header, void **Payload);
 };
 
 /* don't know what MS's structure looks like */
index e70731a..cae77c4 100644 (file)
@@ -31,13 +31,13 @@ typedef struct
   unsigned char drep[4];          /* Data representation */
   unsigned short frag_len;        /* Data size in bytes including header and tail. */
   unsigned short auth_len;        /* Authentication length  */
-  unsigned int  call_id;          /* Call identifier. */
+  unsigned long call_id;          /* Call identifier. */
 } RpcPktCommonHdr;
 
 typedef struct
 {
   RpcPktCommonHdr common;
-  unsigned int   alloc_hint;      /* Data size in bytes excluding header and tail. */
+  unsigned long alloc_hint;       /* Data size in bytes excluding header and tail. */
   unsigned short context_id;      /* Presentation context identifier */
   unsigned short opnum;
 } RpcPktRequestHdr;
@@ -45,7 +45,7 @@ typedef struct
 typedef struct
 {
   RpcPktCommonHdr common;
-  unsigned int   alloc_hint;      /* Data size in bytes excluding header and tail. */
+  unsigned long alloc_hint;       /* Data size in bytes excluding header and tail. */
   unsigned short context_id;      /* Presentation context identifier */
   unsigned char cancel_count;
   unsigned char reserved;
@@ -54,12 +54,12 @@ typedef struct
 typedef struct
 {
   RpcPktCommonHdr common;
-  unsigned int   alloc_hint;      /* Data size in bytes excluding header and tail. */
+  unsigned long alloc_hint;       /* Data size in bytes excluding header and tail. */
   unsigned short context_id;      /* Presentation context identifier */
   unsigned char cancel_count;     /* Received cancel count */
   unsigned char reserved;         /* Force alignment! */
-  unsigned int  status;           /* Runtime fault code (RPC_STATUS) */
-  unsigned int  reserved2;
+  unsigned long status;           /* Runtime fault code (RPC_STATUS) */
+  unsigned long reserved2;
 } RpcPktFaultHdr;
 
 typedef struct
@@ -67,7 +67,7 @@ typedef struct
   RpcPktCommonHdr common;
   unsigned short max_tsize;       /* Maximum transmission fragment size */
   unsigned short max_rsize;       /* Maximum receive fragment size */
-  unsigned int  assoc_gid;        /* Associated group id */
+  unsigned long assoc_gid;        /* Associated group id */
   unsigned char num_elements;     /* Number of elements */
   unsigned char padding[3];       /* Force alignment! */
   unsigned short context_id;      /* Presentation context identifier */
@@ -99,7 +99,7 @@ typedef struct
   RpcPktCommonHdr common;
   unsigned short max_tsize;       /* Maximum transmission fragment size */
   unsigned short max_rsize;       /* Maximum receive fragment size */
-  unsigned int assoc_gid;         /* Associated group id */
+  unsigned long assoc_gid;        /* Associated group id */
   /* 
    * Following this header are these fields:
    *   RpcAddressString server_address;
@@ -120,14 +120,6 @@ typedef struct
   } protocols[1];
 } RpcPktBindNAckHdr;
 
-/* undocumented packet sent during RPC over HTTP */
-typedef struct
-{
-  RpcPktCommonHdr common;
-  unsigned short flags;
-  unsigned short num_data_items;
-} RpcPktHttpHdr;
-
 /* Union representing all possible packet headers */
 typedef union
 {
@@ -138,7 +130,6 @@ typedef union
   RpcPktBindHdr bind;
   RpcPktBindAckHdr bind_ack;
   RpcPktBindNAckHdr bind_nack;
-  RpcPktHttpHdr http;
 } RpcPktHdr;
 
 typedef struct
@@ -147,7 +138,7 @@ typedef struct
   unsigned char auth_level;      /* RPC_C_AUTHN_LEVEL* */
   unsigned char auth_pad_length; /* length of padding to restore n % 4 alignment */
   unsigned char auth_reserved;   /* reserved, must be zero */
-  unsigned int  auth_context_id; /* unique value for the authenticated connection */
+  unsigned long auth_context_id; /* unique value for the authenticated connection */
 } RpcAuthVerifier;
 
 #define RPC_AUTH_VERIFIER_LEN(common_hdr) \
@@ -183,7 +174,6 @@ typedef struct
 #define PKT_SHUTDOWN           17
 #define PKT_CO_CANCEL          18
 #define PKT_ORPHANED           19
-#define PKT_HTTP               20
 
 #define RESULT_ACCEPT               0
 #define RESULT_USER_REJECTION       1
index 60c4255..286ffbf 100644 (file)
@@ -32,7 +32,7 @@
 #include "wine/exception.h"
 
 #include "rpc_binding.h"
-#include "epm.h"
+#include "epm_c.h"
 #include "epm_towers.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -116,7 +116,7 @@ static BOOL start_rpcss(void)
 
 static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle)
 {
-    RpcBinding *bind = handle;
+    RpcBinding *bind = (RpcBinding *)handle;
     const char *protseq = bind->Protseq;
     const char *network_addr = bind->NetworkAddr;
 
@@ -127,7 +127,7 @@ static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle)
 
 static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_HANDLE *epm_handle)
 {
-    RpcBinding *bind = handle;
+    RpcBinding *bind = (RpcBinding *)handle;
     const char * pszEndpoint = NULL;
     RPC_STATUS status;
     RpcBinding* epm_bind;
@@ -149,7 +149,7 @@ static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_H
     status = RpcBindingCopy(handle, epm_handle);
     if (status != RPC_S_OK) return status;
 
-    epm_bind = *epm_handle;
+    epm_bind = (RpcBinding*)*epm_handle;
     if (epm_bind->AuthInfo)
     {
         /* don't bother with authenticating against the EPM by default
@@ -187,8 +187,8 @@ static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *__eptr)
 RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
                                   UUID_VECTOR *UuidVector, RPC_CSTR Annotation )
 {
-  PRPC_SERVER_INTERFACE If = IfSpec;
-  ULONG i;
+  PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
+  unsigned long i;
   RPC_STATUS status = RPC_S_OK;
   error_status_t status2;
   ept_entry_t *entries;
@@ -197,13 +197,13 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
   TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation));
   TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
   for (i=0; i<BindingVector->Count; i++) {
-    RpcBinding* bind = BindingVector->BindingH[i];
-    TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq));
-    TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint));
+    RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
+    TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq));
+    TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint));
   }
   if (UuidVector) {
     for (i=0; i<UuidVector->Count; i++)
-      TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
+      TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
   }
 
   if (!BindingVector->Count) return RPC_S_OK;
@@ -222,9 +222,10 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
   for (i = 0; i < BindingVector->Count; i++)
   {
       unsigned j;
-      RpcBinding* bind = BindingVector->BindingH[i];
+      RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
       for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++)
       {
+          int len = strlen((char *)Annotation);
           status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax,
                                   bind->Protseq, bind->Endpoint,
                                   bind->NetworkAddr,
@@ -235,9 +236,7 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
               memcpy(&entries[i * UuidVector->Count].object, &UuidVector->Uuid[j], sizeof(GUID));
           else
               memset(&entries[i].object, 0, sizeof(entries[i].object));
-          if (Annotation)
-              memcpy(entries[i].annotation, Annotation,
-                     min(strlen((char *)Annotation) + 1, ept_max_annotation_size));
+          memcpy(entries[i].annotation, Annotation, min(len + 1, ept_max_annotation_size));
       }
   }
 
@@ -281,29 +280,14 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
   return status;
 }
 
-/***********************************************************************
- *             RpcEpRegisterW (RPCRT4.@)
- */
-RPC_STATUS WINAPI RpcEpRegisterW( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
-                                  UUID_VECTOR *UuidVector, RPC_WSTR Annotation )
-{
-  LPSTR annA = RPCRT4_strdupWtoA(Annotation);
-  RPC_STATUS status;
-
-  status = RpcEpRegisterA(IfSpec, BindingVector, UuidVector, (RPC_CSTR)annA);
-
-  HeapFree(GetProcessHeap(), 0, annA);
-  return status;
-}
-
 /***********************************************************************
  *             RpcEpUnregister (RPCRT4.@)
  */
 RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
                                    UUID_VECTOR *UuidVector )
 {
-  PRPC_SERVER_INTERFACE If = IfSpec;
-  ULONG i;
+  PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
+  unsigned long i;
   RPC_STATUS status = RPC_S_OK;
   error_status_t status2;
   ept_entry_t *entries;
@@ -312,13 +296,13 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
   TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector);
   TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
   for (i=0; i<BindingVector->Count; i++) {
-    RpcBinding* bind = BindingVector->BindingH[i];
-    TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq));
-    TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint));
+    RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
+    TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq));
+    TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint));
   }
   if (UuidVector) {
     for (i=0; i<UuidVector->Count; i++)
-      TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
+      TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
   }
 
   entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*entries) * BindingVector->Count * (UuidVector ? UuidVector->Count : 1));
@@ -335,7 +319,7 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
   for (i = 0; i < BindingVector->Count; i++)
   {
       unsigned j;
-      RpcBinding* bind = BindingVector->BindingH[i];
+      RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
       for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++)
       {
           status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax,
@@ -388,8 +372,8 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
  */
 RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec )
 {
-  PRPC_CLIENT_INTERFACE If = IfSpec;
-  RpcBinding* bind = Binding;
+  PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec;
+  RpcBinding* bind = (RpcBinding*)Binding;
   RPC_STATUS status;
   error_status_t status2;
   handle_t handle;
index 5e7c857..e4f96a9 100644 (file)
@@ -59,13 +59,13 @@ enum secure_packet_direction
 
 static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg);
 
-DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
+static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
 {
   static const DWORD header_sizes[] = {
     sizeof(Header->request), 0, sizeof(Header->response),
     sizeof(Header->fault), 0, 0, 0, 0, 0, 0, 0, sizeof(Header->bind),
     sizeof(Header->bind_ack), sizeof(Header->bind_nack),
-    0, 0, 0, 0, 0, 0, sizeof(Header->http)
+    0, 0, 0, 0, 0
   };
   ULONG ret = 0;
   
@@ -76,7 +76,7 @@ DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
     if (Header->common.flags & RPC_FLG_OBJECT_UUID)
       ret += sizeof(UUID);
   } else {
-    WARN("invalid packet type %u\n", Header->common.ptype);
+    TRACE("invalid packet type\n");
   }
 
   return ret;
@@ -96,7 +96,7 @@ static int packet_has_auth_verifier(const RpcPktHdr *Header)
 }
 
 static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType,
-                                     ULONG DataRepresentation)
+                              unsigned long DataRepresentation)
 {
   Header->common.rpc_ver = RPC_VER_MAJOR;
   Header->common.rpc_ver_minor = RPC_VER_MINOR;
@@ -111,8 +111,8 @@ static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType
   /* Flags and fragment length are computed in RPCRT4_Send. */
 }                              
 
-static RpcPktHdr *RPCRT4_BuildRequestHeader(ULONG DataRepresentation,
-                                     ULONG BufferLength,
+static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation,
+                                     unsigned long BufferLength,
                                      unsigned short ProcNum,
                                      UUID *ObjectUuid)
 {
@@ -141,7 +141,8 @@ static RpcPktHdr *RPCRT4_BuildRequestHeader(ULONG DataRepresentation,
   return header;
 }
 
-RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength)
+RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation,
+                                      unsigned long BufferLength)
 {
   RpcPktHdr *header;
 
@@ -157,7 +158,8 @@ RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLeng
   return header;
 }
 
-RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status)
+RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation,
+                                   RPC_STATUS Status)
 {
   RpcPktHdr *header;
 
@@ -173,10 +175,10 @@ RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status)
   return header;
 }
 
-RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation,
+RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation,
                                   unsigned short MaxTransmissionSize,
                                   unsigned short MaxReceiveSize,
-                                  ULONG  AssocGroupId,
+                                  unsigned long  AssocGroupId,
                                   const RPC_SYNTAX_IDENTIFIER *AbstractId,
                                   const RPC_SYNTAX_IDENTIFIER *TransferId)
 {
@@ -200,7 +202,7 @@ RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation,
   return header;
 }
 
-static RpcPktHdr *RPCRT4_BuildAuthHeader(ULONG DataRepresentation)
+static RpcPktHdr *RPCRT4_BuildAuthHeader(unsigned long DataRepresentation)
 {
   RpcPktHdr *header;
 
@@ -216,7 +218,7 @@ static RpcPktHdr *RPCRT4_BuildAuthHeader(ULONG DataRepresentation)
   return header;
 }
 
-RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation,
+RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation,
                                       unsigned char RpcVersion,
                                       unsigned char RpcVersionMinor)
 {
@@ -237,17 +239,17 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation,
   return header;
 }
 
-RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation,
+RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation,
                                      unsigned short MaxTransmissionSize,
                                      unsigned short MaxReceiveSize,
-                                     ULONG AssocGroupId,
+                                     unsigned long AssocGroupId,
                                      LPCSTR ServerAddress,
-                                     unsigned short Result,
-                                     unsigned short Reason,
+                                     unsigned long Result,
+                                     unsigned long Reason,
                                      const RPC_SYNTAX_IDENTIFIER *TransferId)
 {
   RpcPktHdr *header;
-  ULONG header_size;
+  unsigned long header_size;
   RpcAddressString *server_address;
   RpcResults *results;
   RPC_SYNTAX_IDENTIFIER *transfer_id;
@@ -281,118 +283,6 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation,
   return header;
 }
 
-RpcPktHdr *RPCRT4_BuildHttpHeader(ULONG DataRepresentation,
-                                  unsigned short flags,
-                                  unsigned short num_data_items,
-                                  unsigned int payload_size)
-{
-  RpcPktHdr *header;
-
-  header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->http) + payload_size);
-  if (header == NULL) {
-      ERR("failed to allocate memory\n");
-    return NULL;
-  }
-
-  RPCRT4_BuildCommonHeader(header, PKT_HTTP, DataRepresentation);
-  /* since the packet isn't current sent using RPCRT4_Send, set the flags
-   * manually here */
-  header->common.flags = RPC_FLG_FIRST|RPC_FLG_LAST;
-  header->common.call_id = 0;
-  header->common.frag_len = sizeof(header->http) + payload_size;
-  header->http.flags = flags;
-  header->http.num_data_items = num_data_items;
-
-  return header;
-}
-
-#define WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, type, value) \
-    do { \
-        *(unsigned int *)(payload) = (type); \
-        (payload) += 4; \
-        *(unsigned int *)(payload) = (value); \
-        (payload) += 4; \
-    } while (0)
-
-#define WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, type, uuid) \
-    do { \
-        *(unsigned int *)(payload) = (type); \
-        (payload) += 4; \
-        *(UUID *)(payload) = (uuid); \
-        (payload) += sizeof(UUID); \
-    } while (0)
-
-#define WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted, flow_control_increment, uuid) \
-    do { \
-        *(unsigned int *)(payload) = 0x00000001; \
-        (payload) += 4; \
-        *(unsigned int *)(payload) = (bytes_transmitted); \
-        (payload) += 4; \
-        *(unsigned int *)(payload) = (flow_control_increment); \
-        (payload) += 4; \
-        *(UUID *)(payload) = (uuid); \
-        (payload) += sizeof(UUID); \
-    } while (0)
-
-RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe,
-                                         const UUID *connection_uuid,
-                                         const UUID *pipe_uuid,
-                                         const UUID *association_uuid)
-{
-  RpcPktHdr *header;
-  unsigned int size;
-  char *payload;
-
-  size = 8 + 4 + sizeof(UUID) + 4 + sizeof(UUID) + 8;
-  if (!out_pipe)
-    size += 8 + 4 + sizeof(UUID);
-
-  header = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, flags,
-                                  out_pipe ? 4 : 6, size);
-  if (!header) return NULL;
-  payload = (char *)(&header->http+1);
-
-  /* FIXME: what does this part of the payload do? */
-  WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000006, 0x00000001);
-
-  WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *connection_uuid);
-  WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *pipe_uuid);
-
-  if (out_pipe)
-    /* FIXME: what does this part of the payload do? */
-    WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000000, 0x00010000);
-  else
-  {
-    /* FIXME: what does this part of the payload do? */
-    WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000004, 0x40000000);
-    /* FIXME: what does this part of the payload do? */
-    WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000005, 0x000493e0);
-
-    WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x0000000c, *association_uuid);
-  }
-
-  return header;
-}
-
-RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted,
-                                             ULONG flow_control_increment,
-                                             const UUID *pipe_uuid)
-{
-  RpcPktHdr *header;
-  char *payload;
-
-  header = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, 0x2, 2,
-                                  5 * sizeof(ULONG) + sizeof(UUID));
-  if (!header) return NULL;
-  payload = (char *)(&header->http+1);
-
-  WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x0000000d, (server ? 0x0 : 0x3));
-
-  WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted,
-                                        flow_control_increment, *pipe_uuid);
-  return header;
-}
-
 VOID RPCRT4_FreeHeader(RpcPktHdr *Header)
 {
   HeapFree(GetProcessHeap(), 0, Header);
@@ -472,206 +362,6 @@ static RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status)
     }
 }
 
-/* assumes the common header fields have already been validated */
-BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data,
-                              unsigned short data_len)
-{
-  unsigned short i;
-  BYTE *p = data;
-
-  for (i = 0; i < hdr->http.num_data_items; i++)
-  {
-    ULONG type;
-
-    if (data_len < sizeof(ULONG))
-      return FALSE;
-
-    type = *(ULONG *)p;
-    p += sizeof(ULONG);
-    data_len -= sizeof(ULONG);
-
-    switch (type)
-    {
-      case 0x3:
-      case 0xc:
-        if (data_len < sizeof(GUID))
-          return FALSE;
-        p += sizeof(GUID);
-        data_len -= sizeof(GUID);
-        break;
-      case 0x0:
-      case 0x2:
-      case 0x4:
-      case 0x5:
-      case 0x6:
-      case 0xd:
-        if (data_len < sizeof(ULONG))
-          return FALSE;
-        p += sizeof(ULONG);
-        data_len -= sizeof(ULONG);
-        break;
-      case 0x1:
-        if (data_len < 24)
-          return FALSE;
-        p += 24;
-        data_len -= 24;
-        break;
-      default:
-        FIXME("unimplemented type 0x%x\n", type);
-        break;
-    }
-  }
-  return TRUE;
-}
-
-/* assumes the HTTP packet has been validated */
-static unsigned char *RPCRT4_NextHttpHeaderField(unsigned char *data)
-{
-  ULONG type;
-
-  type = *(ULONG *)data;
-  data += sizeof(ULONG);
-
-  switch (type)
-  {
-    case 0x3:
-    case 0xc:
-      return data + sizeof(GUID);
-    case 0x0:
-    case 0x2:
-    case 0x4:
-    case 0x5:
-    case 0x6:
-    case 0xd:
-      return data + sizeof(ULONG);
-    case 0x1:
-      return data + 24;
-    default:
-      FIXME("unimplemented type 0x%x\n", type);
-      return data;
-  }
-}
-
-#define READ_HTTP_PAYLOAD_FIELD_TYPE(data) *(ULONG *)(data)
-#define GET_HTTP_PAYLOAD_FIELD_DATA(data) ((data) + sizeof(ULONG))
-
-/* assumes the HTTP packet has been validated */
-RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header,
-                                          unsigned char *data, ULONG *field1)
-{
-  ULONG type;
-  if (header->http.flags != 0x0)
-  {
-    ERR("invalid flags 0x%x\n", header->http.flags);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  if (header->http.num_data_items != 1)
-  {
-    ERR("invalid number of data items %d\n", header->http.num_data_items);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
-  if (type != 0x00000002)
-  {
-    ERR("invalid type 0x%08x\n", type);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  *field1 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
-  return RPC_S_OK;
-}
-
-/* assumes the HTTP packet has been validated */
-RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header,
-                                          unsigned char *data, ULONG *field1,
-                                          ULONG *bytes_until_next_packet,
-                                          ULONG *field3)
-{
-  ULONG type;
-  if (header->http.flags != 0x0)
-  {
-    ERR("invalid flags 0x%x\n", header->http.flags);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  if (header->http.num_data_items != 3)
-  {
-    ERR("invalid number of data items %d\n", header->http.num_data_items);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-
-  type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
-  if (type != 0x00000006)
-  {
-    ERR("invalid type for field 1: 0x%08x\n", type);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  *field1 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
-  data = RPCRT4_NextHttpHeaderField(data);
-
-  type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
-  if (type != 0x00000000)
-  {
-    ERR("invalid type for field 2: 0x%08x\n", type);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  *bytes_until_next_packet = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
-  data = RPCRT4_NextHttpHeaderField(data);
-
-  type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
-  if (type != 0x00000002)
-  {
-    ERR("invalid type for field 3: 0x%08x\n", type);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  *field3 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
-
-  return RPC_S_OK;
-}
-
-RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header,
-                                             unsigned char *data, BOOL server,
-                                             ULONG *bytes_transmitted,
-                                             ULONG *flow_control_increment,
-                                             UUID *pipe_uuid)
-{
-  ULONG type;
-  if (header->http.flags != 0x2)
-  {
-    ERR("invalid flags 0x%x\n", header->http.flags);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  if (header->http.num_data_items != 2)
-  {
-    ERR("invalid number of data items %d\n", header->http.num_data_items);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-
-  type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
-  if (type != 0x0000000d)
-  {
-    ERR("invalid type for field 1: 0x%08x\n", type);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  if (*(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data) != (server ? 0x3 : 0x0))
-  {
-    ERR("invalid type for 0xd field data: 0x%08x\n", *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data));
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  data = RPCRT4_NextHttpHeaderField(data);
-
-  type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
-  if (type != 0x00000001)
-  {
-    ERR("invalid type for field 2: 0x%08x\n", type);
-    return RPC_S_PROTOCOL_ERROR;
-  }
-  *bytes_transmitted = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
-  *flow_control_increment = *(ULONG *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 4);
-  *pipe_uuid = *(UUID *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 8);
-
-  return RPC_S_OK;
-}
-
-
 static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection,
     enum secure_packet_direction dir,
     RpcPktHdr *hdr, unsigned int hdr_size,
@@ -819,7 +509,7 @@ static RPC_STATUS RPCRT4_SendWithAuth(RpcConnection *Connection, RpcPktHdr *Head
       auth_hdr->auth_pad_length = auth_pad_len;
       auth_hdr->auth_reserved = 0;
       /* a unique number... */
-      auth_hdr->auth_context_id = Connection->auth_context_id;
+      auth_hdr->auth_context_id = (unsigned long)Connection;
 
       if (AuthLength)
         memcpy(auth_hdr + 1, Auth, AuthLength);
@@ -997,7 +687,7 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
 }
 
 /* validates version and frag_len fields */
-RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr)
+static RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr)
 {
   DWORD hdr_length;
 
@@ -1026,11 +716,11 @@ RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr)
 }
 
 /***********************************************************************
- *           RPCRT4_default_receive_fragment (internal)
+ *           RPCRT4_receive_fragment (internal)
  * 
  * Receive a fragment from a connection.
  */
-static RPC_STATUS RPCRT4_default_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload)
+static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload)
 {
   RPC_STATUS status;
   DWORD hdr_length;
@@ -1104,14 +794,6 @@ fail:
   return status;
 }
 
-static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload)
-{
-    if (Connection->ops->receive_fragment)
-        return Connection->ops->receive_fragment(Connection, Header, Payload);
-    else
-        return RPCRT4_default_receive_fragment(Connection, Header, Payload);
-}
-
 /***********************************************************************
  *           RPCRT4_ReceiveWithAuth (internal)
  *
@@ -1121,14 +803,14 @@ static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr *
 RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header,
                                   PRPC_MESSAGE pMsg,
                                   unsigned char **auth_data_out,
-                                  ULONG *auth_length_out)
+                                  unsigned long *auth_length_out)
 {
   RPC_STATUS status;
   DWORD hdr_length;
   unsigned short first_flag;
-  ULONG data_length;
-  ULONG buffer_length;
-  ULONG auth_length = 0;
+  unsigned long data_length;
+  unsigned long buffer_length;
+  unsigned long auth_length = 0;
   unsigned char *auth_data = NULL;
   RpcPktHdr *CurrentHeader = NULL;
   void *payload = NULL;
@@ -1192,7 +874,7 @@ RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header,
     }
 
     if (CurrentHeader->common.auth_len != auth_length) {
-      WARN("auth_len header field changed from %d to %d\n",
+      WARN("auth_len header field changed from %ld to %d\n",
         auth_length, CurrentHeader->common.auth_len);
       status = RPC_S_PROTOCOL_ERROR;
       goto fail;
@@ -1206,7 +888,7 @@ RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header,
 
     data_length = CurrentHeader->common.frag_len - hdr_length - header_auth_len;
     if (data_length + buffer_length > pMsg->BufferLength) {
-      TRACE("allocation hint exceeded, new buffer length = %d\n",
+      TRACE("allocation hint exceeded, new buffer length = %ld\n",
         data_length + buffer_length);
       pMsg->BufferLength = data_length + buffer_length;
       status = I_RpcReAllocateBuffer(pMsg);
@@ -1316,7 +998,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
  */
 RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg)
 {
-  RpcBinding* bind = pMsg->Handle;
+  RpcBinding* bind = (RpcBinding*)pMsg->Handle;
   RpcConnection* conn;
   RPC_STATUS status = RPC_S_OK;
 
@@ -1381,7 +1063,7 @@ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg)
 RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
 {
   RPC_STATUS status;
-  RpcBinding* bind = pMsg->Handle;
+  RpcBinding* bind = (RpcBinding*)pMsg->Handle;
 
   TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
 
@@ -1438,7 +1120,7 @@ static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg)
  */
 RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
 {
-  RpcBinding* bind = pMsg->Handle;
+  RpcBinding* bind = (RpcBinding*)pMsg->Handle;
 
   TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer);
 
@@ -1532,7 +1214,7 @@ static DWORD WINAPI async_notifier_proc(LPVOID p)
  */
 RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
 {
-  RpcBinding* bind = pMsg->Handle;
+  RpcBinding* bind = (RpcBinding*)pMsg->Handle;
   RpcConnection* conn;
   RPC_STATUS status;
   RpcPktHdr *hdr;
@@ -1586,7 +1268,7 @@ static inline BOOL is_hard_error(RPC_STATUS status)
  */
 RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
 {
-  RpcBinding* bind = pMsg->Handle;
+  RpcBinding* bind = (RpcBinding*)pMsg->Handle;
   RPC_STATUS status;
   RpcPktHdr *hdr = NULL;
   RpcConnection *conn;
@@ -1605,7 +1287,7 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
   case PKT_RESPONSE:
     break;
   case PKT_FAULT:
-    ERR ("we got fault packet with status 0x%x\n", hdr->fault.status);
+    ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status);
     status = NCA2RPC_STATUS(hdr->fault.status);
     if (is_hard_error(status))
         goto fail;
@@ -1678,7 +1360,7 @@ RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg)
  */
 RPC_STATUS WINAPI I_RpcAsyncSetHandle(PRPC_MESSAGE pMsg, PRPC_ASYNC_STATE pAsync)
 {
-    RpcBinding* bind = pMsg->Handle;
+    RpcBinding* bind = (RpcBinding*)pMsg->Handle;
     RpcConnection *conn;
 
     TRACE("(%p, %p)\n", pMsg, pAsync);
index aeeef07..e403388 100644 (file)
 
 typedef unsigned int NCA_STATUS;
 
-RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status);
-RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength);
-RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId);
-RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor);
-RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, LPCSTR ServerAddress, unsigned short Result, unsigned short Reason, const RPC_SYNTAX_IDENTIFIER *TransferId);
-RpcPktHdr *RPCRT4_BuildHttpHeader(ULONG DataRepresentation, unsigned short flags, unsigned short num_data_items, unsigned int payload_size);
-RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe, const UUID *connection_uuid, const UUID *pipe_uuid, const UUID *association_uuid);
-RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted, ULONG flow_control_increment, const UUID *pipe_uuid);
+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, unsigned long AssocGroupId, LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId);
 VOID RPCRT4_FreeHeader(RpcPktHdr *Header);
 RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength);
 RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg);
-RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, ULONG *auth_length_out);
-DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header);
-RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr);
-
-BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, unsigned short data_len);
-RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, unsigned char *data, ULONG *field1);
-RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, unsigned char *data, ULONG *field1, ULONG *bytes_until_next_packet, ULONG *field3);
-RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, unsigned char *data, BOOL server, ULONG *bytes_transmitted, ULONG *flow_control_increment, UUID *pipe_uuid);
+RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, unsigned long *auth_length_out);
 NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status);
 RPC_STATUS RPCRT4_AuthorizeConnection(RpcConnection* conn, BYTE *challenge, ULONG count);
 
index 3400639..473c7ba 100644 (file)
@@ -367,7 +367,7 @@ static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg)
 
 static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
 {
-  RpcConnection* conn = the_arg;
+  RpcConnection* conn = (RpcConnection*)the_arg;
   RpcPktHdr *hdr;
   RPC_MESSAGE *msg;
   RPC_STATUS status;
@@ -449,23 +449,27 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
 
     /* start waiting */
     res = cps->ops->wait_for_new_connection(cps, count, objs);
-
-    if (res == -1 || (res == 0 && !std_listen))
-    {
-      /* cleanup */
-      cps->ops->free_wait_array(cps, objs);
-      EnterCriticalSection(&cps->cs);
-      for (conn = cps->conn; conn; conn = conn->Next)
-        RPCRT4_CloseConnection(conn);
-      LeaveCriticalSection(&cps->cs);
-
-      if (res == 0 && !std_listen)
-        SetEvent(cps->server_ready_event);
+    if (res == -1)
       break;
-    }
     else if (res == 0)
+    {
+      if (!std_listen)
+      {
+        SetEvent(cps->server_ready_event);
+        break;
+      }
       set_ready_event = TRUE;
+    }
   }
+  cps->ops->free_wait_array(cps, objs);
+  EnterCriticalSection(&cps->cs);
+  /* close connections */
+  conn = cps->conn;
+  while (conn) {
+    RPCRT4_CloseConnection(conn);
+    conn = conn->Next;
+  }
+  LeaveCriticalSection(&cps->cs);
   return 0;
 }
 
@@ -566,32 +570,11 @@ static void RPCRT4_stop_listen(BOOL auto_listen)
   LeaveCriticalSection(&listen_cs);
 }
 
-static BOOL RPCRT4_protseq_is_endpoint_registered(RpcServerProtseq *protseq, const char *endpoint)
-{
-  RpcConnection *conn;
-  EnterCriticalSection(&protseq->cs);
-  for (conn = protseq->conn; conn; conn = conn->Next)
-  {
-    if (!endpoint || !strcmp(endpoint, conn->Endpoint))
-      break;
-  }
-  LeaveCriticalSection(&protseq->cs);
-  return (conn != NULL);
-}
-
-static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, const char *endpoint)
+static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, LPSTR endpoint)
 {
   RPC_STATUS status;
 
-  EnterCriticalSection(&ps->cs);
-
-  if (RPCRT4_protseq_is_endpoint_registered(ps, endpoint))
-    status = RPC_S_OK;
-  else
-    status = ps->ops->open_endpoint(ps, endpoint);
-
-  LeaveCriticalSection(&ps->cs);
-
+  status = ps->ops->open_endpoint(ps, endpoint);
   if (status != RPC_S_OK)
     return status;
 
@@ -625,8 +608,11 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
   count = 0;
   LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
     EnterCriticalSection(&ps->cs);
-    for (conn = ps->conn; conn; conn = conn->Next)
+    conn = ps->conn;
+    while (conn) {
       count++;
+      conn = conn->Next;
+    }
     LeaveCriticalSection(&ps->cs);
   }
   if (count) {
@@ -638,10 +624,12 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
     count = 0;
     LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
       EnterCriticalSection(&ps->cs);
-      for (conn = ps->conn; conn; conn = conn->Next) {
+      conn = ps->conn;
+      while (conn) {
        RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count],
                           conn);
        count++;
+       conn = conn->Next;
       }
       LeaveCriticalSection(&ps->cs);
     }
@@ -693,7 +681,7 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_W
  *
  * Must be called with server_cs held.
  */
-static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps)
+static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps)
 {
   const struct protseq_ops *ops = rpcrt4_get_protseq_ops(Protseq);
 
@@ -707,7 +695,7 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcSe
   if (!*ps)
     return RPC_S_OUT_OF_RESOURCES;
   (*ps)->MaxCalls = MaxCalls;
-  (*ps)->Protseq = RPCRT4_strdupA(Protseq);
+  (*ps)->Protseq = Protseq;
   (*ps)->ops = ops;
   (*ps)->MaxCalls = 0;
   (*ps)->conn = NULL;
@@ -723,19 +711,8 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcSe
   return RPC_S_OK;
 }
 
-/* must be called with server_cs held */
-static void destroy_serverprotoseq(RpcServerProtseq *ps)
-{
-    RPCRT4_strfree(ps->Protseq);
-    DeleteCriticalSection(&ps->cs);
-    CloseHandle(ps->mgr_mutex);
-    CloseHandle(ps->server_ready_event);
-    list_remove(&ps->entry);
-    HeapFree(GetProcessHeap(), 0, ps);
-}
-
 /* Finds a given protseq or creates a new one if one doesn't already exist */
-static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps)
+static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps)
 {
     RPC_STATUS status;
     RpcServerProtseq *cps;
@@ -764,18 +741,19 @@ static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, const char *
 RPC_STATUS WINAPI RpcServerUseProtseqEpExA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor,
                                             PRPC_POLICY lpPolicy )
 {
+  char *szps = (char*)Protseq, *szep = (char*)Endpoint;
   RpcServerProtseq* ps;
   RPC_STATUS status;
 
-  TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a((const char *)Protseq),
-       MaxCalls, debugstr_a((const char *)Endpoint), SecurityDescriptor,
+  TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a(szps), MaxCalls,
+       debugstr_a(szep), SecurityDescriptor,
        lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
 
-  status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps);
+  status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupA(szps), &ps);
   if (status != RPC_S_OK)
     return status;
 
-  return RPCRT4_use_protseq(ps, (const char *)Endpoint);
+  return RPCRT4_use_protseq(ps, szep);
 }
 
 /***********************************************************************
@@ -786,16 +764,13 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC
 {
   RpcServerProtseq* ps;
   RPC_STATUS status;
-  LPSTR ProtseqA;
   LPSTR EndpointA;
 
   TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_w( Protseq ), MaxCalls,
        debugstr_w( Endpoint ), SecurityDescriptor,
        lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
 
-  ProtseqA = RPCRT4_strdupWtoA(Protseq);
-  status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps);
-  RPCRT4_strfree(ProtseqA);
+  status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps);
   if (status != RPC_S_OK)
     return status;
 
@@ -810,16 +785,8 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC
  */
 RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
 {
-  RPC_STATUS status;
-  RpcServerProtseq* ps;
-
   TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_a((char*)Protseq), MaxCalls, SecurityDescriptor);
-
-  status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps);
-  if (status != RPC_S_OK)
-    return status;
-
-  return RPCRT4_use_protseq(ps, NULL);
+  return RpcServerUseProtseqEpA(Protseq, MaxCalls, NULL, SecurityDescriptor);
 }
 
 /***********************************************************************
@@ -827,36 +794,8 @@ RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls,
  */
 RPC_STATUS WINAPI RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
 {
-  RPC_STATUS status;
-  RpcServerProtseq* ps;
-  LPSTR ProtseqA;
-
   TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_w(Protseq), MaxCalls, SecurityDescriptor);
-
-  ProtseqA = RPCRT4_strdupWtoA(Protseq);
-  status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps);
-  RPCRT4_strfree(ProtseqA);
-  if (status != RPC_S_OK)
-    return status;
-
-  return RPCRT4_use_protseq(ps, NULL);
-}
-
-void RPCRT4_destroy_all_protseqs(void)
-{
-    RpcServerProtseq *cps, *cursor2;
-
-    if (listen_count != 0)
-        std_listen = FALSE;
-
-    EnterCriticalSection(&server_cs);
-    LIST_FOR_EACH_ENTRY_SAFE(cps, cursor2, &protseqs, RpcServerProtseq, entry)
-    {
-        if (listen_count != 0)
-            RPCRT4_sync_with_server_thread(cps);
-        destroy_serverprotoseq(cps);
-    }
-    LeaveCriticalSection(&server_cs);
+  return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor);
 }
 
 /***********************************************************************
@@ -884,7 +823,7 @@ RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid
 RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
                       UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn )
 {
-  PRPC_SERVER_INTERFACE If = IfSpec;
+  PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
   RpcServerInterface* sif;
   unsigned int i;
 
@@ -937,7 +876,7 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid,
  */
 RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete )
 {
-  PRPC_SERVER_INTERFACE If = IfSpec;
+  PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
   HANDLE event = NULL;
   BOOL found = FALSE;
   BOOL completed = TRUE;
index cacce79..ffd5b01 100644 (file)
@@ -56,7 +56,7 @@ struct protseq_ops
      * new connection was established */
     int (*wait_for_new_connection)(RpcServerProtseq *protseq, unsigned int count, void *wait_array);
     /* opens the endpoint and optionally begins listening */
-    RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, const char *endpoint);
+    RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, LPSTR endpoint);
 };
 
 typedef struct _RpcServerInterface
@@ -79,6 +79,4 @@ typedef struct _RpcServerInterface
 void RPCRT4_new_client(RpcConnection* conn);
 const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq);
 
-void RPCRT4_destroy_all_protseqs(void);
-
 #endif  /* __WINE_RPC_SERVER_H */
index dddc513..735a19d 100644 (file)
@@ -40,8 +40,6 @@
 # ifndef EAGAIN
 #  define EAGAIN WSAEWOULDBLOCK
 # endif
-# undef errno
-# define errno WSAGetLastError()
 #else
 # include <errno.h>
 # ifdef HAVE_UNISTD_H
 # ifdef HAVE_SYS_POLL_H
 #  include <sys/poll.h>
 # endif
-# ifdef HAVE_SYS_FILIO_H
-#  include <sys/filio.h>
-# endif
-# ifdef HAVE_SYS_IOCTL_H
-#  include <sys/ioctl.h>
-# endif
 # define closesocket close
-# define ioctlsocket ioctl
 #endif /* defined(__MINGW32__) || defined (_MSC_VER) */
 
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
 #include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
 #include "winerror.h"
-#include "wininet.h"
 #include "winternl.h"
 #include "wine/unicode.h"
 
 #include "wine/debug.h"
 
 #include "rpc_binding.h"
-#include "rpc_assoc.h"
 #include "rpc_message.h"
 #include "rpc_server.h"
 #include "epm_towers.h"
 
+#include "unix_func.h"
+
 #ifndef SOL_TCP
 # define SOL_TCP IPPROTO_TCP
 #endif
 
-#define DEFAULT_NCACN_HTTP_TIMEOUT (60 * 1000)
-
 WINE_DEFAULT_DEBUG_CHANNEL(rpc);
 
 static RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection);
@@ -266,23 +258,12 @@ static RPC_STATUS rpcrt4_ncalrpc_open(RpcConnection* Connection)
   return r;
 }
 
-static RPC_STATUS rpcrt4_protseq_ncalrpc_open_endpoint(RpcServerProtseq* protseq, const char *endpoint)
+static RPC_STATUS rpcrt4_protseq_ncalrpc_open_endpoint(RpcServerProtseq* protseq, LPSTR endpoint)
 {
   static const char prefix[] = "\\\\.\\pipe\\lrpc\\";
   RPC_STATUS r;
   LPSTR pname;
   RpcConnection *Connection;
-  char generated_endpoint[22];
-
-  if (!endpoint)
-  {
-    static LONG lrpc_nameless_id;
-    DWORD process_id = GetCurrentProcessId();
-    ULONG id = InterlockedIncrement(&lrpc_nameless_id);
-    snprintf(generated_endpoint, sizeof(generated_endpoint),
-             "LRPC%08x.%08x", process_id, id);
-    endpoint = generated_endpoint;
-  }
 
   r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL,
                               endpoint, NULL, NULL, NULL);
@@ -324,23 +305,12 @@ static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection)
   return r;
 }
 
-static RPC_STATUS rpcrt4_protseq_ncacn_np_open_endpoint(RpcServerProtseq *protseq, const char *endpoint)
+static RPC_STATUS rpcrt4_protseq_ncacn_np_open_endpoint(RpcServerProtseq *protseq, LPSTR endpoint)
 {
   static const char prefix[] = "\\\\.";
   RPC_STATUS r;
   LPSTR pname;
   RpcConnection *Connection;
-  char generated_endpoint[21];
-
-  if (!endpoint)
-  {
-    static LONG np_nameless_id;
-    DWORD process_id = GetCurrentProcessId();
-    ULONG id = InterlockedExchangeAdd(&np_nameless_id, 1 );
-    snprintf(generated_endpoint, sizeof(generated_endpoint),
-             "\\\\pipe\\\\%08x.%03x", process_id, id);
-    endpoint = generated_endpoint;
-  }
 
   r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL,
                               endpoint, NULL, NULL, NULL);
@@ -370,7 +340,7 @@ static void rpcrt4_conn_np_handoff(RpcConnection_np *old_npc, RpcConnection_np *
   new_npc->ovl[0] = old_npc->ovl[0];
   new_npc->ovl[1] = old_npc->ovl[1];
   old_npc->pipe = 0;
-  memset(&old_npc->ovl[0], 0, sizeof(old_npc->ovl));
+  memset(&old_npc->ovl, 0, sizeof(old_npc->ovl));
   old_npc->listening = FALSE;
 }
 
@@ -422,11 +392,11 @@ static int rpcrt4_conn_np_read(RpcConnection *Connection,
     ret = ReadFile(npc->pipe, buf, bytes_left, &bytes_read, &npc->ovl[0]);
     if ((!ret || !bytes_read) && (GetLastError() != ERROR_IO_PENDING))
         break;
+
     ret = GetOverlappedResult(npc->pipe, &npc->ovl[0], &bytes_read, TRUE);
-    if (!ret && GetLastError() == ERROR_MORE_DATA)
-        ret = TRUE;
-    if (!ret || !bytes_read)
+    if (!ret && (GetLastError() != ERROR_MORE_DATA))
         break;
+
     bytes_left -= bytes_read;
     buf += bytes_read;
   }
@@ -447,11 +417,11 @@ static int rpcrt4_conn_np_write(RpcConnection *Connection,
     ret = WriteFile(npc->pipe, buf, bytes_left, &bytes_written, &npc->ovl[1]);
     if ((!ret || !bytes_written) && (GetLastError() != ERROR_IO_PENDING))
         break;
+
     ret = GetOverlappedResult(npc->pipe, &npc->ovl[1], &bytes_written, TRUE);
-    if (!ret && GetLastError() == ERROR_MORE_DATA)
-        ret = TRUE;
-    if (!ret || !bytes_written)
+    if (!ret && (GetLastError() != ERROR_MORE_DATA))
         break;
+
     bytes_left -= bytes_written;
     buf += bytes_written;
   }
@@ -786,294 +756,15 @@ static RPC_STATUS rpcrt4_ncalrpc_parse_top_of_tower(const unsigned char *tower_d
 
 /**** ncacn_ip_tcp support ****/
 
-static size_t rpcrt4_ip_tcp_get_top_of_tower(unsigned char *tower_data,
-                                             const char *networkaddr,
-                                             unsigned char tcp_protid,
-                                             const char *endpoint)
-{
-    twr_tcp_floor_t *tcp_floor;
-    twr_ipv4_floor_t *ipv4_floor;
-    struct addrinfo *ai;
-    struct addrinfo hints;
-    int ret;
-    size_t size = sizeof(*tcp_floor) + sizeof(*ipv4_floor);
-
-    TRACE("(%p, %s, %s)\n", tower_data, networkaddr, endpoint);
-
-    if (!tower_data)
-        return size;
-
-    tcp_floor = (twr_tcp_floor_t *)tower_data;
-    tower_data += sizeof(*tcp_floor);
-
-    ipv4_floor = (twr_ipv4_floor_t *)tower_data;
-
-    tcp_floor->count_lhs = sizeof(tcp_floor->protid);
-    tcp_floor->protid = tcp_protid;
-    tcp_floor->count_rhs = sizeof(tcp_floor->port);
-
-    ipv4_floor->count_lhs = sizeof(ipv4_floor->protid);
-    ipv4_floor->protid = EPM_PROTOCOL_IP;
-    ipv4_floor->count_rhs = sizeof(ipv4_floor->ipv4addr);
-
-    hints.ai_flags          = AI_NUMERICHOST;
-    /* FIXME: only support IPv4 at the moment. how is IPv6 represented by the EPM? */
-    hints.ai_family         = PF_INET;
-    hints.ai_socktype       = SOCK_STREAM;
-    hints.ai_protocol       = IPPROTO_TCP;
-    hints.ai_addrlen        = 0;
-    hints.ai_addr           = NULL;
-    hints.ai_canonname      = NULL;
-    hints.ai_next           = NULL;
-
-    ret = getaddrinfo(networkaddr, endpoint, &hints, &ai);
-    if (ret)
-    {
-        ret = getaddrinfo("0.0.0.0", endpoint, &hints, &ai);
-        if (ret)
-        {
-            ERR("getaddrinfo failed: %s\n", gai_strerror(ret));
-            return 0;
-        }
-    }
-
-    if (ai->ai_family == PF_INET)
-    {
-        const struct sockaddr_in *sin = (const struct sockaddr_in *)ai->ai_addr;
-        tcp_floor->port = sin->sin_port;
-        ipv4_floor->ipv4addr = sin->sin_addr.s_addr;
-    }
-    else
-    {
-        ERR("unexpected protocol family %d\n", ai->ai_family);
-        return 0;
-    }
-
-    freeaddrinfo(ai);
-
-    return size;
-}
-
-static RPC_STATUS rpcrt4_ip_tcp_parse_top_of_tower(const unsigned char *tower_data,
-                                                   size_t tower_size,
-                                                   char **networkaddr,
-                                                   unsigned char tcp_protid,
-                                                   char **endpoint)
-{
-    const twr_tcp_floor_t *tcp_floor = (const twr_tcp_floor_t *)tower_data;
-    const twr_ipv4_floor_t *ipv4_floor;
-    struct in_addr in_addr;
-
-    TRACE("(%p, %d, %p, %p)\n", tower_data, (int)tower_size, networkaddr, endpoint);
-
-    if (tower_size < sizeof(*tcp_floor))
-        return EPT_S_NOT_REGISTERED;
-
-    tower_data += sizeof(*tcp_floor);
-    tower_size -= sizeof(*tcp_floor);
-
-    if (tower_size < sizeof(*ipv4_floor))
-        return EPT_S_NOT_REGISTERED;
-
-    ipv4_floor = (const twr_ipv4_floor_t *)tower_data;
-
-    if ((tcp_floor->count_lhs != sizeof(tcp_floor->protid)) ||
-        (tcp_floor->protid != tcp_protid) ||
-        (tcp_floor->count_rhs != sizeof(tcp_floor->port)) ||
-        (ipv4_floor->count_lhs != sizeof(ipv4_floor->protid)) ||
-        (ipv4_floor->protid != EPM_PROTOCOL_IP) ||
-        (ipv4_floor->count_rhs != sizeof(ipv4_floor->ipv4addr)))
-        return EPT_S_NOT_REGISTERED;
-
-    if (endpoint)
-    {
-        *endpoint = I_RpcAllocate(6 /* sizeof("65535") + 1 */);
-        if (!*endpoint)
-            return RPC_S_OUT_OF_RESOURCES;
-        sprintf(*endpoint, "%u", ntohs(tcp_floor->port));
-    }
-
-    if (networkaddr)
-    {
-        *networkaddr = I_RpcAllocate(INET_ADDRSTRLEN);
-        if (!*networkaddr)
-        {
-            if (endpoint)
-            {
-                I_RpcFree(*endpoint);
-                *endpoint = NULL;
-            }
-            return RPC_S_OUT_OF_RESOURCES;
-        }
-        in_addr.s_addr = ipv4_floor->ipv4addr;
-        if (!inet_ntop(AF_INET, &in_addr, *networkaddr, INET_ADDRSTRLEN))
-        {
-            ERR("inet_ntop: %s\n", strerror(errno));
-            I_RpcFree(*networkaddr);
-            *networkaddr = NULL;
-            if (endpoint)
-            {
-                I_RpcFree(*endpoint);
-                *endpoint = NULL;
-            }
-            return EPT_S_NOT_REGISTERED;
-        }
-    }
-
-    return RPC_S_OK;
-}
+#ifdef HAVE_SOCKETPAIR
 
 typedef struct _RpcConnection_tcp
 {
   RpcConnection common;
   int sock;
-#ifdef HAVE_SOCKETPAIR
   int cancel_fds[2];
-#else
-  HANDLE sock_event;
-  HANDLE cancel_event;
-#endif
 } RpcConnection_tcp;
 
-#ifdef HAVE_SOCKETPAIR
-
-static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc)
-{
-  if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0)
-  {
-    ERR("socketpair() failed: %s\n", strerror(errno));
-    return FALSE;
-  }
-  return TRUE;
-}
-
-static BOOL rpcrt4_sock_wait_for_recv(RpcConnection_tcp *tcpc)
-{
-  struct pollfd pfds[2];
-  pfds[0].fd = tcpc->sock;
-  pfds[0].events = POLLIN;
-  pfds[1].fd = tcpc->cancel_fds[0];
-  pfds[1].events = POLLIN;
-  if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR)
-  {
-    ERR("poll() failed: %s\n", strerror(errno));
-    return FALSE;
-  }
-  if (pfds[1].revents & POLLIN) /* canceled */
-  {
-    char dummy;
-    read(pfds[1].fd, &dummy, sizeof(dummy));
-    return FALSE;
-  }
-  return TRUE;
-}
-
-static BOOL rpcrt4_sock_wait_for_send(RpcConnection_tcp *tcpc)
-{
-  struct pollfd pfd;
-  pfd.fd = tcpc->sock;
-  pfd.events = POLLOUT;
-  if (poll(&pfd, 1, -1 /* infinite */) == -1 && errno != EINTR)
-  {
-    ERR("poll() failed: %s\n", strerror(errno));
-    return FALSE;
-  }
-  return TRUE;
-}
-
-static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc)
-{
-  char dummy = 1;
-
-  write(tcpc->cancel_fds[1], &dummy, 1);
-}
-
-static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc)
-{
-  close(tcpc->cancel_fds[0]);
-  close(tcpc->cancel_fds[1]);
-}
-
-#else /* HAVE_SOCKETPAIR */
-
-static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc)
-{
-  static BOOL wsa_inited;
-  if (!wsa_inited)
-  {
-    WSADATA wsadata;
-    WSAStartup(MAKEWORD(2, 2), &wsadata);
-    /* Note: WSAStartup can be called more than once so we don't bother with
-     * making accesses to wsa_inited thread-safe */
-    wsa_inited = TRUE;
-  }
-  tcpc->sock_event = CreateEventW(NULL, FALSE, FALSE, NULL);
-  tcpc->cancel_event = CreateEventW(NULL, FALSE, FALSE, NULL);
-  if (!tcpc->sock_event || !tcpc->cancel_event)
-  {
-    ERR("event creation failed\n");
-    if (tcpc->sock_event) CloseHandle(tcpc->sock_event);
-    return FALSE;
-  }
-  return TRUE;
-}
-
-static BOOL rpcrt4_sock_wait_for_recv(RpcConnection_tcp *tcpc)
-{
-  HANDLE wait_handles[2];
-  DWORD res;
-  if (WSAEventSelect(tcpc->sock, tcpc->sock_event, FD_READ | FD_CLOSE) == SOCKET_ERROR)
-  {
-    ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError());
-    return FALSE;
-  }
-  wait_handles[0] = tcpc->sock_event;
-  wait_handles[1] = tcpc->cancel_event;
-  res = WaitForMultipleObjects(2, wait_handles, FALSE, INFINITE);
-  switch (res)
-  {
-  case WAIT_OBJECT_0:
-    return TRUE;
-  case WAIT_OBJECT_0 + 1:
-    return FALSE;
-  default:
-    ERR("WaitForMultipleObjects() failed with error %d\n", GetLastError());
-    return FALSE;
-  }
-}
-
-static BOOL rpcrt4_sock_wait_for_send(RpcConnection_tcp *tcpc)
-{
-  DWORD res;
-  if (WSAEventSelect(tcpc->sock, tcpc->sock_event, FD_WRITE | FD_CLOSE) == SOCKET_ERROR)
-  {
-    ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError());
-    return FALSE;
-  }
-  res = WaitForSingleObject(tcpc->sock_event, INFINITE);
-  switch (res)
-  {
-  case WAIT_OBJECT_0:
-    return TRUE;
-  default:
-    ERR("WaitForMultipleObjects() failed with error %d\n", GetLastError());
-    return FALSE;
-  }
-}
-
-static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc)
-{
-  SetEvent(tcpc->cancel_event);
-}
-
-static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc)
-{
-  CloseHandle(tcpc->sock_event);
-  CloseHandle(tcpc->cancel_event);
-}
-
-#endif
-
 static RpcConnection *rpcrt4_conn_tcp_alloc(void)
 {
   RpcConnection_tcp *tcpc;
@@ -1081,8 +772,9 @@ static RpcConnection *rpcrt4_conn_tcp_alloc(void)
   if (tcpc == NULL)
     return NULL;
   tcpc->sock = -1;
-  if (!rpcrt4_sock_wait_init(tcpc))
+  if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0)
   {
+    ERR("socketpair() failed: %s\n", strerror(errno));
     HeapFree(GetProcessHeap(), 0, tcpc);
     return NULL;
   }
@@ -1123,13 +815,6 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection)
   for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next)
   {
     int val;
-    u_long nonblocking;
-
-    if (ai_cur->ai_family != AF_INET && ai_cur->ai_family != AF_INET6)
-    {
-      TRACE("skipping non-IP/IPv6 address family\n");
-      continue;
-    }
 
     if (TRACE_ON(rpc))
     {
@@ -1157,9 +842,8 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection)
 
     /* RPC depends on having minimal latency so disable the Nagle algorithm */
     val = 1;
-    setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
-    nonblocking = 1;
-    ioctlsocket(sock, FIONBIO, &nonblocking);
+    setsockopt(sock, SOL_TCP, TCP_NODELAY, &val, sizeof(val));
+    fcntl(sock, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
 
     tcpc->sock = sock;
 
@@ -1173,7 +857,7 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection)
   return RPC_S_SERVER_UNAVAILABLE;
 }
 
-static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *protseq, const char *endpoint)
+static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *protseq, LPSTR endpoint)
 {
     RPC_STATUS status = RPC_S_CANT_CREATE_ENDPOINT;
     int sock;
@@ -1194,7 +878,7 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
     hints.ai_canonname      = NULL;
     hints.ai_next           = NULL;
 
-    ret = getaddrinfo(NULL, endpoint ? endpoint : "0", &hints, &ai);
+    ret = getaddrinfo(NULL, endpoint, &hints, &ai);
     if (ret)
     {
         ERR("getaddrinfo for port %s failed: %s\n", endpoint,
@@ -1208,20 +892,11 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
     {
         RpcConnection_tcp *tcpc;
         RPC_STATUS create_status;
-        struct sockaddr_storage sa;
-        socklen_t sa_len;
-        char service[NI_MAXSERV];
-        u_long nonblocking;
-
-        if (ai_cur->ai_family != AF_INET && ai_cur->ai_family != AF_INET6)
-        {
-            TRACE("skipping non-IP/IPv6 address family\n");
-            continue;
-        }
 
         if (TRACE_ON(rpc))
         {
             char host[256];
+            char service[256];
             getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen,
                         host, sizeof(host), service, sizeof(service),
                         NI_NUMERICHOST | NI_NUMERICSERV);
@@ -1247,28 +922,9 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
               status = RPC_S_CANT_CREATE_ENDPOINT;
             continue;
         }
-
-        sa_len = sizeof(sa);
-        if (getsockname(sock, (struct sockaddr *)&sa, &sa_len))
-        {
-            WARN("getsockname() failed: %s\n", strerror(errno));
-            status = RPC_S_CANT_CREATE_ENDPOINT;
-            continue;
-        }
-
-        ret = getnameinfo((struct sockaddr *)&sa, sa_len,
-                          NULL, 0, service, sizeof(service),
-                          NI_NUMERICSERV);
-        if (ret)
-        {
-            WARN("getnameinfo failed: %s\n", gai_strerror(ret));
-            status = RPC_S_CANT_CREATE_ENDPOINT;
-            continue;
-        }
-
         create_status = RPCRT4_CreateConnection((RpcConnection **)&tcpc, TRUE,
                                                 protseq->Protseq, NULL,
-                                                service, NULL, NULL, NULL);
+                                                endpoint, NULL, NULL, NULL);
         if (create_status != RPC_S_OK)
         {
             closesocket(sock);
@@ -1289,8 +945,7 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
          * race-condition (poll() says it is readable, connection drops,
          * and accept() blocks until the next connection comes...)
          */
-        nonblocking = 1;
-        ret = ioctlsocket(sock, FIONBIO, &nonblocking);
+        ret = fcntl(sock, F_SETFL, O_NONBLOCK);
         if (ret < 0)
         {
             WARN("couldn't make socket non-blocking, error %d\n", ret);
@@ -1301,10 +956,6 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
 
         tcpc->common.Next = first_connection;
         first_connection = &tcpc->common;
-
-        /* since IPv4 and IPv6 share the same port space, we only need one
-         * successful bind to listen for both */
-        break;
     }
 
     freeaddrinfo(ai);
@@ -1339,7 +990,6 @@ static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection
   socklen_t addrsize;
   RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn;
   RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn;
-  u_long nonblocking;
 
   addrsize = sizeof(address);
   ret = accept(server->sock, (struct sockaddr*) &address, &addrsize);
@@ -1348,8 +998,8 @@ static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection
     ERR("Failed to accept a TCP connection: error %d\n", ret);
     return RPC_S_OUT_OF_RESOURCES;
   }
-  nonblocking = 1;
-  ioctlsocket(ret, FIONBIO, &nonblocking);
+  /* reset to blocking behaviour */
+  fcntl(ret, F_SETFL, 0);
   client->sock = ret;
   TRACE("Accepted a new TCP connection\n");
   return RPC_S_OK;
@@ -1374,8 +1024,22 @@ static int rpcrt4_conn_tcp_read(RpcConnection *Connection,
     }
     else
     {
-      if (!rpcrt4_sock_wait_for_recv(tcpc))
+      struct pollfd pfds[2];
+      pfds[0].fd = tcpc->sock;
+      pfds[0].events = POLLIN;
+      pfds[1].fd = tcpc->cancel_fds[0];
+      pfds[1].events = POLLIN;
+      if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR)
+      {
+        ERR("poll() failed: %s\n", strerror(errno));
+        return -1;
+      }
+      if (pfds[1].revents & POLLIN) /* canceled */
+      {
+        char dummy;
+        read(pfds[1].fd, &dummy, sizeof(dummy));
         return -1;
+      }
     }
   } while (bytes_read != count);
   TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_read);
@@ -1396,8 +1060,14 @@ static int rpcrt4_conn_tcp_write(RpcConnection *Connection,
       return -1;
     else
     {
-      if (!rpcrt4_sock_wait_for_send(tcpc))
+      struct pollfd pfd;
+      pfd.fd = tcpc->sock;
+      pfd.events = POLLOUT;
+      if (poll(&pfd, 1, -1 /* infinite */) == -1 && errno != EINTR)
+      {
+        ERR("poll() failed: %s\n", strerror(errno));
         return -1;
+      }
     }
   } while (bytes_written != count);
   TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_written);
@@ -1413,25 +1083,44 @@ static int rpcrt4_conn_tcp_close(RpcConnection *Connection)
   if (tcpc->sock != -1)
     closesocket(tcpc->sock);
   tcpc->sock = -1;
-  rpcrt4_sock_wait_destroy(tcpc);
+  close(tcpc->cancel_fds[0]);
+  close(tcpc->cancel_fds[1]);
   return 0;
 }
 
 static void rpcrt4_conn_tcp_cancel_call(RpcConnection *Connection)
 {
     RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection;
+    char dummy = 1;
+
     TRACE("%p\n", Connection);
-    rpcrt4_sock_wait_cancel(tcpc);
+
+    write(tcpc->cancel_fds[1], &dummy, 1);
 }
 
 static int rpcrt4_conn_tcp_wait_for_incoming_data(RpcConnection *Connection)
 {
     RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection;
+    struct pollfd pfds[2];
 
     TRACE("%p\n", Connection);
 
-    if (!rpcrt4_sock_wait_for_recv(tcpc))
-        return -1;
+    pfds[0].fd = tcpc->sock;
+    pfds[0].events = POLLIN;
+    pfds[1].fd = tcpc->cancel_fds[0];
+    pfds[1].events = POLLIN;
+    if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR)
+    {
+      ERR("poll() failed: %s\n", strerror(errno));
+      return -1;
+    }
+    if (pfds[1].revents & POLLIN) /* canceled */
+    {
+      char dummy;
+      read(pfds[1].fd, &dummy, sizeof(dummy));
+      return -1;
+    }
+
     return 0;
 }
 
@@ -1439,11 +1128,136 @@ static size_t rpcrt4_ncacn_ip_tcp_get_top_of_tower(unsigned char *tower_data,
                                                    const char *networkaddr,
                                                    const char *endpoint)
 {
-    return rpcrt4_ip_tcp_get_top_of_tower(tower_data, networkaddr,
-                                          EPM_PROTOCOL_TCP, endpoint);
-}
+    twr_tcp_floor_t *tcp_floor;
+    twr_ipv4_floor_t *ipv4_floor;
+    struct addrinfo *ai;
+    struct addrinfo hints;
+    int ret;
+    size_t size = sizeof(*tcp_floor) + sizeof(*ipv4_floor);
 
-#ifdef HAVE_SOCKETPAIR
+    TRACE("(%p, %s, %s)\n", tower_data, networkaddr, endpoint);
+
+    if (!tower_data)
+        return size;
+
+    tcp_floor = (twr_tcp_floor_t *)tower_data;
+    tower_data += sizeof(*tcp_floor);
+
+    ipv4_floor = (twr_ipv4_floor_t *)tower_data;
+
+    tcp_floor->count_lhs = sizeof(tcp_floor->protid);
+    tcp_floor->protid = EPM_PROTOCOL_TCP;
+    tcp_floor->count_rhs = sizeof(tcp_floor->port);
+
+    ipv4_floor->count_lhs = sizeof(ipv4_floor->protid);
+    ipv4_floor->protid = EPM_PROTOCOL_IP;
+    ipv4_floor->count_rhs = sizeof(ipv4_floor->ipv4addr);
+
+    hints.ai_flags          = AI_NUMERICHOST;
+    /* FIXME: only support IPv4 at the moment. how is IPv6 represented by the EPM? */
+    hints.ai_family         = PF_INET;
+    hints.ai_socktype       = SOCK_STREAM;
+    hints.ai_protocol       = IPPROTO_TCP;
+    hints.ai_addrlen        = 0;
+    hints.ai_addr           = NULL;
+    hints.ai_canonname      = NULL;
+    hints.ai_next           = NULL;
+
+    ret = getaddrinfo(networkaddr, endpoint, &hints, &ai);
+    if (ret)
+    {
+        ret = getaddrinfo("0.0.0.0", endpoint, &hints, &ai);
+        if (ret)
+        {
+            ERR("getaddrinfo failed: %s\n", gai_strerror(ret));
+            return 0;
+        }
+    }
+
+    if (ai->ai_family == PF_INET)
+    {
+        const struct sockaddr_in *sin = (const struct sockaddr_in *)ai->ai_addr;
+        tcp_floor->port = sin->sin_port;
+        ipv4_floor->ipv4addr = sin->sin_addr.s_addr;
+    }
+    else
+    {
+        ERR("unexpected protocol family %d\n", ai->ai_family);
+        return 0;
+    }
+
+    freeaddrinfo(ai);
+
+    return size;
+}
+
+static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *tower_data,
+                                                         size_t tower_size,
+                                                         char **networkaddr,
+                                                         char **endpoint)
+{
+    const twr_tcp_floor_t *tcp_floor = (const twr_tcp_floor_t *)tower_data;
+    const twr_ipv4_floor_t *ipv4_floor;
+    struct in_addr in_addr;
+
+    TRACE("(%p, %d, %p, %p)\n", tower_data, (int)tower_size, networkaddr, endpoint);
+
+    if (tower_size < sizeof(*tcp_floor))
+        return EPT_S_NOT_REGISTERED;
+
+    tower_data += sizeof(*tcp_floor);
+    tower_size -= sizeof(*tcp_floor);
+
+    if (tower_size < sizeof(*ipv4_floor))
+        return EPT_S_NOT_REGISTERED;
+
+    ipv4_floor = (const twr_ipv4_floor_t *)tower_data;
+
+    if ((tcp_floor->count_lhs != sizeof(tcp_floor->protid)) ||
+        (tcp_floor->protid != EPM_PROTOCOL_TCP) ||
+        (tcp_floor->count_rhs != sizeof(tcp_floor->port)) ||
+        (ipv4_floor->count_lhs != sizeof(ipv4_floor->protid)) ||
+        (ipv4_floor->protid != EPM_PROTOCOL_IP) ||
+        (ipv4_floor->count_rhs != sizeof(ipv4_floor->ipv4addr)))
+        return EPT_S_NOT_REGISTERED;
+
+    if (endpoint)
+    {
+        *endpoint = I_RpcAllocate(6 /* sizeof("65535") + 1 */);
+        if (!*endpoint)
+            return RPC_S_OUT_OF_RESOURCES;
+        sprintf(*endpoint, "%u", ntohs(tcp_floor->port));
+    }
+
+    if (networkaddr)
+    {
+        *networkaddr = I_RpcAllocate(INET_ADDRSTRLEN);
+        if (!*networkaddr)
+        {
+            if (endpoint)
+            {
+                I_RpcFree(*endpoint);
+                *endpoint = NULL;
+            }
+            return RPC_S_OUT_OF_RESOURCES;
+        }
+        in_addr.s_addr = ipv4_floor->ipv4addr;
+        if (!inet_ntop(AF_INET, &in_addr, *networkaddr, INET_ADDRSTRLEN))
+        {
+            ERR("inet_ntop: %s\n", strerror(errno));
+            I_RpcFree(*networkaddr);
+            *networkaddr = NULL;
+            if (endpoint)
+            {
+                I_RpcFree(*endpoint);
+                *endpoint = NULL;
+            }
+            return EPT_S_NOT_REGISTERED;
+        }
+    }
+
+    return RPC_S_OK;
+}
 
 typedef struct _RpcServerProtseq_sock
 {
@@ -1584,1182 +1398,74 @@ static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq
     return 1;
 }
 
-#else /* HAVE_SOCKETPAIR */
-
-typedef struct _RpcServerProtseq_sock
-{
-    RpcServerProtseq common;
-    HANDLE mgr_event;
-} RpcServerProtseq_sock;
+#endif  /* HAVE_SOCKETPAIR */
 
-static RpcServerProtseq *rpcrt4_protseq_sock_alloc(void)
-{
-    RpcServerProtseq_sock *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps));
-    if (ps)
-    {
-        static BOOL wsa_inited;
-        if (!wsa_inited)
-        {
-            WSADATA wsadata;
-            WSAStartup(MAKEWORD(2, 2), &wsadata);
-            /* Note: WSAStartup can be called more than once so we don't bother with
-             * making accesses to wsa_inited thread-safe */
-            wsa_inited = TRUE;
-        }
-        ps->mgr_event = CreateEventW(NULL, FALSE, FALSE, NULL);
-    }
-    return &ps->common;
-}
+static const struct connection_ops conn_protseq_list[] = {
+  { "ncacn_np",
+    { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_SMB },
+    rpcrt4_conn_np_alloc,
+    rpcrt4_ncacn_np_open,
+    rpcrt4_ncacn_np_handoff,
+    rpcrt4_conn_np_read,
+    rpcrt4_conn_np_write,
+    rpcrt4_conn_np_close,
+    rpcrt4_conn_np_cancel_call,
+    rpcrt4_conn_np_wait_for_incoming_data,
+    rpcrt4_ncacn_np_get_top_of_tower,
+    rpcrt4_ncacn_np_parse_top_of_tower,
+  },
+  { "ncalrpc",
+    { EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_PIPE },
+    rpcrt4_conn_np_alloc,
+    rpcrt4_ncalrpc_open,
+    rpcrt4_ncalrpc_handoff,
+    rpcrt4_conn_np_read,
+    rpcrt4_conn_np_write,
+    rpcrt4_conn_np_close,
+    rpcrt4_conn_np_cancel_call,
+    rpcrt4_conn_np_wait_for_incoming_data,
+    rpcrt4_ncalrpc_get_top_of_tower,
+    rpcrt4_ncalrpc_parse_top_of_tower,
+  },
+#ifdef HAVE_SOCKETPAIR
+  { "ncacn_ip_tcp",
+    { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_TCP },
+    rpcrt4_conn_tcp_alloc,
+    rpcrt4_ncacn_ip_tcp_open,
+    rpcrt4_conn_tcp_handoff,
+    rpcrt4_conn_tcp_read,
+    rpcrt4_conn_tcp_write,
+    rpcrt4_conn_tcp_close,
+    rpcrt4_conn_tcp_cancel_call,
+    rpcrt4_conn_tcp_wait_for_incoming_data,
+    rpcrt4_ncacn_ip_tcp_get_top_of_tower,
+    rpcrt4_ncacn_ip_tcp_parse_top_of_tower,
+  }
+#endif
+};
 
-static void rpcrt4_protseq_sock_signal_state_changed(RpcServerProtseq *protseq)
-{
-    RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, RpcServerProtseq_sock, common);
-    SetEvent(sockps->mgr_event);
-}
 
-static void *rpcrt4_protseq_sock_get_wait_array(RpcServerProtseq *protseq, void *prev_array, unsigned int *count)
+static const struct protseq_ops protseq_list[] =
 {
-    HANDLE *objs = prev_array;
-    RpcConnection_tcp *conn;
-    RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, RpcServerProtseq_sock, common);
-
-    EnterCriticalSection(&protseq->cs);
-
-    /* open and count connections */
-    *count = 1;
-    conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common);
-    while (conn)
     {
-        if (conn->sock != -1)
-            (*count)++;
-        conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common);
-    }
-
-    /* make array of connections */
-    if (objs)
-        objs = HeapReAlloc(GetProcessHeap(), 0, objs, *count*sizeof(HANDLE));
-    else
-        objs = HeapAlloc(GetProcessHeap(), 0, *count*sizeof(HANDLE));
-    if (!objs)
+        "ncacn_np",
+        rpcrt4_protseq_np_alloc,
+        rpcrt4_protseq_np_signal_state_changed,
+        rpcrt4_protseq_np_get_wait_array,
+        rpcrt4_protseq_np_free_wait_array,
+        rpcrt4_protseq_np_wait_for_new_connection,
+        rpcrt4_protseq_ncacn_np_open_endpoint,
+    },
     {
-        ERR("couldn't allocate objs\n");
-        LeaveCriticalSection(&protseq->cs);
-        return NULL;
-    }
-
-    objs[0] = sockps->mgr_event;
-    *count = 1;
-    conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common);
-    while (conn)
-    {
-        if (conn->sock != -1)
-        {
-            int res = WSAEventSelect(conn->sock, conn->sock_event, FD_ACCEPT);
-            if (res == SOCKET_ERROR)
-                ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError());
-            else
-            {
-                objs[*count] = conn->sock_event;
-                (*count)++;
-            }
-        }
-        conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common);
-    }
-    LeaveCriticalSection(&protseq->cs);
-    return objs;
-}
-
-static void rpcrt4_protseq_sock_free_wait_array(RpcServerProtseq *protseq, void *array)
-{
-    HeapFree(GetProcessHeap(), 0, array);
-}
-
-static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq, unsigned int count, void *wait_array)
-{
-    HANDLE b_handle;
-    HANDLE *objs = wait_array;
-    DWORD res;
-    RpcConnection *cconn;
-    RpcConnection_tcp *conn;
-
-    if (!objs)
-        return -1;
-
-    do
-    {
-        /* an alertable wait isn't strictly necessary, but due to our
-         * overlapped I/O implementation in Wine we need to free some memory
-         * by the file user APC being called, even if no completion routine was
-         * specified at the time of starting the async operation */
-        res = WaitForMultipleObjectsEx(count, objs, FALSE, INFINITE, TRUE);
-    } while (res == WAIT_IO_COMPLETION);
-
-    if (res == WAIT_OBJECT_0)
-        return 0;
-    else if (res == WAIT_FAILED)
-    {
-        ERR("wait failed with error %d\n", GetLastError());
-        return -1;
-    }
-    else
-    {
-        b_handle = objs[res - WAIT_OBJECT_0];
-        /* find which connection got a RPC */
-        EnterCriticalSection(&protseq->cs);
-        conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common);
-        while (conn)
-        {
-            if (b_handle == conn->sock_event) break;
-            conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common);
-        }
-        cconn = NULL;
-        if (conn)
-            RPCRT4_SpawnConnection(&cconn, &conn->common);
-        else
-            ERR("failed to locate connection for handle %p\n", b_handle);
-        LeaveCriticalSection(&protseq->cs);
-        if (cconn)
-        {
-            RPCRT4_new_client(cconn);
-            return 1;
-        }
-        else return -1;
-    }
-}
-
-#endif  /* HAVE_SOCKETPAIR */
-
-static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *tower_data,
-                                                         size_t tower_size,
-                                                         char **networkaddr,
-                                                         char **endpoint)
-{
-    return rpcrt4_ip_tcp_parse_top_of_tower(tower_data, tower_size,
-                                            networkaddr, EPM_PROTOCOL_TCP,
-                                            endpoint);
-}
-
-/**** ncacn_http support ****/
-#if 0
-/* 60 seconds is the period native uses */
-#define HTTP_IDLE_TIME 60000
-
-/* reference counted to avoid a race between a cancelled call's connection
- * being destroyed and the asynchronous InternetReadFileEx call being
- * completed */
-typedef struct _RpcHttpAsyncData
-{
-    LONG refs;
-    HANDLE completion_event;
-    INTERNET_BUFFERSA inet_buffers;
-    void *destination_buffer; /* the address that inet_buffers.lpvBuffer will be
-                               * copied into when the call completes */
-    CRITICAL_SECTION cs;
-} RpcHttpAsyncData;
-
-static ULONG RpcHttpAsyncData_AddRef(RpcHttpAsyncData *data)
-{
-    return InterlockedIncrement(&data->refs);
-}
-
-static ULONG RpcHttpAsyncData_Release(RpcHttpAsyncData *data)
-{
-    ULONG refs = InterlockedDecrement(&data->refs);
-    if (!refs)
-    {
-        TRACE("destroying async data %p\n", data);
-        CloseHandle(data->completion_event);
-        HeapFree(GetProcessHeap(), 0, data->inet_buffers.lpvBuffer);
-        DeleteCriticalSection(&data->cs);
-        HeapFree(GetProcessHeap(), 0, data);
-    }
-    return refs;
-}
-
-typedef struct _RpcConnection_http
-{
-    RpcConnection common;
-    HINTERNET app_info;
-    HINTERNET session;
-    HINTERNET in_request;
-    HINTERNET out_request;
-    HANDLE timer_cancelled;
-    HANDLE cancel_event;
-    DWORD last_sent_time;
-    ULONG bytes_received;
-    ULONG flow_control_mark; /* send a control packet to the server when this many bytes received */
-    ULONG flow_control_increment; /* number of bytes to increment flow_control_mark by */
-    UUID connection_uuid;
-    UUID in_pipe_uuid;
-    UUID out_pipe_uuid;
-    RpcHttpAsyncData *async_data;
-} RpcConnection_http;
-
-static RpcConnection *rpcrt4_ncacn_http_alloc(void)
-{
-    RpcConnection_http *httpc;
-    httpc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*httpc));
-    if (!httpc) return NULL;
-    httpc->async_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcHttpAsyncData));
-    if (!httpc->async_data)
-    {
-        HeapFree(GetProcessHeap(), 0, httpc);
-        return NULL;
-    }
-    TRACE("async data = %p\n", httpc->async_data);
-    httpc->cancel_event = CreateEventW(NULL, FALSE, FALSE, NULL);
-    httpc->async_data->refs = 1;
-    httpc->async_data->inet_buffers.dwStructSize = sizeof(INTERNET_BUFFERSA);
-    httpc->async_data->inet_buffers.lpvBuffer = NULL;
-    httpc->async_data->destination_buffer = NULL;
-    InitializeCriticalSection(&httpc->async_data->cs);
-    return &httpc->common;
-}
-
-typedef struct _HttpTimerThreadData
-{
-    PVOID timer_param;
-    DWORD *last_sent_time;
-    HANDLE timer_cancelled;
-} HttpTimerThreadData;
-
-static VOID rpcrt4_http_keep_connection_active_timer_proc(PVOID param, BOOLEAN dummy)
-{
-    HINTERNET in_request = param;
-    RpcPktHdr *idle_pkt;
-
-    idle_pkt = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, 0x0001,
-                                      0, 0);
-    if (idle_pkt)
-    {
-        DWORD bytes_written;
-        InternetWriteFile(in_request, idle_pkt, idle_pkt->common.frag_len, &bytes_written);
-        RPCRT4_FreeHeader(idle_pkt);
-    }
-}
-
-static inline DWORD rpcrt4_http_timer_calc_timeout(DWORD *last_sent_time)
-{
-    DWORD cur_time = GetTickCount();
-    DWORD cached_last_sent_time = *last_sent_time;
-    return HTTP_IDLE_TIME - (cur_time - cached_last_sent_time > HTTP_IDLE_TIME ? 0 : cur_time - cached_last_sent_time);
-}
-
-static DWORD CALLBACK rpcrt4_http_timer_thread(PVOID param)
-{
-    HttpTimerThreadData *data_in = param;
-    HttpTimerThreadData data;
-    DWORD timeout;
-
-    data = *data_in;
-    HeapFree(GetProcessHeap(), 0, data_in);
-
-    for (timeout = HTTP_IDLE_TIME;
-         WaitForSingleObject(data.timer_cancelled, timeout) == WAIT_TIMEOUT;
-         timeout = rpcrt4_http_timer_calc_timeout(data.last_sent_time))
-    {
-        /* are we too soon after last send? */
-        if (GetTickCount() - HTTP_IDLE_TIME < *data.last_sent_time)
-            continue;
-        rpcrt4_http_keep_connection_active_timer_proc(data.timer_param, TRUE);
-    }
-
-    CloseHandle(data.timer_cancelled);
-    return 0;
-}
-
-static VOID WINAPI rpcrt4_http_internet_callback(
-     HINTERNET hInternet,
-     DWORD_PTR dwContext,
-     DWORD dwInternetStatus,
-     LPVOID lpvStatusInformation,
-     DWORD dwStatusInformationLength)
-{
-    RpcHttpAsyncData *async_data = (RpcHttpAsyncData *)dwContext;
-
-    switch (dwInternetStatus)
-    {
-    case INTERNET_STATUS_REQUEST_COMPLETE:
-        TRACE("INTERNET_STATUS_REQUEST_COMPLETED\n");
-        if (async_data)
-        {
-            if (async_data->inet_buffers.lpvBuffer)
-            {
-                EnterCriticalSection(&async_data->cs);
-                if (async_data->destination_buffer)
-                {
-                    memcpy(async_data->destination_buffer,
-                           async_data->inet_buffers.lpvBuffer,
-                           async_data->inet_buffers.dwBufferLength);
-                    async_data->destination_buffer = NULL;
-                }
-                LeaveCriticalSection(&async_data->cs);
-            }
-            HeapFree(GetProcessHeap(), 0, async_data->inet_buffers.lpvBuffer);
-            async_data->inet_buffers.lpvBuffer = NULL;
-            SetEvent(async_data->completion_event);
-            RpcHttpAsyncData_Release(async_data);
-        }
-        break;
-    }
-}
-
-static RPC_STATUS rpcrt4_http_check_response(HINTERNET hor)
-{
-    BOOL ret;
-    DWORD status_code;
-    DWORD size;
-    DWORD index;
-    WCHAR buf[32];
-    WCHAR *status_text = buf;
-    TRACE("\n");
-
-    index = 0;
-    size = sizeof(status_code);
-    ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status_code, &size, &index);
-    if (!ret)
-        return GetLastError();
-    if (status_code < 400)
-        return RPC_S_OK;
-    index = 0;
-    size = sizeof(buf);
-    ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_TEXT, status_text, &size, &index);
-    if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
-    {
-        status_text = HeapAlloc(GetProcessHeap(), 0, size);
-        ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_TEXT, status_text, &size, &index);
-    }
-
-    ERR("server returned: %d %s\n", status_code, ret ? debugstr_w(status_text) : "<status text unavailable>");
-    if(status_text != buf) HeapFree(GetProcessHeap(), 0, status_text);
-
-    if (status_code == HTTP_STATUS_DENIED)
-        return ERROR_ACCESS_DENIED;
-    return RPC_S_SERVER_UNAVAILABLE;
-}
-
-static RPC_STATUS rpcrt4_http_internet_connect(RpcConnection_http *httpc)
-{
-    static const WCHAR wszUserAgent[] = {'M','S','R','P','C',0};
-    LPWSTR proxy = NULL;
-    LPWSTR user = NULL;
-    LPWSTR password = NULL;
-    LPWSTR servername = NULL;
-    const WCHAR *option;
-    INTERNET_PORT port = INTERNET_INVALID_PORT_NUMBER; /* use default port */
-
-    if (httpc->common.QOS &&
-        (httpc->common.QOS->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP))
-    {
-        const RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_cred = httpc->common.QOS->qos->u.HttpCredentials;
-        if (http_cred->TransportCredentials)
-        {
-            WCHAR *p;
-            const SEC_WINNT_AUTH_IDENTITY_W *cred = http_cred->TransportCredentials;
-            ULONG len = cred->DomainLength + 1 + cred->UserLength;
-            user = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
-            if (!user)
-                return RPC_S_OUT_OF_RESOURCES;
-            p = user;
-            if (cred->DomainLength)
-            {
-                memcpy(p, cred->Domain, cred->DomainLength * sizeof(WCHAR));
-                p += cred->DomainLength;
-                *p = '\\';
-                p++;
-            }
-            memcpy(p, cred->User, cred->UserLength * sizeof(WCHAR));
-            p[cred->UserLength] = 0;
-
-            password = RPCRT4_strndupW(cred->Password, cred->PasswordLength);
-        }
-    }
-
-    for (option = httpc->common.NetworkOptions; option;
-         option = (strchrW(option, ',') ? strchrW(option, ',')+1 : NULL))
-    {
-        static const WCHAR wszRpcProxy[] = {'R','p','c','P','r','o','x','y','=',0};
-        static const WCHAR wszHttpProxy[] = {'H','t','t','p','P','r','o','x','y','=',0};
-
-        if (!strncmpiW(option, wszRpcProxy, sizeof(wszRpcProxy)/sizeof(wszRpcProxy[0])-1))
-        {
-            const WCHAR *value_start = option + sizeof(wszRpcProxy)/sizeof(wszRpcProxy[0])-1;
-            const WCHAR *value_end;
-            const WCHAR *p;
-
-            value_end = strchrW(option, ',');
-            if (!value_end)
-                value_end = value_start + strlenW(value_start);
-            for (p = value_start; p < value_end; p++)
-                if (*p == ':')
-                {
-                    port = atoiW(p+1);
-                    value_end = p;
-                    break;
-                }
-            TRACE("RpcProxy value is %s\n", debugstr_wn(value_start, value_end-value_start));
-            servername = RPCRT4_strndupW(value_start, value_end-value_start);
-        }
-        else if (!strncmpiW(option, wszHttpProxy, sizeof(wszHttpProxy)/sizeof(wszHttpProxy[0])-1))
-        {
-            const WCHAR *value_start = option + sizeof(wszHttpProxy)/sizeof(wszHttpProxy[0])-1;
-            const WCHAR *value_end;
-
-            value_end = strchrW(option, ',');
-            if (!value_end)
-                value_end = value_start + strlenW(value_start);
-            TRACE("HttpProxy value is %s\n", debugstr_wn(value_start, value_end-value_start));
-            proxy = RPCRT4_strndupW(value_start, value_end-value_start);
-        }
-        else
-            FIXME("unhandled option %s\n", debugstr_w(option));
-    }
-
-    httpc->app_info = InternetOpenW(wszUserAgent, proxy ? INTERNET_OPEN_TYPE_PROXY : INTERNET_OPEN_TYPE_PRECONFIG,
-                                    NULL, NULL, INTERNET_FLAG_ASYNC);
-    if (!httpc->app_info)
-    {
-        HeapFree(GetProcessHeap(), 0, password);
-        HeapFree(GetProcessHeap(), 0, user);
-        ERR("InternetOpenW failed with error %d\n", GetLastError());
-        return RPC_S_SERVER_UNAVAILABLE;
-    }
-    InternetSetStatusCallbackW(httpc->app_info, rpcrt4_http_internet_callback);
-
-    /* if no RpcProxy option specified, set the HTTP server address to the
-     * RPC server address */
-    if (!servername)
-    {
-        servername = HeapAlloc(GetProcessHeap(), 0, (strlen(httpc->common.NetworkAddr) + 1)*sizeof(WCHAR));
-        if (!servername)
-        {
-            HeapFree(GetProcessHeap(), 0, password);
-            HeapFree(GetProcessHeap(), 0, user);
-            return RPC_S_OUT_OF_RESOURCES;
-        }
-        MultiByteToWideChar(CP_ACP, 0, httpc->common.NetworkAddr, -1, servername, strlen(httpc->common.NetworkAddr) + 1);
-    }
-
-    httpc->session = InternetConnectW(httpc->app_info, servername, port, user, password,
-                                      INTERNET_SERVICE_HTTP, 0, 0);
-
-    HeapFree(GetProcessHeap(), 0, password);
-    HeapFree(GetProcessHeap(), 0, user);
-    HeapFree(GetProcessHeap(), 0, servername);
-
-    if (!httpc->session)
-    {
-        ERR("InternetConnectW failed with error %d\n", GetLastError());
-        return RPC_S_SERVER_UNAVAILABLE;
-    }
-
-    return RPC_S_OK;
-}
-
-/* prepare the in pipe for use by RPC packets */
-static RPC_STATUS rpcrt4_http_prepare_in_pipe(HINTERNET in_request, RpcHttpAsyncData *async_data,
-                                              const UUID *connection_uuid,
-                                              const UUID *in_pipe_uuid,
-                                              const UUID *association_uuid)
-{
-    BYTE packet[44];
-    BOOL ret;
-    RPC_STATUS status;
-    RpcPktHdr *hdr;
-    INTERNET_BUFFERSW buffers_in;
-    DWORD bytes_read, bytes_written;
-
-    /* prepare in pipe */
-    ResetEvent(async_data->completion_event);
-    RpcHttpAsyncData_AddRef(async_data);
-    ret = HttpSendRequestW(in_request, NULL, 0, NULL, 0);
-    if (!ret)
-    {
-        if (GetLastError() == ERROR_IO_PENDING)
-            WaitForSingleObject(async_data->completion_event, INFINITE);
-        else
-        {
-            RpcHttpAsyncData_Release(async_data);
-            ERR("HttpSendRequestW failed with error %d\n", GetLastError());
-            return RPC_S_SERVER_UNAVAILABLE;
-        }
-    }
-    status = rpcrt4_http_check_response(in_request);
-    if (status != RPC_S_OK) return status;
-
-    InternetReadFile(in_request, packet, 20, &bytes_read);
-    /* FIXME: do something with retrieved data */
-
-    memset(&buffers_in, 0, sizeof(buffers_in));
-    buffers_in.dwStructSize = sizeof(buffers_in);
-    /* FIXME: get this from the registry */
-    buffers_in.dwBufferTotal = 1024 * 1024 * 1024; /* 1Gb */
-    ResetEvent(async_data->completion_event);
-    RpcHttpAsyncData_AddRef(async_data);
-    ret = HttpSendRequestExW(in_request, &buffers_in, NULL, 0, 0);
-    if (!ret)
-    {
-        if (GetLastError() == ERROR_IO_PENDING)
-            WaitForSingleObject(async_data->completion_event, INFINITE);
-        else
-        {
-            RpcHttpAsyncData_Release(async_data);
-            ERR("HttpSendRequestExW failed with error %d\n", GetLastError());
-            return RPC_S_SERVER_UNAVAILABLE;
-        }
-    }
-
-    TRACE("sending HTTP connect header to server\n");
-    hdr = RPCRT4_BuildHttpConnectHeader(0, FALSE, connection_uuid, in_pipe_uuid, association_uuid);
-    if (!hdr) return RPC_S_OUT_OF_RESOURCES;
-    ret = InternetWriteFile(in_request, hdr, hdr->common.frag_len, &bytes_written);
-    RPCRT4_FreeHeader(hdr);
-    if (!ret)
-    {
-        ERR("InternetWriteFile failed with error %d\n", GetLastError());
-        return RPC_S_SERVER_UNAVAILABLE;
-    }
-
-    return RPC_S_OK;
-}
-
-static RPC_STATUS rpcrt4_http_read_http_packet(HINTERNET request, RpcPktHdr *hdr, BYTE **data)
-{
-    BOOL ret;
-    DWORD bytes_read;
-    unsigned short data_len;
-
-    ret = InternetReadFile(request, hdr, sizeof(hdr->common), &bytes_read);
-    if (!ret)
-        return RPC_S_SERVER_UNAVAILABLE;
-    if (hdr->common.ptype != PKT_HTTP || hdr->common.frag_len < sizeof(hdr->http))
-    {
-        ERR("wrong packet type received %d or wrong frag_len %d\n",
-            hdr->common.ptype, hdr->common.frag_len);
-        return RPC_S_PROTOCOL_ERROR;
-    }
-
-    ret = InternetReadFile(request, &hdr->common + 1, sizeof(hdr->http) - sizeof(hdr->common), &bytes_read);
-    if (!ret)
-        return RPC_S_SERVER_UNAVAILABLE;
-
-    data_len = hdr->common.frag_len - sizeof(hdr->http);
-    if (data_len)
-    {
-        *data = HeapAlloc(GetProcessHeap(), 0, data_len);
-        if (!*data)
-            return RPC_S_OUT_OF_RESOURCES;
-        ret = InternetReadFile(request, *data, data_len, &bytes_read);
-        if (!ret)
-        {
-            HeapFree(GetProcessHeap(), 0, *data);
-            return RPC_S_SERVER_UNAVAILABLE;
-        }
-    }
-    else
-        *data = NULL;
-
-    if (!RPCRT4_IsValidHttpPacket(hdr, *data, data_len))
-    {
-        ERR("invalid http packet\n");
-        return RPC_S_PROTOCOL_ERROR;
-    }
-
-    return RPC_S_OK;
-}
-
-/* prepare the out pipe for use by RPC packets */
-static RPC_STATUS rpcrt4_http_prepare_out_pipe(HINTERNET out_request,
-                                               RpcHttpAsyncData *async_data,
-                                               const UUID *connection_uuid,
-                                               const UUID *out_pipe_uuid,
-                                               ULONG *flow_control_increment)
-{
-    BYTE packet[20];
-    BOOL ret;
-    RPC_STATUS status;
-    RpcPktHdr *hdr;
-    DWORD bytes_read;
-    BYTE *data_from_server;
-    RpcPktHdr pkt_from_server;
-    ULONG field1, field3;
-
-    ResetEvent(async_data->completion_event);
-    RpcHttpAsyncData_AddRef(async_data);
-    ret = HttpSendRequestW(out_request, NULL, 0, NULL, 0);
-    if (!ret)
-    {
-        if (GetLastError() == ERROR_IO_PENDING)
-            WaitForSingleObject(async_data->completion_event, INFINITE);
-        else
-        {
-            RpcHttpAsyncData_Release(async_data);
-            ERR("HttpSendRequestW failed with error %d\n", GetLastError());
-            return RPC_S_SERVER_UNAVAILABLE;
-        }
-    }
-    status = rpcrt4_http_check_response(out_request);
-    if (status != RPC_S_OK) return status;
-
-    InternetReadFile(out_request, packet, 20, &bytes_read);
-    /* FIXME: do something with retrieved data */
-
-    hdr = RPCRT4_BuildHttpConnectHeader(0, TRUE, connection_uuid, out_pipe_uuid, NULL);
-    if (!hdr) return RPC_S_OUT_OF_RESOURCES;
-    ResetEvent(async_data->completion_event);
-    RpcHttpAsyncData_AddRef(async_data);
-    ret = HttpSendRequestW(out_request, NULL, 0, hdr, hdr->common.frag_len);
-    if (!ret)
-    {
-        if (GetLastError() == ERROR_IO_PENDING)
-            WaitForSingleObject(async_data->completion_event, INFINITE);
-        else
-        {
-            RpcHttpAsyncData_Release(async_data);
-            ERR("HttpSendRequestW failed with error %d\n", GetLastError());
-            RPCRT4_FreeHeader(hdr);
-            return RPC_S_SERVER_UNAVAILABLE;
-        }
-    }
-    RPCRT4_FreeHeader(hdr);
-    status = rpcrt4_http_check_response(out_request);
-    if (status != RPC_S_OK) return status;
-
-    status = rpcrt4_http_read_http_packet(out_request, &pkt_from_server,
-                                          &data_from_server);
-    if (status != RPC_S_OK) return status;
-    status = RPCRT4_ParseHttpPrepareHeader1(&pkt_from_server, data_from_server,
-                                            &field1);
-    HeapFree(GetProcessHeap(), 0, data_from_server);
-    if (status != RPC_S_OK) return status;
-    TRACE("received (%d) from first prepare header\n", field1);
-
-    status = rpcrt4_http_read_http_packet(out_request, &pkt_from_server,
-                                          &data_from_server);
-    if (status != RPC_S_OK) return status;
-    status = RPCRT4_ParseHttpPrepareHeader2(&pkt_from_server, data_from_server,
-                                            &field1, flow_control_increment,
-                                            &field3);
-    HeapFree(GetProcessHeap(), 0, data_from_server);
-    if (status != RPC_S_OK) return status;
-    TRACE("received (0x%08x 0x%08x %d) from second prepare header\n", field1, *flow_control_increment, field3);
-
-    return RPC_S_OK;
-}
-
-static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection)
-{
-    RpcConnection_http *httpc = (RpcConnection_http *)Connection;
-    static const WCHAR wszVerbIn[] = {'R','P','C','_','I','N','_','D','A','T','A',0};
-    static const WCHAR wszVerbOut[] = {'R','P','C','_','O','U','T','_','D','A','T','A',0};
-    static const WCHAR wszRpcProxyPrefix[] = {'/','r','p','c','/','r','p','c','p','r','o','x','y','.','d','l','l','?',0};
-    static const WCHAR wszColon[] = {':',0};
-    static const WCHAR wszAcceptType[] = {'a','p','p','l','i','c','a','t','i','o','n','/','r','p','c',0};
-    LPCWSTR wszAcceptTypes[] = { wszAcceptType, NULL };
-    WCHAR *url;
-    RPC_STATUS status;
-    BOOL secure;
-    HttpTimerThreadData *timer_data;
-    HANDLE thread;
-
-    TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint);
-
-    if (Connection->server)
-    {
-        ERR("ncacn_http servers not supported yet\n");
-        return RPC_S_SERVER_UNAVAILABLE;
-    }
-
-    if (httpc->in_request)
-        return RPC_S_OK;
-
-    httpc->async_data->completion_event = CreateEventW(NULL, FALSE, FALSE, NULL);
-
-    status = UuidCreate(&httpc->connection_uuid);
-    status = UuidCreate(&httpc->in_pipe_uuid);
-    status = UuidCreate(&httpc->out_pipe_uuid);
-
-    status = rpcrt4_http_internet_connect(httpc);
-    if (status != RPC_S_OK)
-        return status;
-
-    url = HeapAlloc(GetProcessHeap(), 0, sizeof(wszRpcProxyPrefix) + (strlen(Connection->NetworkAddr) + 1 + strlen(Connection->Endpoint))*sizeof(WCHAR));
-    if (!url)
-        return RPC_S_OUT_OF_MEMORY;
-    memcpy(url, wszRpcProxyPrefix, sizeof(wszRpcProxyPrefix));
-    MultiByteToWideChar(CP_ACP, 0, Connection->NetworkAddr, -1, url+sizeof(wszRpcProxyPrefix)/sizeof(wszRpcProxyPrefix[0])-1, strlen(Connection->NetworkAddr)+1);
-    strcatW(url, wszColon);
-    MultiByteToWideChar(CP_ACP, 0, Connection->Endpoint, -1, url+strlenW(url), strlen(Connection->Endpoint)+1);
-
-    secure = httpc->common.QOS &&
-             (httpc->common.QOS->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) &&
-             (httpc->common.QOS->qos->u.HttpCredentials->Flags & RPC_C_HTTP_FLAG_USE_SSL);
-
-    httpc->in_request = HttpOpenRequestW(httpc->session, wszVerbIn, url, NULL, NULL,
-                                         wszAcceptTypes,
-                                         (secure ? INTERNET_FLAG_SECURE : 0)|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_PRAGMA_NOCACHE,
-                                         (DWORD_PTR)httpc->async_data);
-    if (!httpc->in_request)
-    {
-        ERR("HttpOpenRequestW failed with error %d\n", GetLastError());
-        return RPC_S_SERVER_UNAVAILABLE;
-    }
-    httpc->out_request = HttpOpenRequestW(httpc->session, wszVerbOut, url, NULL, NULL,
-                                          wszAcceptTypes,
-                                          (secure ? INTERNET_FLAG_SECURE : 0)|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_PRAGMA_NOCACHE,
-                                          (DWORD_PTR)httpc->async_data);
-    if (!httpc->out_request)
-    {
-        ERR("HttpOpenRequestW failed with error %d\n", GetLastError());
-        return RPC_S_SERVER_UNAVAILABLE;
-    }
-
-    status = rpcrt4_http_prepare_in_pipe(httpc->in_request,
-                                         httpc->async_data,
-                                         &httpc->connection_uuid,
-                                         &httpc->in_pipe_uuid,
-                                         &Connection->assoc->http_uuid);
-    if (status != RPC_S_OK)
-        return status;
-
-    status = rpcrt4_http_prepare_out_pipe(httpc->out_request,
-                                          httpc->async_data,
-                                          &httpc->connection_uuid,
-                                          &httpc->out_pipe_uuid,
-                                          &httpc->flow_control_increment);
-    if (status != RPC_S_OK)
-        return status;
-
-    httpc->flow_control_mark = httpc->flow_control_increment / 2;
-    httpc->last_sent_time = GetTickCount();
-    httpc->timer_cancelled = CreateEventW(NULL, FALSE, FALSE, NULL);
-
-    timer_data = HeapAlloc(GetProcessHeap(), 0, sizeof(*timer_data));
-    if (!timer_data)
-        return ERROR_OUTOFMEMORY;
-    timer_data->timer_param = httpc->in_request;
-    timer_data->last_sent_time = &httpc->last_sent_time;
-    timer_data->timer_cancelled = httpc->timer_cancelled;
-    /* FIXME: should use CreateTimerQueueTimer when implemented */
-    thread = CreateThread(NULL, 0, rpcrt4_http_timer_thread, timer_data, 0, NULL);
-    if (!thread)
-    {
-        HeapFree(GetProcessHeap(), 0, timer_data);
-        return GetLastError();
-    }
-    CloseHandle(thread);
-
-    return RPC_S_OK;
-}
-
-static RPC_STATUS rpcrt4_ncacn_http_handoff(RpcConnection *old_conn, RpcConnection *new_conn)
-{
-    assert(0);
-    return RPC_S_SERVER_UNAVAILABLE;
-}
-
-static int rpcrt4_ncacn_http_read(RpcConnection *Connection,
-                                void *buffer, unsigned int count)
-{
-  RpcConnection_http *httpc = (RpcConnection_http *) Connection;
-  char *buf = buffer;
-  BOOL ret = TRUE;
-  unsigned int bytes_left = count;
-
-  ResetEvent(httpc->async_data->completion_event);
-  while (bytes_left)
-  {
-    RpcHttpAsyncData_AddRef(httpc->async_data);
-    httpc->async_data->inet_buffers.dwBufferLength = bytes_left;
-    httpc->async_data->inet_buffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, bytes_left);
-    httpc->async_data->destination_buffer = buf;
-    ret = InternetReadFileExA(httpc->out_request, &httpc->async_data->inet_buffers, IRF_ASYNC, 0);
-    if (ret)
-    {
-        /* INTERNET_STATUS_REQUEST_COMPLETED won't be sent, so release our
-         * async ref now */
-        RpcHttpAsyncData_Release(httpc->async_data);
-        memcpy(buf, httpc->async_data->inet_buffers.lpvBuffer,
-               httpc->async_data->inet_buffers.dwBufferLength);
-        HeapFree(GetProcessHeap(), 0, httpc->async_data->inet_buffers.lpvBuffer);
-        httpc->async_data->inet_buffers.lpvBuffer = NULL;
-        httpc->async_data->destination_buffer = NULL;
-    }
-    else
-    {
-        if (GetLastError() == ERROR_IO_PENDING)
-        {
-            HANDLE handles[2] = { httpc->async_data->completion_event, httpc->cancel_event };
-            DWORD result = WaitForMultipleObjects(2, handles, FALSE, DEFAULT_NCACN_HTTP_TIMEOUT);
-            if (result == WAIT_OBJECT_0)
-                ret = TRUE;
-            else
-            {
-                TRACE("call cancelled\n");
-                EnterCriticalSection(&httpc->async_data->cs);
-                httpc->async_data->destination_buffer = NULL;
-                LeaveCriticalSection(&httpc->async_data->cs);
-                break;
-            }
-        }
-        else
-        {
-            HeapFree(GetProcessHeap(), 0, httpc->async_data->inet_buffers.lpvBuffer);
-            httpc->async_data->inet_buffers.lpvBuffer = NULL;
-            httpc->async_data->destination_buffer = NULL;
-            RpcHttpAsyncData_Release(httpc->async_data);
-            break;
-        }
-    }
-    if (!httpc->async_data->inet_buffers.dwBufferLength)
-        break;
-    bytes_left -= httpc->async_data->inet_buffers.dwBufferLength;
-    buf += httpc->async_data->inet_buffers.dwBufferLength;
-  }
-  TRACE("%p %p %u -> %s\n", httpc->out_request, buffer, count, ret ? "TRUE" : "FALSE");
-  return ret ? count : -1;
-}
-
-static RPC_STATUS rpcrt4_ncacn_http_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload)
-{
-  RpcConnection_http *httpc = (RpcConnection_http *) Connection;
-  RPC_STATUS status;
-  DWORD hdr_length;
-  LONG dwRead;
-  RpcPktCommonHdr common_hdr;
-
-  *Header = NULL;
-
-  TRACE("(%p, %p, %p)\n", Connection, Header, Payload);
-
-again:
-  /* read packet common header */
-  dwRead = rpcrt4_ncacn_http_read(Connection, &common_hdr, sizeof(common_hdr));
-  if (dwRead != sizeof(common_hdr)) {
-    WARN("Short read of header, %d bytes\n", dwRead);
-    status = RPC_S_PROTOCOL_ERROR;
-    goto fail;
-  }
-  if (!memcmp(&common_hdr, "HTTP/1.1", sizeof("HTTP/1.1")) ||
-      !memcmp(&common_hdr, "HTTP/1.0", sizeof("HTTP/1.0")))
-  {
-    FIXME("server returned %s\n", debugstr_a((const char *)&common_hdr));
-    status = RPC_S_PROTOCOL_ERROR;
-    goto fail;
-  }
-
-  status = RPCRT4_ValidateCommonHeader(&common_hdr);
-  if (status != RPC_S_OK) goto fail;
-
-  hdr_length = RPCRT4_GetHeaderSize((RpcPktHdr*)&common_hdr);
-  if (hdr_length == 0) {
-    WARN("header length == 0\n");
-    status = RPC_S_PROTOCOL_ERROR;
-    goto fail;
-  }
-
-  *Header = HeapAlloc(GetProcessHeap(), 0, hdr_length);
-  if (!*Header)
-  {
-    status = RPC_S_OUT_OF_RESOURCES;
-    goto fail;
-  }
-  memcpy(*Header, &common_hdr, sizeof(common_hdr));
-
-  /* read the rest of packet header */
-  dwRead = rpcrt4_ncacn_http_read(Connection, &(*Header)->common + 1, hdr_length - sizeof(common_hdr));
-  if (dwRead != hdr_length - sizeof(common_hdr)) {
-    WARN("bad header length, %d bytes, hdr_length %d\n", dwRead, hdr_length);
-    status = RPC_S_PROTOCOL_ERROR;
-    goto fail;
-  }
-
-  if (common_hdr.frag_len - hdr_length)
-  {
-    *Payload = HeapAlloc(GetProcessHeap(), 0, common_hdr.frag_len - hdr_length);
-    if (!*Payload)
-    {
-      status = RPC_S_OUT_OF_RESOURCES;
-      goto fail;
-    }
-
-    dwRead = rpcrt4_ncacn_http_read(Connection, *Payload, common_hdr.frag_len - hdr_length);
-    if (dwRead != common_hdr.frag_len - hdr_length)
-    {
-      WARN("bad data length, %d/%d\n", dwRead, common_hdr.frag_len - hdr_length);
-      status = RPC_S_PROTOCOL_ERROR;
-      goto fail;
-    }
-  }
-  else
-    *Payload = NULL;
-
-  if ((*Header)->common.ptype == PKT_HTTP)
-  {
-    if (!RPCRT4_IsValidHttpPacket(*Header, *Payload, common_hdr.frag_len - hdr_length))
-    {
-      ERR("invalid http packet of length %d bytes\n", (*Header)->common.frag_len);
-      status = RPC_S_PROTOCOL_ERROR;
-      goto fail;
-    }
-    if ((*Header)->http.flags == 0x0001)
-    {
-      TRACE("http idle packet, waiting for real packet\n");
-      if ((*Header)->http.num_data_items != 0)
-      {
-        ERR("HTTP idle packet should have no data items instead of %d\n", (*Header)->http.num_data_items);
-        status = RPC_S_PROTOCOL_ERROR;
-        goto fail;
-      }
-    }
-    else if ((*Header)->http.flags == 0x0002)
-    {
-      ULONG bytes_transmitted;
-      ULONG flow_control_increment;
-      UUID pipe_uuid;
-      status = RPCRT4_ParseHttpFlowControlHeader(*Header, *Payload,
-                                                 Connection->server,
-                                                 &bytes_transmitted,
-                                                 &flow_control_increment,
-                                                 &pipe_uuid);
-      if (status != RPC_S_OK)
-        goto fail;
-      TRACE("received http flow control header (0x%x, 0x%x, %s)\n",
-            bytes_transmitted, flow_control_increment, debugstr_guid(&pipe_uuid));
-      /* FIXME: do something with parsed data */
-    }
-    else
-    {
-      FIXME("unrecognised http packet with flags 0x%04x\n", (*Header)->http.flags);
-      status = RPC_S_PROTOCOL_ERROR;
-      goto fail;
-    }
-    RPCRT4_FreeHeader(*Header);
-    *Header = NULL;
-    HeapFree(GetProcessHeap(), 0, *Payload);
-    *Payload = NULL;
-    goto again;
-  }
-
-  /* success */
-  status = RPC_S_OK;
-
-  httpc->bytes_received += common_hdr.frag_len;
-
-  TRACE("httpc->bytes_received = 0x%x\n", httpc->bytes_received);
-
-  if (httpc->bytes_received > httpc->flow_control_mark)
-  {
-    RpcPktHdr *hdr = RPCRT4_BuildHttpFlowControlHeader(httpc->common.server,
-                                                       httpc->bytes_received,
-                                                       httpc->flow_control_increment,
-                                                       &httpc->out_pipe_uuid);
-    if (hdr)
-    {
-      DWORD bytes_written;
-      BOOL ret2;
-      TRACE("sending flow control packet at 0x%x\n", httpc->bytes_received);
-      ret2 = InternetWriteFile(httpc->in_request, hdr, hdr->common.frag_len, &bytes_written);
-      RPCRT4_FreeHeader(hdr);
-      if (ret2)
-        httpc->flow_control_mark = httpc->bytes_received + httpc->flow_control_increment / 2;
-    }
-  }
-
-fail:
-  if (status != RPC_S_OK) {
-    RPCRT4_FreeHeader(*Header);
-    *Header = NULL;
-    HeapFree(GetProcessHeap(), 0, *Payload);
-    *Payload = NULL;
-  }
-  return status;
-}
-
-static int rpcrt4_ncacn_http_write(RpcConnection *Connection,
-                                 const void *buffer, unsigned int count)
-{
-  RpcConnection_http *httpc = (RpcConnection_http *) Connection;
-  DWORD bytes_written;
-  BOOL ret;
-
-  httpc->last_sent_time = ~0U; /* disable idle packet sending */
-  ret = InternetWriteFile(httpc->in_request, buffer, count, &bytes_written);
-  httpc->last_sent_time = GetTickCount();
-  TRACE("%p %p %u -> %s\n", httpc->in_request, buffer, count, ret ? "TRUE" : "FALSE");
-  return ret ? bytes_written : -1;
-}
-
-static int rpcrt4_ncacn_http_close(RpcConnection *Connection)
-{
-  RpcConnection_http *httpc = (RpcConnection_http *) Connection;
-
-  TRACE("\n");
-
-  SetEvent(httpc->timer_cancelled);
-  if (httpc->in_request)
-    InternetCloseHandle(httpc->in_request);
-  httpc->in_request = NULL;
-  if (httpc->out_request)
-    InternetCloseHandle(httpc->out_request);
-  httpc->out_request = NULL;
-  if (httpc->app_info)
-    InternetCloseHandle(httpc->app_info);
-  httpc->app_info = NULL;
-  if (httpc->session)
-    InternetCloseHandle(httpc->session);
-  httpc->session = NULL;
-  RpcHttpAsyncData_Release(httpc->async_data);
-  if (httpc->cancel_event)
-    CloseHandle(httpc->cancel_event);
-
-  return 0;
-}
-
-static void rpcrt4_ncacn_http_cancel_call(RpcConnection *Connection)
-{
-  RpcConnection_http *httpc = (RpcConnection_http *) Connection;
-
-  SetEvent(httpc->cancel_event);
-}
-
-static int rpcrt4_ncacn_http_wait_for_incoming_data(RpcConnection *Connection)
-{
-  BOOL ret;
-  RpcConnection_http *httpc = (RpcConnection_http *) Connection;
-
-  RpcHttpAsyncData_AddRef(httpc->async_data);
-  ret = InternetQueryDataAvailable(httpc->out_request,
-    &httpc->async_data->inet_buffers.dwBufferLength, IRF_ASYNC, 0);
-  if (ret)
-  {
-      /* INTERNET_STATUS_REQUEST_COMPLETED won't be sent, so release our
-       * async ref now */
-      RpcHttpAsyncData_Release(httpc->async_data);
-  }
-  else
-  {
-    if (GetLastError() == ERROR_IO_PENDING)
-    {
-      HANDLE handles[2] = { httpc->async_data->completion_event, httpc->cancel_event };
-      DWORD result = WaitForMultipleObjects(2, handles, FALSE, DEFAULT_NCACN_HTTP_TIMEOUT);
-      if (result != WAIT_OBJECT_0)
-      {
-        TRACE("call cancelled\n");
-        return -1;
-      }
-    }
-    else
-    {
-      RpcHttpAsyncData_Release(httpc->async_data);
-      return -1;
-    }
-  }
-
-  /* success */
-  return 0;
-}
-
-static size_t rpcrt4_ncacn_http_get_top_of_tower(unsigned char *tower_data,
-                                                 const char *networkaddr,
-                                                 const char *endpoint)
-{
-    return rpcrt4_ip_tcp_get_top_of_tower(tower_data, networkaddr,
-                                          EPM_PROTOCOL_HTTP, endpoint);
-}
-
-static RPC_STATUS rpcrt4_ncacn_http_parse_top_of_tower(const unsigned char *tower_data,
-                                                       size_t tower_size,
-                                                       char **networkaddr,
-                                                       char **endpoint)
-{
-    return rpcrt4_ip_tcp_parse_top_of_tower(tower_data, tower_size,
-                                            networkaddr, EPM_PROTOCOL_HTTP,
-                                            endpoint);
-}
-#endif
-static const struct connection_ops conn_protseq_list[] = {
-  { "ncacn_np",
-    { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_SMB },
-    rpcrt4_conn_np_alloc,
-    rpcrt4_ncacn_np_open,
-    rpcrt4_ncacn_np_handoff,
-    rpcrt4_conn_np_read,
-    rpcrt4_conn_np_write,
-    rpcrt4_conn_np_close,
-    rpcrt4_conn_np_cancel_call,
-    rpcrt4_conn_np_wait_for_incoming_data,
-    rpcrt4_ncacn_np_get_top_of_tower,
-    rpcrt4_ncacn_np_parse_top_of_tower,
-    NULL,
-  },
-  { "ncalrpc",
-    { EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_PIPE },
-    rpcrt4_conn_np_alloc,
-    rpcrt4_ncalrpc_open,
-    rpcrt4_ncalrpc_handoff,
-    rpcrt4_conn_np_read,
-    rpcrt4_conn_np_write,
-    rpcrt4_conn_np_close,
-    rpcrt4_conn_np_cancel_call,
-    rpcrt4_conn_np_wait_for_incoming_data,
-    rpcrt4_ncalrpc_get_top_of_tower,
-    rpcrt4_ncalrpc_parse_top_of_tower,
-    NULL,
-  },
-  { "ncacn_ip_tcp",
-    { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_TCP },
-    rpcrt4_conn_tcp_alloc,
-    rpcrt4_ncacn_ip_tcp_open,
-    rpcrt4_conn_tcp_handoff,
-    rpcrt4_conn_tcp_read,
-    rpcrt4_conn_tcp_write,
-    rpcrt4_conn_tcp_close,
-    rpcrt4_conn_tcp_cancel_call,
-    rpcrt4_conn_tcp_wait_for_incoming_data,
-    rpcrt4_ncacn_ip_tcp_get_top_of_tower,
-    rpcrt4_ncacn_ip_tcp_parse_top_of_tower,
-    NULL,
-  },
-#if 0
-  { "ncacn_http",
-    { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_HTTP },
-    rpcrt4_ncacn_http_alloc,
-    rpcrt4_ncacn_http_open,
-    rpcrt4_ncacn_http_handoff,
-    rpcrt4_ncacn_http_read,
-    rpcrt4_ncacn_http_write,
-    rpcrt4_ncacn_http_close,
-    rpcrt4_ncacn_http_cancel_call,
-    rpcrt4_ncacn_http_wait_for_incoming_data,
-    rpcrt4_ncacn_http_get_top_of_tower,
-    rpcrt4_ncacn_http_parse_top_of_tower,
-    rpcrt4_ncacn_http_receive_fragment,
-  },
-#endif
-};
-
-
-static const struct protseq_ops protseq_list[] =
-{
-    {
-        "ncacn_np",
-        rpcrt4_protseq_np_alloc,
-        rpcrt4_protseq_np_signal_state_changed,
-        rpcrt4_protseq_np_get_wait_array,
-        rpcrt4_protseq_np_free_wait_array,
-        rpcrt4_protseq_np_wait_for_new_connection,
-        rpcrt4_protseq_ncacn_np_open_endpoint,
-    },
-    {
-        "ncalrpc",
-        rpcrt4_protseq_np_alloc,
-        rpcrt4_protseq_np_signal_state_changed,
-        rpcrt4_protseq_np_get_wait_array,
-        rpcrt4_protseq_np_free_wait_array,
-        rpcrt4_protseq_np_wait_for_new_connection,
-        rpcrt4_protseq_ncalrpc_open_endpoint,
-    },
+        "ncalrpc",
+        rpcrt4_protseq_np_alloc,
+        rpcrt4_protseq_np_signal_state_changed,
+        rpcrt4_protseq_np_get_wait_array,
+        rpcrt4_protseq_np_free_wait_array,
+        rpcrt4_protseq_np_wait_for_new_connection,
+        rpcrt4_protseq_ncalrpc_open_endpoint,
+    },
+#ifdef HAVE_SOCKETPAIR
     {
         "ncacn_ip_tcp",
         rpcrt4_protseq_sock_alloc,
@@ -2769,6 +1475,7 @@ static const struct protseq_ops protseq_list[] =
         rpcrt4_protseq_sock_wait_for_new_connection,
         rpcrt4_protseq_ncacn_ip_tcp_open_endpoint,
     },
+#endif
 };
 
 #define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0]))
@@ -2817,7 +1524,6 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server,
     LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint,
     LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS)
 {
-  static LONG next_id;
   const struct connection_ops *ops;
   RpcConnection* NewConnection;
 
@@ -2845,7 +1551,6 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server,
   NewConnection->attr = 0;
   if (AuthInfo) RpcAuthInfo_AddRef(AuthInfo);
   NewConnection->AuthInfo = AuthInfo;
-  NewConnection->auth_context_id = InterlockedIncrement( &next_id );
   NewConnection->encryption_auth_len = 0;
   NewConnection->signature_auth_len = 0;
   if (QOS) RpcQualityOfService_AddRef(QOS);
index 59f9fe2..67f05ae 100644 (file)
@@ -14,7 +14,6 @@
        <library>user32</library>
        <library>advapi32</library>
        <library>secur32</library>
-       <!--library>wininet</library-->
        <library>iphlpapi</library>
        <library>ws2_32</library>
        <library>ntdll</library>
index 0a04769..4550889 100644 (file)
 @ stdcall NDRSContextUnmarshallEx(ptr ptr ptr)
 @ stub NDRcopy
 @ stdcall NdrAllocate(ptr long)
-@ varargs NdrAsyncClientCall(ptr ptr)
+@ stub NdrAsyncClientCall
 @ stub NdrAsyncServerCall
-@ stdcall NdrAsyncStubCall(ptr ptr ptr ptr)
 @ stdcall NdrByteCountPointerBufferSize(ptr ptr ptr)
 @ stdcall NdrByteCountPointerFree(ptr ptr ptr)
 @ stdcall NdrByteCountPointerMarshall(ptr ptr ptr)
 @ stdcall RpcEpRegisterA(ptr ptr ptr str)
 @ stub RpcEpRegisterNoReplaceA
 @ stub RpcEpRegisterNoReplaceW
-@ stdcall RpcEpRegisterW(ptr ptr ptr wstr)
+@ stub RpcEpRegisterW
 @ stdcall RpcEpResolveBinding(ptr ptr)
 @ stdcall RpcEpUnregister(ptr ptr ptr)
 @ stub RpcErrorAddRecord # wxp
index 2cc7429..537a005 100644 (file)
 #include "winuser.h"
 #include "winnt.h"
 #include "winternl.h"
-#define _NTDEF_
-typedef NTSTATUS *PNTSTATUS;
-#include "ntsecapi.h"
-#undef _NTDEF_
+#include "iptypes.h"
+#include "iphlpapi.h"
 #include "wine/unicode.h"
 #include "rpc.h"
 
@@ -55,7 +53,6 @@ typedef NTSTATUS *PNTSTATUS;
 #include "rpcproxy.h"
 
 #include "rpc_binding.h"
-#include "rpc_server.h"
 
 #include "wine/debug.h"
 
@@ -63,6 +60,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(rpc);
 
 static UUID uuid_nil;
 
+static CRITICAL_SECTION uuid_cs;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+    0, 0, &uuid_cs,
+    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": uuid_cs") }
+};
+static CRITICAL_SECTION uuid_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
+
 static CRITICAL_SECTION threaddata_cs;
 static CRITICAL_SECTION_DEBUG threaddata_cs_debug =
 {
@@ -129,7 +135,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
         break;
 
     case DLL_PROCESS_DETACH:
-        RPCRT4_destroy_all_protseqs();
         break;
     }
 
@@ -275,6 +280,61 @@ RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid)
   return RPC_S_OK;
 }
 
+/* Number of 100ns ticks per clock tick. To be safe, assume that the clock
+   resolution is at least 1000 * 100 * (1/1000000) = 1/10 of a second */
+#define TICKS_PER_CLOCK_TICK 1000
+#define SECSPERDAY  86400
+#define TICKSPERSEC 10000000
+/* UUID system time starts at October 15, 1582 */
+#define SECS_15_OCT_1582_TO_1601  ((17 + 30 + 31 + 365 * 18 + 5) * SECSPERDAY)
+#define TICKS_15_OCT_1582_TO_1601 ((ULONGLONG)SECS_15_OCT_1582_TO_1601 * TICKSPERSEC)
+
+static void RPC_UuidGetSystemTime(ULONGLONG *time)
+{
+    FILETIME ft;
+
+    GetSystemTimeAsFileTime(&ft);
+
+    *time = ((ULONGLONG)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
+    *time += TICKS_15_OCT_1582_TO_1601;
+}
+
+/* Assume that a hardware address is at least 6 bytes long */ 
+#define ADDRESS_BYTES_NEEDED 6
+
+static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address)
+{
+    int i;
+    DWORD status = RPC_S_OK;
+
+    ULONG buflen = sizeof(IP_ADAPTER_INFO);
+    PIP_ADAPTER_INFO adapter = HeapAlloc(GetProcessHeap(), 0, buflen);
+
+    if (GetAdaptersInfo(adapter, &buflen) == ERROR_BUFFER_OVERFLOW) {
+        HeapFree(GetProcessHeap(), 0, adapter);
+        adapter = HeapAlloc(GetProcessHeap(), 0, buflen);
+    }
+
+    if (GetAdaptersInfo(adapter, &buflen) == NO_ERROR) {
+        for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) {
+            address[i] = adapter->Address[i];
+        }
+    }
+    /* We can't get a hardware address, just use random numbers.
+       Set the multicast bit to prevent conflicts with real cards. */
+    else {
+        for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) {
+            address[i] = rand() & 0xff;
+        }
+
+        address[0] |= 0x01;
+        status = RPC_S_UUID_LOCAL_ONLY;
+    }
+
+    HeapFree(GetProcessHeap(), 0, adapter);
+    return status;
+}
+
 /*************************************************************************
  *           UuidCreate   [RPCRT4.@]
  *
@@ -285,26 +345,83 @@ RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid)
  *  RPC_S_OK if successful.
  *  RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique.
  *
- * NOTES
- *
- *  Follows RFC 4122, section 4.4 (Algorithms for Creating a UUID from
- *  Truly Random or Pseudo-Random Numbers)
+ *  FIXME: No compensation for changes across reloading
+ *         this dll or across reboots (e.g. clock going 
+ *         backwards and swapped network cards). The RFC
+ *         suggests using NVRAM for storing persistent 
+ *         values.
  */
 RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
 {
-    RtlGenRandom(Uuid, sizeof(*Uuid));
-    /* Clear the version bits and set the version (4) */
-    Uuid->Data3 &= 0x0fff;
-    Uuid->Data3 |= (4 << 12);
-    /* Set the topmost bits of Data4 (clock_seq_hi_and_reserved) as
-     * specified in RFC 4122, section 4.4.
-     */
-    Uuid->Data4[0] &= 0x3f;
-    Uuid->Data4[0] |= 0x80;
+    static int initialised, count;
+
+    ULONGLONG time;
+    static ULONGLONG timelast;
+    static WORD sequence;
+
+    static DWORD status;
+    static BYTE address[MAX_ADAPTER_ADDRESS_LENGTH];
+
+    EnterCriticalSection(&uuid_cs);
+
+    if (!initialised) {
+        RPC_UuidGetSystemTime(&timelast);
+        count = TICKS_PER_CLOCK_TICK;
+
+        sequence = ((rand() & 0xff) << 8) + (rand() & 0xff);
+        sequence &= 0x1fff;
+
+        status = RPC_UuidGetNodeAddress(address);
+        initialised = 1;
+    }
+
+    /* Generate time element of the UUID. Account for going faster
+       than our clock as well as the clock going backwards. */
+    while (1) {
+        RPC_UuidGetSystemTime(&time);
+        if (time > timelast) {
+            count = 0;
+            break;
+        }
+        if (time < timelast) {
+            sequence = (sequence + 1) & 0x1fff;
+            count = 0;
+            break;
+        }
+        if (count < TICKS_PER_CLOCK_TICK) {
+            count++;
+            break;
+        }
+    }
+
+    timelast = time;
+    time += count;
+
+    /* Pack the information into the UUID structure. */
+
+    Uuid->Data1  = (unsigned long)(time & 0xffffffff);
+    Uuid->Data2  = (unsigned short)((time >> 32) & 0xffff);
+    Uuid->Data3  = (unsigned short)((time >> 48) & 0x0fff);
+
+    /* This is a version 1 UUID */
+    Uuid->Data3 |= (1 << 12);
+
+    Uuid->Data4[0]  = sequence & 0xff;
+    Uuid->Data4[1]  = (sequence & 0x3f00) >> 8;
+    Uuid->Data4[1] |= 0x80;
+
+    Uuid->Data4[2] = address[0];
+    Uuid->Data4[3] = address[1];
+    Uuid->Data4[4] = address[2];
+    Uuid->Data4[5] = address[3];
+    Uuid->Data4[6] = address[4];
+    Uuid->Data4[7] = address[5];
+
+    LeaveCriticalSection(&uuid_cs);
 
     TRACE("%s\n", debugstr_guid(Uuid));
 
-    return RPC_S_OK;
+    return status;
 }
 
 /*************************************************************************