- Revert rpcrt4 back to 1.1.31-partial. Fixes various RPC related regressions.

svn path=/trunk/; revision=44287
This commit is contained in:
Aleksey Bragin 2009-11-25 19:36:10 +00:00
parent 3384debaf5
commit f41f818156
25 changed files with 900 additions and 2962 deletions

View file

@ -2,7 +2,6 @@
* COM proxy implementation
*
* Copyright 2001 Ove Kåven, TransGaming Technologies
* Copyright 2009 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -21,9 +20,6 @@
* TODO: Handle non-i386 architectures
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#define COBJMACROS
@ -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;
}

View file

@ -145,41 +145,6 @@ static const IPSFactoryBufferVtbl CStdPSFactory_Vtbl =
CStdPSFactory_CreateStub
};
static void init_psfactory( CStdPSFactoryBuffer *psfac, const ProxyFileInfo **file_list )
{
DWORD i, j, k;
psfac->lpVtbl = &CStdPSFactory_Vtbl;
psfac->RefCount = 0;
psfac->pProxyFileList = file_list;
for (i = 0; file_list[i]; i++)
{
const PCInterfaceProxyVtblList *proxies = file_list[i]->pProxyVtblList;
const PCInterfaceStubVtblList *stubs = file_list[i]->pStubVtblList;
for (j = 0; j < file_list[i]->TableSize; j++)
{
/* FIXME: i think that different vtables should be copied for
* async interfaces */
void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl;
void **pRpcStubVtbl = (void **)&stubs[j]->Vtbl;
if (file_list[i]->pDelegatedIIDs && file_list[i]->pDelegatedIIDs[j])
{
void **vtbl = proxies[j]->Vtbl;
if (file_list[i]->TableVersion > 1) vtbl++;
fill_delegated_proxy_table( (IUnknownVtbl *)vtbl, stubs[j]->header.DispatchTableCount );
pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl;
}
for (k = 0; k < sizeof(IRpcStubBufferVtbl)/sizeof(void *); k++)
if (!pRpcStubVtbl[k]) pRpcStubVtbl[k] = pSrcRpcStubVtbl[k];
}
}
}
/***********************************************************************
* NdrDllGetClassObject [RPCRT4.@]
*/
@ -193,8 +158,35 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
pPSFactoryBuffer);
*ppv = NULL;
if (!pPSFactoryBuffer->lpVtbl) init_psfactory( pPSFactoryBuffer, pProxyFileList );
if (!pPSFactoryBuffer->lpVtbl) {
const ProxyFileInfo **pProxyFileList2;
DWORD max_delegating_vtbl_size = 0;
pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl;
pPSFactoryBuffer->RefCount = 0;
pPSFactoryBuffer->pProxyFileList = pProxyFileList;
for (pProxyFileList2 = pProxyFileList; *pProxyFileList2; pProxyFileList2++) {
int i;
for (i = 0; i < (*pProxyFileList2)->TableSize; i++) {
/* FIXME: i think that different vtables should be copied for
* async interfaces */
void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl;
void **pRpcStubVtbl = (void **)&(*pProxyFileList2)->pStubVtblList[i]->Vtbl;
unsigned int j;
if ((*pProxyFileList2)->pDelegatedIIDs && (*pProxyFileList2)->pDelegatedIIDs[i]) {
pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl;
if ((*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount > max_delegating_vtbl_size)
max_delegating_vtbl_size = (*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount;
}
for (j = 0; j < sizeof(IRpcStubBufferVtbl)/sizeof(void *); j++)
if (!pRpcStubVtbl[j])
pRpcStubVtbl[j] = pSrcRpcStubVtbl[j];
}
}
if(max_delegating_vtbl_size > 0)
create_delegating_vtbl(max_delegating_vtbl_size);
}
if (pclsid && IsEqualGUID(rclsid, pclsid))
return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
else {
@ -215,7 +207,7 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
*/
HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer)
{
return pPSFactoryBuffer->RefCount != 0 ? S_FALSE : S_OK;
return !(pPSFactoryBuffer->RefCount);
}
@ -274,7 +266,7 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll,
if (len && len < sizeof(module)) {
TRACE("registering CLSID %s => %s\n", debugstr_w(clsid), debugstr_w(module));
if (RegCreateKeyW(HKEY_CLASSES_ROOT, keyname, &key) == ERROR_SUCCESS) {
RegSetValueExW(key, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW));
RegSetValueExW(subkey, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW));
if (RegCreateKeyW(key, inprocserverW, &subkey) == ERROR_SUCCESS) {
RegSetValueExW(subkey, NULL, 0, REG_SZ, (LPBYTE)module, (strlenW(module)+1)*sizeof(WCHAR));
RegSetValueExW(subkey, threadingmodelW, 0, REG_SZ, (const BYTE *)bothW, sizeof(bothW));

View file

@ -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 */

View file

@ -2,7 +2,6 @@
* COM stub (CStdStubBuffer) implementation
*
* Copyright 2001 Ove Kåven, TransGaming Technologies
* Copyright 2009 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -62,12 +61,12 @@ static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer
return (cstdstubbuffer_delegating_t*)((char *)iface - FIELD_OFFSET(cstdstubbuffer_delegating_t, stub_buffer));
}
HRESULT CStdStubBuffer_Construct(REFIID riid,
LPUNKNOWN pUnkServer,
PCInterfaceName name,
CInterfaceStubVtbl *vtbl,
LPPSFACTORYBUFFER pPSFactory,
LPRPCSTUBBUFFER *ppStub)
HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
LPUNKNOWN pUnkServer,
PCInterfaceName name,
CInterfaceStubVtbl *vtbl,
LPPSFACTORYBUFFER pPSFactory,
LPRPCSTUBBUFFER *ppStub)
{
CStdStubBuffer *This;
IUnknown *pvServer;
@ -114,16 +113,20 @@ typedef struct
{
DWORD ref;
DWORD size;
void **methods;
IUnknownVtbl vtbl;
/* remaining entries in vtbl */
} ref_counted_vtbl;
static ref_counted_vtbl *current_vtbl;
static struct
{
ref_counted_vtbl *table;
} current_vtbl;
static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv)
{
*ppv = pUnk;
*ppv = (void *)pUnk;
return S_OK;
}
@ -158,137 +161,87 @@ typedef struct {
} vtbl_method_t;
#include "poppack.h"
#define BLOCK_SIZE 1024
#define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */
static const vtbl_method_t *method_blocks[MAX_BLOCKS];
static const vtbl_method_t *allocate_block( unsigned int num )
static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num)
{
unsigned int i;
vtbl_method_t *prev, *block;
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(&current_vtbl.table->vtbl, current_vtbl.table->methods, num_methods);
VirtualProtect(current_vtbl.table->methods, size, PAGE_EXECUTE_READ, &old_protect);
}
LeaveCriticalSection(&delegating_vtbl_section);
}
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 = &current_vtbl->vtbl;
current_vtbl.table->ref++;
ret = &current_vtbl.table->vtbl;
LeaveCriticalSection(&delegating_vtbl_section);
return ret;
}
@ -300,21 +253,22 @@ static void release_delegating_vtbl(IUnknownVtbl *vtbl)
EnterCriticalSection(&delegating_vtbl_section);
table->ref--;
TRACE("ref now %d\n", table->ref);
if(table->ref == 0 && table != current_vtbl)
if(table->ref == 0 && table != current_vtbl.table)
{
TRACE("... and we're not current so free'ing\n");
VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE);
HeapFree(GetProcessHeap(), 0, table);
}
LeaveCriticalSection(&delegating_vtbl_section);
}
HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid,
LPUNKNOWN pUnkServer,
PCInterfaceName name,
CInterfaceStubVtbl *vtbl,
REFIID delegating_iid,
LPPSFACTORYBUFFER pPSFactory,
LPRPCSTUBBUFFER *ppStub)
HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid,
LPUNKNOWN pUnkServer,
PCInterfaceName name,
CInterfaceStubVtbl *vtbl,
REFIID delegating_iid,
LPPSFACTORYBUFFER pPSFactory,
LPRPCSTUBBUFFER *ppStub)
{
cstdstubbuffer_delegating_t *This;
IUnknown *pvServer;
@ -340,7 +294,7 @@ HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid,
return E_OUTOFMEMORY;
}
This->base_obj = get_delegating_vtbl( vtbl->header.DispatchTableCount );
This->base_obj = get_delegating_vtbl();
r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub);
if(FAILED(r))
{

View file

@ -19,7 +19,7 @@
*
*/
#include "epm.h"
#include "epm_c.h"
#define EPM_PROTOCOL_DNET_NSP 0x04
#define EPM_PROTOCOL_OSI_TP4 0x05

View file

@ -59,7 +59,7 @@ static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
{
struct context_handle_entry *che = CContext;
struct context_handle_entry *che = (struct context_handle_entry*) CContext;
if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
return NULL;
@ -111,7 +111,7 @@ void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
}
else
{
ndr_context_handle *wire_data = pBuff;
ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
wire_data->attributes = 0;
wire_data->uuid = GUID_NULL;
}

View file

@ -62,6 +62,6 @@ extern const NDR_BUFFERSIZE NdrBufferSizer[];
extern const NDR_MEMORYSIZE NdrMemorySizer[];
extern const NDR_FREE NdrFreer[];
ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat);
unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat);
#endif /* __WINE_NDR_MISC_H */

