mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[rpcrt4]
- Revert rpcrt4 back to 1.1.31-partial. Fixes various RPC related regressions. svn path=/trunk/; revision=44287
This commit is contained in:
parent
3384debaf5
commit
f41f818156
25 changed files with 900 additions and 2962 deletions
|
@ -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
|
||||
|
@ -41,19 +37,21 @@
|
|||
|
||||
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" );
|
||||
/* adjust the stack size since we don't use Windows's method */
|
||||
#define STACK_ADJUST sizeof(DWORD)
|
||||
|
||||
HRESULT WINAPI ObjectStubless(DWORD *args)
|
||||
#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];
|
||||
char *args = (char*)(&index + 2);
|
||||
LPVOID iface = *(LPVOID*)args;
|
||||
|
||||
/* 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]);
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
|
||||
return NdrClientCall2(stubless->pStubDesc, fs, args + 2);
|
||||
}
|
||||
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));
|
||||
|
||||
#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;
|
||||
|
||||
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].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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -21,25 +21,36 @@
|
|||
#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 WINAPI 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 WINAPI 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 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 */
|
||||
|
|
|
@ -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;
|
||||
vtbl_method_t *method;
|
||||
void **entry;
|
||||
DWORD i;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
for(i = 3; i < num; i++)
|
||||
{
|
||||
FIXME( "%u methods not supported\n", num );
|
||||
return FALSE;
|
||||
*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++;
|
||||
}
|
||||
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++)
|
||||
{
|
||||
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];
|
||||
}
|
||||
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)
|
||||
{
|
||||
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.table || num_methods > current_vtbl.table->size)
|
||||
{
|
||||
DWORD size;
|
||||
DWORD old_protect;
|
||||
if(current_vtbl.table && current_vtbl.table->ref == 0)
|
||||
{
|
||||
TRACE("freeing old table\n");
|
||||
VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE);
|
||||
HeapFree(GetProcessHeap(), 0, 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(¤t_vtbl.table->vtbl, current_vtbl.table->methods, num_methods);
|
||||
VirtualProtect(current_vtbl.table->methods, size, PAGE_EXECUTE_READ, &old_protect);
|
||||
}
|
||||
LeaveCriticalSection(&delegating_vtbl_section);
|
||||
}
|
||||
|
||||
static IUnknownVtbl *get_delegating_vtbl(void)
|
||||
{
|
||||
IUnknownVtbl *ret;
|
||||
|
||||
if (num_methods < 256) num_methods = 256; /* avoid frequent reallocations */
|
||||
|
||||
EnterCriticalSection(&delegating_vtbl_section);
|
||||
|
||||
if(!current_vtbl || num_methods > current_vtbl->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)
|
||||
{
|
||||
TRACE("freeing old table\n");
|
||||
HeapFree(GetProcessHeap(), 0, current_vtbl);
|
||||
}
|
||||
current_vtbl = table;
|
||||
}
|
||||
|
||||
current_vtbl->ref++;
|
||||
ret = ¤t_vtbl->vtbl;
|
||||
current_vtbl.table->ref++;
|
||||
ret = ¤t_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))
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "epm.h"
|
||||
#include "epm_c.h"
|
||||
|
||||
#define EPM_PROTOCOL_DNET_NSP 0x04
|
||||
#define EPM_PROTOCOL_OSI_TP4 0x05
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -29,17 +29,11 @@
|
|||
|
||||
#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;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -25,25 +25,15 @@
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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>
|
||||
|
|
|
@ -116,9 +116,8 @@
|
|||
@ 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)
|
||||
|
@ -371,7 +370,7 @@
|
|||
@ 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
|
||||
|
|
|
@ -43,10 +43,8 @@
|
|||
#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;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
Loading…
Reference in a new issue