View file

@ -369,30 +369,6 @@ void WINAPI NdrOleFree(void *NodeToFree)
COM_MemFree(NodeToFree);
}
/***********************************************************************
* Helper function to create a proxy.
* Probably similar to NdrpCreateProxy.
*/
HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv)
{
CLSID clsid;
IPSFactoryBuffer *psfac;
HRESULT r;
if(!LoadCOM()) return E_FAIL;
r = COM_GetPSClsid( iid, &clsid );
if(FAILED(r)) return r;
r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac );
if(FAILED(r)) return r;
r = IPSFactoryBuffer_CreateProxy(psfac, pUnkOuter, iid, pproxy, ppv);
IPSFactoryBuffer_Release(psfac);
return r;
}
/***********************************************************************
* Helper function to create a stub.
* This probably looks very much like NdrpCreateStub.

View file

@ -173,7 +173,7 @@ static PFORMAT_STRING client_get_handle(
if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR)
pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
else
pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf);
pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index];
*phBinding = pGenPair->pfnBind(pObject);
@ -256,7 +256,7 @@ static void client_free_handle(
if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR)
pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
else
pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset);
memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf);
pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index];
pGenPair->pfnUnbind(pObject, hBinding);
@ -867,14 +867,9 @@ __declspec(naked) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigne
LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size);
__ASM_GLOBAL_FUNC(call_server_func,
"pushl %ebp\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
"movl %esp,%ebp\n\t"
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
"movl %esp, %ebp\n\t"
"pushl %edi\n\t" /* Save registers */
__ASM_CFI(".cfi_rel_offset %edi,-4\n\t")
"pushl %esi\n\t"
__ASM_CFI(".cfi_rel_offset %esi,-8\n\t")
"movl 16(%ebp), %eax\n\t" /* Get stack size */
"subl %eax, %esp\n\t" /* Make room in stack for arguments */
"andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for Mac OS X */
@ -887,13 +882,9 @@ __ASM_GLOBAL_FUNC(call_server_func,
"call *8(%ebp)\n\t" /* Call function */
"leal -8(%ebp), %esp\n\t" /* Restore stack */
"popl %esi\n\t" /* Restore registers */
__ASM_CFI(".cfi_same_value %esi\n\t")
"popl %edi\n\t"
__ASM_CFI(".cfi_same_value %edi\n\t")
"popl %ebp\n\t"
__ASM_CFI(".cfi_def_cfa %esp,4\n\t")
__ASM_CFI(".cfi_same_value %ebp\n\t")
"ret" )
"ret\n" )
#else
#warning call_server_func not implemented for your architecture
LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size)
@ -1531,339 +1522,3 @@ void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg)
DWORD dwPhase;
NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase);
}
struct async_call_data
{
MIDL_STUB_MESSAGE *pStubMsg;
const NDR_PROC_HEADER *pProcHeader;
PFORMAT_STRING pHandleFormat;
PFORMAT_STRING pParamFormat;
RPC_BINDING_HANDLE hBinding;
/* size of stack */
unsigned short stack_size;
/* number of parameters. optional for client to give it to us */
unsigned char number_of_params;
/* correlation cache */
unsigned long NdrCorrCache[256];
};
LONG_PTR WINAPIV NdrAsyncClientCall(PMIDL_STUB_DESC pStubDesc,
PFORMAT_STRING pFormat, ...)
{
/* pointer to start of stack where arguments start */
PRPC_MESSAGE pRpcMsg;
PMIDL_STUB_MESSAGE pStubMsg;
RPC_ASYNC_STATE *pAsync;
struct async_call_data *async_call_data;
/* procedure number */
unsigned short procedure_number;
/* cache of Oif_flags from v2 procedure header */
INTERPRETER_OPT_FLAGS Oif_flags = { 0 };
/* cache of extension flags from NDR_PROC_HEADER_EXTS */
INTERPRETER_OPT_FLAGS2 ext_flags = { 0 };
/* the type of pass we are currently doing */
int phase;
/* header for procedure string */
const NDR_PROC_HEADER * pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0];
/* -Oif or -Oicf generated format */
BOOL bV2Format = FALSE;
TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat);
/* Later NDR language versions probably won't be backwards compatible */
if (pStubDesc->Version > 0x50002)
{
FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version);
RpcRaiseException(RPC_X_WRONG_STUB_VERSION);
}
async_call_data = I_RpcAllocate(sizeof(*async_call_data) + sizeof(MIDL_STUB_MESSAGE) + sizeof(RPC_MESSAGE));
if (!async_call_data) RpcRaiseException(ERROR_OUTOFMEMORY);
async_call_data->number_of_params = ~0;
async_call_data->pProcHeader = pProcHeader;
async_call_data->pStubMsg = pStubMsg = (PMIDL_STUB_MESSAGE)(async_call_data + 1);
pRpcMsg = (PRPC_MESSAGE)(pStubMsg + 1);
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
{
const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0];
async_call_data->stack_size = pProcHeader->stack_size;
procedure_number = pProcHeader->proc_num;
pFormat += sizeof(NDR_PROC_HEADER_RPC);
}
else
{
async_call_data->stack_size = pProcHeader->stack_size;
procedure_number = pProcHeader->proc_num;
pFormat += sizeof(NDR_PROC_HEADER);
}
TRACE("stack size: 0x%x\n", async_call_data->stack_size);
TRACE("proc num: %d\n", procedure_number);
/* create the full pointer translation tables, if requested */
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT);
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
{
ERR("objects not supported\n");
I_RpcFree(async_call_data);
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDesc, procedure_number);
TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags);
TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion);
/* needed for conformance of top-level objects */
#ifdef __i386__
pStubMsg->StackTop = I_RpcAllocate(async_call_data->stack_size);
/* FIXME: this may read one more DWORD than is necessary, but it shouldn't hurt */
memcpy(pStubMsg->StackTop, *(unsigned char **)(&pFormat+1), async_call_data->stack_size);
#else
# warning Stack not retrieved for your CPU architecture
#endif
pAsync = *(RPC_ASYNC_STATE **)pStubMsg->StackTop;
pAsync->StubInfo = async_call_data;
async_call_data->pHandleFormat = pFormat;
pFormat = client_get_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, &async_call_data->hBinding);
if (!pFormat) return 0;
bV2Format = (pStubDesc->Version >= 0x20000);
if (bV2Format)
{
const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader =
(const NDR_PROC_PARTIAL_OIF_HEADER *)pFormat;
Oif_flags = pOIFHeader->Oi2Flags;
async_call_data->number_of_params = pOIFHeader->number_of_params;
pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER);
}
TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags);
if (Oif_flags.HasExtensions)
{
const NDR_PROC_HEADER_EXTS *pExtensions =
(const NDR_PROC_HEADER_EXTS *)pFormat;
ext_flags = pExtensions->Flags2;
pFormat += pExtensions->Size;
}
async_call_data->pParamFormat = pFormat;
pStubMsg->BufferLength = 0;
/* store the RPC flags away */
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
pRpcMsg->RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags;
/* use alternate memory allocation routines */
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC)
NdrRpcSmSetClientToOsf(pStubMsg);
if (Oif_flags.HasPipes)
{
FIXME("pipes not supported yet\n");
RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */
/* init pipes package */
/* NdrPipesInitialize(...) */
}
if (ext_flags.HasNewCorrDesc)
{
/* initialize extra correlation package */
NdrCorrelationInitialize(pStubMsg, async_call_data->NdrCorrCache, sizeof(async_call_data->NdrCorrCache), 0);
}
/* order of phases:
* 1. PROXY_CALCSIZE - calculate the buffer size
* 2. PROXY_GETBUFFER - allocate the buffer
* 3. PROXY_MARHSAL - marshal [in] params into the buffer
* 4. PROXY_SENDRECEIVE - send buffer
* Then in NdrpCompleteAsyncClientCall:
* 1. PROXY_SENDRECEIVE - receive buffer
* 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer
*/
for (phase = PROXY_CALCSIZE; phase <= PROXY_SENDRECEIVE; phase++)
{
RPC_STATUS status;
TRACE("phase = %d\n", phase);
switch (phase)
{
case PROXY_GETBUFFER:
/* allocate the buffer */
if (Oif_flags.HasPipes)
/* NdrGetPipeBuffer(...) */
FIXME("pipes not supported yet\n");
else
{
if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
#if 0
NdrNsGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding);
#else
FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n");
#endif
else
NdrGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding);
}
pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
status = I_RpcAsyncSetHandle(pRpcMsg, pAsync);
if (status != RPC_S_OK)
RpcRaiseException(status);
break;
case PROXY_SENDRECEIVE:
pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
/* send the [in] params only */
if (Oif_flags.HasPipes)
/* NdrPipesSend(...) */
FIXME("pipes not supported yet\n");
else
{
if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
#if 0
NdrNsSend(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle);
#else
FIXME("using auto handle - call NdrNsSend when it gets implemented\n");
#endif
else
{
pStubMsg->RpcMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
status = I_RpcSend(pStubMsg->RpcMsg);
if (status != RPC_S_OK)
RpcRaiseException(status);
}
}
break;
case PROXY_CALCSIZE:
case PROXY_MARSHAL:
if (bV2Format)
client_do_args(pStubMsg, pFormat, phase, pStubMsg->StackTop,
async_call_data->number_of_params, NULL);
else
client_do_args_old_format(pStubMsg, pFormat, phase,
pStubMsg->StackTop, async_call_data->stack_size, NULL,
(pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT), FALSE);
break;
default:
ERR("shouldn't reach here. phase %d\n", phase);
break;
}
}
TRACE("returning 0\n");
return 0;
}
RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply)
{
/* pointer to start of stack where arguments start */
PMIDL_STUB_MESSAGE pStubMsg;
struct async_call_data *async_call_data;
/* the type of pass we are currently doing */
int phase;
/* header for procedure string */
const NDR_PROC_HEADER * pProcHeader;
/* -Oif or -Oicf generated format */
BOOL bV2Format;
RPC_STATUS status = RPC_S_OK;
if (!pAsync->StubInfo)
return RPC_S_INVALID_ASYNC_HANDLE;
async_call_data = pAsync->StubInfo;
pStubMsg = async_call_data->pStubMsg;
pProcHeader = async_call_data->pProcHeader;
bV2Format = (pStubMsg->StubDesc->Version >= 0x20000);
/* order of phases:
* 1. PROXY_CALCSIZE - calculate the buffer size
* 2. PROXY_GETBUFFER - allocate the buffer
* 3. PROXY_MARHSAL - marshal [in] params into the buffer
* 4. PROXY_SENDRECEIVE - send buffer
* Then in NdrpCompleteAsyncClientCall:
* 1. PROXY_SENDRECEIVE - receive buffer
* 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer
*/
for (phase = PROXY_SENDRECEIVE; phase <= PROXY_UNMARSHAL; phase++)
{
switch (phase)
{
case PROXY_SENDRECEIVE:
pStubMsg->RpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
/* receive the [out] params */
if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
#if 0
NdrNsReceive(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle);
#else
FIXME("using auto handle - call NdrNsReceive when it gets implemented\n");
#endif
else
{
status = I_RpcReceive(pStubMsg->RpcMsg);
if (status != RPC_S_OK)
goto cleanup;
pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
pStubMsg->Buffer = pStubMsg->BufferStart;
}
/* convert strings, floating point values and endianess into our
* preferred format */
#if 0
if ((pStubMsg->RpcMsg.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)
NdrConvert(pStubMsg, pFormat);
#endif
break;
case PROXY_UNMARSHAL:
if (bV2Format)
client_do_args(pStubMsg, async_call_data->pParamFormat, phase, pStubMsg->StackTop,
async_call_data->number_of_params, Reply);
else
client_do_args_old_format(pStubMsg, async_call_data->pParamFormat, phase,
pStubMsg->StackTop, async_call_data->stack_size, Reply, FALSE, FALSE);
break;
default:
ERR("shouldn't reach here. phase %d\n", phase);
break;
}
}
cleanup:
if (pStubMsg->fHasNewCorrDesc)
{
/* free extra correlation package */
NdrCorrelationFree(pStubMsg);
}
/* free the full pointer translation tables */
if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);
/* free marshalling buffer */
NdrFreeBuffer(pStubMsg);
client_free_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, async_call_data->hBinding);
I_RpcFree(pStubMsg->StackTop);
I_RpcFree(async_call_data);
TRACE("-- 0x%x\n", status);
return status;
}
RPCRTAPI LONG RPC_ENTRY NdrAsyncStubCall(struct IRpcStubBuffer* pThis,
struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg,
DWORD * pdwStubPhase)
{
FIXME("unimplemented, expect crash!\n");
return 0;
}

View file

@ -85,7 +85,7 @@ typedef struct _NDR_PROC_HEADER_RPC
* RPCF_Asynchronous = 0x4000 - [async] MIDL attribute
* Reserved = 0x8000
*/
unsigned int rpc_flags;
unsigned long rpc_flags;
unsigned short proc_num;
unsigned short stack_size;
@ -240,4 +240,3 @@ void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg,
PFORMAT_STRING pFormat, int phase, unsigned char *args,
unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc,
BOOL ignore_retval);
RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply);

View file

@ -125,7 +125,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr,
RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr,
LPCSTR Endpoint, LPCWSTR NetworkOptions,
ULONG assoc_gid,
unsigned long assoc_gid,
RpcAssoc **assoc_out)
{
RpcAssoc *assoc;
@ -223,7 +223,7 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection *
RPC_MESSAGE msg;
RPC_STATUS status;
unsigned char *auth_data = NULL;
ULONG auth_length;
unsigned long auth_length;
TRACE("sending bind request to server\n");
@ -394,7 +394,6 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
if (status != RPC_S_OK)
return status;
NewConnection->assoc = assoc;
status = RPCRT4_OpenClientConnection(NewConnection);
if (status != RPC_S_OK)
{
@ -417,7 +416,6 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection)
{
assert(!Connection->server);
Connection->async_state = NULL;
EnterCriticalSection(&assoc->cs);
if (!assoc->assoc_group_id) assoc->assoc_group_id = Connection->assoc_group_id;
list_add_head(&assoc->free_connection_pool, &Connection->conn_pool_entry);

View file

@ -34,7 +34,6 @@ typedef struct _RpcAssoc
/* id of this association group */
ULONG assoc_group_id;
UUID http_uuid;
CRITICAL_SECTION cs;
@ -50,7 +49,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endp
RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, RpcConnection **Connection);
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection);
ULONG RpcAssoc_Release(RpcAssoc *assoc);
RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, ULONG assoc_gid, RpcAssoc **assoc_out);
RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, unsigned long assoc_gid, RpcAssoc **assoc_out);
RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext);
RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext);
RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine);

View file

@ -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;
}
/***********************************************************************

View file

@ -661,11 +661,11 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU
return RPC_S_OK;
fail:
if (ObjUuid) RpcStringFreeA(ObjUuid);
if (Protseq) RpcStringFreeA(Protseq);
if (NetworkAddr) RpcStringFreeA(NetworkAddr);
if (Endpoint) RpcStringFreeA(Endpoint);
if (Options) RpcStringFreeA(Options);
if (ObjUuid) RpcStringFreeA((unsigned char**)ObjUuid);
if (Protseq) RpcStringFreeA((unsigned char**)Protseq);
if (NetworkAddr) RpcStringFreeA((unsigned char**)NetworkAddr);
if (Endpoint) RpcStringFreeA((unsigned char**)Endpoint);
if (Options) RpcStringFreeA((unsigned char**)Options);
return RPC_S_INVALID_STRING_BINDING;
}
@ -796,7 +796,7 @@ RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding )
RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector )
{
RPC_STATUS status;
ULONG c;
unsigned long c;
TRACE("(%p)\n", BindingVector);
for (c=0; c<(*BindingVector)->Count; c++) {
@ -812,7 +812,7 @@ RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector )
*/
RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid )
{
RpcBinding* bind = Binding;
RpcBinding* bind = (RpcBinding*)Binding;
TRACE("(%p,%p) = %s\n", Binding, ObjectUuid, debugstr_guid(&bind->ObjectUuid));
*ObjectUuid = bind->ObjectUuid;
@ -824,7 +824,7 @@ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU
*/
RPC_STATUS WINAPI RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid )
{
RpcBinding* bind = Binding;
RpcBinding* bind = (RpcBinding*)Binding;
TRACE("(%p,%s)\n", Binding, debugstr_guid(ObjectUuid));
if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING;
@ -856,11 +856,11 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BIND
if (ret == RPC_S_OK)
ret = RPCRT4_CompleteBindingA(bind, (char*)NetworkAddr, (char*)Endpoint, (char*)Options);
RpcStringFreeA(&Options);
RpcStringFreeA(&Endpoint);
RpcStringFreeA(&NetworkAddr);
RpcStringFreeA(&Protseq);
RpcStringFreeA(&ObjectUuid);
RpcStringFreeA((unsigned char**)&Options);
RpcStringFreeA((unsigned char**)&Endpoint);
RpcStringFreeA((unsigned char**)&NetworkAddr);
RpcStringFreeA((unsigned char**)&Protseq);
RpcStringFreeA((unsigned char**)&ObjectUuid);
if (ret == RPC_S_OK)
*Binding = (RPC_BINDING_HANDLE)bind;
@ -915,7 +915,7 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BIND
RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CSTR *StringBinding )
{
RPC_STATUS ret;
RpcBinding* bind = Binding;
RpcBinding* bind = (RpcBinding*)Binding;
RPC_CSTR ObjectUuid;
TRACE("(%p,%p)\n", Binding, StringBinding);
@ -946,7 +946,7 @@ RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, RPC_WS
TRACE("(%p,%p)\n", Binding, StringBinding);
ret = RpcBindingToStringBindingA(Binding, &str);
*StringBinding = RPCRT4_strdupAtoW((char*)str);
RpcStringFreeA(&str);
RpcStringFreeA((unsigned char**)&str);
return ret;
}
@ -969,7 +969,7 @@ RPC_STATUS WINAPI I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding, unsi
*/
RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn)
{
RpcBinding* bind = Binding;
RpcBinding* bind = (RpcBinding*)Binding;
TRACE( "(%p,%p): stub\n", Binding, BlockingFn );
@ -986,7 +986,7 @@ RPC_STATUS RPC_ENTRY RpcBindingCopy(
RPC_BINDING_HANDLE* DestinationBinding)
{
RpcBinding *DestBinding;
RpcBinding *SrcBinding = SourceBinding;
RpcBinding *SrcBinding = (RpcBinding*)SourceBinding;
RPC_STATUS status;
TRACE("(%p, %p)\n", SourceBinding, DestinationBinding);
@ -1501,7 +1501,7 @@ RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName,
RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr,
RPC_SECURITY_QOS *SecurityQos )
{
RpcBinding* bind = Binding;
RpcBinding* bind = (RpcBinding*)Binding;
SECURITY_STATUS r;
CredHandle cred;
TimeStamp exp;
@ -1631,7 +1631,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName,
ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr,
RPC_SECURITY_QOS *SecurityQos )
{
RpcBinding* bind = Binding;
RpcBinding* bind = (RpcBinding*)Binding;
SECURITY_STATUS r;
CredHandle cred;
TimeStamp exp;
@ -1640,7 +1640,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName,
PSecPkgInfoW packages;
ULONG cbMaxToken;
TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w(ServerPrincName),
TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w((const WCHAR*)ServerPrincName),
AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos);
if (SecurityQos)
@ -1772,7 +1772,7 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnLevel,
ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr )
{
TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w(ServerPrincName),
TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w((const WCHAR*)ServerPrincName),
AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr);
return RpcBindingSetAuthInfoExW(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, NULL);
}

View file

@ -24,7 +24,6 @@
#include "rpcndr.h"
#include "security.h"
#include "wine/list.h"
#include "rpc_defs.h"
typedef struct _RpcAuthInfo
@ -67,7 +66,6 @@ typedef struct _RpcConnection
TimeStamp exp;
ULONG attr;
RpcAuthInfo *AuthInfo;
ULONG auth_context_id;
ULONG encryption_auth_len;
ULONG signature_auth_len;
RpcQualityOfService *QOS;
@ -76,7 +74,6 @@ typedef struct _RpcConnection
struct list conn_pool_entry;
ULONG assoc_group_id; /* association group returned during binding */
RPC_ASYNC_STATE *async_state;
struct _RpcAssoc *assoc; /* association this connection is part of */
/* server-only */
/* The active interface bound to server. */
@ -99,7 +96,6 @@ struct connection_ops {
int (*wait_for_incoming_data)(RpcConnection *conn);
size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint);
RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint);
RPC_STATUS (*receive_fragment)(RpcConnection *conn, RpcPktHdr **Header, void **Payload);
};
/* don't know what MS's structure looks like */

View file

@ -31,13 +31,13 @@ typedef struct
unsigned char drep[4]; /* Data representation */
unsigned short frag_len; /* Data size in bytes including header and tail. */
unsigned short auth_len; /* Authentication length */
unsigned int call_id; /* Call identifier. */
unsigned long call_id; /* Call identifier. */
} RpcPktCommonHdr;
typedef struct
{
RpcPktCommonHdr common;
unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */
unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */
unsigned short context_id; /* Presentation context identifier */
unsigned short opnum;
} RpcPktRequestHdr;
@ -45,7 +45,7 @@ typedef struct
typedef struct
{
RpcPktCommonHdr common;
unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */
unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */
unsigned short context_id; /* Presentation context identifier */
unsigned char cancel_count;
unsigned char reserved;
@ -54,12 +54,12 @@ typedef struct
typedef struct
{
RpcPktCommonHdr common;
unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */
unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */
unsigned short context_id; /* Presentation context identifier */
unsigned char cancel_count; /* Received cancel count */
unsigned char reserved; /* Force alignment! */
unsigned int status; /* Runtime fault code (RPC_STATUS) */
unsigned int reserved2;
unsigned long status; /* Runtime fault code (RPC_STATUS) */
unsigned long reserved2;
} RpcPktFaultHdr;
typedef struct
@ -67,7 +67,7 @@ typedef struct
RpcPktCommonHdr common;
unsigned short max_tsize; /* Maximum transmission fragment size */
unsigned short max_rsize; /* Maximum receive fragment size */
unsigned int assoc_gid; /* Associated group id */
unsigned long assoc_gid; /* Associated group id */
unsigned char num_elements; /* Number of elements */
unsigned char padding[3]; /* Force alignment! */
unsigned short context_id; /* Presentation context identifier */
@ -99,7 +99,7 @@ typedef struct
RpcPktCommonHdr common;
unsigned short max_tsize; /* Maximum transmission fragment size */
unsigned short max_rsize; /* Maximum receive fragment size */
unsigned int assoc_gid; /* Associated group id */
unsigned long assoc_gid; /* Associated group id */
/*
* Following this header are these fields:
* RpcAddressString server_address;
@ -120,14 +120,6 @@ typedef struct
} protocols[1];
} RpcPktBindNAckHdr;
/* undocumented packet sent during RPC over HTTP */
typedef struct
{
RpcPktCommonHdr common;
unsigned short flags;
unsigned short num_data_items;
} RpcPktHttpHdr;
/* Union representing all possible packet headers */
typedef union
{
@ -138,7 +130,6 @@ typedef union
RpcPktBindHdr bind;
RpcPktBindAckHdr bind_ack;
RpcPktBindNAckHdr bind_nack;
RpcPktHttpHdr http;
} RpcPktHdr;
typedef struct
@ -147,7 +138,7 @@ typedef struct
unsigned char auth_level; /* RPC_C_AUTHN_LEVEL* */
unsigned char auth_pad_length; /* length of padding to restore n % 4 alignment */
unsigned char auth_reserved; /* reserved, must be zero */
unsigned int auth_context_id; /* unique value for the authenticated connection */
unsigned long auth_context_id; /* unique value for the authenticated connection */
} RpcAuthVerifier;
#define RPC_AUTH_VERIFIER_LEN(common_hdr) \
@ -183,7 +174,6 @@ typedef struct
#define PKT_SHUTDOWN 17
#define PKT_CO_CANCEL 18
#define PKT_ORPHANED 19
#define PKT_HTTP 20
#define RESULT_ACCEPT 0
#define RESULT_USER_REJECTION 1

View file

@ -32,7 +32,7 @@
#include "wine/exception.h"
#include "rpc_binding.h"
#include "epm.h"
#include "epm_c.h"
#include "epm_towers.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@ -116,7 +116,7 @@ static BOOL start_rpcss(void)
static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle)
{
RpcBinding *bind = handle;
RpcBinding *bind = (RpcBinding *)handle;
const char *protseq = bind->Protseq;
const char *network_addr = bind->NetworkAddr;
@ -127,7 +127,7 @@ static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle)
static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_HANDLE *epm_handle)
{
RpcBinding *bind = handle;
RpcBinding *bind = (RpcBinding *)handle;
const char * pszEndpoint = NULL;
RPC_STATUS status;
RpcBinding* epm_bind;
@ -149,7 +149,7 @@ static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_H
status = RpcBindingCopy(handle, epm_handle);
if (status != RPC_S_OK) return status;
epm_bind = *epm_handle;
epm_bind = (RpcBinding*)*epm_handle;
if (epm_bind->AuthInfo)
{
/* don't bother with authenticating against the EPM by default
@ -187,8 +187,8 @@ static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *__eptr)
RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
UUID_VECTOR *UuidVector, RPC_CSTR Annotation )
{
PRPC_SERVER_INTERFACE If = IfSpec;
ULONG i;
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
unsigned long i;
RPC_STATUS status = RPC_S_OK;
error_status_t status2;
ept_entry_t *entries;
@ -197,13 +197,13 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation));
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
for (i=0; i<BindingVector->Count; i++) {
RpcBinding* bind = BindingVector->BindingH[i];
TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq));
TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint));
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq));
TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint));
}
if (UuidVector) {
for (i=0; i<UuidVector->Count; i++)
TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
}
if (!BindingVector->Count) return RPC_S_OK;
@ -222,9 +222,10 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
for (i = 0; i < BindingVector->Count; i++)
{
unsigned j;
RpcBinding* bind = BindingVector->BindingH[i];
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++)
{
int len = strlen((char *)Annotation);
status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax,
bind->Protseq, bind->Endpoint,
bind->NetworkAddr,
@ -235,9 +236,7 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
memcpy(&entries[i * UuidVector->Count].object, &UuidVector->Uuid[j], sizeof(GUID));
else
memset(&entries[i].object, 0, sizeof(entries[i].object));
if (Annotation)
memcpy(entries[i].annotation, Annotation,
min(strlen((char *)Annotation) + 1, ept_max_annotation_size));
memcpy(entries[i].annotation, Annotation, min(len + 1, ept_max_annotation_size));
}
}
@ -281,29 +280,14 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
return status;
}
/***********************************************************************
* RpcEpRegisterW (RPCRT4.@)
*/
RPC_STATUS WINAPI RpcEpRegisterW( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
UUID_VECTOR *UuidVector, RPC_WSTR Annotation )
{
LPSTR annA = RPCRT4_strdupWtoA(Annotation);
RPC_STATUS status;
status = RpcEpRegisterA(IfSpec, BindingVector, UuidVector, (RPC_CSTR)annA);
HeapFree(GetProcessHeap(), 0, annA);
return status;
}
/***********************************************************************
* RpcEpUnregister (RPCRT4.@)
*/
RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
UUID_VECTOR *UuidVector )
{
PRPC_SERVER_INTERFACE If = IfSpec;
ULONG i;
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
unsigned long i;
RPC_STATUS status = RPC_S_OK;
error_status_t status2;
ept_entry_t *entries;
@ -312,13 +296,13 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector);
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
for (i=0; i<BindingVector->Count; i++) {
RpcBinding* bind = BindingVector->BindingH[i];
TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq));
TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint));
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq));
TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint));
}
if (UuidVector) {
for (i=0; i<UuidVector->Count; i++)
TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
}
entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*entries) * BindingVector->Count * (UuidVector ? UuidVector->Count : 1));
@ -335,7 +319,7 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
for (i = 0; i < BindingVector->Count; i++)
{
unsigned j;
RpcBinding* bind = BindingVector->BindingH[i];
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++)
{
status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax,
@ -388,8 +372,8 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
*/
RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec )
{
PRPC_CLIENT_INTERFACE If = IfSpec;
RpcBinding* bind = Binding;
PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec;
RpcBinding* bind = (RpcBinding*)Binding;
RPC_STATUS status;
error_status_t status2;
handle_t handle;

View file

@ -59,13 +59,13 @@ enum secure_packet_direction
static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg);
DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
{
static const DWORD header_sizes[] = {
sizeof(Header->request), 0, sizeof(Header->response),
sizeof(Header->fault), 0, 0, 0, 0, 0, 0, 0, sizeof(Header->bind),
sizeof(Header->bind_ack), sizeof(Header->bind_nack),
0, 0, 0, 0, 0, 0, sizeof(Header->http)
0, 0, 0, 0, 0
};
ULONG ret = 0;
@ -76,7 +76,7 @@ DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
if (Header->common.flags & RPC_FLG_OBJECT_UUID)
ret += sizeof(UUID);
} else {
WARN("invalid packet type %u\n", Header->common.ptype);
TRACE("invalid packet type\n");
}
return ret;
@ -96,7 +96,7 @@ static int packet_has_auth_verifier(const RpcPktHdr *Header)
}
static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType,
ULONG DataRepresentation)
unsigned long DataRepresentation)
{
Header->common.rpc_ver = RPC_VER_MAJOR;
Header->common.rpc_ver_minor = RPC_VER_MINOR;
@ -111,8 +111,8 @@ static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType
/* Flags and fragment length are computed in RPCRT4_Send. */
}
static RpcPktHdr *RPCRT4_BuildRequestHeader(ULONG DataRepresentation,
ULONG BufferLength,
static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation,
unsigned long BufferLength,
unsigned short ProcNum,
UUID *ObjectUuid)
{
@ -141,7 +141,8 @@ static RpcPktHdr *RPCRT4_BuildRequestHeader(ULONG DataRepresentation,
return header;
}
RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength)
RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation,
unsigned long BufferLength)
{
RpcPktHdr *header;
@ -157,7 +158,8 @@ RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLeng
return header;
}
RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status)
RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation,
RPC_STATUS Status)
{
RpcPktHdr *header;
@ -173,10 +175,10 @@ RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status)
return header;
}
RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation,
RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation,
unsigned short MaxTransmissionSize,
unsigned short MaxReceiveSize,
ULONG AssocGroupId,
unsigned long AssocGroupId,
const RPC_SYNTAX_IDENTIFIER *AbstractId,
const RPC_SYNTAX_IDENTIFIER *TransferId)
{
@ -200,7 +202,7 @@ RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation,
return header;
}
static RpcPktHdr *RPCRT4_BuildAuthHeader(ULONG DataRepresentation)
static RpcPktHdr *RPCRT4_BuildAuthHeader(unsigned long DataRepresentation)
{
RpcPktHdr *header;
@ -216,7 +218,7 @@ static RpcPktHdr *RPCRT4_BuildAuthHeader(ULONG DataRepresentation)
return header;
}
RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation,
RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation,
unsigned char RpcVersion,
unsigned char RpcVersionMinor)
{
@ -237,17 +239,17 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation,
return header;
}
RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation,
RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation,
unsigned short MaxTransmissionSize,
unsigned short MaxReceiveSize,
ULONG AssocGroupId,
unsigned long AssocGroupId,
LPCSTR ServerAddress,
unsigned short Result,
unsigned short Reason,
unsigned long Result,
unsigned long Reason,
const RPC_SYNTAX_IDENTIFIER *TransferId)
{
RpcPktHdr *header;
ULONG header_size;
unsigned long header_size;
RpcAddressString *server_address;
RpcResults *results;
RPC_SYNTAX_IDENTIFIER *transfer_id;
@ -281,118 +283,6 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation,
return header;
}
RpcPktHdr *RPCRT4_BuildHttpHeader(ULONG DataRepresentation,
unsigned short flags,
unsigned short num_data_items,
unsigned int payload_size)
{
RpcPktHdr *header;
header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->http) + payload_size);
if (header == NULL) {
ERR("failed to allocate memory\n");
return NULL;
}
RPCRT4_BuildCommonHeader(header, PKT_HTTP, DataRepresentation);
/* since the packet isn't current sent using RPCRT4_Send, set the flags
* manually here */
header->common.flags = RPC_FLG_FIRST|RPC_FLG_LAST;
header->common.call_id = 0;
header->common.frag_len = sizeof(header->http) + payload_size;
header->http.flags = flags;
header->http.num_data_items = num_data_items;
return header;
}
#define WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, type, value) \
do { \
*(unsigned int *)(payload) = (type); \
(payload) += 4; \
*(unsigned int *)(payload) = (value); \
(payload) += 4; \
} while (0)
#define WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, type, uuid) \
do { \
*(unsigned int *)(payload) = (type); \
(payload) += 4; \
*(UUID *)(payload) = (uuid); \
(payload) += sizeof(UUID); \
} while (0)
#define WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted, flow_control_increment, uuid) \
do { \
*(unsigned int *)(payload) = 0x00000001; \
(payload) += 4; \
*(unsigned int *)(payload) = (bytes_transmitted); \
(payload) += 4; \
*(unsigned int *)(payload) = (flow_control_increment); \
(payload) += 4; \
*(UUID *)(payload) = (uuid); \
(payload) += sizeof(UUID); \
} while (0)
RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe,
const UUID *connection_uuid,
const UUID *pipe_uuid,
const UUID *association_uuid)
{
RpcPktHdr *header;
unsigned int size;
char *payload;
size = 8 + 4 + sizeof(UUID) + 4 + sizeof(UUID) + 8;
if (!out_pipe)
size += 8 + 4 + sizeof(UUID);
header = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, flags,
out_pipe ? 4 : 6, size);
if (!header) return NULL;
payload = (char *)(&header->http+1);
/* FIXME: what does this part of the payload do? */
WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000006, 0x00000001);
WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *connection_uuid);
WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *pipe_uuid);
if (out_pipe)
/* FIXME: what does this part of the payload do? */
WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000000, 0x00010000);
else
{
/* FIXME: what does this part of the payload do? */
WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000004, 0x40000000);
/* FIXME: what does this part of the payload do? */
WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000005, 0x000493e0);
WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x0000000c, *association_uuid);
}
return header;
}
RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted,
ULONG flow_control_increment,
const UUID *pipe_uuid)
{
RpcPktHdr *header;
char *payload;
header = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, 0x2, 2,
5 * sizeof(ULONG) + sizeof(UUID));
if (!header) return NULL;
payload = (char *)(&header->http+1);
WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x0000000d, (server ? 0x0 : 0x3));
WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted,
flow_control_increment, *pipe_uuid);
return header;
}
VOID RPCRT4_FreeHeader(RpcPktHdr *Header)
{
HeapFree(GetProcessHeap(), 0, Header);
@ -472,206 +362,6 @@ static RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status)
}
}
/* assumes the common header fields have already been validated */
BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data,
unsigned short data_len)
{
unsigned short i;
BYTE *p = data;
for (i = 0; i < hdr->http.num_data_items; i++)
{
ULONG type;
if (data_len < sizeof(ULONG))
return FALSE;
type = *(ULONG *)p;
p += sizeof(ULONG);
data_len -= sizeof(ULONG);
switch (type)
{
case 0x3:
case 0xc:
if (data_len < sizeof(GUID))
return FALSE;
p += sizeof(GUID);
data_len -= sizeof(GUID);
break;
case 0x0:
case 0x2:
case 0x4:
case 0x5:
case 0x6:
case 0xd:
if (data_len < sizeof(ULONG))
return FALSE;
p += sizeof(ULONG);
data_len -= sizeof(ULONG);
break;
case 0x1:
if (data_len < 24)
return FALSE;
p += 24;
data_len -= 24;
break;
default:
FIXME("unimplemented type 0x%x\n", type);
break;
}
}
return TRUE;
}
/* assumes the HTTP packet has been validated */
static unsigned char *RPCRT4_NextHttpHeaderField(unsigned char *data)
{
ULONG type;
type = *(ULONG *)data;
data += sizeof(ULONG);
switch (type)
{
case 0x3:
case 0xc:
return data + sizeof(GUID);
case 0x0:
case 0x2:
case 0x4:
case 0x5:
case 0x6:
case 0xd:
return data + sizeof(ULONG);
case 0x1:
return data + 24;
default:
FIXME("unimplemented type 0x%x\n", type);
return data;
}
}
#define READ_HTTP_PAYLOAD_FIELD_TYPE(data) *(ULONG *)(data)
#define GET_HTTP_PAYLOAD_FIELD_DATA(data) ((data) + sizeof(ULONG))
/* assumes the HTTP packet has been validated */
RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header,
unsigned char *data, ULONG *field1)
{
ULONG type;
if (header->http.flags != 0x0)
{
ERR("invalid flags 0x%x\n", header->http.flags);
return RPC_S_PROTOCOL_ERROR;
}
if (header->http.num_data_items != 1)
{
ERR("invalid number of data items %d\n", header->http.num_data_items);
return RPC_S_PROTOCOL_ERROR;
}
type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
if (type != 0x00000002)
{
ERR("invalid type 0x%08x\n", type);
return RPC_S_PROTOCOL_ERROR;
}
*field1 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
return RPC_S_OK;
}
/* assumes the HTTP packet has been validated */
RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header,
unsigned char *data, ULONG *field1,
ULONG *bytes_until_next_packet,
ULONG *field3)
{
ULONG type;
if (header->http.flags != 0x0)
{
ERR("invalid flags 0x%x\n", header->http.flags);
return RPC_S_PROTOCOL_ERROR;
}
if (header->http.num_data_items != 3)
{
ERR("invalid number of data items %d\n", header->http.num_data_items);
return RPC_S_PROTOCOL_ERROR;
}
type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
if (type != 0x00000006)
{
ERR("invalid type for field 1: 0x%08x\n", type);
return RPC_S_PROTOCOL_ERROR;
}
*field1 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
data = RPCRT4_NextHttpHeaderField(data);
type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
if (type != 0x00000000)
{
ERR("invalid type for field 2: 0x%08x\n", type);
return RPC_S_PROTOCOL_ERROR;
}
*bytes_until_next_packet = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
data = RPCRT4_NextHttpHeaderField(data);
type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
if (type != 0x00000002)
{
ERR("invalid type for field 3: 0x%08x\n", type);
return RPC_S_PROTOCOL_ERROR;
}
*field3 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
return RPC_S_OK;
}
RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header,
unsigned char *data, BOOL server,
ULONG *bytes_transmitted,
ULONG *flow_control_increment,
UUID *pipe_uuid)
{
ULONG type;
if (header->http.flags != 0x2)
{
ERR("invalid flags 0x%x\n", header->http.flags);
return RPC_S_PROTOCOL_ERROR;
}
if (header->http.num_data_items != 2)
{
ERR("invalid number of data items %d\n", header->http.num_data_items);
return RPC_S_PROTOCOL_ERROR;
}
type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
if (type != 0x0000000d)
{
ERR("invalid type for field 1: 0x%08x\n", type);
return RPC_S_PROTOCOL_ERROR;
}
if (*(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data) != (server ? 0x3 : 0x0))
{
ERR("invalid type for 0xd field data: 0x%08x\n", *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data));
return RPC_S_PROTOCOL_ERROR;
}
data = RPCRT4_NextHttpHeaderField(data);
type = READ_HTTP_PAYLOAD_FIELD_TYPE(data);
if (type != 0x00000001)
{
ERR("invalid type for field 2: 0x%08x\n", type);
return RPC_S_PROTOCOL_ERROR;
}
*bytes_transmitted = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
*flow_control_increment = *(ULONG *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 4);
*pipe_uuid = *(UUID *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 8);
return RPC_S_OK;
}
static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection,
enum secure_packet_direction dir,
RpcPktHdr *hdr, unsigned int hdr_size,
@ -819,7 +509,7 @@ static RPC_STATUS RPCRT4_SendWithAuth(RpcConnection *Connection, RpcPktHdr *Head
auth_hdr->auth_pad_length = auth_pad_len;
auth_hdr->auth_reserved = 0;
/* a unique number... */
auth_hdr->auth_context_id = Connection->auth_context_id;
auth_hdr->auth_context_id = (unsigned long)Connection;
if (AuthLength)
memcpy(auth_hdr + 1, Auth, AuthLength);
@ -997,7 +687,7 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
}
/* validates version and frag_len fields */
RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr)
static RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr)
{
DWORD hdr_length;
@ -1026,11 +716,11 @@ RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr)
}
/***********************************************************************
* RPCRT4_default_receive_fragment (internal)
* RPCRT4_receive_fragment (internal)
*
* Receive a fragment from a connection.
*/
static RPC_STATUS RPCRT4_default_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload)
static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload)
{
RPC_STATUS status;
DWORD hdr_length;
@ -1104,14 +794,6 @@ fail:
return status;
}
static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload)
{
if (Connection->ops->receive_fragment)
return Connection->ops->receive_fragment(Connection, Header, Payload);
else
return RPCRT4_default_receive_fragment(Connection, Header, Payload);
}
/***********************************************************************
* RPCRT4_ReceiveWithAuth (internal)
*
@ -1121,14 +803,14 @@ static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr *
RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header,
PRPC_MESSAGE pMsg,
unsigned char **auth_data_out,
ULONG *auth_length_out)
unsigned long *auth_length_out)
{
RPC_STATUS status;
DWORD hdr_length;
unsigned short first_flag;
ULONG data_length;
ULONG buffer_length;
ULONG auth_length = 0;
unsigned long data_length;
unsigned long buffer_length;
unsigned long auth_length = 0;
unsigned char *auth_data = NULL;
RpcPktHdr *CurrentHeader = NULL;
void *payload = NULL;
@ -1192,7 +874,7 @@ RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header,
}
if (CurrentHeader->common.auth_len != auth_length) {
WARN("auth_len header field changed from %d to %d\n",
WARN("auth_len header field changed from %ld to %d\n",
auth_length, CurrentHeader->common.auth_len);
status = RPC_S_PROTOCOL_ERROR;
goto fail;
@ -1206,7 +888,7 @@ RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header,
data_length = CurrentHeader->common.frag_len - hdr_length - header_auth_len;
if (data_length + buffer_length > pMsg->BufferLength) {
TRACE("allocation hint exceeded, new buffer length = %d\n",
TRACE("allocation hint exceeded, new buffer length = %ld\n",
data_length + buffer_length);
pMsg->BufferLength = data_length + buffer_length;
status = I_RpcReAllocateBuffer(pMsg);
@ -1316,7 +998,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
*/
RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg)
{
RpcBinding* bind = pMsg->Handle;
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
RpcConnection* conn;
RPC_STATUS status = RPC_S_OK;
@ -1381,7 +1063,7 @@ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg)
RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
{
RPC_STATUS status;
RpcBinding* bind = pMsg->Handle;
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
@ -1438,7 +1120,7 @@ static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg)
*/
RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
{
RpcBinding* bind = pMsg->Handle;
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer);
@ -1532,7 +1214,7 @@ static DWORD WINAPI async_notifier_proc(LPVOID p)
*/
RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
{
RpcBinding* bind = pMsg->Handle;
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
RpcConnection* conn;
RPC_STATUS status;
RpcPktHdr *hdr;
@ -1586,7 +1268,7 @@ static inline BOOL is_hard_error(RPC_STATUS status)
*/
RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
{
RpcBinding* bind = pMsg->Handle;
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
RPC_STATUS status;
RpcPktHdr *hdr = NULL;
RpcConnection *conn;
@ -1605,7 +1287,7 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
case PKT_RESPONSE:
break;
case PKT_FAULT:
ERR ("we got fault packet with status 0x%x\n", hdr->fault.status);
ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status);
status = NCA2RPC_STATUS(hdr->fault.status);
if (is_hard_error(status))
goto fail;
@ -1678,7 +1360,7 @@ RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg)
*/
RPC_STATUS WINAPI I_RpcAsyncSetHandle(PRPC_MESSAGE pMsg, PRPC_ASYNC_STATE pAsync)
{
RpcBinding* bind = pMsg->Handle;
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
RpcConnection *conn;
TRACE("(%p, %p)\n", pMsg, pAsync);

View file

@ -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);

View file

@ -367,7 +367,7 @@ static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg)
static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
{
RpcConnection* conn = the_arg;
RpcConnection* conn = (RpcConnection*)the_arg;
RpcPktHdr *hdr;
RPC_MESSAGE *msg;
RPC_STATUS status;
@ -449,23 +449,27 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
/* start waiting */
res = cps->ops->wait_for_new_connection(cps, count, objs);
if (res == -1 || (res == 0 && !std_listen))
{
/* cleanup */
cps->ops->free_wait_array(cps, objs);
EnterCriticalSection(&cps->cs);
for (conn = cps->conn; conn; conn = conn->Next)
RPCRT4_CloseConnection(conn);
LeaveCriticalSection(&cps->cs);
if (res == 0 && !std_listen)
SetEvent(cps->server_ready_event);
if (res == -1)
break;
}
else if (res == 0)
{
if (!std_listen)
{
SetEvent(cps->server_ready_event);
break;
}
set_ready_event = TRUE;
}
}
cps->ops->free_wait_array(cps, objs);
EnterCriticalSection(&cps->cs);
/* close connections */
conn = cps->conn;
while (conn) {
RPCRT4_CloseConnection(conn);
conn = conn->Next;
}
LeaveCriticalSection(&cps->cs);
return 0;
}
@ -566,32 +570,11 @@ static void RPCRT4_stop_listen(BOOL auto_listen)
LeaveCriticalSection(&listen_cs);
}
static BOOL RPCRT4_protseq_is_endpoint_registered(RpcServerProtseq *protseq, const char *endpoint)
{
RpcConnection *conn;
EnterCriticalSection(&protseq->cs);
for (conn = protseq->conn; conn; conn = conn->Next)
{
if (!endpoint || !strcmp(endpoint, conn->Endpoint))
break;
}
LeaveCriticalSection(&protseq->cs);
return (conn != NULL);
}
static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, const char *endpoint)
static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, LPSTR endpoint)
{
RPC_STATUS status;
EnterCriticalSection(&ps->cs);
if (RPCRT4_protseq_is_endpoint_registered(ps, endpoint))
status = RPC_S_OK;
else
status = ps->ops->open_endpoint(ps, endpoint);
LeaveCriticalSection(&ps->cs);
status = ps->ops->open_endpoint(ps, endpoint);
if (status != RPC_S_OK)
return status;
@ -625,8 +608,11 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
count = 0;
LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
EnterCriticalSection(&ps->cs);
for (conn = ps->conn; conn; conn = conn->Next)
conn = ps->conn;
while (conn) {
count++;
conn = conn->Next;
}
LeaveCriticalSection(&ps->cs);
}
if (count) {
@ -638,10 +624,12 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
count = 0;
LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
EnterCriticalSection(&ps->cs);
for (conn = ps->conn; conn; conn = conn->Next) {
conn = ps->conn;
while (conn) {
RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count],
conn);
count++;
conn = conn->Next;
}
LeaveCriticalSection(&ps->cs);
}
@ -693,7 +681,7 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_W
*
* Must be called with server_cs held.
*/
static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps)
static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps)
{
const struct protseq_ops *ops = rpcrt4_get_protseq_ops(Protseq);
@ -707,7 +695,7 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcSe
if (!*ps)
return RPC_S_OUT_OF_RESOURCES;
(*ps)->MaxCalls = MaxCalls;
(*ps)->Protseq = RPCRT4_strdupA(Protseq);
(*ps)->Protseq = Protseq;
(*ps)->ops = ops;
(*ps)->MaxCalls = 0;
(*ps)->conn = NULL;
@ -723,19 +711,8 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcSe
return RPC_S_OK;
}
/* must be called with server_cs held */
static void destroy_serverprotoseq(RpcServerProtseq *ps)
{
RPCRT4_strfree(ps->Protseq);
DeleteCriticalSection(&ps->cs);
CloseHandle(ps->mgr_mutex);
CloseHandle(ps->server_ready_event);
list_remove(&ps->entry);
HeapFree(GetProcessHeap(), 0, ps);
}
/* Finds a given protseq or creates a new one if one doesn't already exist */
static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps)
static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps)
{
RPC_STATUS status;
RpcServerProtseq *cps;
@ -764,18 +741,19 @@ static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, const char *
RPC_STATUS WINAPI RpcServerUseProtseqEpExA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor,
PRPC_POLICY lpPolicy )
{
char *szps = (char*)Protseq, *szep = (char*)Endpoint;
RpcServerProtseq* ps;
RPC_STATUS status;
TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a((const char *)Protseq),
MaxCalls, debugstr_a((const char *)Endpoint), SecurityDescriptor,
TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a(szps), MaxCalls,
debugstr_a(szep), SecurityDescriptor,
lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps);
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupA(szps), &ps);
if (status != RPC_S_OK)
return status;
return RPCRT4_use_protseq(ps, (const char *)Endpoint);
return RPCRT4_use_protseq(ps, szep);
}
/***********************************************************************
@ -786,16 +764,13 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC
{
RpcServerProtseq* ps;
RPC_STATUS status;
LPSTR ProtseqA;
LPSTR EndpointA;
TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_w( Protseq ), MaxCalls,
debugstr_w( Endpoint ), SecurityDescriptor,
lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
ProtseqA = RPCRT4_strdupWtoA(Protseq);
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps);
RPCRT4_strfree(ProtseqA);
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps);
if (status != RPC_S_OK)
return status;
@ -810,16 +785,8 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC
*/
RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
{
RPC_STATUS status;
RpcServerProtseq* ps;
TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_a((char*)Protseq), MaxCalls, SecurityDescriptor);
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps);
if (status != RPC_S_OK)
return status;
return RPCRT4_use_protseq(ps, NULL);
return RpcServerUseProtseqEpA(Protseq, MaxCalls, NULL, SecurityDescriptor);
}
/***********************************************************************
@ -827,36 +794,8 @@ RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls,
*/
RPC_STATUS WINAPI RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
{
RPC_STATUS status;
RpcServerProtseq* ps;
LPSTR ProtseqA;
TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_w(Protseq), MaxCalls, SecurityDescriptor);
ProtseqA = RPCRT4_strdupWtoA(Protseq);
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps);
RPCRT4_strfree(ProtseqA);
if (status != RPC_S_OK)
return status;
return RPCRT4_use_protseq(ps, NULL);
}
void RPCRT4_destroy_all_protseqs(void)
{
RpcServerProtseq *cps, *cursor2;
if (listen_count != 0)
std_listen = FALSE;
EnterCriticalSection(&server_cs);
LIST_FOR_EACH_ENTRY_SAFE(cps, cursor2, &protseqs, RpcServerProtseq, entry)
{
if (listen_count != 0)
RPCRT4_sync_with_server_thread(cps);
destroy_serverprotoseq(cps);
}
LeaveCriticalSection(&server_cs);
return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor);
}
/***********************************************************************
@ -884,7 +823,7 @@ RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid
RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn )
{
PRPC_SERVER_INTERFACE If = IfSpec;
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
RpcServerInterface* sif;
unsigned int i;
@ -937,7 +876,7 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid,
*/
RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete )
{
PRPC_SERVER_INTERFACE If = IfSpec;
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
HANDLE event = NULL;
BOOL found = FALSE;
BOOL completed = TRUE;

View file

@ -56,7 +56,7 @@ struct protseq_ops
* new connection was established */
int (*wait_for_new_connection)(RpcServerProtseq *protseq, unsigned int count, void *wait_array);
/* opens the endpoint and optionally begins listening */
RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, const char *endpoint);
RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, LPSTR endpoint);
};
typedef struct _RpcServerInterface
@ -79,6 +79,4 @@ typedef struct _RpcServerInterface
void RPCRT4_new_client(RpcConnection* conn);
const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq);
void RPCRT4_destroy_all_protseqs(void);
#endif /* __WINE_RPC_SERVER_H */

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,6 @@
<library>user32</library>
<library>advapi32</library>
<library>secur32</library>
<!--library>wininet</library-->
<library>iphlpapi</library>
<library>ws2_32</library>
<library>ntdll</library>

View file

@ -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

View file

@ -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;
}
/*************************************************************************