mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 12:29:56 +00:00
- Add ros-specific changes patch.
- Set svn:eol-style properties. svn path=/trunk/; revision=31632
This commit is contained in:
parent
ecdee48d72
commit
1a8f12eaee
30 changed files with 17137 additions and 17151 deletions
|
@ -1,450 +1,450 @@
|
|||
/*
|
||||
* COM proxy implementation
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO: Handle non-i386 architectures
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "cpsf.h"
|
||||
#include "ndr_misc.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
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;
|
||||
PCInterfaceName name;
|
||||
LPPSFACTORYBUFFER pPSFactory;
|
||||
LPRPCCHANNELBUFFER pChannel;
|
||||
struct StublessThunk *thunks;
|
||||
} StdProxyImpl;
|
||||
|
||||
static const IRpcProxyBufferVtbl StdProxy_Vtbl;
|
||||
|
||||
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
|
||||
|
||||
/* How the Windows stubless proxy thunks work is explained at
|
||||
* http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp,
|
||||
* but I'll use a slightly different method, to make life easier */
|
||||
|
||||
#if defined(__i386__)
|
||||
|
||||
#include "pshpack1.h"
|
||||
|
||||
struct StublessThunk {
|
||||
BYTE push;
|
||||
DWORD index;
|
||||
BYTE call;
|
||||
LONG handler;
|
||||
BYTE ret;
|
||||
WORD bytes;
|
||||
BYTE pad[3];
|
||||
};
|
||||
|
||||
#include "poppack.h"
|
||||
|
||||
/* adjust the stack size since we don't use Windows's method */
|
||||
#define STACK_ADJUST sizeof(DWORD)
|
||||
|
||||
#define FILL_STUBLESS(x,idx,stk) \
|
||||
x->push = 0x68; /* pushl [immediate] */ \
|
||||
x->index = (idx); \
|
||||
x->call = 0xe8; /* call [near] */ \
|
||||
x->handler = (char*)ObjectStubless - (char*)&x->ret; \
|
||||
x->ret = 0xc2; /* ret [immediate] */ \
|
||||
x->bytes = stk; \
|
||||
x->pad[0] = 0x8d; /* leal (%esi),%esi */ \
|
||||
x->pad[1] = 0x76; \
|
||||
x->pad[2] = 0x00;
|
||||
|
||||
static HRESULT WINAPI ObjectStubless(DWORD index)
|
||||
{
|
||||
char *args = (char*)(&index + 2);
|
||||
LPVOID iface = *(LPVOID*)args;
|
||||
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
|
||||
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));
|
||||
|
||||
return NdrClientCall2(This->stubless->pStubDesc, fs, args);
|
||||
}
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
/* 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 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];
|
||||
|
||||
TRACE("(%p,%p,%p,%p,%p) %s\n", pUnkOuter, vtbl, pPSFactory, ppProxy, ppvObj, name);
|
||||
|
||||
/* TableVersion = 2 means it is the stubless version of CInterfaceProxyVtbl */
|
||||
if (ProxyInfo->TableVersion > 1) {
|
||||
stubless = *(const void **)vtbl;
|
||||
vtbl = (CInterfaceProxyVtbl *)((const void **)vtbl + 1);
|
||||
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;
|
||||
}
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(StdProxyImpl));
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
|
||||
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;
|
||||
/* one reference for the proxy */
|
||||
This->RefCount = 1;
|
||||
This->stubless = stubless;
|
||||
This->piid = vtbl->header.piid;
|
||||
This->pUnkOuter = pUnkOuter;
|
||||
This->name = name;
|
||||
This->pPSFactory = pPSFactory;
|
||||
This->pChannel = NULL;
|
||||
*ppProxy = (LPRPCPROXYBUFFER)&This->lpVtbl;
|
||||
*ppvObj = &This->PVtbl;
|
||||
/* 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);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void WINAPI StdProxy_Destruct(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
|
||||
if (This->pChannel)
|
||||
IRpcProxyBuffer_Disconnect(iface);
|
||||
|
||||
IPSFactoryBuffer_Release(This->pPSFactory);
|
||||
if (This->thunks) {
|
||||
HeapFree(GetProcessHeap(),0,This->PVtbl);
|
||||
HeapFree(GetProcessHeap(),0,This->thunks);
|
||||
}
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj);
|
||||
|
||||
if (IsEqualGUID(&IID_IUnknown,riid) ||
|
||||
IsEqualGUID(This->piid,riid)) {
|
||||
*obj = &This->PVtbl;
|
||||
InterlockedIncrement(&This->RefCount);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (IsEqualGUID(&IID_IRpcProxyBuffer,riid)) {
|
||||
*obj = &This->lpVtbl;
|
||||
InterlockedIncrement(&This->RefCount);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI StdProxy_AddRef(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->AddRef()\n",This);
|
||||
|
||||
return InterlockedIncrement(&This->RefCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI StdProxy_Release(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ULONG refs;
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->Release()\n",This);
|
||||
|
||||
refs = InterlockedDecrement(&This->RefCount);
|
||||
if (!refs)
|
||||
StdProxy_Destruct((LPRPCPROXYBUFFER)&This->lpVtbl);
|
||||
return refs;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface,
|
||||
LPRPCCHANNELBUFFER pChannel)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->Connect(%p)\n",This,pChannel);
|
||||
|
||||
This->pChannel = pChannel;
|
||||
IRpcChannelBuffer_AddRef(pChannel);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->Disconnect()\n",This);
|
||||
|
||||
IRpcChannelBuffer_Release(This->pChannel);
|
||||
This->pChannel = NULL;
|
||||
}
|
||||
|
||||
static const IRpcProxyBufferVtbl StdProxy_Vtbl =
|
||||
{
|
||||
StdProxy_QueryInterface,
|
||||
StdProxy_AddRef,
|
||||
StdProxy_Release,
|
||||
StdProxy_Connect,
|
||||
StdProxy_Disconnect
|
||||
};
|
||||
|
||||
static void StdProxy_GetChannel(LPVOID iface,
|
||||
LPRPCCHANNELBUFFER *ppChannel)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->GetChannel(%p) %s\n",This,ppChannel,This->name);
|
||||
|
||||
*ppChannel = This->pChannel;
|
||||
}
|
||||
|
||||
static void StdProxy_GetIID(LPVOID iface,
|
||||
const IID **ppiid)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->GetIID(%p) %s\n",This,ppiid,This->name);
|
||||
|
||||
*ppiid = This->piid;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IUnknown_QueryInterface_Proxy(LPUNKNOWN iface,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObj)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->QueryInterface(%s,%p) %s\n",This,debugstr_guid(riid),ppvObj,This->name);
|
||||
return IUnknown_QueryInterface(This->pUnkOuter,riid,ppvObj);
|
||||
}
|
||||
|
||||
ULONG WINAPI IUnknown_AddRef_Proxy(LPUNKNOWN iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->AddRef() %s\n",This,This->name);
|
||||
return IUnknown_AddRef(This->pUnkOuter);
|
||||
}
|
||||
|
||||
ULONG WINAPI IUnknown_Release_Proxy(LPUNKNOWN iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->Release() %s\n",This,This->name);
|
||||
return IUnknown_Release(This->pUnkOuter);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyInitialize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyInitialize(void *This,
|
||||
PRPC_MESSAGE pRpcMsg,
|
||||
PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDescriptor,
|
||||
unsigned int ProcNum)
|
||||
{
|
||||
TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
|
||||
NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
|
||||
StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer);
|
||||
IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
|
||||
&pStubMsg->dwDestContext,
|
||||
&pStubMsg->pvDestContext);
|
||||
TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyGetBuffer(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
HRESULT hr;
|
||||
const IID *riid = NULL;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
|
||||
pStubMsg->dwStubPhase = PROXY_GETBUFFER;
|
||||
StdProxy_GetIID(This, &riid);
|
||||
hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg,
|
||||
riid);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RpcRaiseException(hr);
|
||||
return;
|
||||
}
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
pStubMsg->dwStubPhase = PROXY_MARSHAL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxySendReceive [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxySendReceive(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
ULONG Status = 0;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
|
||||
if (!pStubMsg->pRpcChannelBuffer)
|
||||
{
|
||||
WARN("Trying to use disconnected proxy %p\n", This);
|
||||
RpcRaiseException(RPC_E_DISCONNECTED);
|
||||
}
|
||||
|
||||
pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
|
||||
hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg,
|
||||
&Status);
|
||||
pStubMsg->dwStubPhase = PROXY_UNMARSHAL;
|
||||
pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
|
||||
/* raise exception if call failed */
|
||||
if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer);
|
||||
else if (FAILED(hr)) RpcRaiseException(hr);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyFreeBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyFreeBuffer(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
hr = IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyErrorHandler [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode)
|
||||
{
|
||||
WARN("(0x%08x): a proxy call failed\n", dwExceptionCode);
|
||||
|
||||
if (FAILED(dwExceptionCode))
|
||||
return dwExceptionCode;
|
||||
else
|
||||
return HRESULT_FROM_WIN32(dwExceptionCode);
|
||||
}
|
||||
|
||||
HRESULT WINAPI
|
||||
CreateProxyFromTypeInfo( LPTYPEINFO pTypeInfo, LPUNKNOWN pUnkOuter, REFIID riid,
|
||||
LPRPCPROXYBUFFER *ppProxy, LPVOID *ppv )
|
||||
{
|
||||
typedef INT (WINAPI *MessageBoxA)(HWND,LPCSTR,LPCSTR,UINT);
|
||||
HMODULE hUser32 = LoadLibraryA("user32");
|
||||
MessageBoxA pMessageBoxA = (void *)GetProcAddress(hUser32, "MessageBoxA");
|
||||
|
||||
FIXME("%p %p %s %p %p\n", pTypeInfo, pUnkOuter, debugstr_guid(riid), ppProxy, ppv);
|
||||
if (pMessageBoxA)
|
||||
{
|
||||
pMessageBoxA(NULL,
|
||||
"The native implementation of OLEAUT32.DLL cannot be used "
|
||||
"with Wine's RPCRT4.DLL. Remove OLEAUT32.DLL and try again.\n",
|
||||
"Wine: Unimplemented CreateProxyFromTypeInfo",
|
||||
0x10);
|
||||
ExitProcess(1);
|
||||
}
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
/*
|
||||
* COM proxy implementation
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO: Handle non-i386 architectures
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "cpsf.h"
|
||||
#include "ndr_misc.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
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;
|
||||
PCInterfaceName name;
|
||||
LPPSFACTORYBUFFER pPSFactory;
|
||||
LPRPCCHANNELBUFFER pChannel;
|
||||
struct StublessThunk *thunks;
|
||||
} StdProxyImpl;
|
||||
|
||||
static const IRpcProxyBufferVtbl StdProxy_Vtbl;
|
||||
|
||||
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
|
||||
|
||||
/* How the Windows stubless proxy thunks work is explained at
|
||||
* http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp,
|
||||
* but I'll use a slightly different method, to make life easier */
|
||||
|
||||
#if defined(__i386__)
|
||||
|
||||
#include "pshpack1.h"
|
||||
|
||||
struct StublessThunk {
|
||||
BYTE push;
|
||||
DWORD index;
|
||||
BYTE call;
|
||||
LONG handler;
|
||||
BYTE ret;
|
||||
WORD bytes;
|
||||
BYTE pad[3];
|
||||
};
|
||||
|
||||
#include "poppack.h"
|
||||
|
||||
/* adjust the stack size since we don't use Windows's method */
|
||||
#define STACK_ADJUST sizeof(DWORD)
|
||||
|
||||
#define FILL_STUBLESS(x,idx,stk) \
|
||||
x->push = 0x68; /* pushl [immediate] */ \
|
||||
x->index = (idx); \
|
||||
x->call = 0xe8; /* call [near] */ \
|
||||
x->handler = (char*)ObjectStubless - (char*)&x->ret; \
|
||||
x->ret = 0xc2; /* ret [immediate] */ \
|
||||
x->bytes = stk; \
|
||||
x->pad[0] = 0x8d; /* leal (%esi),%esi */ \
|
||||
x->pad[1] = 0x76; \
|
||||
x->pad[2] = 0x00;
|
||||
|
||||
static HRESULT WINAPI ObjectStubless(DWORD index)
|
||||
{
|
||||
char *args = (char*)(&index + 2);
|
||||
LPVOID iface = *(LPVOID*)args;
|
||||
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
|
||||
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));
|
||||
|
||||
return NdrClientCall2(This->stubless->pStubDesc, fs, args);
|
||||
}
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
/* 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 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];
|
||||
|
||||
TRACE("(%p,%p,%p,%p,%p) %s\n", pUnkOuter, vtbl, pPSFactory, ppProxy, ppvObj, name);
|
||||
|
||||
/* TableVersion = 2 means it is the stubless version of CInterfaceProxyVtbl */
|
||||
if (ProxyInfo->TableVersion > 1) {
|
||||
stubless = *(const void **)vtbl;
|
||||
vtbl = (CInterfaceProxyVtbl *)((const void **)vtbl + 1);
|
||||
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;
|
||||
}
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(StdProxyImpl));
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
|
||||
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;
|
||||
/* one reference for the proxy */
|
||||
This->RefCount = 1;
|
||||
This->stubless = stubless;
|
||||
This->piid = vtbl->header.piid;
|
||||
This->pUnkOuter = pUnkOuter;
|
||||
This->name = name;
|
||||
This->pPSFactory = pPSFactory;
|
||||
This->pChannel = NULL;
|
||||
*ppProxy = (LPRPCPROXYBUFFER)&This->lpVtbl;
|
||||
*ppvObj = &This->PVtbl;
|
||||
/* 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);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void WINAPI StdProxy_Destruct(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
|
||||
if (This->pChannel)
|
||||
IRpcProxyBuffer_Disconnect(iface);
|
||||
|
||||
IPSFactoryBuffer_Release(This->pPSFactory);
|
||||
if (This->thunks) {
|
||||
HeapFree(GetProcessHeap(),0,This->PVtbl);
|
||||
HeapFree(GetProcessHeap(),0,This->thunks);
|
||||
}
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj);
|
||||
|
||||
if (IsEqualGUID(&IID_IUnknown,riid) ||
|
||||
IsEqualGUID(This->piid,riid)) {
|
||||
*obj = &This->PVtbl;
|
||||
InterlockedIncrement(&This->RefCount);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (IsEqualGUID(&IID_IRpcProxyBuffer,riid)) {
|
||||
*obj = &This->lpVtbl;
|
||||
InterlockedIncrement(&This->RefCount);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI StdProxy_AddRef(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->AddRef()\n",This);
|
||||
|
||||
return InterlockedIncrement(&This->RefCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI StdProxy_Release(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ULONG refs;
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->Release()\n",This);
|
||||
|
||||
refs = InterlockedDecrement(&This->RefCount);
|
||||
if (!refs)
|
||||
StdProxy_Destruct((LPRPCPROXYBUFFER)&This->lpVtbl);
|
||||
return refs;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface,
|
||||
LPRPCCHANNELBUFFER pChannel)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->Connect(%p)\n",This,pChannel);
|
||||
|
||||
This->pChannel = pChannel;
|
||||
IRpcChannelBuffer_AddRef(pChannel);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->Disconnect()\n",This);
|
||||
|
||||
IRpcChannelBuffer_Release(This->pChannel);
|
||||
This->pChannel = NULL;
|
||||
}
|
||||
|
||||
static const IRpcProxyBufferVtbl StdProxy_Vtbl =
|
||||
{
|
||||
StdProxy_QueryInterface,
|
||||
StdProxy_AddRef,
|
||||
StdProxy_Release,
|
||||
StdProxy_Connect,
|
||||
StdProxy_Disconnect
|
||||
};
|
||||
|
||||
static void StdProxy_GetChannel(LPVOID iface,
|
||||
LPRPCCHANNELBUFFER *ppChannel)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->GetChannel(%p) %s\n",This,ppChannel,This->name);
|
||||
|
||||
*ppChannel = This->pChannel;
|
||||
}
|
||||
|
||||
static void StdProxy_GetIID(LPVOID iface,
|
||||
const IID **ppiid)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->GetIID(%p) %s\n",This,ppiid,This->name);
|
||||
|
||||
*ppiid = This->piid;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IUnknown_QueryInterface_Proxy(LPUNKNOWN iface,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObj)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->QueryInterface(%s,%p) %s\n",This,debugstr_guid(riid),ppvObj,This->name);
|
||||
return IUnknown_QueryInterface(This->pUnkOuter,riid,ppvObj);
|
||||
}
|
||||
|
||||
ULONG WINAPI IUnknown_AddRef_Proxy(LPUNKNOWN iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->AddRef() %s\n",This,This->name);
|
||||
return IUnknown_AddRef(This->pUnkOuter);
|
||||
}
|
||||
|
||||
ULONG WINAPI IUnknown_Release_Proxy(LPUNKNOWN iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->Release() %s\n",This,This->name);
|
||||
return IUnknown_Release(This->pUnkOuter);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyInitialize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyInitialize(void *This,
|
||||
PRPC_MESSAGE pRpcMsg,
|
||||
PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDescriptor,
|
||||
unsigned int ProcNum)
|
||||
{
|
||||
TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
|
||||
NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
|
||||
StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer);
|
||||
IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
|
||||
&pStubMsg->dwDestContext,
|
||||
&pStubMsg->pvDestContext);
|
||||
TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyGetBuffer(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
HRESULT hr;
|
||||
const IID *riid = NULL;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
|
||||
pStubMsg->dwStubPhase = PROXY_GETBUFFER;
|
||||
StdProxy_GetIID(This, &riid);
|
||||
hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg,
|
||||
riid);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RpcRaiseException(hr);
|
||||
return;
|
||||
}
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
pStubMsg->dwStubPhase = PROXY_MARSHAL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxySendReceive [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxySendReceive(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
ULONG Status = 0;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
|
||||
if (!pStubMsg->pRpcChannelBuffer)
|
||||
{
|
||||
WARN("Trying to use disconnected proxy %p\n", This);
|
||||
RpcRaiseException(RPC_E_DISCONNECTED);
|
||||
}
|
||||
|
||||
pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
|
||||
hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg,
|
||||
&Status);
|
||||
pStubMsg->dwStubPhase = PROXY_UNMARSHAL;
|
||||
pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
|
||||
/* raise exception if call failed */
|
||||
if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer);
|
||||
else if (FAILED(hr)) RpcRaiseException(hr);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyFreeBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyFreeBuffer(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
hr = IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyErrorHandler [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode)
|
||||
{
|
||||
WARN("(0x%08x): a proxy call failed\n", dwExceptionCode);
|
||||
|
||||
if (FAILED(dwExceptionCode))
|
||||
return dwExceptionCode;
|
||||
else
|
||||
return HRESULT_FROM_WIN32(dwExceptionCode);
|
||||
}
|
||||
|
||||
HRESULT WINAPI
|
||||
CreateProxyFromTypeInfo( LPTYPEINFO pTypeInfo, LPUNKNOWN pUnkOuter, REFIID riid,
|
||||
LPRPCPROXYBUFFER *ppProxy, LPVOID *ppv )
|
||||
{
|
||||
typedef INT (WINAPI *MessageBoxA)(HWND,LPCSTR,LPCSTR,UINT);
|
||||
HMODULE hUser32 = LoadLibraryA("user32");
|
||||
MessageBoxA pMessageBoxA = (void *)GetProcAddress(hUser32, "MessageBoxA");
|
||||
|
||||
FIXME("%p %p %s %p %p\n", pTypeInfo, pUnkOuter, debugstr_guid(riid), ppProxy, ppv);
|
||||
if (pMessageBoxA)
|
||||
{
|
||||
pMessageBoxA(NULL,
|
||||
"The native implementation of OLEAUT32.DLL cannot be used "
|
||||
"with Wine's RPCRT4.DLL. Remove OLEAUT32.DLL and try again.\n",
|
||||
"Wine: Unimplemented CreateProxyFromTypeInfo",
|
||||
0x10);
|
||||
ExitProcess(1);
|
||||
}
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
|
|
@ -1,307 +1,307 @@
|
|||
/*
|
||||
* COM proxy/stub factory (CStdPSFactory) implementation
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "cpsf.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
static BOOL FindProxyInfo(const ProxyFileInfo **pProxyFileList, REFIID riid, const ProxyFileInfo **pProxyInfo, int *pIndex)
|
||||
{
|
||||
while (*pProxyFileList) {
|
||||
if ((*pProxyFileList)->pIIDLookupRtn(riid, pIndex)) {
|
||||
*pProxyInfo = *pProxyFileList;
|
||||
TRACE("found: ProxyInfo %p Index %d\n", *pProxyInfo, *pIndex);
|
||||
return TRUE;
|
||||
}
|
||||
pProxyFileList++;
|
||||
}
|
||||
TRACE("not found\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CStdPSFactory_QueryInterface(LPPSFACTORYBUFFER iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
{
|
||||
CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface;
|
||||
TRACE("(%p)->QueryInterface(%s,%p)\n",iface,debugstr_guid(riid),obj);
|
||||
if (IsEqualGUID(&IID_IUnknown,riid) ||
|
||||
IsEqualGUID(&IID_IPSFactoryBuffer,riid)) {
|
||||
*obj = This;
|
||||
This->RefCount++;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI CStdPSFactory_AddRef(LPPSFACTORYBUFFER iface)
|
||||
{
|
||||
CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface;
|
||||
TRACE("(%p)->AddRef()\n",iface);
|
||||
return ++(This->RefCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI CStdPSFactory_Release(LPPSFACTORYBUFFER iface)
|
||||
{
|
||||
CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface;
|
||||
TRACE("(%p)->Release()\n",iface);
|
||||
return --(This->RefCount);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CStdPSFactory_CreateProxy(LPPSFACTORYBUFFER iface,
|
||||
LPUNKNOWN pUnkOuter,
|
||||
REFIID riid,
|
||||
LPRPCPROXYBUFFER *ppProxy,
|
||||
LPVOID *ppv)
|
||||
{
|
||||
CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface;
|
||||
const ProxyFileInfo *ProxyInfo;
|
||||
int Index;
|
||||
TRACE("(%p)->CreateProxy(%p,%s,%p,%p)\n",iface,pUnkOuter,
|
||||
debugstr_guid(riid),ppProxy,ppv);
|
||||
if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index))
|
||||
return E_NOINTERFACE;
|
||||
return StdProxy_Construct(riid, pUnkOuter, ProxyInfo, Index, iface, ppProxy, ppv);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface,
|
||||
REFIID riid,
|
||||
LPUNKNOWN pUnkServer,
|
||||
LPRPCSTUBBUFFER *ppStub)
|
||||
{
|
||||
CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface;
|
||||
const ProxyFileInfo *ProxyInfo;
|
||||
int Index;
|
||||
TRACE("(%p)->CreateStub(%s,%p,%p)\n",iface,debugstr_guid(riid),
|
||||
pUnkServer,ppStub);
|
||||
if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index))
|
||||
return E_NOINTERFACE;
|
||||
|
||||
if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index])
|
||||
return CStdStubBuffer_Delegating_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index],
|
||||
ProxyInfo->pStubVtblList[Index], ProxyInfo->pDelegatedIIDs[Index],
|
||||
iface, ppStub);
|
||||
|
||||
return CStdStubBuffer_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index],
|
||||
ProxyInfo->pStubVtblList[Index], iface, ppStub);
|
||||
}
|
||||
|
||||
static const IPSFactoryBufferVtbl CStdPSFactory_Vtbl =
|
||||
{
|
||||
CStdPSFactory_QueryInterface,
|
||||
CStdPSFactory_AddRef,
|
||||
CStdPSFactory_Release,
|
||||
CStdPSFactory_CreateProxy,
|
||||
CStdPSFactory_CreateStub
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* NdrDllGetClassObject [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
|
||||
const ProxyFileInfo **pProxyFileList,
|
||||
const CLSID *pclsid,
|
||||
CStdPSFactoryBuffer *pPSFactoryBuffer)
|
||||
{
|
||||
TRACE("(%s, %s, %p, %p, %s, %p)\n", debugstr_guid(rclsid),
|
||||
debugstr_guid(iid), ppv, pProxyFileList, debugstr_guid(pclsid),
|
||||
pPSFactoryBuffer);
|
||||
|
||||
*ppv = NULL;
|
||||
if (!pPSFactoryBuffer->lpVtbl) {
|
||||
const ProxyFileInfo **pProxyFileList2;
|
||||
int 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;
|
||||
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 (IsEqualGUID(rclsid, pclsid))
|
||||
return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
|
||||
else {
|
||||
const ProxyFileInfo *info;
|
||||
int index;
|
||||
/* otherwise, the dll may be using the iid as the clsid, so
|
||||
* search for it in the proxy file list */
|
||||
if (FindProxyInfo(pProxyFileList, rclsid, &info, &index))
|
||||
return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
|
||||
|
||||
WARN("class %s not available\n", debugstr_guid(rclsid));
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrDllCanUnloadNow [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer)
|
||||
{
|
||||
return !(pPSFactoryBuffer->RefCount);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrDllRegisterProxy [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll,
|
||||
const ProxyFileInfo **pProxyFileList,
|
||||
const CLSID *pclsid)
|
||||
{
|
||||
LPSTR clsid;
|
||||
char keyname[120], module[MAX_PATH];
|
||||
HKEY key, subkey;
|
||||
DWORD len;
|
||||
|
||||
TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid));
|
||||
UuidToStringA((UUID*)pclsid, (unsigned char**)&clsid);
|
||||
|
||||
/* register interfaces to point to clsid */
|
||||
while (*pProxyFileList) {
|
||||
unsigned u;
|
||||
for (u=0; u<(*pProxyFileList)->TableSize; u++) {
|
||||
CInterfaceStubVtbl *proxy = (*pProxyFileList)->pStubVtblList[u];
|
||||
PCInterfaceName name = (*pProxyFileList)->pNamesArray[u];
|
||||
LPSTR iid;
|
||||
|
||||
TRACE("registering %s %s => %s\n", name, debugstr_guid(proxy->header.piid), clsid);
|
||||
|
||||
UuidToStringA((UUID*)proxy->header.piid, (unsigned char**)&iid);
|
||||
snprintf(keyname, sizeof(keyname), "Interface\\{%s}", iid);
|
||||
RpcStringFreeA((unsigned char**)&iid);
|
||||
if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
|
||||
if (name)
|
||||
RegSetValueExA(key, NULL, 0, REG_SZ, (const BYTE *)name, strlen(name));
|
||||
if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) {
|
||||
snprintf(module, sizeof(module), "{%s}", clsid);
|
||||
RegSetValueExA(subkey, NULL, 0, REG_SZ, (LPBYTE)module, strlen(module));
|
||||
RegCloseKey(subkey);
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
pProxyFileList++;
|
||||
}
|
||||
|
||||
/* register clsid to point to module */
|
||||
snprintf(keyname, sizeof(keyname), "CLSID\\{%s}", clsid);
|
||||
len = GetModuleFileNameA(hDll, module, sizeof(module));
|
||||
if (len && len < sizeof(module)) {
|
||||
TRACE("registering CLSID %s => %s\n", clsid, module);
|
||||
if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
|
||||
RegSetValueExA(subkey, NULL, 0, REG_SZ, (const BYTE *)"PSFactoryBuffer", strlen("PSFactoryBuffer"));
|
||||
if (RegCreateKeyExA(key, "InProcServer32", 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) {
|
||||
RegSetValueExA(subkey, NULL, 0, REG_SZ, (LPBYTE)module, strlen(module));
|
||||
RegSetValueExA(subkey, "ThreadingModel", 0, REG_SZ, (const BYTE *)"Both", strlen("Both"));
|
||||
RegCloseKey(subkey);
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
/* done */
|
||||
RpcStringFreeA((unsigned char**)&clsid);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrDllUnregisterProxy [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrDllUnregisterProxy(HMODULE hDll,
|
||||
const ProxyFileInfo **pProxyFileList,
|
||||
const CLSID *pclsid)
|
||||
{
|
||||
LPSTR clsid;
|
||||
char keyname[120], module[MAX_PATH];
|
||||
DWORD len;
|
||||
|
||||
TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid));
|
||||
UuidToStringA((UUID*)pclsid, (unsigned char**)&clsid);
|
||||
|
||||
/* unregister interfaces */
|
||||
while (*pProxyFileList) {
|
||||
unsigned u;
|
||||
for (u=0; u<(*pProxyFileList)->TableSize; u++) {
|
||||
CInterfaceStubVtbl *proxy = (*pProxyFileList)->pStubVtblList[u];
|
||||
PCInterfaceName name = (*pProxyFileList)->pNamesArray[u];
|
||||
LPSTR iid;
|
||||
|
||||
TRACE("unregistering %s %s <= %s\n", name, debugstr_guid(proxy->header.piid), clsid);
|
||||
|
||||
UuidToStringA((UUID*)proxy->header.piid, (unsigned char**)&iid);
|
||||
snprintf(keyname, sizeof(keyname), "Interface\\{%s}", iid);
|
||||
RpcStringFreeA((unsigned char**)&iid);
|
||||
RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname);
|
||||
}
|
||||
pProxyFileList++;
|
||||
}
|
||||
|
||||
/* unregister clsid */
|
||||
snprintf(keyname, sizeof(keyname), "CLSID\\{%s}", clsid);
|
||||
len = GetModuleFileNameA(hDll, module, sizeof(module));
|
||||
if (len && len < sizeof(module)) {
|
||||
TRACE("unregistering CLSID %s <= %s\n", clsid, module);
|
||||
RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname);
|
||||
}
|
||||
|
||||
/* done */
|
||||
RpcStringFreeA((unsigned char**)&clsid);
|
||||
return S_OK;
|
||||
}
|
||||
/*
|
||||
* COM proxy/stub factory (CStdPSFactory) implementation
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "cpsf.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
static BOOL FindProxyInfo(const ProxyFileInfo **pProxyFileList, REFIID riid, const ProxyFileInfo **pProxyInfo, int *pIndex)
|
||||
{
|
||||
while (*pProxyFileList) {
|
||||
if ((*pProxyFileList)->pIIDLookupRtn(riid, pIndex)) {
|
||||
*pProxyInfo = *pProxyFileList;
|
||||
TRACE("found: ProxyInfo %p Index %d\n", *pProxyInfo, *pIndex);
|
||||
return TRUE;
|
||||
}
|
||||
pProxyFileList++;
|
||||
}
|
||||
TRACE("not found\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CStdPSFactory_QueryInterface(LPPSFACTORYBUFFER iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
{
|
||||
CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface;
|
||||
TRACE("(%p)->QueryInterface(%s,%p)\n",iface,debugstr_guid(riid),obj);
|
||||
if (IsEqualGUID(&IID_IUnknown,riid) ||
|
||||
IsEqualGUID(&IID_IPSFactoryBuffer,riid)) {
|
||||
*obj = This;
|
||||
This->RefCount++;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI CStdPSFactory_AddRef(LPPSFACTORYBUFFER iface)
|
||||
{
|
||||
CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface;
|
||||
TRACE("(%p)->AddRef()\n",iface);
|
||||
return ++(This->RefCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI CStdPSFactory_Release(LPPSFACTORYBUFFER iface)
|
||||
{
|
||||
CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface;
|
||||
TRACE("(%p)->Release()\n",iface);
|
||||
return --(This->RefCount);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CStdPSFactory_CreateProxy(LPPSFACTORYBUFFER iface,
|
||||
LPUNKNOWN pUnkOuter,
|
||||
REFIID riid,
|
||||
LPRPCPROXYBUFFER *ppProxy,
|
||||
LPVOID *ppv)
|
||||
{
|
||||
CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface;
|
||||
const ProxyFileInfo *ProxyInfo;
|
||||
int Index;
|
||||
TRACE("(%p)->CreateProxy(%p,%s,%p,%p)\n",iface,pUnkOuter,
|
||||
debugstr_guid(riid),ppProxy,ppv);
|
||||
if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index))
|
||||
return E_NOINTERFACE;
|
||||
return StdProxy_Construct(riid, pUnkOuter, ProxyInfo, Index, iface, ppProxy, ppv);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface,
|
||||
REFIID riid,
|
||||
LPUNKNOWN pUnkServer,
|
||||
LPRPCSTUBBUFFER *ppStub)
|
||||
{
|
||||
CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface;
|
||||
const ProxyFileInfo *ProxyInfo;
|
||||
int Index;
|
||||
TRACE("(%p)->CreateStub(%s,%p,%p)\n",iface,debugstr_guid(riid),
|
||||
pUnkServer,ppStub);
|
||||
if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index))
|
||||
return E_NOINTERFACE;
|
||||
|
||||
if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index])
|
||||
return CStdStubBuffer_Delegating_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index],
|
||||
ProxyInfo->pStubVtblList[Index], ProxyInfo->pDelegatedIIDs[Index],
|
||||
iface, ppStub);
|
||||
|
||||
return CStdStubBuffer_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index],
|
||||
ProxyInfo->pStubVtblList[Index], iface, ppStub);
|
||||
}
|
||||
|
||||
static const IPSFactoryBufferVtbl CStdPSFactory_Vtbl =
|
||||
{
|
||||
CStdPSFactory_QueryInterface,
|
||||
CStdPSFactory_AddRef,
|
||||
CStdPSFactory_Release,
|
||||
CStdPSFactory_CreateProxy,
|
||||
CStdPSFactory_CreateStub
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* NdrDllGetClassObject [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
|
||||
const ProxyFileInfo **pProxyFileList,
|
||||
const CLSID *pclsid,
|
||||
CStdPSFactoryBuffer *pPSFactoryBuffer)
|
||||
{
|
||||
TRACE("(%s, %s, %p, %p, %s, %p)\n", debugstr_guid(rclsid),
|
||||
debugstr_guid(iid), ppv, pProxyFileList, debugstr_guid(pclsid),
|
||||
pPSFactoryBuffer);
|
||||
|
||||
*ppv = NULL;
|
||||
if (!pPSFactoryBuffer->lpVtbl) {
|
||||
const ProxyFileInfo **pProxyFileList2;
|
||||
int 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;
|
||||
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 (IsEqualGUID(rclsid, pclsid))
|
||||
return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
|
||||
else {
|
||||
const ProxyFileInfo *info;
|
||||
int index;
|
||||
/* otherwise, the dll may be using the iid as the clsid, so
|
||||
* search for it in the proxy file list */
|
||||
if (FindProxyInfo(pProxyFileList, rclsid, &info, &index))
|
||||
return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
|
||||
|
||||
WARN("class %s not available\n", debugstr_guid(rclsid));
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrDllCanUnloadNow [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer)
|
||||
{
|
||||
return !(pPSFactoryBuffer->RefCount);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrDllRegisterProxy [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll,
|
||||
const ProxyFileInfo **pProxyFileList,
|
||||
const CLSID *pclsid)
|
||||
{
|
||||
LPSTR clsid;
|
||||
char keyname[120], module[MAX_PATH];
|
||||
HKEY key, subkey;
|
||||
DWORD len;
|
||||
|
||||
TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid));
|
||||
UuidToStringA((UUID*)pclsid, (unsigned char**)&clsid);
|
||||
|
||||
/* register interfaces to point to clsid */
|
||||
while (*pProxyFileList) {
|
||||
unsigned u;
|
||||
for (u=0; u<(*pProxyFileList)->TableSize; u++) {
|
||||
CInterfaceStubVtbl *proxy = (*pProxyFileList)->pStubVtblList[u];
|
||||
PCInterfaceName name = (*pProxyFileList)->pNamesArray[u];
|
||||
LPSTR iid;
|
||||
|
||||
TRACE("registering %s %s => %s\n", name, debugstr_guid(proxy->header.piid), clsid);
|
||||
|
||||
UuidToStringA((UUID*)proxy->header.piid, (unsigned char**)&iid);
|
||||
snprintf(keyname, sizeof(keyname), "Interface\\{%s}", iid);
|
||||
RpcStringFreeA((unsigned char**)&iid);
|
||||
if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
|
||||
if (name)
|
||||
RegSetValueExA(key, NULL, 0, REG_SZ, (const BYTE *)name, strlen(name));
|
||||
if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) {
|
||||
snprintf(module, sizeof(module), "{%s}", clsid);
|
||||
RegSetValueExA(subkey, NULL, 0, REG_SZ, (LPBYTE)module, strlen(module));
|
||||
RegCloseKey(subkey);
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
pProxyFileList++;
|
||||
}
|
||||
|
||||
/* register clsid to point to module */
|
||||
snprintf(keyname, sizeof(keyname), "CLSID\\{%s}", clsid);
|
||||
len = GetModuleFileNameA(hDll, module, sizeof(module));
|
||||
if (len && len < sizeof(module)) {
|
||||
TRACE("registering CLSID %s => %s\n", clsid, module);
|
||||
if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
|
||||
RegSetValueExA(subkey, NULL, 0, REG_SZ, (const BYTE *)"PSFactoryBuffer", strlen("PSFactoryBuffer"));
|
||||
if (RegCreateKeyExA(key, "InProcServer32", 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) {
|
||||
RegSetValueExA(subkey, NULL, 0, REG_SZ, (LPBYTE)module, strlen(module));
|
||||
RegSetValueExA(subkey, "ThreadingModel", 0, REG_SZ, (const BYTE *)"Both", strlen("Both"));
|
||||
RegCloseKey(subkey);
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
/* done */
|
||||
RpcStringFreeA((unsigned char**)&clsid);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrDllUnregisterProxy [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrDllUnregisterProxy(HMODULE hDll,
|
||||
const ProxyFileInfo **pProxyFileList,
|
||||
const CLSID *pclsid)
|
||||
{
|
||||
LPSTR clsid;
|
||||
char keyname[120], module[MAX_PATH];
|
||||
DWORD len;
|
||||
|
||||
TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid));
|
||||
UuidToStringA((UUID*)pclsid, (unsigned char**)&clsid);
|
||||
|
||||
/* unregister interfaces */
|
||||
while (*pProxyFileList) {
|
||||
unsigned u;
|
||||
for (u=0; u<(*pProxyFileList)->TableSize; u++) {
|
||||
CInterfaceStubVtbl *proxy = (*pProxyFileList)->pStubVtblList[u];
|
||||
PCInterfaceName name = (*pProxyFileList)->pNamesArray[u];
|
||||
LPSTR iid;
|
||||
|
||||
TRACE("unregistering %s %s <= %s\n", name, debugstr_guid(proxy->header.piid), clsid);
|
||||
|
||||
UuidToStringA((UUID*)proxy->header.piid, (unsigned char**)&iid);
|
||||
snprintf(keyname, sizeof(keyname), "Interface\\{%s}", iid);
|
||||
RpcStringFreeA((unsigned char**)&iid);
|
||||
RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname);
|
||||
}
|
||||
pProxyFileList++;
|
||||
}
|
||||
|
||||
/* unregister clsid */
|
||||
snprintf(keyname, sizeof(keyname), "CLSID\\{%s}", clsid);
|
||||
len = GetModuleFileNameA(hDll, module, sizeof(module));
|
||||
if (len && len < sizeof(module)) {
|
||||
TRACE("unregistering CLSID %s <= %s\n", clsid, module);
|
||||
RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname);
|
||||
}
|
||||
|
||||
/* done */
|
||||
RpcStringFreeA((unsigned char**)&clsid);
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -1,56 +1,56 @@
|
|||
/*
|
||||
* COM proxy definitions
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_CPSF_H
|
||||
#define __WINE_CPSF_H
|
||||
|
||||
HRESULT WINAPI StdProxy_Construct(REFIID riid,
|
||||
LPUNKNOWN pUnkOuter,
|
||||
const ProxyFileInfo *ProxyInfo,
|
||||
int Index,
|
||||
LPPSFACTORYBUFFER pPSFactory,
|
||||
LPRPCPROXYBUFFER *ppProxy,
|
||||
LPVOID *ppvObj);
|
||||
|
||||
HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
|
||||
LPUNKNOWN pUnkServer,
|
||||
PCInterfaceName name,
|
||||
CInterfaceStubVtbl *vtbl,
|
||||
LPPSFACTORYBUFFER pPSFactory,
|
||||
LPRPCSTUBBUFFER *ppStub);
|
||||
|
||||
HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid,
|
||||
LPUNKNOWN pUnkServer,
|
||||
PCInterfaceName name,
|
||||
CInterfaceStubVtbl *vtbl,
|
||||
REFIID delegating_iid,
|
||||
LPPSFACTORYBUFFER pPSFactory,
|
||||
LPRPCSTUBBUFFER *ppStub);
|
||||
|
||||
const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface);
|
||||
|
||||
const IRpcStubBufferVtbl CStdStubBuffer_Vtbl;
|
||||
const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl;
|
||||
|
||||
void create_delegating_vtbl(DWORD num_methods);
|
||||
|
||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub);
|
||||
|
||||
#endif /* __WINE_CPSF_H */
|
||||
/*
|
||||
* COM proxy definitions
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_CPSF_H
|
||||
#define __WINE_CPSF_H
|
||||
|
||||
HRESULT WINAPI StdProxy_Construct(REFIID riid,
|
||||
LPUNKNOWN pUnkOuter,
|
||||
const ProxyFileInfo *ProxyInfo,
|
||||
int Index,
|
||||
LPPSFACTORYBUFFER pPSFactory,
|
||||
LPRPCPROXYBUFFER *ppProxy,
|
||||
LPVOID *ppvObj);
|
||||
|
||||
HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
|
||||
LPUNKNOWN pUnkServer,
|
||||
PCInterfaceName name,
|
||||
CInterfaceStubVtbl *vtbl,
|
||||
LPPSFACTORYBUFFER pPSFactory,
|
||||
LPRPCSTUBBUFFER *ppStub);
|
||||
|
||||
HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid,
|
||||
LPUNKNOWN pUnkServer,
|
||||
PCInterfaceName name,
|
||||
CInterfaceStubVtbl *vtbl,
|
||||
REFIID delegating_iid,
|
||||
LPPSFACTORYBUFFER pPSFactory,
|
||||
LPRPCSTUBBUFFER *ppStub);
|
||||
|
||||
const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface);
|
||||
|
||||
const IRpcStubBufferVtbl CStdStubBuffer_Vtbl;
|
||||
const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl;
|
||||
|
||||
void create_delegating_vtbl(DWORD num_methods);
|
||||
|
||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub);
|
||||
|
||||
#endif /* __WINE_CPSF_H */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,88 +1,88 @@
|
|||
/*
|
||||
* Endpoint Mapper Tower Definitions
|
||||
*
|
||||
* Copyright 2006 Robert Shearman (for CodeWeavers)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define EPM_PROTOCOL_DNET_NSP 0x04
|
||||
#define EPM_PROTOCOL_OSI_TP4 0x05
|
||||
#define EPM_PROTOCOL_OSI_CLNS 0x06
|
||||
#define EPM_PROTOCOL_TCP 0x07
|
||||
#define EPM_PROTOCOL_UDP 0x08
|
||||
#define EPM_PROTOCOL_IP 0x09
|
||||
#define EPM_PROTOCOL_NCADG 0x0a /* Connectionless RPC */
|
||||
#define EPM_PROTOCOL_NCACN 0x0b
|
||||
#define EPM_PROTOCOL_NCALRPC 0x0c /* Local RPC */
|
||||
#define EPM_PROTOCOL_UUID 0x0d
|
||||
#define EPM_PROTOCOL_IPX 0x0e
|
||||
#define EPM_PROTOCOL_SMB 0x0f
|
||||
#define EPM_PROTOCOL_PIPE 0x10
|
||||
#define EPM_PROTOCOL_NETBIOS 0x11
|
||||
#define EPM_PROTOCOL_NETBEUI 0x12
|
||||
#define EPM_PROTOCOL_SPX 0x13
|
||||
#define EPM_PROTOCOL_NB_IPX 0x14 /* NetBIOS over IPX */
|
||||
#define EPM_PROTOCOL_DSP 0x16 /* AppleTalk Data Stream Protocol */
|
||||
#define EPM_PROTOCOL_DDP 0x17 /* AppleTalk Data Datagram Protocol */
|
||||
#define EPM_PROTOCOL_APPLETALK 0x18 /* AppleTalk */
|
||||
#define EPM_PROTOCOL_VINES_SPP 0x1a
|
||||
#define EPM_PROTOCOL_VINES_IPC 0x1b /* Inter Process Communication */
|
||||
#define EPM_PROTOCOL_STREETTALK 0x1c /* Vines Streettalk */
|
||||
#define EPM_PROTOCOL_HTTP 0x1f
|
||||
#define EPM_PROTOCOL_UNIX_DS 0x20 /* Unix domain socket */
|
||||
#define EPM_PROTOCOL_NULL 0x21
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
typedef unsigned char u_int8;
|
||||
typedef unsigned short u_int16;
|
||||
typedef unsigned int u_int32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
GUID uuid;
|
||||
u_int16 major_version;
|
||||
u_int16 count_rhs;
|
||||
u_int16 minor_version;
|
||||
} twr_uuid_floor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
u_int16 count_rhs;
|
||||
u_int16 port;
|
||||
} twr_tcp_floor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
u_int16 count_rhs;
|
||||
u_int32 ipv4addr;
|
||||
} twr_ipv4_floor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
u_int16 count_rhs;
|
||||
} twr_empty_floor_t;
|
||||
|
||||
#include <poppack.h>
|
||||
/*
|
||||
* Endpoint Mapper Tower Definitions
|
||||
*
|
||||
* Copyright 2006 Robert Shearman (for CodeWeavers)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define EPM_PROTOCOL_DNET_NSP 0x04
|
||||
#define EPM_PROTOCOL_OSI_TP4 0x05
|
||||
#define EPM_PROTOCOL_OSI_CLNS 0x06
|
||||
#define EPM_PROTOCOL_TCP 0x07
|
||||
#define EPM_PROTOCOL_UDP 0x08
|
||||
#define EPM_PROTOCOL_IP 0x09
|
||||
#define EPM_PROTOCOL_NCADG 0x0a /* Connectionless RPC */
|
||||
#define EPM_PROTOCOL_NCACN 0x0b
|
||||
#define EPM_PROTOCOL_NCALRPC 0x0c /* Local RPC */
|
||||
#define EPM_PROTOCOL_UUID 0x0d
|
||||
#define EPM_PROTOCOL_IPX 0x0e
|
||||
#define EPM_PROTOCOL_SMB 0x0f
|
||||
#define EPM_PROTOCOL_PIPE 0x10
|
||||
#define EPM_PROTOCOL_NETBIOS 0x11
|
||||
#define EPM_PROTOCOL_NETBEUI 0x12
|
||||
#define EPM_PROTOCOL_SPX 0x13
|
||||
#define EPM_PROTOCOL_NB_IPX 0x14 /* NetBIOS over IPX */
|
||||
#define EPM_PROTOCOL_DSP 0x16 /* AppleTalk Data Stream Protocol */
|
||||
#define EPM_PROTOCOL_DDP 0x17 /* AppleTalk Data Datagram Protocol */
|
||||
#define EPM_PROTOCOL_APPLETALK 0x18 /* AppleTalk */
|
||||
#define EPM_PROTOCOL_VINES_SPP 0x1a
|
||||
#define EPM_PROTOCOL_VINES_IPC 0x1b /* Inter Process Communication */
|
||||
#define EPM_PROTOCOL_STREETTALK 0x1c /* Vines Streettalk */
|
||||
#define EPM_PROTOCOL_HTTP 0x1f
|
||||
#define EPM_PROTOCOL_UNIX_DS 0x20 /* Unix domain socket */
|
||||
#define EPM_PROTOCOL_NULL 0x21
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
typedef unsigned char u_int8;
|
||||
typedef unsigned short u_int16;
|
||||
typedef unsigned int u_int32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
GUID uuid;
|
||||
u_int16 major_version;
|
||||
u_int16 count_rhs;
|
||||
u_int16 minor_version;
|
||||
} twr_uuid_floor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
u_int16 count_rhs;
|
||||
u_int16 port;
|
||||
} twr_tcp_floor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
u_int16 count_rhs;
|
||||
u_int32 ipv4addr;
|
||||
} twr_ipv4_floor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
u_int16 count_rhs;
|
||||
} twr_empty_floor_t;
|
||||
|
||||
#include <poppack.h>
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
/*
|
||||
* NCA Status definitions
|
||||
*
|
||||
* Copyright 2007 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define NCA_S_COMM_FAILURE 0x1C010001
|
||||
#define NCA_S_OP_RNG_ERROR 0x1C010002
|
||||
#define NCA_S_UNK_IF 0x1C010003
|
||||
#define NCA_S_WRONG_BOOT_TIME 0x1C010006
|
||||
#define NCA_S_YOU_CRASHED 0x1C010009
|
||||
#define NCA_S_PROTO_ERROR 0x1C01000B
|
||||
#define NCA_S_OUT_ARGS_TOO_BIG 0x1C010013
|
||||
#define NCA_S_SERVER_TOO_BUSY 0x1C010014
|
||||
#define NCA_S_FAULT_STRING_TOO_LONG 0x1C010015
|
||||
#define NCA_S_UNSUPPORTED_TYPE 0x1C010017
|
||||
|
||||
#define NCA_S_FAULT_INT_DIV_BY_ZERO 0x1C000001
|
||||
#define NCA_S_FAULT_ADDR_ERROR 0x1C000002
|
||||
#define NCA_S_FAULT_FP_DIV_ZERO 0x1C000003
|
||||
#define NCA_S_FAULT_FP_UNDERFLOW 0x1C000004
|
||||
#define NCA_S_FAULT_FP_OVERFLOW 0x1C000005
|
||||
#define NCA_S_FAULT_INVALID_TAG 0x1C000006
|
||||
#define NCA_S_FAULT_INVALID_BOUND 0x1C000007
|
||||
#define NCA_S_RPC_VERSION_MISMATCH 0x1C000008
|
||||
#define NCA_S_UNSPEC_REJECT 0x1C000009
|
||||
#define NCA_S_BAD_ACTID 0x1C00000A
|
||||
#define NCA_S_WHO_ARE_YOU_FAILED 0x1C00000B
|
||||
#define NCA_S_MANAGER_NOT_ENTERED 0x1C00000C
|
||||
#define NCA_S_FAULT_CANCEL 0x1C00000D
|
||||
#define NCA_S_FAULT_ILL_INST 0x1C00000E
|
||||
#define NCA_S_FAULT_FP_ERROR 0x1C00000F
|
||||
#define NCA_S_FAULT_INT_OVERFLOW 0x1C000010
|
||||
#define NCA_S_FAULT_UNSPEC 0x1C000012
|
||||
#define NCA_S_FAULT_REMOTE_COMM_FAILURE 0x1C000013
|
||||
#define NCA_S_FAULT_PIPE_EMPTY 0x1C000014
|
||||
#define NCA_S_FAULT_PIPE_CLOSED 0x1C000015
|
||||
#define NCA_S_FAULT_PIPE_ORDER 0x1C000016
|
||||
#define NCA_S_FAULT_PIPE_DISCIPLINE 0x1C000017
|
||||
#define NCA_S_FAULT_PIPE_COMM_ERROR 0x1C000018
|
||||
#define NCA_S_FAULT_PIPE_MEMORY 0x1C000019
|
||||
#define NCA_S_FAULT_CONTEXT_MISMATCH 0x1C00001A
|
||||
#define NCA_S_FAULT_REMOTE_NO_MEMORY 0x1C00001B
|
||||
#define NCA_S_INVALID_PRES_CONTEXT_ID 0x1C00001C
|
||||
#define NCA_S_UNSUPPORTED_AUTHN_LEVEL 0x1C00001D
|
||||
#define NCA_S_INVALID_CHECKSUM 0x1C00001F
|
||||
#define NCA_S_INVALID_CRC 0x1C000020
|
||||
#define NCA_S_FAULT_USER_DEFINED 0x1C000021
|
||||
#define NCA_S_FAULT_TX_OPEN_FAILED 0x1C000022
|
||||
#define NCA_S_FAULT_CODESET_CONV_ERROR 0x1C000023
|
||||
#define NCA_S_FAULT_OBJECT_NOT_FOUND 0x1C000024
|
||||
#define NCA_S_FAULT_NO_CLIENT_STUB 0x1C000025
|
||||
/*
|
||||
* NCA Status definitions
|
||||
*
|
||||
* Copyright 2007 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define NCA_S_COMM_FAILURE 0x1C010001
|
||||
#define NCA_S_OP_RNG_ERROR 0x1C010002
|
||||
#define NCA_S_UNK_IF 0x1C010003
|
||||
#define NCA_S_WRONG_BOOT_TIME 0x1C010006
|
||||
#define NCA_S_YOU_CRASHED 0x1C010009
|
||||
#define NCA_S_PROTO_ERROR 0x1C01000B
|
||||
#define NCA_S_OUT_ARGS_TOO_BIG 0x1C010013
|
||||
#define NCA_S_SERVER_TOO_BUSY 0x1C010014
|
||||
#define NCA_S_FAULT_STRING_TOO_LONG 0x1C010015
|
||||
#define NCA_S_UNSUPPORTED_TYPE 0x1C010017
|
||||
|
||||
#define NCA_S_FAULT_INT_DIV_BY_ZERO 0x1C000001
|
||||
#define NCA_S_FAULT_ADDR_ERROR 0x1C000002
|
||||
#define NCA_S_FAULT_FP_DIV_ZERO 0x1C000003
|
||||
#define NCA_S_FAULT_FP_UNDERFLOW 0x1C000004
|
||||
#define NCA_S_FAULT_FP_OVERFLOW 0x1C000005
|
||||
#define NCA_S_FAULT_INVALID_TAG 0x1C000006
|
||||
#define NCA_S_FAULT_INVALID_BOUND 0x1C000007
|
||||
#define NCA_S_RPC_VERSION_MISMATCH 0x1C000008
|
||||
#define NCA_S_UNSPEC_REJECT 0x1C000009
|
||||
#define NCA_S_BAD_ACTID 0x1C00000A
|
||||
#define NCA_S_WHO_ARE_YOU_FAILED 0x1C00000B
|
||||
#define NCA_S_MANAGER_NOT_ENTERED 0x1C00000C
|
||||
#define NCA_S_FAULT_CANCEL 0x1C00000D
|
||||
#define NCA_S_FAULT_ILL_INST 0x1C00000E
|
||||
#define NCA_S_FAULT_FP_ERROR 0x1C00000F
|
||||
#define NCA_S_FAULT_INT_OVERFLOW 0x1C000010
|
||||
#define NCA_S_FAULT_UNSPEC 0x1C000012
|
||||
#define NCA_S_FAULT_REMOTE_COMM_FAILURE 0x1C000013
|
||||
#define NCA_S_FAULT_PIPE_EMPTY 0x1C000014
|
||||
#define NCA_S_FAULT_PIPE_CLOSED 0x1C000015
|
||||
#define NCA_S_FAULT_PIPE_ORDER 0x1C000016
|
||||
#define NCA_S_FAULT_PIPE_DISCIPLINE 0x1C000017
|
||||
#define NCA_S_FAULT_PIPE_COMM_ERROR 0x1C000018
|
||||
#define NCA_S_FAULT_PIPE_MEMORY 0x1C000019
|
||||
#define NCA_S_FAULT_CONTEXT_MISMATCH 0x1C00001A
|
||||
#define NCA_S_FAULT_REMOTE_NO_MEMORY 0x1C00001B
|
||||
#define NCA_S_INVALID_PRES_CONTEXT_ID 0x1C00001C
|
||||
#define NCA_S_UNSUPPORTED_AUTHN_LEVEL 0x1C00001D
|
||||
#define NCA_S_INVALID_CHECKSUM 0x1C00001F
|
||||
#define NCA_S_INVALID_CRC 0x1C000020
|
||||
#define NCA_S_FAULT_USER_DEFINED 0x1C000021
|
||||
#define NCA_S_FAULT_TX_OPEN_FAILED 0x1C000022
|
||||
#define NCA_S_FAULT_CODESET_CONV_ERROR 0x1C000023
|
||||
#define NCA_S_FAULT_OBJECT_NOT_FOUND 0x1C000024
|
||||
#define NCA_S_FAULT_NO_CLIENT_STUB 0x1C000025
|
||||
|
|
|
@ -1,227 +1,227 @@
|
|||
/*
|
||||
* MIDL proxy/stub stuff
|
||||
*
|
||||
* Copyright 2002 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - figure out whether we *really* got this right
|
||||
* - check for errors and throw exceptions
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
/************************************************************************
|
||||
* NdrClientInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum )
|
||||
{
|
||||
TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n",
|
||||
pRpcMessage, pStubMsg, pStubDesc, ProcNum);
|
||||
|
||||
pRpcMessage->Handle = NULL;
|
||||
pRpcMessage->ProcNum = ProcNum;
|
||||
pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
|
||||
pRpcMessage->RpcFlags = 0;
|
||||
pRpcMessage->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
|
||||
|
||||
pStubMsg->RpcMsg = pRpcMessage;
|
||||
pStubMsg->BufferStart = NULL;
|
||||
pStubMsg->BufferEnd = NULL;
|
||||
pStubMsg->BufferLength = 0;
|
||||
pStubMsg->IsClient = TRUE;
|
||||
pStubMsg->ReuseBuffer = FALSE;
|
||||
pStubMsg->pAllocAllNodesContext = NULL;
|
||||
pStubMsg->pPointerQueueState = NULL;
|
||||
pStubMsg->IgnoreEmbeddedPointers = 0;
|
||||
pStubMsg->PointerBufferMark = NULL;
|
||||
pStubMsg->fBufferValid = 0;
|
||||
pStubMsg->uFlags = 0;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->StackTop = NULL;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->FullPtrRefId = 0;
|
||||
pStubMsg->PointerLength = 0;
|
||||
pStubMsg->fInDontFree = 0;
|
||||
pStubMsg->fDontCallFreeInst = 0;
|
||||
pStubMsg->fInOnlyParam = 0;
|
||||
pStubMsg->fHasReturn = 0;
|
||||
pStubMsg->fHasExtensions = 0;
|
||||
pStubMsg->fHasNewCorrDesc = 0;
|
||||
pStubMsg->fUnused = 0;
|
||||
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
|
||||
pStubMsg->pvDestContext = NULL;
|
||||
pStubMsg->pRpcChannelBuffer = NULL;
|
||||
pStubMsg->pArrayInfo = NULL;
|
||||
pStubMsg->dwStubPhase = 0;
|
||||
/* FIXME: LowStackMark */
|
||||
pStubMsg->pAsyncMsg = NULL;
|
||||
pStubMsg->pCorrInfo = NULL;
|
||||
pStubMsg->pCorrMemory = NULL;
|
||||
pStubMsg->pMemoryList = NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrServerInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc )
|
||||
{
|
||||
TRACE("(pRpcMsg == ^%p, pStubMsg == ^%p, pStubDesc == ^%p)\n", pRpcMsg, pStubMsg, pStubDesc);
|
||||
|
||||
pStubMsg->RpcMsg = pRpcMsg;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart = pRpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->Buffer + pRpcMsg->BufferLength;
|
||||
pStubMsg->BufferLength = pRpcMsg->BufferLength;
|
||||
pStubMsg->IsClient = FALSE;
|
||||
pStubMsg->ReuseBuffer = FALSE;
|
||||
pStubMsg->pAllocAllNodesContext = NULL;
|
||||
pStubMsg->pPointerQueueState = NULL;
|
||||
pStubMsg->IgnoreEmbeddedPointers = 0;
|
||||
pStubMsg->PointerBufferMark = NULL;
|
||||
pStubMsg->uFlags = 0;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->StackTop = NULL;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->FullPtrXlatTables = NULL;
|
||||
pStubMsg->FullPtrRefId = 0;
|
||||
pStubMsg->PointerLength = 0;
|
||||
pStubMsg->fInDontFree = 0;
|
||||
pStubMsg->fDontCallFreeInst = 0;
|
||||
pStubMsg->fInOnlyParam = 0;
|
||||
pStubMsg->fHasReturn = 0;
|
||||
pStubMsg->fHasExtensions = 0;
|
||||
pStubMsg->fHasNewCorrDesc = 0;
|
||||
pStubMsg->fUnused = 0;
|
||||
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
|
||||
pStubMsg->pvDestContext = NULL;
|
||||
pStubMsg->pRpcChannelBuffer = NULL;
|
||||
pStubMsg->pArrayInfo = NULL;
|
||||
pStubMsg->dwStubPhase = 0;
|
||||
/* FIXME: LowStackMark */
|
||||
pStubMsg->pAsyncMsg = NULL;
|
||||
pStubMsg->pCorrInfo = NULL;
|
||||
pStubMsg->pCorrMemory = NULL;
|
||||
pStubMsg->pMemoryList = NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrGetBuffer(PMIDL_STUB_MESSAGE stubmsg, ULONG buflen, RPC_BINDING_HANDLE handle)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(stubmsg == ^%p, buflen == %u, handle == %p)\n", stubmsg, buflen, handle);
|
||||
|
||||
stubmsg->RpcMsg->Handle = handle;
|
||||
stubmsg->RpcMsg->BufferLength = buflen;
|
||||
|
||||
status = I_RpcGetBuffer(stubmsg->RpcMsg);
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
|
||||
stubmsg->Buffer = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->fBufferValid = TRUE;
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
return stubmsg->Buffer;
|
||||
}
|
||||
/***********************************************************************
|
||||
* NdrFreeBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrFreeBuffer(PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
TRACE("(pStubMsg == ^%p)\n", pStubMsg);
|
||||
if (pStubMsg->fBufferValid)
|
||||
{
|
||||
I_RpcFreeBuffer(pStubMsg->RpcMsg);
|
||||
pStubMsg->fBufferValid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrSendReceive [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrSendReceive( PMIDL_STUB_MESSAGE stubmsg, unsigned char *buffer )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);
|
||||
|
||||
/* FIXME: how to handle errors? (raise exception?) */
|
||||
if (!stubmsg) {
|
||||
ERR("NULL stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!stubmsg->RpcMsg) {
|
||||
ERR("RPC Message not present in stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stubmsg->RpcMsg->BufferLength = buffer - (unsigned char *)stubmsg->RpcMsg->Buffer;
|
||||
status = I_RpcSendReceive(stubmsg->RpcMsg);
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->BufferEnd = stubmsg->BufferStart + stubmsg->BufferLength;
|
||||
stubmsg->Buffer = stubmsg->BufferStart;
|
||||
|
||||
/* FIXME: is this the right return value? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrMapCommAndFaultStatus [RPCRT4.@]
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY NdrMapCommAndFaultStatus( PMIDL_STUB_MESSAGE pStubMsg,
|
||||
ULONG *pCommStatus,
|
||||
ULONG *pFaultStatus,
|
||||
RPC_STATUS Status )
|
||||
{
|
||||
FIXME("(%p, %p, %p, %ld): stub\n", pStubMsg, pCommStatus, pFaultStatus, Status);
|
||||
|
||||
*pCommStatus = 0;
|
||||
*pFaultStatus = 0;
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
/*
|
||||
* MIDL proxy/stub stuff
|
||||
*
|
||||
* Copyright 2002 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - figure out whether we *really* got this right
|
||||
* - check for errors and throw exceptions
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
/************************************************************************
|
||||
* NdrClientInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum )
|
||||
{
|
||||
TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n",
|
||||
pRpcMessage, pStubMsg, pStubDesc, ProcNum);
|
||||
|
||||
pRpcMessage->Handle = NULL;
|
||||
pRpcMessage->ProcNum = ProcNum;
|
||||
pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
|
||||
pRpcMessage->RpcFlags = 0;
|
||||
pRpcMessage->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
|
||||
|
||||
pStubMsg->RpcMsg = pRpcMessage;
|
||||
pStubMsg->BufferStart = NULL;
|
||||
pStubMsg->BufferEnd = NULL;
|
||||
pStubMsg->BufferLength = 0;
|
||||
pStubMsg->IsClient = TRUE;
|
||||
pStubMsg->ReuseBuffer = FALSE;
|
||||
pStubMsg->pAllocAllNodesContext = NULL;
|
||||
pStubMsg->pPointerQueueState = NULL;
|
||||
pStubMsg->IgnoreEmbeddedPointers = 0;
|
||||
pStubMsg->PointerBufferMark = NULL;
|
||||
pStubMsg->fBufferValid = 0;
|
||||
pStubMsg->uFlags = 0;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->StackTop = NULL;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->FullPtrRefId = 0;
|
||||
pStubMsg->PointerLength = 0;
|
||||
pStubMsg->fInDontFree = 0;
|
||||
pStubMsg->fDontCallFreeInst = 0;
|
||||
pStubMsg->fInOnlyParam = 0;
|
||||
pStubMsg->fHasReturn = 0;
|
||||
pStubMsg->fHasExtensions = 0;
|
||||
pStubMsg->fHasNewCorrDesc = 0;
|
||||
pStubMsg->fUnused = 0;
|
||||
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
|
||||
pStubMsg->pvDestContext = NULL;
|
||||
pStubMsg->pRpcChannelBuffer = NULL;
|
||||
pStubMsg->pArrayInfo = NULL;
|
||||
pStubMsg->dwStubPhase = 0;
|
||||
/* FIXME: LowStackMark */
|
||||
pStubMsg->pAsyncMsg = NULL;
|
||||
pStubMsg->pCorrInfo = NULL;
|
||||
pStubMsg->pCorrMemory = NULL;
|
||||
pStubMsg->pMemoryList = NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrServerInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc )
|
||||
{
|
||||
TRACE("(pRpcMsg == ^%p, pStubMsg == ^%p, pStubDesc == ^%p)\n", pRpcMsg, pStubMsg, pStubDesc);
|
||||
|
||||
pStubMsg->RpcMsg = pRpcMsg;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart = pRpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->Buffer + pRpcMsg->BufferLength;
|
||||
pStubMsg->BufferLength = pRpcMsg->BufferLength;
|
||||
pStubMsg->IsClient = FALSE;
|
||||
pStubMsg->ReuseBuffer = FALSE;
|
||||
pStubMsg->pAllocAllNodesContext = NULL;
|
||||
pStubMsg->pPointerQueueState = NULL;
|
||||
pStubMsg->IgnoreEmbeddedPointers = 0;
|
||||
pStubMsg->PointerBufferMark = NULL;
|
||||
pStubMsg->uFlags = 0;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->StackTop = NULL;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->FullPtrXlatTables = NULL;
|
||||
pStubMsg->FullPtrRefId = 0;
|
||||
pStubMsg->PointerLength = 0;
|
||||
pStubMsg->fInDontFree = 0;
|
||||
pStubMsg->fDontCallFreeInst = 0;
|
||||
pStubMsg->fInOnlyParam = 0;
|
||||
pStubMsg->fHasReturn = 0;
|
||||
pStubMsg->fHasExtensions = 0;
|
||||
pStubMsg->fHasNewCorrDesc = 0;
|
||||
pStubMsg->fUnused = 0;
|
||||
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
|
||||
pStubMsg->pvDestContext = NULL;
|
||||
pStubMsg->pRpcChannelBuffer = NULL;
|
||||
pStubMsg->pArrayInfo = NULL;
|
||||
pStubMsg->dwStubPhase = 0;
|
||||
/* FIXME: LowStackMark */
|
||||
pStubMsg->pAsyncMsg = NULL;
|
||||
pStubMsg->pCorrInfo = NULL;
|
||||
pStubMsg->pCorrMemory = NULL;
|
||||
pStubMsg->pMemoryList = NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrGetBuffer(PMIDL_STUB_MESSAGE stubmsg, ULONG buflen, RPC_BINDING_HANDLE handle)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(stubmsg == ^%p, buflen == %u, handle == %p)\n", stubmsg, buflen, handle);
|
||||
|
||||
stubmsg->RpcMsg->Handle = handle;
|
||||
stubmsg->RpcMsg->BufferLength = buflen;
|
||||
|
||||
status = I_RpcGetBuffer(stubmsg->RpcMsg);
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
|
||||
stubmsg->Buffer = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->fBufferValid = TRUE;
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
return stubmsg->Buffer;
|
||||
}
|
||||
/***********************************************************************
|
||||
* NdrFreeBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrFreeBuffer(PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
TRACE("(pStubMsg == ^%p)\n", pStubMsg);
|
||||
if (pStubMsg->fBufferValid)
|
||||
{
|
||||
I_RpcFreeBuffer(pStubMsg->RpcMsg);
|
||||
pStubMsg->fBufferValid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrSendReceive [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrSendReceive( PMIDL_STUB_MESSAGE stubmsg, unsigned char *buffer )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);
|
||||
|
||||
/* FIXME: how to handle errors? (raise exception?) */
|
||||
if (!stubmsg) {
|
||||
ERR("NULL stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!stubmsg->RpcMsg) {
|
||||
ERR("RPC Message not present in stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stubmsg->RpcMsg->BufferLength = buffer - (unsigned char *)stubmsg->RpcMsg->Buffer;
|
||||
status = I_RpcSendReceive(stubmsg->RpcMsg);
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->BufferEnd = stubmsg->BufferStart + stubmsg->BufferLength;
|
||||
stubmsg->Buffer = stubmsg->BufferStart;
|
||||
|
||||
/* FIXME: is this the right return value? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrMapCommAndFaultStatus [RPCRT4.@]
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY NdrMapCommAndFaultStatus( PMIDL_STUB_MESSAGE pStubMsg,
|
||||
ULONG *pCommStatus,
|
||||
ULONG *pFaultStatus,
|
||||
RPC_STATUS Status )
|
||||
{
|
||||
FIXME("(%p, %p, %p, %ld): stub\n", pStubMsg, pCommStatus, pFaultStatus, Status);
|
||||
|
||||
*pCommStatus = 0;
|
||||
*pFaultStatus = 0;
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
|
|
@ -1,239 +1,239 @@
|
|||
/*
|
||||
* Full Pointer Translation Routines
|
||||
*
|
||||
* Copyright 2006 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
PFULL_PTR_XLAT_TABLES WINAPI NdrFullPointerXlatInit(ULONG NumberOfPointers,
|
||||
XLAT_SIDE XlatSide)
|
||||
{
|
||||
ULONG NumberOfBuckets;
|
||||
PFULL_PTR_XLAT_TABLES pXlatTables = HeapAlloc(GetProcessHeap(), 0, sizeof(*pXlatTables));
|
||||
|
||||
TRACE("(%d, %d)\n", NumberOfPointers, XlatSide);
|
||||
|
||||
if (!NumberOfPointers) NumberOfPointers = 512;
|
||||
NumberOfBuckets = ((NumberOfPointers + 3) & ~3) - 1;
|
||||
|
||||
pXlatTables->RefIdToPointer.XlatTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(void *) * NumberOfPointers);
|
||||
pXlatTables->RefIdToPointer.StateTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(unsigned char) * NumberOfPointers);
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = NumberOfPointers;
|
||||
|
||||
TRACE("NumberOfBuckets = %d\n", NumberOfBuckets);
|
||||
pXlatTables->PointerToRefId.XlatTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(PFULL_PTR_TO_REFID_ELEMENT) * NumberOfBuckets);
|
||||
pXlatTables->PointerToRefId.NumberOfBuckets = NumberOfBuckets;
|
||||
pXlatTables->PointerToRefId.HashMask = NumberOfBuckets - 1;
|
||||
|
||||
pXlatTables->NextRefId = 1;
|
||||
pXlatTables->XlatSide = XlatSide;
|
||||
|
||||
return pXlatTables;
|
||||
}
|
||||
|
||||
void WINAPI NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
TRACE("(%p)\n", pXlatTables);
|
||||
|
||||
/* free the entries in the table */
|
||||
for (i = 0; i < pXlatTables->RefIdToPointer.NumberOfEntries; i++)
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable[i]);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable);
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.StateTable);
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->PointerToRefId.XlatTable);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables);
|
||||
}
|
||||
|
||||
static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId)
|
||||
{
|
||||
if (RefId >= pXlatTables->RefIdToPointer.NumberOfEntries)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = RefId * 2;
|
||||
pXlatTables->RefIdToPointer.XlatTable =
|
||||
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
pXlatTables->RefIdToPointer.XlatTable,
|
||||
sizeof(void *) * pXlatTables->RefIdToPointer.NumberOfEntries);
|
||||
pXlatTables->RefIdToPointer.StateTable =
|
||||
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
pXlatTables->RefIdToPointer.StateTable,
|
||||
sizeof(unsigned char) * pXlatTables->RefIdToPointer.NumberOfEntries);
|
||||
|
||||
if (!pXlatTables->RefIdToPointer.XlatTable || !pXlatTables->RefIdToPointer.StateTable)
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
void *pPointer, unsigned char QueryType,
|
||||
ULONG *pRefId )
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
|
||||
TRACE("(%p, %p, %d, %p)\n", pXlatTables, pPointer, QueryType, pRefId);
|
||||
|
||||
if (!pPointer)
|
||||
{
|
||||
*pRefId = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(pPointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
|
||||
|
||||
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
|
||||
if (pPointer == XlatTableEntry->Pointer)
|
||||
{
|
||||
*pRefId = XlatTableEntry->RefId;
|
||||
if (XlatTableEntry->State & QueryType)
|
||||
return 1;
|
||||
XlatTableEntry->State |= QueryType;
|
||||
return 0;
|
||||
}
|
||||
|
||||
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
|
||||
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
XlatTableEntry->Pointer = pPointer;
|
||||
XlatTableEntry->RefId = *pRefId = pXlatTables->NextRefId++;
|
||||
XlatTableEntry->State = QueryType;
|
||||
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
|
||||
|
||||
/* insert pointer into mapping table */
|
||||
expand_pointer_table_if_necessary(pXlatTables, XlatTableEntry->RefId);
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > XlatTableEntry->RefId)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
|
||||
pXlatTables->RefIdToPointer.StateTable[XlatTableEntry->RefId] = QueryType;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
ULONG RefId, unsigned char QueryType,
|
||||
void **ppPointer)
|
||||
{
|
||||
TRACE("(%p, 0x%x, %d, %p)\n", pXlatTables, RefId, QueryType, ppPointer);
|
||||
|
||||
expand_pointer_table_if_necessary(pXlatTables, RefId);
|
||||
|
||||
pXlatTables->NextRefId = max(RefId + 1, pXlatTables->NextRefId);
|
||||
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
{
|
||||
*ppPointer = pXlatTables->RefIdToPointer.XlatTable[RefId];
|
||||
if (QueryType)
|
||||
{
|
||||
if (pXlatTables->RefIdToPointer.StateTable[RefId] & QueryType)
|
||||
return 1;
|
||||
pXlatTables->RefIdToPointer.StateTable[RefId] |= QueryType;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
*ppPointer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WINAPI NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
ULONG RefId, void *pPointer)
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
|
||||
TRACE("(%p, 0x%x, %p)\n", pXlatTables, RefId, pPointer);
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(pPointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
|
||||
|
||||
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
|
||||
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
XlatTableEntry->Pointer = pPointer;
|
||||
XlatTableEntry->RefId = RefId;
|
||||
XlatTableEntry->State = 0;
|
||||
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
|
||||
|
||||
/* insert pointer into mapping table */
|
||||
expand_pointer_table_if_necessary(pXlatTables, RefId);
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables, void *Pointer)
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
ULONG RefId = 0;
|
||||
|
||||
TRACE("(%p, %p)\n", pXlatTables, Pointer);
|
||||
|
||||
if (!Pointer)
|
||||
return 1;
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(Pointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&Pointer)[i];
|
||||
|
||||
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
|
||||
if (Pointer == XlatTableEntry->Pointer)
|
||||
{
|
||||
if (XlatTableEntry->State & 0x20)
|
||||
return 0;
|
||||
XlatTableEntry->State |= 0x20;
|
||||
RefId = XlatTableEntry->RefId;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!XlatTableEntry)
|
||||
return 0;
|
||||
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.StateTable[RefId] |= 0x20;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Full Pointer Translation Routines
|
||||
*
|
||||
* Copyright 2006 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
PFULL_PTR_XLAT_TABLES WINAPI NdrFullPointerXlatInit(ULONG NumberOfPointers,
|
||||
XLAT_SIDE XlatSide)
|
||||
{
|
||||
ULONG NumberOfBuckets;
|
||||
PFULL_PTR_XLAT_TABLES pXlatTables = HeapAlloc(GetProcessHeap(), 0, sizeof(*pXlatTables));
|
||||
|
||||
TRACE("(%d, %d)\n", NumberOfPointers, XlatSide);
|
||||
|
||||
if (!NumberOfPointers) NumberOfPointers = 512;
|
||||
NumberOfBuckets = ((NumberOfPointers + 3) & ~3) - 1;
|
||||
|
||||
pXlatTables->RefIdToPointer.XlatTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(void *) * NumberOfPointers);
|
||||
pXlatTables->RefIdToPointer.StateTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(unsigned char) * NumberOfPointers);
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = NumberOfPointers;
|
||||
|
||||
TRACE("NumberOfBuckets = %d\n", NumberOfBuckets);
|
||||
pXlatTables->PointerToRefId.XlatTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(PFULL_PTR_TO_REFID_ELEMENT) * NumberOfBuckets);
|
||||
pXlatTables->PointerToRefId.NumberOfBuckets = NumberOfBuckets;
|
||||
pXlatTables->PointerToRefId.HashMask = NumberOfBuckets - 1;
|
||||
|
||||
pXlatTables->NextRefId = 1;
|
||||
pXlatTables->XlatSide = XlatSide;
|
||||
|
||||
return pXlatTables;
|
||||
}
|
||||
|
||||
void WINAPI NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
TRACE("(%p)\n", pXlatTables);
|
||||
|
||||
/* free the entries in the table */
|
||||
for (i = 0; i < pXlatTables->RefIdToPointer.NumberOfEntries; i++)
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable[i]);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable);
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.StateTable);
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->PointerToRefId.XlatTable);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables);
|
||||
}
|
||||
|
||||
static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId)
|
||||
{
|
||||
if (RefId >= pXlatTables->RefIdToPointer.NumberOfEntries)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = RefId * 2;
|
||||
pXlatTables->RefIdToPointer.XlatTable =
|
||||
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
pXlatTables->RefIdToPointer.XlatTable,
|
||||
sizeof(void *) * pXlatTables->RefIdToPointer.NumberOfEntries);
|
||||
pXlatTables->RefIdToPointer.StateTable =
|
||||
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
pXlatTables->RefIdToPointer.StateTable,
|
||||
sizeof(unsigned char) * pXlatTables->RefIdToPointer.NumberOfEntries);
|
||||
|
||||
if (!pXlatTables->RefIdToPointer.XlatTable || !pXlatTables->RefIdToPointer.StateTable)
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
void *pPointer, unsigned char QueryType,
|
||||
ULONG *pRefId )
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
|
||||
TRACE("(%p, %p, %d, %p)\n", pXlatTables, pPointer, QueryType, pRefId);
|
||||
|
||||
if (!pPointer)
|
||||
{
|
||||
*pRefId = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(pPointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
|
||||
|
||||
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
|
||||
if (pPointer == XlatTableEntry->Pointer)
|
||||
{
|
||||
*pRefId = XlatTableEntry->RefId;
|
||||
if (XlatTableEntry->State & QueryType)
|
||||
return 1;
|
||||
XlatTableEntry->State |= QueryType;
|
||||
return 0;
|
||||
}
|
||||
|
||||
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
|
||||
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
XlatTableEntry->Pointer = pPointer;
|
||||
XlatTableEntry->RefId = *pRefId = pXlatTables->NextRefId++;
|
||||
XlatTableEntry->State = QueryType;
|
||||
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
|
||||
|
||||
/* insert pointer into mapping table */
|
||||
expand_pointer_table_if_necessary(pXlatTables, XlatTableEntry->RefId);
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > XlatTableEntry->RefId)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
|
||||
pXlatTables->RefIdToPointer.StateTable[XlatTableEntry->RefId] = QueryType;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
ULONG RefId, unsigned char QueryType,
|
||||
void **ppPointer)
|
||||
{
|
||||
TRACE("(%p, 0x%x, %d, %p)\n", pXlatTables, RefId, QueryType, ppPointer);
|
||||
|
||||
expand_pointer_table_if_necessary(pXlatTables, RefId);
|
||||
|
||||
pXlatTables->NextRefId = max(RefId + 1, pXlatTables->NextRefId);
|
||||
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
{
|
||||
*ppPointer = pXlatTables->RefIdToPointer.XlatTable[RefId];
|
||||
if (QueryType)
|
||||
{
|
||||
if (pXlatTables->RefIdToPointer.StateTable[RefId] & QueryType)
|
||||
return 1;
|
||||
pXlatTables->RefIdToPointer.StateTable[RefId] |= QueryType;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
*ppPointer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WINAPI NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
ULONG RefId, void *pPointer)
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
|
||||
TRACE("(%p, 0x%x, %p)\n", pXlatTables, RefId, pPointer);
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(pPointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
|
||||
|
||||
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
|
||||
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
XlatTableEntry->Pointer = pPointer;
|
||||
XlatTableEntry->RefId = RefId;
|
||||
XlatTableEntry->State = 0;
|
||||
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
|
||||
|
||||
/* insert pointer into mapping table */
|
||||
expand_pointer_table_if_necessary(pXlatTables, RefId);
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables, void *Pointer)
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
ULONG RefId = 0;
|
||||
|
||||
TRACE("(%p, %p)\n", pXlatTables, Pointer);
|
||||
|
||||
if (!Pointer)
|
||||
return 1;
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(Pointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&Pointer)[i];
|
||||
|
||||
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
|
||||
if (Pointer == XlatTableEntry->Pointer)
|
||||
{
|
||||
if (XlatTableEntry->State & 0x20)
|
||||
return 0;
|
||||
XlatTableEntry->State |= 0x20;
|
||||
RefId = XlatTableEntry->RefId;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!XlatTableEntry)
|
||||
return 0;
|
||||
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.StateTable[RefId] |= 0x20;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,65 +1,65 @@
|
|||
/*
|
||||
* NDR definitions
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_NDR_MISC_H
|
||||
#define __WINE_NDR_MISC_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
struct IPSFactoryBuffer;
|
||||
|
||||
PFORMAT_STRING ComputeConformanceOrVariance(
|
||||
MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount);
|
||||
|
||||
static inline PFORMAT_STRING ComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
return ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount);
|
||||
}
|
||||
|
||||
static inline PFORMAT_STRING ComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
PFORMAT_STRING ret;
|
||||
ULONG_PTR ActualCount = pStubMsg->ActualCount;
|
||||
|
||||
pStubMsg->Offset = 0;
|
||||
ret = ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &ActualCount);
|
||||
pStubMsg->ActualCount = (ULONG)ActualCount;
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef unsigned char* (WINAPI *NDR_MARSHALL) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
typedef unsigned char* (WINAPI *NDR_UNMARSHALL)(PMIDL_STUB_MESSAGE, unsigned char**,PFORMAT_STRING, unsigned char);
|
||||
typedef void (WINAPI *NDR_BUFFERSIZE)(PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
typedef ULONG (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
|
||||
typedef void (WINAPI *NDR_FREE) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
|
||||
extern const NDR_MARSHALL NdrMarshaller[];
|
||||
extern const NDR_UNMARSHALL NdrUnmarshaller[];
|
||||
extern const NDR_BUFFERSIZE NdrBufferSizer[];
|
||||
extern const NDR_MEMORYSIZE NdrMemorySizer[];
|
||||
extern const NDR_FREE NdrFreer[];
|
||||
|
||||
#endif /* __WINE_NDR_MISC_H */
|
||||
/*
|
||||
* NDR definitions
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_NDR_MISC_H
|
||||
#define __WINE_NDR_MISC_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
struct IPSFactoryBuffer;
|
||||
|
||||
PFORMAT_STRING ComputeConformanceOrVariance(
|
||||
MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount);
|
||||
|
||||
static inline PFORMAT_STRING ComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
return ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount);
|
||||
}
|
||||
|
||||
static inline PFORMAT_STRING ComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
PFORMAT_STRING ret;
|
||||
ULONG_PTR ActualCount = pStubMsg->ActualCount;
|
||||
|
||||
pStubMsg->Offset = 0;
|
||||
ret = ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &ActualCount);
|
||||
pStubMsg->ActualCount = (ULONG)ActualCount;
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef unsigned char* (WINAPI *NDR_MARSHALL) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
typedef unsigned char* (WINAPI *NDR_UNMARSHALL)(PMIDL_STUB_MESSAGE, unsigned char**,PFORMAT_STRING, unsigned char);
|
||||
typedef void (WINAPI *NDR_BUFFERSIZE)(PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
typedef ULONG (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
|
||||
typedef void (WINAPI *NDR_FREE) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
|
||||
extern const NDR_MARSHALL NdrMarshaller[];
|
||||
extern const NDR_UNMARSHALL NdrUnmarshaller[];
|
||||
extern const NDR_BUFFERSIZE NdrBufferSizer[];
|
||||
extern const NDR_MEMORYSIZE NdrMemorySizer[];
|
||||
extern const NDR_FREE NdrFreer[];
|
||||
|
||||
#endif /* __WINE_NDR_MISC_H */
|
||||
|
|
|
@ -1,393 +1,393 @@
|
|||
/*
|
||||
* OLE32 callouts, COM interface marshalling
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - fix the wire-protocol to match MS/RPC
|
||||
* - finish RpcStream_Vtbl
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
#include "rpcproxy.h"
|
||||
#include "wine/rpcfc.h"
|
||||
#include "cpsf.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
static HMODULE hOLE;
|
||||
|
||||
static HRESULT (WINAPI *COM_GetMarshalSizeMax)(ULONG *,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD);
|
||||
static HRESULT (WINAPI *COM_MarshalInterface)(LPSTREAM,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD);
|
||||
static HRESULT (WINAPI *COM_UnmarshalInterface)(LPSTREAM,REFIID,LPVOID*);
|
||||
static HRESULT (WINAPI *COM_ReleaseMarshalData)(LPSTREAM);
|
||||
static HRESULT (WINAPI *COM_GetClassObject)(REFCLSID,DWORD,COSERVERINFO *,REFIID,LPVOID *);
|
||||
static HRESULT (WINAPI *COM_GetPSClsid)(REFIID,CLSID *);
|
||||
static LPVOID (WINAPI *COM_MemAlloc)(ULONG);
|
||||
static void (WINAPI *COM_MemFree)(LPVOID);
|
||||
|
||||
static HMODULE LoadCOM(void)
|
||||
{
|
||||
if (hOLE) return hOLE;
|
||||
hOLE = LoadLibraryA("OLE32.DLL");
|
||||
if (!hOLE) return 0;
|
||||
COM_GetMarshalSizeMax = (LPVOID)GetProcAddress(hOLE, "CoGetMarshalSizeMax");
|
||||
COM_MarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoMarshalInterface");
|
||||
COM_UnmarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoUnmarshalInterface");
|
||||
COM_ReleaseMarshalData = (LPVOID)GetProcAddress(hOLE, "CoReleaseMarshalData");
|
||||
COM_GetClassObject = (LPVOID)GetProcAddress(hOLE, "CoGetClassObject");
|
||||
COM_GetPSClsid = (LPVOID)GetProcAddress(hOLE, "CoGetPSClsid");
|
||||
COM_MemAlloc = (LPVOID)GetProcAddress(hOLE, "CoTaskMemAlloc");
|
||||
COM_MemFree = (LPVOID)GetProcAddress(hOLE, "CoTaskMemFree");
|
||||
return hOLE;
|
||||
}
|
||||
|
||||
/* CoMarshalInterface/CoUnmarshalInterface works on streams,
|
||||
* so implement a simple stream on top of the RPC buffer
|
||||
* (which also implements the MInterfacePointer structure) */
|
||||
typedef struct RpcStreamImpl
|
||||
{
|
||||
const IStreamVtbl *lpVtbl;
|
||||
DWORD RefCount;
|
||||
PMIDL_STUB_MESSAGE pMsg;
|
||||
LPDWORD size;
|
||||
unsigned char *data;
|
||||
DWORD pos;
|
||||
} RpcStreamImpl;
|
||||
|
||||
static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (IsEqualGUID(&IID_IUnknown, riid) ||
|
||||
IsEqualGUID(&IID_ISequentialStream, riid) ||
|
||||
IsEqualGUID(&IID_IStream, riid)) {
|
||||
*obj = This;
|
||||
This->RefCount++;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStream_AddRef(LPSTREAM iface)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
return ++(This->RefCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStream_Release(LPSTREAM iface)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (!--(This->RefCount)) {
|
||||
TRACE("size=%d\n", *This->size);
|
||||
This->pMsg->Buffer = (unsigned char*)This->data + *This->size;
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return 0;
|
||||
}
|
||||
return This->RefCount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Read(LPSTREAM iface,
|
||||
void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbRead)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
HRESULT hr = S_OK;
|
||||
if (This->pos + cb > *This->size)
|
||||
{
|
||||
cb = *This->size - This->pos;
|
||||
hr = S_FALSE;
|
||||
}
|
||||
if (cb) {
|
||||
memcpy(pv, This->data + This->pos, cb);
|
||||
This->pos += cb;
|
||||
}
|
||||
if (pcbRead) *pcbRead = cb;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Write(LPSTREAM iface,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (This->data + cb > (unsigned char *)This->pMsg->RpcMsg->Buffer + This->pMsg->BufferLength)
|
||||
return STG_E_MEDIUMFULL;
|
||||
memcpy(This->data + This->pos, pv, cb);
|
||||
This->pos += cb;
|
||||
if (This->pos > *This->size) *This->size = This->pos;
|
||||
if (pcbWritten) *pcbWritten = cb;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Seek(LPSTREAM iface,
|
||||
LARGE_INTEGER move,
|
||||
DWORD origin,
|
||||
ULARGE_INTEGER *newPos)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
switch (origin) {
|
||||
case STREAM_SEEK_SET:
|
||||
This->pos = move.u.LowPart;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
This->pos = This->pos + move.u.LowPart;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
This->pos = *This->size + move.u.LowPart;
|
||||
break;
|
||||
default:
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
if (newPos) {
|
||||
newPos->u.LowPart = This->pos;
|
||||
newPos->u.HighPart = 0;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_SetSize(LPSTREAM iface,
|
||||
ULARGE_INTEGER newSize)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
*This->size = newSize.u.LowPart;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IStreamVtbl RpcStream_Vtbl =
|
||||
{
|
||||
RpcStream_QueryInterface,
|
||||
RpcStream_AddRef,
|
||||
RpcStream_Release,
|
||||
RpcStream_Read,
|
||||
RpcStream_Write,
|
||||
RpcStream_Seek,
|
||||
RpcStream_SetSize,
|
||||
NULL, /* CopyTo */
|
||||
NULL, /* Commit */
|
||||
NULL, /* Revert */
|
||||
NULL, /* LockRegion */
|
||||
NULL, /* UnlockRegion */
|
||||
NULL, /* Stat */
|
||||
NULL /* Clone */
|
||||
};
|
||||
|
||||
static LPSTREAM RpcStream_Create(PMIDL_STUB_MESSAGE pStubMsg, BOOL init)
|
||||
{
|
||||
RpcStreamImpl *This;
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(RpcStreamImpl));
|
||||
if (!This) return NULL;
|
||||
This->lpVtbl = &RpcStream_Vtbl;
|
||||
This->RefCount = 1;
|
||||
This->pMsg = pStubMsg;
|
||||
This->size = (LPDWORD)pStubMsg->Buffer;
|
||||
This->data = (unsigned char*)(This->size + 1);
|
||||
This->pos = 0;
|
||||
if (init) *This->size = 0;
|
||||
TRACE("init size=%d\n", *This->size);
|
||||
return (LPSTREAM)This;
|
||||
}
|
||||
|
||||
static const IID* get_ip_iid(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid;
|
||||
if (!pFormat) return &IID_IUnknown;
|
||||
TRACE("format=%02x %02x\n", pFormat[0], pFormat[1]);
|
||||
if (pFormat[0] != RPC_FC_IP) FIXME("format=%d\n", pFormat[0]);
|
||||
if (pFormat[1] == RPC_FC_CONSTANT_IID) {
|
||||
riid = (const IID *)&pFormat[2];
|
||||
} else {
|
||||
ComputeConformance(pStubMsg, pMemory, pFormat+2, 0);
|
||||
riid = (const IID *)pStubMsg->MaxCount;
|
||||
}
|
||||
if (!riid) riid = &IID_IUnknown;
|
||||
TRACE("got %s\n", debugstr_guid(riid));
|
||||
return riid;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerMarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat);
|
||||
LPSTREAM stream;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
pStubMsg->MaxCount = 0;
|
||||
if (!LoadCOM()) return NULL;
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
stream = RpcStream_Create(pStubMsg, TRUE);
|
||||
if (stream) {
|
||||
if (pMemory)
|
||||
hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory,
|
||||
pStubMsg->dwDestContext, pStubMsg->pvDestContext,
|
||||
MSHLFLAGS_NORMAL);
|
||||
else
|
||||
hr = S_OK;
|
||||
|
||||
IStream_Release(stream);
|
||||
if (FAILED(hr))
|
||||
RpcRaiseException(hr);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerUnmarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char **ppMemory,
|
||||
PFORMAT_STRING pFormat,
|
||||
unsigned char fMustAlloc)
|
||||
{
|
||||
LPSTREAM stream;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
|
||||
if (!LoadCOM()) return NULL;
|
||||
*(LPVOID*)ppMemory = NULL;
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
stream = RpcStream_Create(pStubMsg, FALSE);
|
||||
if (!stream) RpcRaiseException(E_OUTOFMEMORY);
|
||||
if (*((RpcStreamImpl *)stream)->size != 0)
|
||||
hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory);
|
||||
else
|
||||
hr = S_OK;
|
||||
IStream_Release(stream);
|
||||
if (FAILED(hr))
|
||||
RpcRaiseException(hr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerBufferSize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat);
|
||||
ULONG size = 0;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
if (!LoadCOM()) return;
|
||||
hr = COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory,
|
||||
pStubMsg->dwDestContext, pStubMsg->pvDestContext,
|
||||
MSHLFLAGS_NORMAL);
|
||||
TRACE("size=%d\n", size);
|
||||
pStubMsg->BufferLength += sizeof(DWORD) + size;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerMemorySize [RPCRT4.@]
|
||||
*/
|
||||
ULONG WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG size;
|
||||
|
||||
TRACE("(%p,%p)\n", pStubMsg, pFormat);
|
||||
|
||||
size = *(ULONG *)pStubMsg->Buffer;
|
||||
pStubMsg->Buffer += 4;
|
||||
pStubMsg->MemorySize += 4;
|
||||
|
||||
pStubMsg->Buffer += size;
|
||||
|
||||
return pStubMsg->MemorySize;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerFree [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
LPUNKNOWN pUnk = (LPUNKNOWN)pMemory;
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
if (pUnk) IUnknown_Release(pUnk);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrOleAllocate [RPCRT4.@]
|
||||
*/
|
||||
void * WINAPI NdrOleAllocate(size_t Size)
|
||||
{
|
||||
if (!LoadCOM()) return NULL;
|
||||
return COM_MemAlloc(Size);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrOleFree [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrOleFree(void *NodeToFree)
|
||||
{
|
||||
if (!LoadCOM()) return;
|
||||
COM_MemFree(NodeToFree);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Helper function to create a stub.
|
||||
* This probably looks very much like NdrpCreateStub.
|
||||
*/
|
||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub)
|
||||
{
|
||||
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_CreateStub(psfac, iid, pUnk, ppstub);
|
||||
|
||||
IPSFactoryBuffer_Release(psfac);
|
||||
return r;
|
||||
}
|
||||
/*
|
||||
* OLE32 callouts, COM interface marshalling
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - fix the wire-protocol to match MS/RPC
|
||||
* - finish RpcStream_Vtbl
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
#include "rpcproxy.h"
|
||||
#include "wine/rpcfc.h"
|
||||
#include "cpsf.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
static HMODULE hOLE;
|
||||
|
||||
static HRESULT (WINAPI *COM_GetMarshalSizeMax)(ULONG *,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD);
|
||||
static HRESULT (WINAPI *COM_MarshalInterface)(LPSTREAM,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD);
|
||||
static HRESULT (WINAPI *COM_UnmarshalInterface)(LPSTREAM,REFIID,LPVOID*);
|
||||
static HRESULT (WINAPI *COM_ReleaseMarshalData)(LPSTREAM);
|
||||
static HRESULT (WINAPI *COM_GetClassObject)(REFCLSID,DWORD,COSERVERINFO *,REFIID,LPVOID *);
|
||||
static HRESULT (WINAPI *COM_GetPSClsid)(REFIID,CLSID *);
|
||||
static LPVOID (WINAPI *COM_MemAlloc)(ULONG);
|
||||
static void (WINAPI *COM_MemFree)(LPVOID);
|
||||
|
||||
static HMODULE LoadCOM(void)
|
||||
{
|
||||
if (hOLE) return hOLE;
|
||||
hOLE = LoadLibraryA("OLE32.DLL");
|
||||
if (!hOLE) return 0;
|
||||
COM_GetMarshalSizeMax = (LPVOID)GetProcAddress(hOLE, "CoGetMarshalSizeMax");
|
||||
COM_MarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoMarshalInterface");
|
||||
COM_UnmarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoUnmarshalInterface");
|
||||
COM_ReleaseMarshalData = (LPVOID)GetProcAddress(hOLE, "CoReleaseMarshalData");
|
||||
COM_GetClassObject = (LPVOID)GetProcAddress(hOLE, "CoGetClassObject");
|
||||
COM_GetPSClsid = (LPVOID)GetProcAddress(hOLE, "CoGetPSClsid");
|
||||
COM_MemAlloc = (LPVOID)GetProcAddress(hOLE, "CoTaskMemAlloc");
|
||||
COM_MemFree = (LPVOID)GetProcAddress(hOLE, "CoTaskMemFree");
|
||||
return hOLE;
|
||||
}
|
||||
|
||||
/* CoMarshalInterface/CoUnmarshalInterface works on streams,
|
||||
* so implement a simple stream on top of the RPC buffer
|
||||
* (which also implements the MInterfacePointer structure) */
|
||||
typedef struct RpcStreamImpl
|
||||
{
|
||||
const IStreamVtbl *lpVtbl;
|
||||
DWORD RefCount;
|
||||
PMIDL_STUB_MESSAGE pMsg;
|
||||
LPDWORD size;
|
||||
unsigned char *data;
|
||||
DWORD pos;
|
||||
} RpcStreamImpl;
|
||||
|
||||
static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (IsEqualGUID(&IID_IUnknown, riid) ||
|
||||
IsEqualGUID(&IID_ISequentialStream, riid) ||
|
||||
IsEqualGUID(&IID_IStream, riid)) {
|
||||
*obj = This;
|
||||
This->RefCount++;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStream_AddRef(LPSTREAM iface)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
return ++(This->RefCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStream_Release(LPSTREAM iface)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (!--(This->RefCount)) {
|
||||
TRACE("size=%d\n", *This->size);
|
||||
This->pMsg->Buffer = (unsigned char*)This->data + *This->size;
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return 0;
|
||||
}
|
||||
return This->RefCount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Read(LPSTREAM iface,
|
||||
void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbRead)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
HRESULT hr = S_OK;
|
||||
if (This->pos + cb > *This->size)
|
||||
{
|
||||
cb = *This->size - This->pos;
|
||||
hr = S_FALSE;
|
||||
}
|
||||
if (cb) {
|
||||
memcpy(pv, This->data + This->pos, cb);
|
||||
This->pos += cb;
|
||||
}
|
||||
if (pcbRead) *pcbRead = cb;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Write(LPSTREAM iface,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (This->data + cb > (unsigned char *)This->pMsg->RpcMsg->Buffer + This->pMsg->BufferLength)
|
||||
return STG_E_MEDIUMFULL;
|
||||
memcpy(This->data + This->pos, pv, cb);
|
||||
This->pos += cb;
|
||||
if (This->pos > *This->size) *This->size = This->pos;
|
||||
if (pcbWritten) *pcbWritten = cb;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Seek(LPSTREAM iface,
|
||||
LARGE_INTEGER move,
|
||||
DWORD origin,
|
||||
ULARGE_INTEGER *newPos)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
switch (origin) {
|
||||
case STREAM_SEEK_SET:
|
||||
This->pos = move.u.LowPart;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
This->pos = This->pos + move.u.LowPart;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
This->pos = *This->size + move.u.LowPart;
|
||||
break;
|
||||
default:
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
if (newPos) {
|
||||
newPos->u.LowPart = This->pos;
|
||||
newPos->u.HighPart = 0;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_SetSize(LPSTREAM iface,
|
||||
ULARGE_INTEGER newSize)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
*This->size = newSize.u.LowPart;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IStreamVtbl RpcStream_Vtbl =
|
||||
{
|
||||
RpcStream_QueryInterface,
|
||||
RpcStream_AddRef,
|
||||
RpcStream_Release,
|
||||
RpcStream_Read,
|
||||
RpcStream_Write,
|
||||
RpcStream_Seek,
|
||||
RpcStream_SetSize,
|
||||
NULL, /* CopyTo */
|
||||
NULL, /* Commit */
|
||||
NULL, /* Revert */
|
||||
NULL, /* LockRegion */
|
||||
NULL, /* UnlockRegion */
|
||||
NULL, /* Stat */
|
||||
NULL /* Clone */
|
||||
};
|
||||
|
||||
static LPSTREAM RpcStream_Create(PMIDL_STUB_MESSAGE pStubMsg, BOOL init)
|
||||
{
|
||||
RpcStreamImpl *This;
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(RpcStreamImpl));
|
||||
if (!This) return NULL;
|
||||
This->lpVtbl = &RpcStream_Vtbl;
|
||||
This->RefCount = 1;
|
||||
This->pMsg = pStubMsg;
|
||||
This->size = (LPDWORD)pStubMsg->Buffer;
|
||||
This->data = (unsigned char*)(This->size + 1);
|
||||
This->pos = 0;
|
||||
if (init) *This->size = 0;
|
||||
TRACE("init size=%d\n", *This->size);
|
||||
return (LPSTREAM)This;
|
||||
}
|
||||
|
||||
static const IID* get_ip_iid(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid;
|
||||
if (!pFormat) return &IID_IUnknown;
|
||||
TRACE("format=%02x %02x\n", pFormat[0], pFormat[1]);
|
||||
if (pFormat[0] != RPC_FC_IP) FIXME("format=%d\n", pFormat[0]);
|
||||
if (pFormat[1] == RPC_FC_CONSTANT_IID) {
|
||||
riid = (const IID *)&pFormat[2];
|
||||
} else {
|
||||
ComputeConformance(pStubMsg, pMemory, pFormat+2, 0);
|
||||
riid = (const IID *)pStubMsg->MaxCount;
|
||||
}
|
||||
if (!riid) riid = &IID_IUnknown;
|
||||
TRACE("got %s\n", debugstr_guid(riid));
|
||||
return riid;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerMarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat);
|
||||
LPSTREAM stream;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
pStubMsg->MaxCount = 0;
|
||||
if (!LoadCOM()) return NULL;
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
stream = RpcStream_Create(pStubMsg, TRUE);
|
||||
if (stream) {
|
||||
if (pMemory)
|
||||
hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory,
|
||||
pStubMsg->dwDestContext, pStubMsg->pvDestContext,
|
||||
MSHLFLAGS_NORMAL);
|
||||
else
|
||||
hr = S_OK;
|
||||
|
||||
IStream_Release(stream);
|
||||
if (FAILED(hr))
|
||||
RpcRaiseException(hr);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerUnmarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char **ppMemory,
|
||||
PFORMAT_STRING pFormat,
|
||||
unsigned char fMustAlloc)
|
||||
{
|
||||
LPSTREAM stream;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
|
||||
if (!LoadCOM()) return NULL;
|
||||
*(LPVOID*)ppMemory = NULL;
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
stream = RpcStream_Create(pStubMsg, FALSE);
|
||||
if (!stream) RpcRaiseException(E_OUTOFMEMORY);
|
||||
if (*((RpcStreamImpl *)stream)->size != 0)
|
||||
hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory);
|
||||
else
|
||||
hr = S_OK;
|
||||
IStream_Release(stream);
|
||||
if (FAILED(hr))
|
||||
RpcRaiseException(hr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerBufferSize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat);
|
||||
ULONG size = 0;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
if (!LoadCOM()) return;
|
||||
hr = COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory,
|
||||
pStubMsg->dwDestContext, pStubMsg->pvDestContext,
|
||||
MSHLFLAGS_NORMAL);
|
||||
TRACE("size=%d\n", size);
|
||||
pStubMsg->BufferLength += sizeof(DWORD) + size;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerMemorySize [RPCRT4.@]
|
||||
*/
|
||||
ULONG WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG size;
|
||||
|
||||
TRACE("(%p,%p)\n", pStubMsg, pFormat);
|
||||
|
||||
size = *(ULONG *)pStubMsg->Buffer;
|
||||
pStubMsg->Buffer += 4;
|
||||
pStubMsg->MemorySize += 4;
|
||||
|
||||
pStubMsg->Buffer += size;
|
||||
|
||||
return pStubMsg->MemorySize;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerFree [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
LPUNKNOWN pUnk = (LPUNKNOWN)pMemory;
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
if (pUnk) IUnknown_Release(pUnk);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrOleAllocate [RPCRT4.@]
|
||||
*/
|
||||
void * WINAPI NdrOleAllocate(size_t Size)
|
||||
{
|
||||
if (!LoadCOM()) return NULL;
|
||||
return COM_MemAlloc(Size);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrOleFree [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrOleFree(void *NodeToFree)
|
||||
{
|
||||
if (!LoadCOM()) return;
|
||||
COM_MemFree(NodeToFree);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Helper function to create a stub.
|
||||
* This probably looks very much like NdrpCreateStub.
|
||||
*/
|
||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub)
|
||||
{
|
||||
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_CreateStub(psfac, iid, pUnk, ppstub);
|
||||
|
||||
IPSFactoryBuffer_Release(psfac);
|
||||
return r;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,197 +1,197 @@
|
|||
/*
|
||||
* RPC binding API
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_BINDING_H
|
||||
#define __WINE_RPC_BINDING_H
|
||||
|
||||
#include "wine/rpcss_shared.h"
|
||||
#include "rpcndr.h"
|
||||
#include "security.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
|
||||
typedef struct _RpcAuthInfo
|
||||
{
|
||||
LONG refs;
|
||||
|
||||
ULONG AuthnLevel;
|
||||
ULONG AuthnSvc;
|
||||
CredHandle cred;
|
||||
TimeStamp exp;
|
||||
ULONG cbMaxToken;
|
||||
/* the auth identity pointer that the application passed us (freed by application) */
|
||||
RPC_AUTH_IDENTITY_HANDLE *identity;
|
||||
/* our copy of NT auth identity structure, if the authentication service
|
||||
* takes an NT auth identity */
|
||||
SEC_WINNT_AUTH_IDENTITY_W *nt_identity;
|
||||
} RpcAuthInfo;
|
||||
|
||||
typedef struct _RpcQualityOfService
|
||||
{
|
||||
LONG refs;
|
||||
|
||||
RPC_SECURITY_QOS_V2_W *qos;
|
||||
} RpcQualityOfService;
|
||||
|
||||
struct connection_ops;
|
||||
|
||||
typedef struct _RpcConnection
|
||||
{
|
||||
BOOL server;
|
||||
LPSTR NetworkAddr;
|
||||
LPSTR Endpoint;
|
||||
LPWSTR NetworkOptions;
|
||||
const struct connection_ops *ops;
|
||||
USHORT MaxTransmissionSize;
|
||||
|
||||
/* authentication */
|
||||
CtxtHandle ctx;
|
||||
TimeStamp exp;
|
||||
ULONG attr;
|
||||
RpcAuthInfo *AuthInfo;
|
||||
ULONG encryption_auth_len;
|
||||
ULONG signature_auth_len;
|
||||
RpcQualityOfService *QOS;
|
||||
|
||||
/* client-only */
|
||||
struct list conn_pool_entry;
|
||||
ULONG assoc_group_id; /* association group returned during binding */
|
||||
|
||||
/* server-only */
|
||||
/* The active interface bound to server. */
|
||||
RPC_SYNTAX_IDENTIFIER ActiveInterface;
|
||||
USHORT NextCallId;
|
||||
struct _RpcConnection* Next;
|
||||
struct _RpcBinding *server_binding;
|
||||
} RpcConnection;
|
||||
|
||||
struct connection_ops {
|
||||
const char *name;
|
||||
unsigned char epm_protocols[2]; /* only floors 3 and 4. see http://www.opengroup.org/onlinepubs/9629399/apdxl.htm */
|
||||
RpcConnection *(*alloc)(void);
|
||||
RPC_STATUS (*open_connection_client)(RpcConnection *conn);
|
||||
RPC_STATUS (*handoff)(RpcConnection *old_conn, RpcConnection *new_conn);
|
||||
int (*read)(RpcConnection *conn, void *buffer, unsigned int len);
|
||||
int (*write)(RpcConnection *conn, const void *buffer, unsigned int len);
|
||||
int (*close)(RpcConnection *conn);
|
||||
void (*cancel_call)(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);
|
||||
};
|
||||
|
||||
/* don't know what MS's structure looks like */
|
||||
typedef struct _RpcBinding
|
||||
{
|
||||
LONG refs;
|
||||
struct _RpcBinding* Next;
|
||||
BOOL server;
|
||||
UUID ObjectUuid;
|
||||
LPSTR Protseq;
|
||||
LPSTR NetworkAddr;
|
||||
LPSTR Endpoint;
|
||||
LPWSTR NetworkOptions;
|
||||
RPC_BLOCKING_FN BlockingFn;
|
||||
ULONG ServerTid;
|
||||
RpcConnection* FromConn;
|
||||
struct _RpcAssoc *Assoc;
|
||||
|
||||
/* authentication */
|
||||
RpcAuthInfo *AuthInfo;
|
||||
RpcQualityOfService *QOS;
|
||||
} RpcBinding;
|
||||
|
||||
LPSTR RPCRT4_strndupA(LPCSTR src, INT len);
|
||||
LPWSTR RPCRT4_strndupW(LPCWSTR src, INT len);
|
||||
LPSTR RPCRT4_strdupWtoA(LPCWSTR src);
|
||||
LPWSTR RPCRT4_strdupAtoW(LPCSTR src);
|
||||
void RPCRT4_strfree(LPSTR src);
|
||||
|
||||
#define RPCRT4_strdupA(x) RPCRT4_strndupA((x),-1)
|
||||
#define RPCRT4_strdupW(x) RPCRT4_strndupW((x),-1)
|
||||
|
||||
ULONG RpcAuthInfo_AddRef(RpcAuthInfo *AuthInfo);
|
||||
ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo);
|
||||
BOOL RpcAuthInfo_IsEqual(const RpcAuthInfo *AuthInfo1, const RpcAuthInfo *AuthInfo2);
|
||||
ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos);
|
||||
ULONG RpcQualityOfService_Release(RpcQualityOfService *qos);
|
||||
BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQualityOfService *qos2);
|
||||
|
||||
RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS);
|
||||
RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_OpenClientConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection);
|
||||
|
||||
RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint);
|
||||
RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid);
|
||||
RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding);
|
||||
RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding);
|
||||
RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
|
||||
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId);
|
||||
RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection);
|
||||
BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply);
|
||||
HANDLE RPCRT4_GetMasterMutex(void);
|
||||
HANDLE RPCRT4_RpcssNPConnect(void);
|
||||
|
||||
static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection)
|
||||
{
|
||||
return Connection->ops->name;
|
||||
}
|
||||
|
||||
static inline int rpcrt4_conn_read(RpcConnection *Connection,
|
||||
void *buffer, unsigned int len)
|
||||
{
|
||||
return Connection->ops->read(Connection, buffer, len);
|
||||
}
|
||||
|
||||
static inline int rpcrt4_conn_write(RpcConnection *Connection,
|
||||
const void *buffer, unsigned int len)
|
||||
{
|
||||
return Connection->ops->write(Connection, buffer, len);
|
||||
}
|
||||
|
||||
static inline int rpcrt4_conn_close(RpcConnection *Connection)
|
||||
{
|
||||
return Connection->ops->close(Connection);
|
||||
}
|
||||
|
||||
static inline void rpcrt4_conn_cancel_call(RpcConnection *Connection)
|
||||
{
|
||||
Connection->ops->cancel_call(Connection);
|
||||
}
|
||||
|
||||
static inline RPC_STATUS rpcrt4_conn_handoff(RpcConnection *old_conn, RpcConnection *new_conn)
|
||||
{
|
||||
return old_conn->ops->handoff(old_conn, new_conn);
|
||||
}
|
||||
|
||||
/* floors 3 and up */
|
||||
RPC_STATUS RpcTransport_GetTopOfTower(unsigned char *tower_data, size_t *tower_size, const char *protseq, const char *networkaddr, const char *endpoint);
|
||||
RPC_STATUS RpcTransport_ParseTopOfTower(const unsigned char *tower_data, size_t tower_size, char **protseq, char **networkaddr, char **endpoint);
|
||||
|
||||
void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection);
|
||||
void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding);
|
||||
RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void);
|
||||
void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext);
|
||||
void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext);
|
||||
NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* RPC binding API
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_BINDING_H
|
||||
#define __WINE_RPC_BINDING_H
|
||||
|
||||
#include "wine/rpcss_shared.h"
|
||||
#include "rpcndr.h"
|
||||
#include "security.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
|
||||
typedef struct _RpcAuthInfo
|
||||
{
|
||||
LONG refs;
|
||||
|
||||
ULONG AuthnLevel;
|
||||
ULONG AuthnSvc;
|
||||
CredHandle cred;
|
||||
TimeStamp exp;
|
||||
ULONG cbMaxToken;
|
||||
/* the auth identity pointer that the application passed us (freed by application) */
|
||||
RPC_AUTH_IDENTITY_HANDLE *identity;
|
||||
/* our copy of NT auth identity structure, if the authentication service
|
||||
* takes an NT auth identity */
|
||||
SEC_WINNT_AUTH_IDENTITY_W *nt_identity;
|
||||
} RpcAuthInfo;
|
||||
|
||||
typedef struct _RpcQualityOfService
|
||||
{
|
||||
LONG refs;
|
||||
|
||||
RPC_SECURITY_QOS_V2_W *qos;
|
||||
} RpcQualityOfService;
|
||||
|
||||
struct connection_ops;
|
||||
|
||||
typedef struct _RpcConnection
|
||||
{
|
||||
BOOL server;
|
||||
LPSTR NetworkAddr;
|
||||
LPSTR Endpoint;
|
||||
LPWSTR NetworkOptions;
|
||||
const struct connection_ops *ops;
|
||||
USHORT MaxTransmissionSize;
|
||||
|
||||
/* authentication */
|
||||
CtxtHandle ctx;
|
||||
TimeStamp exp;
|
||||
ULONG attr;
|
||||
RpcAuthInfo *AuthInfo;
|
||||
ULONG encryption_auth_len;
|
||||
ULONG signature_auth_len;
|
||||
RpcQualityOfService *QOS;
|
||||
|
||||
/* client-only */
|
||||
struct list conn_pool_entry;
|
||||
ULONG assoc_group_id; /* association group returned during binding */
|
||||
|
||||
/* server-only */
|
||||
/* The active interface bound to server. */
|
||||
RPC_SYNTAX_IDENTIFIER ActiveInterface;
|
||||
USHORT NextCallId;
|
||||
struct _RpcConnection* Next;
|
||||
struct _RpcBinding *server_binding;
|
||||
} RpcConnection;
|
||||
|
||||
struct connection_ops {
|
||||
const char *name;
|
||||
unsigned char epm_protocols[2]; /* only floors 3 and 4. see http://www.opengroup.org/onlinepubs/9629399/apdxl.htm */
|
||||
RpcConnection *(*alloc)(void);
|
||||
RPC_STATUS (*open_connection_client)(RpcConnection *conn);
|
||||
RPC_STATUS (*handoff)(RpcConnection *old_conn, RpcConnection *new_conn);
|
||||
int (*read)(RpcConnection *conn, void *buffer, unsigned int len);
|
||||
int (*write)(RpcConnection *conn, const void *buffer, unsigned int len);
|
||||
int (*close)(RpcConnection *conn);
|
||||
void (*cancel_call)(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);
|
||||
};
|
||||
|
||||
/* don't know what MS's structure looks like */
|
||||
typedef struct _RpcBinding
|
||||
{
|
||||
LONG refs;
|
||||
struct _RpcBinding* Next;
|
||||
BOOL server;
|
||||
UUID ObjectUuid;
|
||||
LPSTR Protseq;
|
||||
LPSTR NetworkAddr;
|
||||
LPSTR Endpoint;
|
||||
LPWSTR NetworkOptions;
|
||||
RPC_BLOCKING_FN BlockingFn;
|
||||
ULONG ServerTid;
|
||||
RpcConnection* FromConn;
|
||||
struct _RpcAssoc *Assoc;
|
||||
|
||||
/* authentication */
|
||||
RpcAuthInfo *AuthInfo;
|
||||
RpcQualityOfService *QOS;
|
||||
} RpcBinding;
|
||||
|
||||
LPSTR RPCRT4_strndupA(LPCSTR src, INT len);
|
||||
LPWSTR RPCRT4_strndupW(LPCWSTR src, INT len);
|
||||
LPSTR RPCRT4_strdupWtoA(LPCWSTR src);
|
||||
LPWSTR RPCRT4_strdupAtoW(LPCSTR src);
|
||||
void RPCRT4_strfree(LPSTR src);
|
||||
|
||||
#define RPCRT4_strdupA(x) RPCRT4_strndupA((x),-1)
|
||||
#define RPCRT4_strdupW(x) RPCRT4_strndupW((x),-1)
|
||||
|
||||
ULONG RpcAuthInfo_AddRef(RpcAuthInfo *AuthInfo);
|
||||
ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo);
|
||||
BOOL RpcAuthInfo_IsEqual(const RpcAuthInfo *AuthInfo1, const RpcAuthInfo *AuthInfo2);
|
||||
ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos);
|
||||
ULONG RpcQualityOfService_Release(RpcQualityOfService *qos);
|
||||
BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQualityOfService *qos2);
|
||||
|
||||
RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS);
|
||||
RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_OpenClientConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection);
|
||||
|
||||
RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint);
|
||||
RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid);
|
||||
RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding);
|
||||
RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding);
|
||||
RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
|
||||
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId);
|
||||
RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection);
|
||||
BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply);
|
||||
HANDLE RPCRT4_GetMasterMutex(void);
|
||||
HANDLE RPCRT4_RpcssNPConnect(void);
|
||||
|
||||
static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection)
|
||||
{
|
||||
return Connection->ops->name;
|
||||
}
|
||||
|
||||
static inline int rpcrt4_conn_read(RpcConnection *Connection,
|
||||
void *buffer, unsigned int len)
|
||||
{
|
||||
return Connection->ops->read(Connection, buffer, len);
|
||||
}
|
||||
|
||||
static inline int rpcrt4_conn_write(RpcConnection *Connection,
|
||||
const void *buffer, unsigned int len)
|
||||
{
|
||||
return Connection->ops->write(Connection, buffer, len);
|
||||
}
|
||||
|
||||
static inline int rpcrt4_conn_close(RpcConnection *Connection)
|
||||
{
|
||||
return Connection->ops->close(Connection);
|
||||
}
|
||||
|
||||
static inline void rpcrt4_conn_cancel_call(RpcConnection *Connection)
|
||||
{
|
||||
Connection->ops->cancel_call(Connection);
|
||||
}
|
||||
|
||||
static inline RPC_STATUS rpcrt4_conn_handoff(RpcConnection *old_conn, RpcConnection *new_conn)
|
||||
{
|
||||
return old_conn->ops->handoff(old_conn, new_conn);
|
||||
}
|
||||
|
||||
/* floors 3 and up */
|
||||
RPC_STATUS RpcTransport_GetTopOfTower(unsigned char *tower_data, size_t *tower_size, const char *protseq, const char *networkaddr, const char *endpoint);
|
||||
RPC_STATUS RpcTransport_ParseTopOfTower(const unsigned char *tower_data, size_t tower_size, char **protseq, char **networkaddr, char **endpoint);
|
||||
|
||||
void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection);
|
||||
void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding);
|
||||
RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void);
|
||||
void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext);
|
||||
void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext);
|
||||
NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,212 +1,212 @@
|
|||
/*
|
||||
* RPC definitions
|
||||
*
|
||||
* Copyright 2001-2002 Ove Kåven, TransGaming Technologies
|
||||
* Copyright 2004 Filip Navara
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_DEFS_H
|
||||
#define __WINE_RPC_DEFS_H
|
||||
|
||||
/* info from http://www.microsoft.com/msj/0398/dcomtextfigs.htm */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char rpc_ver; /* RPC major version (5) */
|
||||
unsigned char rpc_ver_minor; /* RPC minor version (0) */
|
||||
unsigned char ptype; /* Packet type (PKT_*) */
|
||||
unsigned char flags;
|
||||
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 long call_id; /* Call identifier. */
|
||||
} RpcPktCommonHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */
|
||||
unsigned short context_id; /* Presentation context identifier */
|
||||
unsigned short opnum;
|
||||
} RpcPktRequestHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
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;
|
||||
} RpcPktResponseHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
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 long status; /* Runtime fault code (RPC_STATUS) */
|
||||
unsigned long reserved2;
|
||||
} RpcPktFaultHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned short max_tsize; /* Maximum transmission fragment size */
|
||||
unsigned short max_rsize; /* Maximum receive fragment size */
|
||||
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 */
|
||||
unsigned char num_syntaxes; /* Number of syntaxes */
|
||||
RPC_SYNTAX_IDENTIFIER abstract;
|
||||
RPC_SYNTAX_IDENTIFIER transfer;
|
||||
} RpcPktBindHdr;
|
||||
|
||||
#include "pshpack1.h"
|
||||
typedef struct
|
||||
{
|
||||
unsigned short length; /* Length of the string including null terminator */
|
||||
char string[1]; /* String data in single byte, null terminated form */
|
||||
} RpcAddressString;
|
||||
#include "poppack.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char num_results; /* Number of results */
|
||||
unsigned char reserved[3]; /* Force alignment! */
|
||||
struct {
|
||||
unsigned short result;
|
||||
unsigned short reason;
|
||||
} results[1];
|
||||
} RpcResults;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned short max_tsize; /* Maximum transmission fragment size */
|
||||
unsigned short max_rsize; /* Maximum receive fragment size */
|
||||
unsigned long assoc_gid; /* Associated group id */
|
||||
/*
|
||||
* Following this header are these fields:
|
||||
* RpcAddressString server_address;
|
||||
* [0 - 3 bytes of padding so that results is 4-byte aligned]
|
||||
* RpcResults results;
|
||||
* RPC_SYNTAX_IDENTIFIER transfer;
|
||||
*/
|
||||
} RpcPktBindAckHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned short reject_reason;
|
||||
unsigned char protocols_count;
|
||||
struct {
|
||||
unsigned char rpc_ver;
|
||||
unsigned char rpc_ver_minor;
|
||||
} protocols[1];
|
||||
} RpcPktBindNAckHdr;
|
||||
|
||||
/* Union representing all possible packet headers */
|
||||
typedef union
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
RpcPktRequestHdr request;
|
||||
RpcPktResponseHdr response;
|
||||
RpcPktFaultHdr fault;
|
||||
RpcPktBindHdr bind;
|
||||
RpcPktBindAckHdr bind_ack;
|
||||
RpcPktBindNAckHdr bind_nack;
|
||||
} RpcPktHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char auth_type; /* authentication scheme in use */
|
||||
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 long auth_context_id; /* unique value for the authenticated connection */
|
||||
} RpcAuthVerifier;
|
||||
|
||||
#define RPC_AUTH_VERIFIER_LEN(common_hdr) \
|
||||
((common_hdr)->auth_len ? (common_hdr)->auth_len + sizeof(RpcAuthVerifier) : 0)
|
||||
|
||||
#define RPC_VER_MAJOR 5
|
||||
#define RPC_VER_MINOR 0
|
||||
|
||||
#define RPC_FLG_FIRST 1
|
||||
#define RPC_FLG_LAST 2
|
||||
#define RPC_FLG_OBJECT_UUID 0x80
|
||||
|
||||
#define RPC_MIN_PACKET_SIZE 0x1000
|
||||
#define RPC_MAX_PACKET_SIZE 0x16D0
|
||||
|
||||
#define PKT_REQUEST 0
|
||||
#define PKT_PING 1
|
||||
#define PKT_RESPONSE 2
|
||||
#define PKT_FAULT 3
|
||||
#define PKT_WORKING 4
|
||||
#define PKT_NOCALL 5
|
||||
#define PKT_REJECT 6
|
||||
#define PKT_ACK 7
|
||||
#define PKT_CL_CANCEL 8
|
||||
#define PKT_FACK 9
|
||||
#define PKT_CANCEL_ACK 10
|
||||
#define PKT_BIND 11
|
||||
#define PKT_BIND_ACK 12
|
||||
#define PKT_BIND_NACK 13
|
||||
#define PKT_ALTER_CONTEXT 14
|
||||
#define PKT_ALTER_CONTEXT_RESP 15
|
||||
#define PKT_AUTH3 16
|
||||
#define PKT_SHUTDOWN 17
|
||||
#define PKT_CO_CANCEL 18
|
||||
#define PKT_ORPHANED 19
|
||||
|
||||
#define RESULT_ACCEPT 0
|
||||
#define RESULT_USER_REJECTION 1
|
||||
#define RESULT_PROVIDER_REJECTION 2
|
||||
|
||||
#define REASON_NONE 0
|
||||
#define REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED 1
|
||||
#define REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED 2
|
||||
#define REASON_LOCAL_LIMIT_EXCEEDED 3
|
||||
|
||||
#define REJECT_REASON_NOT_SPECIFIED 0
|
||||
#define REJECT_TEMPORARY_CONGESTION 1
|
||||
#define REJECT_LOCAL_LIMIT_EXCEEDED 2
|
||||
#define REJECT_CALLED_PADDR_UNKNOWN 3 /* not used */
|
||||
#define REJECT_PROTOCOL_VERSION_NOT_SUPPORTED 4
|
||||
#define REJECT_DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */
|
||||
#define REJECT_USER_DATA_NOT_READABLE 6 /* not used */
|
||||
#define REJECT_NO_PSAP_AVAILABLE 7 /* not used */
|
||||
#define REJECT_UNKNOWN_AUTHN_SERVICE 8
|
||||
#define REJECT_INVALID_CHECKSUM 9
|
||||
|
||||
#define NCADG_IP_UDP 0x08
|
||||
#define NCACN_IP_TCP 0x07
|
||||
#define NCADG_IPX 0x0E
|
||||
#define NCACN_SPX 0x0C
|
||||
#define NCACN_NB_NB 0x12
|
||||
#define NCACN_NB_IPX 0x0D
|
||||
#define NCACN_DNET_NSP 0x04
|
||||
#define NCACN_HTTP 0x1F
|
||||
|
||||
/* FreeDCE: TWR_C_FLR_PROT_ID_IP */
|
||||
#define TWR_IP 0x09
|
||||
|
||||
#endif /* __WINE_RPC_DEFS_H */
|
||||
/*
|
||||
* RPC definitions
|
||||
*
|
||||
* Copyright 2001-2002 Ove Kåven, TransGaming Technologies
|
||||
* Copyright 2004 Filip Navara
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_DEFS_H
|
||||
#define __WINE_RPC_DEFS_H
|
||||
|
||||
/* info from http://www.microsoft.com/msj/0398/dcomtextfigs.htm */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char rpc_ver; /* RPC major version (5) */
|
||||
unsigned char rpc_ver_minor; /* RPC minor version (0) */
|
||||
unsigned char ptype; /* Packet type (PKT_*) */
|
||||
unsigned char flags;
|
||||
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 long call_id; /* Call identifier. */
|
||||
} RpcPktCommonHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */
|
||||
unsigned short context_id; /* Presentation context identifier */
|
||||
unsigned short opnum;
|
||||
} RpcPktRequestHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
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;
|
||||
} RpcPktResponseHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
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 long status; /* Runtime fault code (RPC_STATUS) */
|
||||
unsigned long reserved2;
|
||||
} RpcPktFaultHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned short max_tsize; /* Maximum transmission fragment size */
|
||||
unsigned short max_rsize; /* Maximum receive fragment size */
|
||||
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 */
|
||||
unsigned char num_syntaxes; /* Number of syntaxes */
|
||||
RPC_SYNTAX_IDENTIFIER abstract;
|
||||
RPC_SYNTAX_IDENTIFIER transfer;
|
||||
} RpcPktBindHdr;
|
||||
|
||||
#include "pshpack1.h"
|
||||
typedef struct
|
||||
{
|
||||
unsigned short length; /* Length of the string including null terminator */
|
||||
char string[1]; /* String data in single byte, null terminated form */
|
||||
} RpcAddressString;
|
||||
#include "poppack.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char num_results; /* Number of results */
|
||||
unsigned char reserved[3]; /* Force alignment! */
|
||||
struct {
|
||||
unsigned short result;
|
||||
unsigned short reason;
|
||||
} results[1];
|
||||
} RpcResults;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned short max_tsize; /* Maximum transmission fragment size */
|
||||
unsigned short max_rsize; /* Maximum receive fragment size */
|
||||
unsigned long assoc_gid; /* Associated group id */
|
||||
/*
|
||||
* Following this header are these fields:
|
||||
* RpcAddressString server_address;
|
||||
* [0 - 3 bytes of padding so that results is 4-byte aligned]
|
||||
* RpcResults results;
|
||||
* RPC_SYNTAX_IDENTIFIER transfer;
|
||||
*/
|
||||
} RpcPktBindAckHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned short reject_reason;
|
||||
unsigned char protocols_count;
|
||||
struct {
|
||||
unsigned char rpc_ver;
|
||||
unsigned char rpc_ver_minor;
|
||||
} protocols[1];
|
||||
} RpcPktBindNAckHdr;
|
||||
|
||||
/* Union representing all possible packet headers */
|
||||
typedef union
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
RpcPktRequestHdr request;
|
||||
RpcPktResponseHdr response;
|
||||
RpcPktFaultHdr fault;
|
||||
RpcPktBindHdr bind;
|
||||
RpcPktBindAckHdr bind_ack;
|
||||
RpcPktBindNAckHdr bind_nack;
|
||||
} RpcPktHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char auth_type; /* authentication scheme in use */
|
||||
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 long auth_context_id; /* unique value for the authenticated connection */
|
||||
} RpcAuthVerifier;
|
||||
|
||||
#define RPC_AUTH_VERIFIER_LEN(common_hdr) \
|
||||
((common_hdr)->auth_len ? (common_hdr)->auth_len + sizeof(RpcAuthVerifier) : 0)
|
||||
|
||||
#define RPC_VER_MAJOR 5
|
||||
#define RPC_VER_MINOR 0
|
||||
|
||||
#define RPC_FLG_FIRST 1
|
||||
#define RPC_FLG_LAST 2
|
||||
#define RPC_FLG_OBJECT_UUID 0x80
|
||||
|
||||
#define RPC_MIN_PACKET_SIZE 0x1000
|
||||
#define RPC_MAX_PACKET_SIZE 0x16D0
|
||||
|
||||
#define PKT_REQUEST 0
|
||||
#define PKT_PING 1
|
||||
#define PKT_RESPONSE 2
|
||||
#define PKT_FAULT 3
|
||||
#define PKT_WORKING 4
|
||||
#define PKT_NOCALL 5
|
||||
#define PKT_REJECT 6
|
||||
#define PKT_ACK 7
|
||||
#define PKT_CL_CANCEL 8
|
||||
#define PKT_FACK 9
|
||||
#define PKT_CANCEL_ACK 10
|
||||
#define PKT_BIND 11
|
||||
#define PKT_BIND_ACK 12
|
||||
#define PKT_BIND_NACK 13
|
||||
#define PKT_ALTER_CONTEXT 14
|
||||
#define PKT_ALTER_CONTEXT_RESP 15
|
||||
#define PKT_AUTH3 16
|
||||
#define PKT_SHUTDOWN 17
|
||||
#define PKT_CO_CANCEL 18
|
||||
#define PKT_ORPHANED 19
|
||||
|
||||
#define RESULT_ACCEPT 0
|
||||
#define RESULT_USER_REJECTION 1
|
||||
#define RESULT_PROVIDER_REJECTION 2
|
||||
|
||||
#define REASON_NONE 0
|
||||
#define REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED 1
|
||||
#define REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED 2
|
||||
#define REASON_LOCAL_LIMIT_EXCEEDED 3
|
||||
|
||||
#define REJECT_REASON_NOT_SPECIFIED 0
|
||||
#define REJECT_TEMPORARY_CONGESTION 1
|
||||
#define REJECT_LOCAL_LIMIT_EXCEEDED 2
|
||||
#define REJECT_CALLED_PADDR_UNKNOWN 3 /* not used */
|
||||
#define REJECT_PROTOCOL_VERSION_NOT_SUPPORTED 4
|
||||
#define REJECT_DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */
|
||||
#define REJECT_USER_DATA_NOT_READABLE 6 /* not used */
|
||||
#define REJECT_NO_PSAP_AVAILABLE 7 /* not used */
|
||||
#define REJECT_UNKNOWN_AUTHN_SERVICE 8
|
||||
#define REJECT_INVALID_CHECKSUM 9
|
||||
|
||||
#define NCADG_IP_UDP 0x08
|
||||
#define NCACN_IP_TCP 0x07
|
||||
#define NCADG_IPX 0x0E
|
||||
#define NCACN_SPX 0x0C
|
||||
#define NCACN_NB_NB 0x12
|
||||
#define NCACN_NB_IPX 0x0D
|
||||
#define NCACN_DNET_NSP 0x04
|
||||
#define NCACN_HTTP 0x1F
|
||||
|
||||
/* FreeDCE: TWR_C_FLR_PROT_ID_IP */
|
||||
#define TWR_IP 0x09
|
||||
|
||||
#endif /* __WINE_RPC_DEFS_H */
|
||||
|
|
|
@ -1,384 +1,384 @@
|
|||
/*
|
||||
* RPC endpoint mapper
|
||||
*
|
||||
* Copyright 2002 Greg Turner
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - actually do things right
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "rpc.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "epm_towers.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
/* The "real" RPC portmapper endpoints that I know of are:
|
||||
*
|
||||
* ncadg_ip_udp: 135
|
||||
* ncacn_ip_tcp: 135
|
||||
* ncacn_np: \\pipe\epmapper (?)
|
||||
* ncalrpc: epmapper
|
||||
*
|
||||
* If the user's machine ran a DCE RPC daemon, it would
|
||||
* probably be possible to connect to it, but there are many
|
||||
* reasons not to, like:
|
||||
* - the user probably does *not* run one, and probably
|
||||
* shouldn't be forced to run one just for local COM
|
||||
* - very few Unix systems use DCE RPC... if they run a RPC
|
||||
* daemon at all, it's usually Sun RPC
|
||||
* - DCE RPC registrations are persistent and saved on disk,
|
||||
* while MS-RPC registrations are documented as non-persistent
|
||||
* and stored only in RAM, and auto-destroyed when the process
|
||||
* dies (something DCE RPC can't do)
|
||||
*
|
||||
* Of course, if the user *did* want to run a DCE RPC daemon anyway,
|
||||
* there would be interoperability advantages, like the possibility
|
||||
* of running a fully functional DCOM server using Wine...
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* RpcEpRegisterA (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
||||
UUID_VECTOR *UuidVector, RPC_CSTR Annotation )
|
||||
{
|
||||
RPCSS_NP_MESSAGE msg;
|
||||
RPCSS_NP_REPLY reply;
|
||||
char *vardata_payload, *vp;
|
||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||
unsigned long c;
|
||||
RPC_STATUS rslt = RPC_S_OK;
|
||||
|
||||
TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation));
|
||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||
for (c=0; c<BindingVector->Count; c++) {
|
||||
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
||||
TRACE(" protseq[%ld]=%s\n", c, debugstr_a(bind->Protseq));
|
||||
TRACE(" endpoint[%ld]=%s\n", c, debugstr_a(bind->Endpoint));
|
||||
}
|
||||
if (UuidVector) {
|
||||
for (c=0; c<UuidVector->Count; c++)
|
||||
TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c]));
|
||||
}
|
||||
|
||||
/* FIXME: Do something with annotation. */
|
||||
|
||||
/* construct the message to rpcss */
|
||||
msg.message_type = RPCSS_NP_MESSAGE_TYPEID_REGISTEREPMSG;
|
||||
msg.message.registerepmsg.iface = If->InterfaceId;
|
||||
msg.message.registerepmsg.no_replace = 0;
|
||||
|
||||
msg.message.registerepmsg.object_count = (UuidVector) ? UuidVector->Count : 0;
|
||||
msg.message.registerepmsg.binding_count = BindingVector->Count;
|
||||
|
||||
/* calculate vardata payload size */
|
||||
msg.vardata_payload_size = msg.message.registerepmsg.object_count * sizeof(UUID);
|
||||
for (c=0; c < msg.message.registerepmsg.binding_count; c++) {
|
||||
RpcBinding *bind = (RpcBinding *)(BindingVector->BindingH[c]);
|
||||
msg.vardata_payload_size += strlen(bind->Protseq) + 1;
|
||||
msg.vardata_payload_size += strlen(bind->Endpoint) + 1;
|
||||
}
|
||||
|
||||
/* allocate the payload buffer */
|
||||
vp = vardata_payload = LocalAlloc(LPTR, msg.vardata_payload_size);
|
||||
if (!vardata_payload)
|
||||
return RPC_S_OUT_OF_MEMORY;
|
||||
|
||||
/* populate the payload data */
|
||||
for (c=0; c < msg.message.registerepmsg.object_count; c++) {
|
||||
CopyMemory(vp, UuidVector->Uuid[c], sizeof(UUID));
|
||||
vp += sizeof(UUID);
|
||||
}
|
||||
|
||||
for (c=0; c < msg.message.registerepmsg.binding_count; c++) {
|
||||
RpcBinding *bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
||||
unsigned long pslen = strlen(bind->Protseq) + 1, eplen = strlen(bind->Endpoint) + 1;
|
||||
CopyMemory(vp, bind->Protseq, pslen);
|
||||
vp += pslen;
|
||||
CopyMemory(vp, bind->Endpoint, eplen);
|
||||
vp += eplen;
|
||||
}
|
||||
|
||||
/* send our request */
|
||||
if (!RPCRT4_RPCSSOnDemandCall(&msg, vardata_payload, &reply))
|
||||
rslt = RPC_S_OUT_OF_MEMORY;
|
||||
|
||||
/* free the payload buffer */
|
||||
LocalFree(vardata_payload);
|
||||
|
||||
return rslt;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcEpUnregister (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
||||
UUID_VECTOR *UuidVector )
|
||||
{
|
||||
RPCSS_NP_MESSAGE msg;
|
||||
RPCSS_NP_REPLY reply;
|
||||
char *vardata_payload, *vp;
|
||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||
unsigned long c;
|
||||
RPC_STATUS rslt = RPC_S_OK;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector);
|
||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||
for (c=0; c<BindingVector->Count; c++) {
|
||||
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
||||
TRACE(" protseq[%ld]=%s\n", c, debugstr_a(bind->Protseq));
|
||||
TRACE(" endpoint[%ld]=%s\n", c, debugstr_a(bind->Endpoint));
|
||||
}
|
||||
if (UuidVector) {
|
||||
for (c=0; c<UuidVector->Count; c++)
|
||||
TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c]));
|
||||
}
|
||||
|
||||
/* construct the message to rpcss */
|
||||
msg.message_type = RPCSS_NP_MESSAGE_TYPEID_UNREGISTEREPMSG;
|
||||
msg.message.unregisterepmsg.iface = If->InterfaceId;
|
||||
|
||||
msg.message.unregisterepmsg.object_count = (UuidVector) ? UuidVector->Count : 0;
|
||||
msg.message.unregisterepmsg.binding_count = BindingVector->Count;
|
||||
|
||||
/* calculate vardata payload size */
|
||||
msg.vardata_payload_size = msg.message.unregisterepmsg.object_count * sizeof(UUID);
|
||||
for (c=0; c < msg.message.unregisterepmsg.binding_count; c++) {
|
||||
RpcBinding *bind = (RpcBinding *)(BindingVector->BindingH[c]);
|
||||
msg.vardata_payload_size += strlen(bind->Protseq) + 1;
|
||||
msg.vardata_payload_size += strlen(bind->Endpoint) + 1;
|
||||
}
|
||||
|
||||
/* allocate the payload buffer */
|
||||
vp = vardata_payload = LocalAlloc(LPTR, msg.vardata_payload_size);
|
||||
if (!vardata_payload)
|
||||
return RPC_S_OUT_OF_MEMORY;
|
||||
|
||||
/* populate the payload data */
|
||||
for (c=0; c < msg.message.unregisterepmsg.object_count; c++) {
|
||||
CopyMemory(vp, UuidVector->Uuid[c], sizeof(UUID));
|
||||
vp += sizeof(UUID);
|
||||
}
|
||||
|
||||
for (c=0; c < msg.message.unregisterepmsg.binding_count; c++) {
|
||||
RpcBinding *bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
||||
unsigned long pslen = strlen(bind->Protseq) + 1, eplen = strlen(bind->Endpoint) + 1;
|
||||
CopyMemory(vp, bind->Protseq, pslen);
|
||||
vp += pslen;
|
||||
CopyMemory(vp, bind->Endpoint, eplen);
|
||||
vp += eplen;
|
||||
}
|
||||
|
||||
/* send our request */
|
||||
if (!RPCRT4_RPCSSOnDemandCall(&msg, vardata_payload, &reply))
|
||||
rslt = RPC_S_OUT_OF_MEMORY;
|
||||
|
||||
/* free the payload buffer */
|
||||
LocalFree(vardata_payload);
|
||||
|
||||
return rslt;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcEpResolveBinding (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec )
|
||||
{
|
||||
RPCSS_NP_MESSAGE msg;
|
||||
RPCSS_NP_REPLY reply;
|
||||
PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec;
|
||||
RpcBinding* bind = (RpcBinding*)Binding;
|
||||
|
||||
TRACE("(%p,%p)\n", Binding, IfSpec);
|
||||
TRACE(" protseq=%s\n", debugstr_a(bind->Protseq));
|
||||
TRACE(" obj=%s\n", debugstr_guid(&bind->ObjectUuid));
|
||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||
|
||||
/* FIXME: totally untested */
|
||||
|
||||
/* just return for fully bound handles */
|
||||
if (bind->Endpoint && (bind->Endpoint[0] != '\0'))
|
||||
return RPC_S_OK;
|
||||
|
||||
/* construct the message to rpcss */
|
||||
msg.message_type = RPCSS_NP_MESSAGE_TYPEID_RESOLVEEPMSG;
|
||||
msg.message.resolveepmsg.iface = If->InterfaceId;
|
||||
msg.message.resolveepmsg.object = bind->ObjectUuid;
|
||||
|
||||
msg.vardata_payload_size = strlen(bind->Protseq) + 1;
|
||||
|
||||
/* send the message */
|
||||
if (!RPCRT4_RPCSSOnDemandCall(&msg, bind->Protseq, &reply))
|
||||
return RPC_S_OUT_OF_MEMORY;
|
||||
|
||||
/* empty-string result means not registered */
|
||||
if (reply.as_string[0] == '\0')
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
/* otherwise we fully bind the handle & return RPC_S_OK */
|
||||
return RPCRT4_ResolveBinding(Binding, reply.as_string);
|
||||
}
|
||||
|
||||
typedef unsigned int unsigned32;
|
||||
typedef struct twr_t
|
||||
{
|
||||
unsigned32 tower_length;
|
||||
/* [size_is] */ BYTE tower_octet_string[ 1 ];
|
||||
} twr_t;
|
||||
|
||||
/***********************************************************************
|
||||
* TowerExplode (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI TowerExplode(
|
||||
const twr_t *tower, PRPC_SYNTAX_IDENTIFIER object, PRPC_SYNTAX_IDENTIFIER syntax,
|
||||
char **protseq, char **endpoint, char **address)
|
||||
{
|
||||
size_t tower_size;
|
||||
RPC_STATUS status;
|
||||
const unsigned char *p;
|
||||
u_int16 floor_count;
|
||||
const twr_uuid_floor_t *object_floor;
|
||||
const twr_uuid_floor_t *syntax_floor;
|
||||
|
||||
if (protseq)
|
||||
*protseq = NULL;
|
||||
if (endpoint)
|
||||
*endpoint = NULL;
|
||||
if (address)
|
||||
*address = NULL;
|
||||
|
||||
tower_size = tower->tower_length;
|
||||
|
||||
if (tower_size < sizeof(u_int16))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
p = &tower->tower_octet_string[0];
|
||||
|
||||
floor_count = *(const u_int16 *)p;
|
||||
p += sizeof(u_int16);
|
||||
tower_size -= sizeof(u_int16);
|
||||
TRACE("floor_count: %d\n", floor_count);
|
||||
/* FIXME: should we do something with the floor count? at the moment we don't */
|
||||
|
||||
if (tower_size < sizeof(*object_floor) + sizeof(*syntax_floor))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
object_floor = (const twr_uuid_floor_t *)p;
|
||||
p += sizeof(*object_floor);
|
||||
tower_size -= sizeof(*object_floor);
|
||||
syntax_floor = (const twr_uuid_floor_t *)p;
|
||||
p += sizeof(*syntax_floor);
|
||||
tower_size -= sizeof(*syntax_floor);
|
||||
|
||||
if ((object_floor->count_lhs != sizeof(object_floor->protid) +
|
||||
sizeof(object_floor->uuid) + sizeof(object_floor->major_version)) ||
|
||||
(object_floor->protid != EPM_PROTOCOL_UUID) ||
|
||||
(object_floor->count_rhs != sizeof(object_floor->minor_version)))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
if ((syntax_floor->count_lhs != sizeof(syntax_floor->protid) +
|
||||
sizeof(syntax_floor->uuid) + sizeof(syntax_floor->major_version)) ||
|
||||
(syntax_floor->protid != EPM_PROTOCOL_UUID) ||
|
||||
(syntax_floor->count_rhs != sizeof(syntax_floor->minor_version)))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
status = RpcTransport_ParseTopOfTower(p, tower_size, protseq, address, endpoint);
|
||||
if ((status == RPC_S_OK) && syntax && object)
|
||||
{
|
||||
syntax->SyntaxGUID = syntax_floor->uuid;
|
||||
syntax->SyntaxVersion.MajorVersion = syntax_floor->major_version;
|
||||
syntax->SyntaxVersion.MinorVersion = syntax_floor->minor_version;
|
||||
object->SyntaxGUID = object_floor->uuid;
|
||||
object->SyntaxVersion.MajorVersion = object_floor->major_version;
|
||||
object->SyntaxVersion.MinorVersion = object_floor->minor_version;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TowerConstruct (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI TowerConstruct(
|
||||
const RPC_SYNTAX_IDENTIFIER *object, const RPC_SYNTAX_IDENTIFIER *syntax,
|
||||
const char *protseq, const char *endpoint, const char *address,
|
||||
twr_t **tower)
|
||||
{
|
||||
size_t tower_size;
|
||||
RPC_STATUS status;
|
||||
unsigned char *p;
|
||||
twr_uuid_floor_t *object_floor;
|
||||
twr_uuid_floor_t *syntax_floor;
|
||||
|
||||
*tower = NULL;
|
||||
|
||||
status = RpcTransport_GetTopOfTower(NULL, &tower_size, protseq, address, endpoint);
|
||||
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
tower_size += sizeof(u_int16) + sizeof(*object_floor) + sizeof(*syntax_floor);
|
||||
*tower = I_RpcAllocate(FIELD_OFFSET(twr_t, tower_octet_string[tower_size]));
|
||||
if (!*tower)
|
||||
return RPC_S_OUT_OF_RESOURCES;
|
||||
|
||||
(*tower)->tower_length = tower_size;
|
||||
p = &(*tower)->tower_octet_string[0];
|
||||
*(u_int16 *)p = 5; /* number of floors */
|
||||
p += sizeof(u_int16);
|
||||
object_floor = (twr_uuid_floor_t *)p;
|
||||
p += sizeof(*object_floor);
|
||||
syntax_floor = (twr_uuid_floor_t *)p;
|
||||
p += sizeof(*syntax_floor);
|
||||
|
||||
object_floor->count_lhs = sizeof(object_floor->protid) + sizeof(object_floor->uuid) +
|
||||
sizeof(object_floor->major_version);
|
||||
object_floor->protid = EPM_PROTOCOL_UUID;
|
||||
object_floor->count_rhs = sizeof(object_floor->minor_version);
|
||||
object_floor->uuid = object->SyntaxGUID;
|
||||
object_floor->major_version = object->SyntaxVersion.MajorVersion;
|
||||
object_floor->minor_version = object->SyntaxVersion.MinorVersion;
|
||||
|
||||
syntax_floor->count_lhs = sizeof(syntax_floor->protid) + sizeof(syntax_floor->uuid) +
|
||||
sizeof(syntax_floor->major_version);
|
||||
syntax_floor->protid = EPM_PROTOCOL_UUID;
|
||||
syntax_floor->count_rhs = sizeof(syntax_floor->minor_version);
|
||||
syntax_floor->uuid = syntax->SyntaxGUID;
|
||||
syntax_floor->major_version = syntax->SyntaxVersion.MajorVersion;
|
||||
syntax_floor->minor_version = syntax->SyntaxVersion.MinorVersion;
|
||||
|
||||
status = RpcTransport_GetTopOfTower(p, &tower_size, protseq, address, endpoint);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
I_RpcFree(*tower);
|
||||
*tower = NULL;
|
||||
return status;
|
||||
}
|
||||
return RPC_S_OK;
|
||||
}
|
||||
/*
|
||||
* RPC endpoint mapper
|
||||
*
|
||||
* Copyright 2002 Greg Turner
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - actually do things right
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "rpc.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "epm_towers.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
/* The "real" RPC portmapper endpoints that I know of are:
|
||||
*
|
||||
* ncadg_ip_udp: 135
|
||||
* ncacn_ip_tcp: 135
|
||||
* ncacn_np: \\pipe\epmapper (?)
|
||||
* ncalrpc: epmapper
|
||||
*
|
||||
* If the user's machine ran a DCE RPC daemon, it would
|
||||
* probably be possible to connect to it, but there are many
|
||||
* reasons not to, like:
|
||||
* - the user probably does *not* run one, and probably
|
||||
* shouldn't be forced to run one just for local COM
|
||||
* - very few Unix systems use DCE RPC... if they run a RPC
|
||||
* daemon at all, it's usually Sun RPC
|
||||
* - DCE RPC registrations are persistent and saved on disk,
|
||||
* while MS-RPC registrations are documented as non-persistent
|
||||
* and stored only in RAM, and auto-destroyed when the process
|
||||
* dies (something DCE RPC can't do)
|
||||
*
|
||||
* Of course, if the user *did* want to run a DCE RPC daemon anyway,
|
||||
* there would be interoperability advantages, like the possibility
|
||||
* of running a fully functional DCOM server using Wine...
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* RpcEpRegisterA (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
||||
UUID_VECTOR *UuidVector, RPC_CSTR Annotation )
|
||||
{
|
||||
RPCSS_NP_MESSAGE msg;
|
||||
RPCSS_NP_REPLY reply;
|
||||
char *vardata_payload, *vp;
|
||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||
unsigned long c;
|
||||
RPC_STATUS rslt = RPC_S_OK;
|
||||
|
||||
TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation));
|
||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||
for (c=0; c<BindingVector->Count; c++) {
|
||||
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
||||
TRACE(" protseq[%ld]=%s\n", c, debugstr_a(bind->Protseq));
|
||||
TRACE(" endpoint[%ld]=%s\n", c, debugstr_a(bind->Endpoint));
|
||||
}
|
||||
if (UuidVector) {
|
||||
for (c=0; c<UuidVector->Count; c++)
|
||||
TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c]));
|
||||
}
|
||||
|
||||
/* FIXME: Do something with annotation. */
|
||||
|
||||
/* construct the message to rpcss */
|
||||
msg.message_type = RPCSS_NP_MESSAGE_TYPEID_REGISTEREPMSG;
|
||||
msg.message.registerepmsg.iface = If->InterfaceId;
|
||||
msg.message.registerepmsg.no_replace = 0;
|
||||
|
||||
msg.message.registerepmsg.object_count = (UuidVector) ? UuidVector->Count : 0;
|
||||
msg.message.registerepmsg.binding_count = BindingVector->Count;
|
||||
|
||||
/* calculate vardata payload size */
|
||||
msg.vardata_payload_size = msg.message.registerepmsg.object_count * sizeof(UUID);
|
||||
for (c=0; c < msg.message.registerepmsg.binding_count; c++) {
|
||||
RpcBinding *bind = (RpcBinding *)(BindingVector->BindingH[c]);
|
||||
msg.vardata_payload_size += strlen(bind->Protseq) + 1;
|
||||
msg.vardata_payload_size += strlen(bind->Endpoint) + 1;
|
||||
}
|
||||
|
||||
/* allocate the payload buffer */
|
||||
vp = vardata_payload = LocalAlloc(LPTR, msg.vardata_payload_size);
|
||||
if (!vardata_payload)
|
||||
return RPC_S_OUT_OF_MEMORY;
|
||||
|
||||
/* populate the payload data */
|
||||
for (c=0; c < msg.message.registerepmsg.object_count; c++) {
|
||||
CopyMemory(vp, UuidVector->Uuid[c], sizeof(UUID));
|
||||
vp += sizeof(UUID);
|
||||
}
|
||||
|
||||
for (c=0; c < msg.message.registerepmsg.binding_count; c++) {
|
||||
RpcBinding *bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
||||
unsigned long pslen = strlen(bind->Protseq) + 1, eplen = strlen(bind->Endpoint) + 1;
|
||||
CopyMemory(vp, bind->Protseq, pslen);
|
||||
vp += pslen;
|
||||
CopyMemory(vp, bind->Endpoint, eplen);
|
||||
vp += eplen;
|
||||
}
|
||||
|
||||
/* send our request */
|
||||
if (!RPCRT4_RPCSSOnDemandCall(&msg, vardata_payload, &reply))
|
||||
rslt = RPC_S_OUT_OF_MEMORY;
|
||||
|
||||
/* free the payload buffer */
|
||||
LocalFree(vardata_payload);
|
||||
|
||||
return rslt;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcEpUnregister (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
||||
UUID_VECTOR *UuidVector )
|
||||
{
|
||||
RPCSS_NP_MESSAGE msg;
|
||||
RPCSS_NP_REPLY reply;
|
||||
char *vardata_payload, *vp;
|
||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||
unsigned long c;
|
||||
RPC_STATUS rslt = RPC_S_OK;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector);
|
||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||
for (c=0; c<BindingVector->Count; c++) {
|
||||
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
||||
TRACE(" protseq[%ld]=%s\n", c, debugstr_a(bind->Protseq));
|
||||
TRACE(" endpoint[%ld]=%s\n", c, debugstr_a(bind->Endpoint));
|
||||
}
|
||||
if (UuidVector) {
|
||||
for (c=0; c<UuidVector->Count; c++)
|
||||
TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c]));
|
||||
}
|
||||
|
||||
/* construct the message to rpcss */
|
||||
msg.message_type = RPCSS_NP_MESSAGE_TYPEID_UNREGISTEREPMSG;
|
||||
msg.message.unregisterepmsg.iface = If->InterfaceId;
|
||||
|
||||
msg.message.unregisterepmsg.object_count = (UuidVector) ? UuidVector->Count : 0;
|
||||
msg.message.unregisterepmsg.binding_count = BindingVector->Count;
|
||||
|
||||
/* calculate vardata payload size */
|
||||
msg.vardata_payload_size = msg.message.unregisterepmsg.object_count * sizeof(UUID);
|
||||
for (c=0; c < msg.message.unregisterepmsg.binding_count; c++) {
|
||||
RpcBinding *bind = (RpcBinding *)(BindingVector->BindingH[c]);
|
||||
msg.vardata_payload_size += strlen(bind->Protseq) + 1;
|
||||
msg.vardata_payload_size += strlen(bind->Endpoint) + 1;
|
||||
}
|
||||
|
||||
/* allocate the payload buffer */
|
||||
vp = vardata_payload = LocalAlloc(LPTR, msg.vardata_payload_size);
|
||||
if (!vardata_payload)
|
||||
return RPC_S_OUT_OF_MEMORY;
|
||||
|
||||
/* populate the payload data */
|
||||
for (c=0; c < msg.message.unregisterepmsg.object_count; c++) {
|
||||
CopyMemory(vp, UuidVector->Uuid[c], sizeof(UUID));
|
||||
vp += sizeof(UUID);
|
||||
}
|
||||
|
||||
for (c=0; c < msg.message.unregisterepmsg.binding_count; c++) {
|
||||
RpcBinding *bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
||||
unsigned long pslen = strlen(bind->Protseq) + 1, eplen = strlen(bind->Endpoint) + 1;
|
||||
CopyMemory(vp, bind->Protseq, pslen);
|
||||
vp += pslen;
|
||||
CopyMemory(vp, bind->Endpoint, eplen);
|
||||
vp += eplen;
|
||||
}
|
||||
|
||||
/* send our request */
|
||||
if (!RPCRT4_RPCSSOnDemandCall(&msg, vardata_payload, &reply))
|
||||
rslt = RPC_S_OUT_OF_MEMORY;
|
||||
|
||||
/* free the payload buffer */
|
||||
LocalFree(vardata_payload);
|
||||
|
||||
return rslt;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcEpResolveBinding (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec )
|
||||
{
|
||||
RPCSS_NP_MESSAGE msg;
|
||||
RPCSS_NP_REPLY reply;
|
||||
PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec;
|
||||
RpcBinding* bind = (RpcBinding*)Binding;
|
||||
|
||||
TRACE("(%p,%p)\n", Binding, IfSpec);
|
||||
TRACE(" protseq=%s\n", debugstr_a(bind->Protseq));
|
||||
TRACE(" obj=%s\n", debugstr_guid(&bind->ObjectUuid));
|
||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||
|
||||
/* FIXME: totally untested */
|
||||
|
||||
/* just return for fully bound handles */
|
||||
if (bind->Endpoint && (bind->Endpoint[0] != '\0'))
|
||||
return RPC_S_OK;
|
||||
|
||||
/* construct the message to rpcss */
|
||||
msg.message_type = RPCSS_NP_MESSAGE_TYPEID_RESOLVEEPMSG;
|
||||
msg.message.resolveepmsg.iface = If->InterfaceId;
|
||||
msg.message.resolveepmsg.object = bind->ObjectUuid;
|
||||
|
||||
msg.vardata_payload_size = strlen(bind->Protseq) + 1;
|
||||
|
||||
/* send the message */
|
||||
if (!RPCRT4_RPCSSOnDemandCall(&msg, bind->Protseq, &reply))
|
||||
return RPC_S_OUT_OF_MEMORY;
|
||||
|
||||
/* empty-string result means not registered */
|
||||
if (reply.as_string[0] == '\0')
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
/* otherwise we fully bind the handle & return RPC_S_OK */
|
||||
return RPCRT4_ResolveBinding(Binding, reply.as_string);
|
||||
}
|
||||
|
||||
typedef unsigned int unsigned32;
|
||||
typedef struct twr_t
|
||||
{
|
||||
unsigned32 tower_length;
|
||||
/* [size_is] */ BYTE tower_octet_string[ 1 ];
|
||||
} twr_t;
|
||||
|
||||
/***********************************************************************
|
||||
* TowerExplode (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI TowerExplode(
|
||||
const twr_t *tower, PRPC_SYNTAX_IDENTIFIER object, PRPC_SYNTAX_IDENTIFIER syntax,
|
||||
char **protseq, char **endpoint, char **address)
|
||||
{
|
||||
size_t tower_size;
|
||||
RPC_STATUS status;
|
||||
const unsigned char *p;
|
||||
u_int16 floor_count;
|
||||
const twr_uuid_floor_t *object_floor;
|
||||
const twr_uuid_floor_t *syntax_floor;
|
||||
|
||||
if (protseq)
|
||||
*protseq = NULL;
|
||||
if (endpoint)
|
||||
*endpoint = NULL;
|
||||
if (address)
|
||||
*address = NULL;
|
||||
|
||||
tower_size = tower->tower_length;
|
||||
|
||||
if (tower_size < sizeof(u_int16))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
p = &tower->tower_octet_string[0];
|
||||
|
||||
floor_count = *(const u_int16 *)p;
|
||||
p += sizeof(u_int16);
|
||||
tower_size -= sizeof(u_int16);
|
||||
TRACE("floor_count: %d\n", floor_count);
|
||||
/* FIXME: should we do something with the floor count? at the moment we don't */
|
||||
|
||||
if (tower_size < sizeof(*object_floor) + sizeof(*syntax_floor))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
object_floor = (const twr_uuid_floor_t *)p;
|
||||
p += sizeof(*object_floor);
|
||||
tower_size -= sizeof(*object_floor);
|
||||
syntax_floor = (const twr_uuid_floor_t *)p;
|
||||
p += sizeof(*syntax_floor);
|
||||
tower_size -= sizeof(*syntax_floor);
|
||||
|
||||
if ((object_floor->count_lhs != sizeof(object_floor->protid) +
|
||||
sizeof(object_floor->uuid) + sizeof(object_floor->major_version)) ||
|
||||
(object_floor->protid != EPM_PROTOCOL_UUID) ||
|
||||
(object_floor->count_rhs != sizeof(object_floor->minor_version)))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
if ((syntax_floor->count_lhs != sizeof(syntax_floor->protid) +
|
||||
sizeof(syntax_floor->uuid) + sizeof(syntax_floor->major_version)) ||
|
||||
(syntax_floor->protid != EPM_PROTOCOL_UUID) ||
|
||||
(syntax_floor->count_rhs != sizeof(syntax_floor->minor_version)))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
status = RpcTransport_ParseTopOfTower(p, tower_size, protseq, address, endpoint);
|
||||
if ((status == RPC_S_OK) && syntax && object)
|
||||
{
|
||||
syntax->SyntaxGUID = syntax_floor->uuid;
|
||||
syntax->SyntaxVersion.MajorVersion = syntax_floor->major_version;
|
||||
syntax->SyntaxVersion.MinorVersion = syntax_floor->minor_version;
|
||||
object->SyntaxGUID = object_floor->uuid;
|
||||
object->SyntaxVersion.MajorVersion = object_floor->major_version;
|
||||
object->SyntaxVersion.MinorVersion = object_floor->minor_version;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TowerConstruct (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI TowerConstruct(
|
||||
const RPC_SYNTAX_IDENTIFIER *object, const RPC_SYNTAX_IDENTIFIER *syntax,
|
||||
const char *protseq, const char *endpoint, const char *address,
|
||||
twr_t **tower)
|
||||
{
|
||||
size_t tower_size;
|
||||
RPC_STATUS status;
|
||||
unsigned char *p;
|
||||
twr_uuid_floor_t *object_floor;
|
||||
twr_uuid_floor_t *syntax_floor;
|
||||
|
||||
*tower = NULL;
|
||||
|
||||
status = RpcTransport_GetTopOfTower(NULL, &tower_size, protseq, address, endpoint);
|
||||
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
tower_size += sizeof(u_int16) + sizeof(*object_floor) + sizeof(*syntax_floor);
|
||||
*tower = I_RpcAllocate(FIELD_OFFSET(twr_t, tower_octet_string[tower_size]));
|
||||
if (!*tower)
|
||||
return RPC_S_OUT_OF_RESOURCES;
|
||||
|
||||
(*tower)->tower_length = tower_size;
|
||||
p = &(*tower)->tower_octet_string[0];
|
||||
*(u_int16 *)p = 5; /* number of floors */
|
||||
p += sizeof(u_int16);
|
||||
object_floor = (twr_uuid_floor_t *)p;
|
||||
p += sizeof(*object_floor);
|
||||
syntax_floor = (twr_uuid_floor_t *)p;
|
||||
p += sizeof(*syntax_floor);
|
||||
|
||||
object_floor->count_lhs = sizeof(object_floor->protid) + sizeof(object_floor->uuid) +
|
||||
sizeof(object_floor->major_version);
|
||||
object_floor->protid = EPM_PROTOCOL_UUID;
|
||||
object_floor->count_rhs = sizeof(object_floor->minor_version);
|
||||
object_floor->uuid = object->SyntaxGUID;
|
||||
object_floor->major_version = object->SyntaxVersion.MajorVersion;
|
||||
object_floor->minor_version = object->SyntaxVersion.MinorVersion;
|
||||
|
||||
syntax_floor->count_lhs = sizeof(syntax_floor->protid) + sizeof(syntax_floor->uuid) +
|
||||
sizeof(syntax_floor->major_version);
|
||||
syntax_floor->protid = EPM_PROTOCOL_UUID;
|
||||
syntax_floor->count_rhs = sizeof(syntax_floor->minor_version);
|
||||
syntax_floor->uuid = syntax->SyntaxGUID;
|
||||
syntax_floor->major_version = syntax->SyntaxVersion.MajorVersion;
|
||||
syntax_floor->minor_version = syntax->SyntaxVersion.MinorVersion;
|
||||
|
||||
status = RpcTransport_GetTopOfTower(p, &tower_size, protseq, address, endpoint);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
I_RpcFree(*tower);
|
||||
*tower = NULL;
|
||||
return status;
|
||||
}
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,40 +1,40 @@
|
|||
/*
|
||||
* RPC message API
|
||||
*
|
||||
* Copyright 2004 Filip Navara
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_MESSAGE_H
|
||||
#define __WINE_RPC_MESSAGE_H
|
||||
|
||||
#include "wine/rpcss_shared.h"
|
||||
#include "rpc_defs.h"
|
||||
|
||||
typedef unsigned int NCA_STATUS;
|
||||
|
||||
RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS Status);
|
||||
RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength);
|
||||
RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId);
|
||||
RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor);
|
||||
RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, 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);
|
||||
NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status);
|
||||
RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* RPC message API
|
||||
*
|
||||
* Copyright 2004 Filip Navara
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_MESSAGE_H
|
||||
#define __WINE_RPC_MESSAGE_H
|
||||
|
||||
#include "wine/rpcss_shared.h"
|
||||
#include "rpc_defs.h"
|
||||
|
||||
typedef unsigned int NCA_STATUS;
|
||||
|
||||
RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS Status);
|
||||
RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength);
|
||||
RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId);
|
||||
RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor);
|
||||
RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, 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);
|
||||
NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status);
|
||||
RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* RPC definitions
|
||||
*
|
||||
* Copyright 2003 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_MISC_H
|
||||
#define __WINE_RPC_MISC_H
|
||||
|
||||
/* flags for RPC_MESSAGE.RpcFlags */
|
||||
#define WINE_RPCFLAG_EXCEPTION 0x0001
|
||||
|
||||
#endif /* __WINE_RPC_MISC_H */
|
File diff suppressed because it is too large
Load diff
|
@ -1,81 +1,81 @@
|
|||
/*
|
||||
* RPC server API
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_SERVER_H
|
||||
#define __WINE_RPC_SERVER_H
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
struct protseq_ops;
|
||||
|
||||
typedef struct _RpcServerProtseq
|
||||
{
|
||||
const struct protseq_ops *ops; /* RO */
|
||||
struct list entry; /* CS ::server_cs */
|
||||
LPSTR Protseq; /* RO */
|
||||
UINT MaxCalls; /* RO */
|
||||
/* list of listening connections */
|
||||
RpcConnection* conn; /* CS cs */
|
||||
CRITICAL_SECTION cs;
|
||||
|
||||
/* is the server currently listening? */
|
||||
BOOL is_listening; /* CS ::listen_cs */
|
||||
/* mutex for ensuring only one thread can change state at a time */
|
||||
HANDLE mgr_mutex;
|
||||
/* set when server thread has finished opening connections */
|
||||
HANDLE server_ready_event;
|
||||
} RpcServerProtseq;
|
||||
|
||||
struct protseq_ops
|
||||
{
|
||||
const char *name;
|
||||
RpcServerProtseq *(*alloc)(void);
|
||||
void (*signal_state_changed)(RpcServerProtseq *protseq);
|
||||
/* previous array is passed in to allow reuse of memory */
|
||||
void *(*get_wait_array)(RpcServerProtseq *protseq, void *prev_array, unsigned int *count);
|
||||
void (*free_wait_array)(RpcServerProtseq *protseq, void *array);
|
||||
/* returns -1 for failure, 0 for server state changed and 1 to indicate a
|
||||
* 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, LPSTR endpoint);
|
||||
};
|
||||
|
||||
typedef struct _RpcServerInterface
|
||||
{
|
||||
struct list entry;
|
||||
RPC_SERVER_INTERFACE* If;
|
||||
UUID MgrTypeUuid;
|
||||
RPC_MGR_EPV* MgrEpv;
|
||||
UINT Flags;
|
||||
UINT MaxCalls;
|
||||
UINT MaxRpcSize;
|
||||
RPC_IF_CALLBACK_FN* IfCallbackFn;
|
||||
LONG CurrentCalls; /* number of calls currently executing */
|
||||
/* set when unregistering interface to let the caller of
|
||||
* RpcServerUnregisterIf* know that all calls have finished */
|
||||
HANDLE CallsCompletedEvent;
|
||||
} RpcServerInterface;
|
||||
|
||||
void RPCRT4_new_client(RpcConnection* conn);
|
||||
const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq);
|
||||
|
||||
#endif /* __WINE_RPC_SERVER_H */
|
||||
/*
|
||||
* RPC server API
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_SERVER_H
|
||||
#define __WINE_RPC_SERVER_H
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
struct protseq_ops;
|
||||
|
||||
typedef struct _RpcServerProtseq
|
||||
{
|
||||
const struct protseq_ops *ops; /* RO */
|
||||
struct list entry; /* CS ::server_cs */
|
||||
LPSTR Protseq; /* RO */
|
||||
UINT MaxCalls; /* RO */
|
||||
/* list of listening connections */
|
||||
RpcConnection* conn; /* CS cs */
|
||||
CRITICAL_SECTION cs;
|
||||
|
||||
/* is the server currently listening? */
|
||||
BOOL is_listening; /* CS ::listen_cs */
|
||||
/* mutex for ensuring only one thread can change state at a time */
|
||||
HANDLE mgr_mutex;
|
||||
/* set when server thread has finished opening connections */
|
||||
HANDLE server_ready_event;
|
||||
} RpcServerProtseq;
|
||||
|
||||
struct protseq_ops
|
||||
{
|
||||
const char *name;
|
||||
RpcServerProtseq *(*alloc)(void);
|
||||
void (*signal_state_changed)(RpcServerProtseq *protseq);
|
||||
/* previous array is passed in to allow reuse of memory */
|
||||
void *(*get_wait_array)(RpcServerProtseq *protseq, void *prev_array, unsigned int *count);
|
||||
void (*free_wait_array)(RpcServerProtseq *protseq, void *array);
|
||||
/* returns -1 for failure, 0 for server state changed and 1 to indicate a
|
||||
* 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, LPSTR endpoint);
|
||||
};
|
||||
|
||||
typedef struct _RpcServerInterface
|
||||
{
|
||||
struct list entry;
|
||||
RPC_SERVER_INTERFACE* If;
|
||||
UUID MgrTypeUuid;
|
||||
RPC_MGR_EPV* MgrEpv;
|
||||
UINT Flags;
|
||||
UINT MaxCalls;
|
||||
UINT MaxRpcSize;
|
||||
RPC_IF_CALLBACK_FN* IfCallbackFn;
|
||||
LONG CurrentCalls; /* number of calls currently executing */
|
||||
/* set when unregistering interface to let the caller of
|
||||
* RpcServerUnregisterIf* know that all calls have finished */
|
||||
HANDLE CallsCompletedEvent;
|
||||
} RpcServerInterface;
|
||||
|
||||
void RPCRT4_new_client(RpcConnection* conn);
|
||||
const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq);
|
||||
|
||||
#endif /* __WINE_RPC_SERVER_H */
|
||||
|
|
|
@ -951,8 +951,8 @@ static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection
|
|||
return RPC_S_OUT_OF_RESOURCES;
|
||||
}
|
||||
/* reset to blocking behaviour */
|
||||
blocking = 0;
|
||||
ret = ioctlsocket(ret, FIONBIO, &blocking);
|
||||
blocking = 0;
|
||||
ret = ioctlsocket(ret, FIONBIO, &blocking);
|
||||
client->sock = ret;
|
||||
TRACE("Accepted a new TCP connection\n");
|
||||
return RPC_S_OK;
|
||||
|
@ -1203,8 +1203,8 @@ static RpcServerProtseq *rpcrt4_protseq_sock_alloc(void)
|
|||
if (!socketpair(PF_UNIX, SOCK_DGRAM, 0, fds))
|
||||
{
|
||||
blocking = 1;
|
||||
ioctlsocket(fds[0], FIONBIO, &blocking);
|
||||
ioctlsocket(fds[1], FIONBIO, &blocking);
|
||||
ioctlsocket(fds[0], FIONBIO, &blocking);
|
||||
ioctlsocket(fds[1], FIONBIO, &blocking);
|
||||
ps->mgr_event_rcv = fds[0];
|
||||
ps->mgr_event_snd = fds[1];
|
||||
}
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
<module name="rpcrt4" type="win32dll" baseaddress="${BASEADDRESS_RPCRT4}" installbase="system32" installname="rpcrt4.dll" allowwarnings="true">
|
||||
<autoregister infsection="OleControlDlls" type="DllRegisterServer" />
|
||||
<importlibrary definition="rpcrt4.spec.def" />
|
||||
<include base="rpcrt4">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<define name="__REACTOS__" />
|
||||
<define name="__USE_W32API" />
|
||||
<define name="_WIN32_IE">0x600</define>
|
||||
<define name="_WIN32_WINNT">0x501</define>
|
||||
<define name="WINVER">0x501</define>
|
||||
<define name="_STDDEF_H" />
|
||||
<define name="_RPCRT4_" />
|
||||
<define name="COM_NO_WINDOWS_H" />
|
||||
<define name="MSWMSG" />
|
||||
<library>wine</library>
|
||||
<library>uuid</library>
|
||||
<library>ntdll</library>
|
||||
<library>kernel32</library>
|
||||
<library>advapi32</library>
|
||||
<library>secur32</library>
|
||||
<library>iphlpapi</library>
|
||||
<library>ws2_32</library>
|
||||
<file>cproxy.c</file>
|
||||
<file>cpsf.c</file>
|
||||
<file>cstub.c</file>
|
||||
<file>ndr_contexthandle.c</file>
|
||||
<file>ndr_clientserver.c</file>
|
||||
<file>ndr_fullpointer.c</file>
|
||||
<file>ndr_marshall.c</file>
|
||||
<file>ndr_ole.c</file>
|
||||
<file>ndr_stubless.c</file>
|
||||
<file>rpc_assoc.c</file>
|
||||
<file>rpc_binding.c</file>
|
||||
<file>rpc_epmap.c</file>
|
||||
<file>rpc_message.c</file>
|
||||
<file>rpc_server.c</file>
|
||||
<file>rpc_transport.c</file>
|
||||
<file>rpcrt4_main.c</file>
|
||||
<file>rpcss_np_client.c</file>
|
||||
<file>unix_func.c</file>
|
||||
<file>rpcrt4.rc</file>
|
||||
<file>rpcrt4.spec</file>
|
||||
</module>
|
||||
<module name="rpcrt4" type="win32dll" baseaddress="${BASEADDRESS_RPCRT4}" installbase="system32" installname="rpcrt4.dll" allowwarnings="true">
|
||||
<autoregister infsection="OleControlDlls" type="DllRegisterServer" />
|
||||
<importlibrary definition="rpcrt4.spec.def" />
|
||||
<include base="rpcrt4">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<define name="__REACTOS__" />
|
||||
<define name="__USE_W32API" />
|
||||
<define name="_WIN32_IE">0x600</define>
|
||||
<define name="_WIN32_WINNT">0x501</define>
|
||||
<define name="WINVER">0x501</define>
|
||||
<define name="_STDDEF_H" />
|
||||
<define name="_RPCRT4_" />
|
||||
<define name="COM_NO_WINDOWS_H" />
|
||||
<define name="MSWMSG" />
|
||||
<library>wine</library>
|
||||
<library>uuid</library>
|
||||
<library>ntdll</library>
|
||||
<library>kernel32</library>
|
||||
<library>advapi32</library>
|
||||
<library>secur32</library>
|
||||
<library>iphlpapi</library>
|
||||
<library>ws2_32</library>
|
||||
<file>cproxy.c</file>
|
||||
<file>cpsf.c</file>
|
||||
<file>cstub.c</file>
|
||||
<file>ndr_contexthandle.c</file>
|
||||
<file>ndr_clientserver.c</file>
|
||||
<file>ndr_fullpointer.c</file>
|
||||
<file>ndr_marshall.c</file>
|
||||
<file>ndr_ole.c</file>
|
||||
<file>ndr_stubless.c</file>
|
||||
<file>rpc_assoc.c</file>
|
||||
<file>rpc_binding.c</file>
|
||||
<file>rpc_epmap.c</file>
|
||||
<file>rpc_message.c</file>
|
||||
<file>rpc_server.c</file>
|
||||
<file>rpc_transport.c</file>
|
||||
<file>rpcrt4_main.c</file>
|
||||
<file>rpcss_np_client.c</file>
|
||||
<file>unix_func.c</file>
|
||||
<file>rpcrt4.rc</file>
|
||||
<file>rpcrt4.spec</file>
|
||||
</module>
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,101 +1,115 @@
|
|||
Index: rpc_transport.c
|
||||
===================================================================
|
||||
--- rpc_transport.c (revision 27793)
|
||||
+++ rpc_transport.c (working copy)
|
||||
@@ -56,9 +56,6 @@
|
||||
--- H:\Working Copies\wine\dlls\rpcrt4\rpc_transport.c Sun Jan 06 19:27:38 2008
|
||||
+++ H:\Working Copies\ReactOS\trunk\reactos\dll\win32\rpcrt4\rpc_transport.c Sun Jan 06 19:28:07 2008
|
||||
@@ -56,6 +56,9 @@
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
-#include <winsock2.h>
|
||||
-#include <ws2tcpip.h>
|
||||
-
|
||||
+#include <winsock2.h>
|
||||
+#include <ws2tcpip.h>
|
||||
+
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
@@ -76,8 +73,6 @@
|
||||
@@ -73,6 +76,8 @@
|
||||
#include "rpc_server.h"
|
||||
#include "epm_towers.h"
|
||||
|
||||
-#include "unix_func.h"
|
||||
-
|
||||
+#include "unix_func.h"
|
||||
+
|
||||
#ifndef SOL_TCP
|
||||
# define SOL_TCP IPPROTO_TCP
|
||||
#endif
|
||||
@@ -781,7 +776,7 @@
|
||||
@@ -128,7 +133,7 @@
|
||||
RpcConnection_np *npc = (RpcConnection_np *) Connection;
|
||||
TRACE("listening on %s\n", pname);
|
||||
|
||||
- npc->pipe = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX,
|
||||
+ npc->pipe = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL);
|
||||
@@ -715,12 +720,14 @@
|
||||
if (tcpc == NULL)
|
||||
return NULL;
|
||||
tcpc->sock = -1;
|
||||
+#ifndef __REACTOS__
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0)
|
||||
{
|
||||
ERR("socketpair() failed: %s\n", strerror(errno));
|
||||
HeapFree(GetProcessHeap(), 0, tcpc);
|
||||
return NULL;
|
||||
}
|
||||
+#endif
|
||||
return &tcpc->common;
|
||||
}
|
||||
|
||||
@@ -785,8 +792,7 @@
|
||||
|
||||
/* RPC depends on having minimal latency so disable the Nagle algorithm */
|
||||
val = 1;
|
||||
- setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
||||
+ setsockopt(sock, SOL_TCP, TCP_NODELAY, &val, sizeof(val));
|
||||
- setsockopt(sock, SOL_TCP, TCP_NODELAY, &val, sizeof(val));
|
||||
- fcntl(sock, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
|
||||
+ setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
||||
|
||||
tcpc->sock = sock;
|
||||
|
||||
@@ -804,7 +799,6 @@
|
||||
@@ -808,6 +814,7 @@
|
||||
struct addrinfo *ai;
|
||||
struct addrinfo *ai_cur;
|
||||
struct addrinfo hints;
|
||||
+ u_long blocking;
|
||||
RpcConnection *first_connection = NULL;
|
||||
- u_long blocking;
|
||||
|
||||
TRACE("(%p, %s)\n", protseq, endpoint);
|
||||
|
||||
@@ -855,7 +849,7 @@
|
||||
@@ -859,7 +866,7 @@
|
||||
{
|
||||
WARN("bind failed: %s\n", strerror(errno));
|
||||
close(sock);
|
||||
- if (errno == WSAEADDRINUSE)
|
||||
+ if (errno == EADDRINUSE)
|
||||
- if (errno == EADDRINUSE)
|
||||
+ if (errno == WSAEADDRINUSE)
|
||||
status = RPC_S_DUPLICATE_ENDPOINT;
|
||||
else
|
||||
status = RPC_S_CANT_CREATE_ENDPOINT;
|
||||
@@ -884,8 +878,7 @@
|
||||
@@ -888,7 +895,8 @@
|
||||
* race-condition (poll() says it is readable, connection drops,
|
||||
* and accept() blocks until the next connection comes...)
|
||||
*/
|
||||
- blocking = 1;
|
||||
- ret = ioctlsocket(sock, FIONBIO, &blocking);
|
||||
+ ret = fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||
- ret = fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||
+ blocking = 1;
|
||||
+ ret = ioctlsocket(sock, FIONBIO, &blocking);
|
||||
if (ret < 0)
|
||||
{
|
||||
WARN("couldn't make socket non-blocking, error %d\n", ret);
|
||||
@@ -928,7 +921,6 @@
|
||||
@@ -931,6 +939,7 @@
|
||||
int ret;
|
||||
struct sockaddr_in address;
|
||||
socklen_t addrsize;
|
||||
- u_long blocking;
|
||||
+ u_long blocking;
|
||||
RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn;
|
||||
RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn;
|
||||
|
||||
@@ -940,8 +932,7 @@
|
||||
@@ -942,7 +951,8 @@
|
||||
return RPC_S_OUT_OF_RESOURCES;
|
||||
}
|
||||
/* reset to blocking behaviour */
|
||||
- blocking = 0;
|
||||
- ret = ioctlsocket(ret, FIONBIO, &blocking);
|
||||
+ fcntl(ret, F_SETFL, 0);
|
||||
- fcntl(ret, F_SETFL, 0);
|
||||
+ blocking = 0;
|
||||
+ ret = ioctlsocket(ret, FIONBIO, &blocking);
|
||||
client->sock = ret;
|
||||
TRACE("Accepted a new TCP connection\n");
|
||||
return RPC_S_OK;
|
||||
@@ -1125,12 +1116,10 @@
|
||||
@@ -1189,10 +1199,12 @@
|
||||
if (ps)
|
||||
{
|
||||
int fds[2];
|
||||
- u_long blocking;
|
||||
+ u_long blocking;
|
||||
if (!socketpair(PF_UNIX, SOCK_DGRAM, 0, fds))
|
||||
{
|
||||
- blocking = 1;
|
||||
- ioctlsocket(fds[0], FIONBIO, &blocking);
|
||||
- ioctlsocket(fds[1], FIONBIO, &blocking);
|
||||
+ fcntl(fds[0], F_SETFL, O_NONBLOCK);
|
||||
+ fcntl(fds[1], F_SETFL, O_NONBLOCK);
|
||||
- fcntl(fds[0], F_SETFL, O_NONBLOCK);
|
||||
- fcntl(fds[1], F_SETFL, O_NONBLOCK);
|
||||
+ blocking = 1;
|
||||
+ ioctlsocket(fds[0], FIONBIO, &blocking);
|
||||
+ ioctlsocket(fds[1], FIONBIO, &blocking);
|
||||
ps->mgr_event_rcv = fds[0];
|
||||
ps->mgr_event_snd = fds[1];
|
||||
}
|
||||
@@ -1211,7 +1200,7 @@
|
||||
|
||||
if (!poll_info)
|
||||
return -1;
|
||||
-
|
||||
+
|
||||
ret = poll(poll_info, count, -1);
|
||||
if (ret < 0)
|
||||
{
|
||||
|
|
|
@ -1,152 +1,152 @@
|
|||
/*
|
||||
* RPCSS named pipe client implementation
|
||||
*
|
||||
* Copyright (C) 2002 Greg Turner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/rpcss_shared.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "rpc_binding.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
HANDLE RPCRT4_RpcssNPConnect(void)
|
||||
{
|
||||
HANDLE the_pipe;
|
||||
DWORD dwmode, wait_result;
|
||||
HANDLE master_mutex = RPCRT4_GetMasterMutex();
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
while (TRUE) {
|
||||
|
||||
wait_result = WaitForSingleObject(master_mutex, MASTER_MUTEX_TIMEOUT);
|
||||
switch (wait_result) {
|
||||
case WAIT_ABANDONED:
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
case WAIT_FAILED:
|
||||
case WAIT_TIMEOUT:
|
||||
default:
|
||||
ERR("This should never happen: couldn't enter mutex.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* try to open the client side of the named pipe. */
|
||||
the_pipe = CreateFileA(
|
||||
NAME_RPCSS_NAMED_PIPE, /* pipe name */
|
||||
GENERIC_READ | GENERIC_WRITE, /* r/w access */
|
||||
0, /* no sharing */
|
||||
NULL, /* no security attributes */
|
||||
OPEN_EXISTING, /* open an existing pipe */
|
||||
0, /* default attributes */
|
||||
NULL /* no template file */
|
||||
);
|
||||
|
||||
if (the_pipe != INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
if (GetLastError() != ERROR_PIPE_BUSY) {
|
||||
WARN("Unable to open named pipe %s (assuming unavailable).\n",
|
||||
debugstr_a(NAME_RPCSS_NAMED_PIPE));
|
||||
break;
|
||||
}
|
||||
|
||||
WARN("Named pipe busy (will wait)\n");
|
||||
|
||||
if (!ReleaseMutex(master_mutex))
|
||||
ERR("Failed to release master mutex. Expect deadlock.\n");
|
||||
|
||||
/* wait for the named pipe. We are only willing to wait for 5 seconds.
|
||||
It should be available /very/ soon. */
|
||||
if (! WaitNamedPipeA(NAME_RPCSS_NAMED_PIPE, MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT))
|
||||
{
|
||||
ERR("Named pipe unavailable after waiting. Something is probably wrong.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (the_pipe != INVALID_HANDLE_VALUE) {
|
||||
dwmode = PIPE_READMODE_MESSAGE;
|
||||
/* SetNamedPipeHandleState not implemented ATM, but still seems to work somehow. */
|
||||
if (! SetNamedPipeHandleState(the_pipe, &dwmode, NULL, NULL))
|
||||
WARN("Failed to set pipe handle state\n");
|
||||
}
|
||||
|
||||
if (!ReleaseMutex(master_mutex))
|
||||
ERR("Uh oh, failed to leave the RPC Master Mutex!\n");
|
||||
|
||||
return the_pipe;
|
||||
}
|
||||
|
||||
BOOL RPCRT4_SendReceiveNPMsg(HANDLE np, PRPCSS_NP_MESSAGE msg, char *vardata, PRPCSS_NP_REPLY reply)
|
||||
{
|
||||
DWORD count;
|
||||
UINT32 payload_offset;
|
||||
RPCSS_NP_MESSAGE vardata_payload_msg;
|
||||
|
||||
TRACE("(np == %p, msg == %p, vardata == %p, reply == %p)\n",
|
||||
np, msg, vardata, reply);
|
||||
|
||||
if (! WriteFile(np, msg, sizeof(RPCSS_NP_MESSAGE), &count, NULL)) {
|
||||
ERR("write failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (count != sizeof(RPCSS_NP_MESSAGE)) {
|
||||
ERR("write count mismatch.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* process the vardata payload if necessary */
|
||||
vardata_payload_msg.message_type = RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG;
|
||||
vardata_payload_msg.vardata_payload_size = 0; /* meaningless */
|
||||
for ( payload_offset = 0; payload_offset < msg->vardata_payload_size;
|
||||
payload_offset += VARDATA_PAYLOAD_BYTES ) {
|
||||
TRACE("sending vardata payload. vd=%p, po=%d, ps=%d\n", vardata,
|
||||
payload_offset, msg->vardata_payload_size);
|
||||
ZeroMemory(vardata_payload_msg.message.vardatapayloadmsg.payload, VARDATA_PAYLOAD_BYTES);
|
||||
CopyMemory(vardata_payload_msg.message.vardatapayloadmsg.payload,
|
||||
vardata,
|
||||
min( VARDATA_PAYLOAD_BYTES, msg->vardata_payload_size - payload_offset ));
|
||||
vardata += VARDATA_PAYLOAD_BYTES;
|
||||
if (! WriteFile(np, &vardata_payload_msg, sizeof(RPCSS_NP_MESSAGE), &count, NULL)) {
|
||||
ERR("vardata write failed at %u bytes.\n", payload_offset);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (! ReadFile(np, reply, sizeof(RPCSS_NP_REPLY), &count, NULL)) {
|
||||
ERR("read failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (count != sizeof(RPCSS_NP_REPLY)) {
|
||||
ERR("read count mismatch. got %d.\n", count);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* message execution was successful */
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* RPCSS named pipe client implementation
|
||||
*
|
||||
* Copyright (C) 2002 Greg Turner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/rpcss_shared.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "rpc_binding.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
HANDLE RPCRT4_RpcssNPConnect(void)
|
||||
{
|
||||
HANDLE the_pipe;
|
||||
DWORD dwmode, wait_result;
|
||||
HANDLE master_mutex = RPCRT4_GetMasterMutex();
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
while (TRUE) {
|
||||
|
||||
wait_result = WaitForSingleObject(master_mutex, MASTER_MUTEX_TIMEOUT);
|
||||
switch (wait_result) {
|
||||
case WAIT_ABANDONED:
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
case WAIT_FAILED:
|
||||
case WAIT_TIMEOUT:
|
||||
default:
|
||||
ERR("This should never happen: couldn't enter mutex.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* try to open the client side of the named pipe. */
|
||||
the_pipe = CreateFileA(
|
||||
NAME_RPCSS_NAMED_PIPE, /* pipe name */
|
||||
GENERIC_READ | GENERIC_WRITE, /* r/w access */
|
||||
0, /* no sharing */
|
||||
NULL, /* no security attributes */
|
||||
OPEN_EXISTING, /* open an existing pipe */
|
||||
0, /* default attributes */
|
||||
NULL /* no template file */
|
||||
);
|
||||
|
||||
if (the_pipe != INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
if (GetLastError() != ERROR_PIPE_BUSY) {
|
||||
WARN("Unable to open named pipe %s (assuming unavailable).\n",
|
||||
debugstr_a(NAME_RPCSS_NAMED_PIPE));
|
||||
break;
|
||||
}
|
||||
|
||||
WARN("Named pipe busy (will wait)\n");
|
||||
|
||||
if (!ReleaseMutex(master_mutex))
|
||||
ERR("Failed to release master mutex. Expect deadlock.\n");
|
||||
|
||||
/* wait for the named pipe. We are only willing to wait for 5 seconds.
|
||||
It should be available /very/ soon. */
|
||||
if (! WaitNamedPipeA(NAME_RPCSS_NAMED_PIPE, MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT))
|
||||
{
|
||||
ERR("Named pipe unavailable after waiting. Something is probably wrong.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (the_pipe != INVALID_HANDLE_VALUE) {
|
||||
dwmode = PIPE_READMODE_MESSAGE;
|
||||
/* SetNamedPipeHandleState not implemented ATM, but still seems to work somehow. */
|
||||
if (! SetNamedPipeHandleState(the_pipe, &dwmode, NULL, NULL))
|
||||
WARN("Failed to set pipe handle state\n");
|
||||
}
|
||||
|
||||
if (!ReleaseMutex(master_mutex))
|
||||
ERR("Uh oh, failed to leave the RPC Master Mutex!\n");
|
||||
|
||||
return the_pipe;
|
||||
}
|
||||
|
||||
BOOL RPCRT4_SendReceiveNPMsg(HANDLE np, PRPCSS_NP_MESSAGE msg, char *vardata, PRPCSS_NP_REPLY reply)
|
||||
{
|
||||
DWORD count;
|
||||
UINT32 payload_offset;
|
||||
RPCSS_NP_MESSAGE vardata_payload_msg;
|
||||
|
||||
TRACE("(np == %p, msg == %p, vardata == %p, reply == %p)\n",
|
||||
np, msg, vardata, reply);
|
||||
|
||||
if (! WriteFile(np, msg, sizeof(RPCSS_NP_MESSAGE), &count, NULL)) {
|
||||
ERR("write failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (count != sizeof(RPCSS_NP_MESSAGE)) {
|
||||
ERR("write count mismatch.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* process the vardata payload if necessary */
|
||||
vardata_payload_msg.message_type = RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG;
|
||||
vardata_payload_msg.vardata_payload_size = 0; /* meaningless */
|
||||
for ( payload_offset = 0; payload_offset < msg->vardata_payload_size;
|
||||
payload_offset += VARDATA_PAYLOAD_BYTES ) {
|
||||
TRACE("sending vardata payload. vd=%p, po=%d, ps=%d\n", vardata,
|
||||
payload_offset, msg->vardata_payload_size);
|
||||
ZeroMemory(vardata_payload_msg.message.vardatapayloadmsg.payload, VARDATA_PAYLOAD_BYTES);
|
||||
CopyMemory(vardata_payload_msg.message.vardatapayloadmsg.payload,
|
||||
vardata,
|
||||
min( VARDATA_PAYLOAD_BYTES, msg->vardata_payload_size - payload_offset ));
|
||||
vardata += VARDATA_PAYLOAD_BYTES;
|
||||
if (! WriteFile(np, &vardata_payload_msg, sizeof(RPCSS_NP_MESSAGE), &count, NULL)) {
|
||||
ERR("vardata write failed at %u bytes.\n", payload_offset);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (! ReadFile(np, reply, sizeof(RPCSS_NP_REPLY), &count, NULL)) {
|
||||
ERR("read failed.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (count != sizeof(RPCSS_NP_REPLY)) {
|
||||
ERR("read count mismatch. got %d.\n", count);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* message execution was successful */
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Greg Turner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPCSS_NP_CLIENT_H
|
||||
#define __WINE_RPCSS_NP_CLIENT_H
|
||||
|
||||
/* rpcss_np_client.c */
|
||||
HANDLE RPC_RpcssNPConnect(void);
|
||||
BOOL RPCRT4_SendReceiveNPMsg(HANDLE, PRPCSS_NP_MESSAGE, char *, PRPCSS_NP_REPLY);
|
||||
|
||||
#endif /* __RPCSS_NP_CLINET_H */
|
||||
/*
|
||||
* Copyright (C) 2002 Greg Turner
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPCSS_NP_CLIENT_H
|
||||
#define __WINE_RPCSS_NP_CLIENT_H
|
||||
|
||||
/* rpcss_np_client.c */
|
||||
HANDLE RPC_RpcssNPConnect(void);
|
||||
BOOL RPCRT4_SendReceiveNPMsg(HANDLE, PRPCSS_NP_MESSAGE, char *, PRPCSS_NP_REPLY);
|
||||
|
||||
#endif /* __RPCSS_NP_CLINET_H */
|
||||
|
|
|
@ -1,169 +1,169 @@
|
|||
#include <string.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include "unix_func.h"
|
||||
|
||||
|
||||
int
|
||||
poll(struct pollfd *fds,
|
||||
unsigned long nfds,
|
||||
int timo)
|
||||
{
|
||||
TIMEVAL timeout, *toptr;
|
||||
FD_SET ifds, ofds, efds, *ip, *op;
|
||||
int i, rc, n = -1;
|
||||
|
||||
ip = op = NULL;
|
||||
|
||||
FD_ZERO(&ifds);
|
||||
FD_ZERO(&ofds);
|
||||
FD_ZERO(&efds);
|
||||
|
||||
for (i = 0; i < nfds; ++i)
|
||||
{
|
||||
fds[i].revents = 0;
|
||||
|
||||
if (fds[i].fd < 0)
|
||||
continue;
|
||||
|
||||
if (fds[i].fd > n)
|
||||
n = fds[i].fd;
|
||||
|
||||
if (fds[i].events & (POLLIN|POLLPRI))
|
||||
{
|
||||
ip = &ifds;
|
||||
FD_SET(fds[i].fd, ip);
|
||||
}
|
||||
|
||||
if (fds[i].events & POLLOUT)
|
||||
{
|
||||
op = &ofds;
|
||||
FD_SET(fds[i].fd, op);
|
||||
}
|
||||
|
||||
FD_SET(fds[i].fd, &efds);
|
||||
}
|
||||
|
||||
if (timo < 0)
|
||||
toptr = 0;
|
||||
else
|
||||
{
|
||||
toptr = &timeout;
|
||||
timeout.tv_sec = timo / 1000;
|
||||
timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
|
||||
}
|
||||
|
||||
rc = select(++n, ip, op, &efds, toptr);
|
||||
|
||||
if (rc <= 0)
|
||||
return rc;
|
||||
|
||||
for (i = 0, n = 0; i < nfds; ++i)
|
||||
{
|
||||
if (fds[i].fd < 0) continue;
|
||||
|
||||
if (fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(i, &ifds))
|
||||
fds[i].revents |= POLLIN;
|
||||
|
||||
if (fds[i].events & POLLOUT && FD_ISSET(i, &ofds))
|
||||
fds[i].revents |= POLLOUT;
|
||||
|
||||
if (FD_ISSET(i, &efds))
|
||||
fds[i].revents |= POLLHUP;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int socketpair(int af,
|
||||
int type,
|
||||
int protocol,
|
||||
SOCKET socks[2])
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
SOCKET listener;
|
||||
int e;
|
||||
int addrlen = sizeof(addr);
|
||||
DWORD flags = 0; //(make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
|
||||
|
||||
if (socks == 0)
|
||||
{
|
||||
WSASetLastError(WSAEINVAL);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
socks[0] = socks[1] = INVALID_SOCKET;
|
||||
if ((listener = socket(af, type, 0)) == INVALID_SOCKET)
|
||||
return SOCKET_ERROR;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(0x7f000001);
|
||||
addr.sin_port = 0;
|
||||
|
||||
e = bind(listener, (const struct sockaddr*) &addr, sizeof(addr));
|
||||
if (e == SOCKET_ERROR)
|
||||
{
|
||||
e = WSAGetLastError();
|
||||
closesocket(listener);
|
||||
WSASetLastError(e);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
e = getsockname(listener, (struct sockaddr*) &addr, &addrlen);
|
||||
if (e == SOCKET_ERROR)
|
||||
{
|
||||
e = WSAGetLastError();
|
||||
closesocket(listener);
|
||||
WSASetLastError(e);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (listen(listener, 1) == SOCKET_ERROR)
|
||||
break;
|
||||
if ((socks[0] = WSASocket(af, type, 0, NULL, 0, flags)) == INVALID_SOCKET)
|
||||
break;
|
||||
if (connect(socks[0], (const struct sockaddr*) &addr, sizeof(addr)) == SOCKET_ERROR)
|
||||
break;
|
||||
if ((socks[1] = accept(listener, NULL, NULL)) == INVALID_SOCKET)
|
||||
break;
|
||||
|
||||
closesocket(listener);
|
||||
return 0;
|
||||
|
||||
} while (0);
|
||||
|
||||
e = WSAGetLastError();
|
||||
closesocket(listener);
|
||||
closesocket(socks[0]);
|
||||
closesocket(socks[1]);
|
||||
WSASetLastError(e);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
inet_ntop (int af,
|
||||
const void *src,
|
||||
char *dst,
|
||||
size_t cnt)
|
||||
{
|
||||
struct in_addr in;
|
||||
char *text_addr;
|
||||
|
||||
if (af == AF_INET)
|
||||
{
|
||||
memcpy(&in.s_addr, src, sizeof(in.s_addr));
|
||||
text_addr = inet_ntoa(in);
|
||||
if (text_addr && dst)
|
||||
{
|
||||
strncpy(dst, text_addr, cnt);
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#include <string.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include "unix_func.h"
|
||||
|
||||
|
||||
int
|
||||
poll(struct pollfd *fds,
|
||||
unsigned long nfds,
|
||||
int timo)
|
||||
{
|
||||
TIMEVAL timeout, *toptr;
|
||||
FD_SET ifds, ofds, efds, *ip, *op;
|
||||
int i, rc, n = -1;
|
||||
|
||||
ip = op = NULL;
|
||||
|
||||
FD_ZERO(&ifds);
|
||||
FD_ZERO(&ofds);
|
||||
FD_ZERO(&efds);
|
||||
|
||||
for (i = 0; i < nfds; ++i)
|
||||
{
|
||||
fds[i].revents = 0;
|
||||
|
||||
if (fds[i].fd < 0)
|
||||
continue;
|
||||
|
||||
if (fds[i].fd > n)
|
||||
n = fds[i].fd;
|
||||
|
||||
if (fds[i].events & (POLLIN|POLLPRI))
|
||||
{
|
||||
ip = &ifds;
|
||||
FD_SET(fds[i].fd, ip);
|
||||
}
|
||||
|
||||
if (fds[i].events & POLLOUT)
|
||||
{
|
||||
op = &ofds;
|
||||
FD_SET(fds[i].fd, op);
|
||||
}
|
||||
|
||||
FD_SET(fds[i].fd, &efds);
|
||||
}
|
||||
|
||||
if (timo < 0)
|
||||
toptr = 0;
|
||||
else
|
||||
{
|
||||
toptr = &timeout;
|
||||
timeout.tv_sec = timo / 1000;
|
||||
timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
|
||||
}
|
||||
|
||||
rc = select(++n, ip, op, &efds, toptr);
|
||||
|
||||
if (rc <= 0)
|
||||
return rc;
|
||||
|
||||
for (i = 0, n = 0; i < nfds; ++i)
|
||||
{
|
||||
if (fds[i].fd < 0) continue;
|
||||
|
||||
if (fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(i, &ifds))
|
||||
fds[i].revents |= POLLIN;
|
||||
|
||||
if (fds[i].events & POLLOUT && FD_ISSET(i, &ofds))
|
||||
fds[i].revents |= POLLOUT;
|
||||
|
||||
if (FD_ISSET(i, &efds))
|
||||
fds[i].revents |= POLLHUP;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int socketpair(int af,
|
||||
int type,
|
||||
int protocol,
|
||||
SOCKET socks[2])
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
SOCKET listener;
|
||||
int e;
|
||||
int addrlen = sizeof(addr);
|
||||
DWORD flags = 0; //(make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
|
||||
|
||||
if (socks == 0)
|
||||
{
|
||||
WSASetLastError(WSAEINVAL);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
socks[0] = socks[1] = INVALID_SOCKET;
|
||||
if ((listener = socket(af, type, 0)) == INVALID_SOCKET)
|
||||
return SOCKET_ERROR;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(0x7f000001);
|
||||
addr.sin_port = 0;
|
||||
|
||||
e = bind(listener, (const struct sockaddr*) &addr, sizeof(addr));
|
||||
if (e == SOCKET_ERROR)
|
||||
{
|
||||
e = WSAGetLastError();
|
||||
closesocket(listener);
|
||||
WSASetLastError(e);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
e = getsockname(listener, (struct sockaddr*) &addr, &addrlen);
|
||||
if (e == SOCKET_ERROR)
|
||||
{
|
||||
e = WSAGetLastError();
|
||||
closesocket(listener);
|
||||
WSASetLastError(e);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (listen(listener, 1) == SOCKET_ERROR)
|
||||
break;
|
||||
if ((socks[0] = WSASocket(af, type, 0, NULL, 0, flags)) == INVALID_SOCKET)
|
||||
break;
|
||||
if (connect(socks[0], (const struct sockaddr*) &addr, sizeof(addr)) == SOCKET_ERROR)
|
||||
break;
|
||||
if ((socks[1] = accept(listener, NULL, NULL)) == INVALID_SOCKET)
|
||||
break;
|
||||
|
||||
closesocket(listener);
|
||||
return 0;
|
||||
|
||||
} while (0);
|
||||
|
||||
e = WSAGetLastError();
|
||||
closesocket(listener);
|
||||
closesocket(socks[0]);
|
||||
closesocket(socks[1]);
|
||||
WSASetLastError(e);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
inet_ntop (int af,
|
||||
const void *src,
|
||||
char *dst,
|
||||
size_t cnt)
|
||||
{
|
||||
struct in_addr in;
|
||||
char *text_addr;
|
||||
|
||||
if (af == AF_INET)
|
||||
{
|
||||
memcpy(&in.s_addr, src, sizeof(in.s_addr));
|
||||
text_addr = inet_ntoa(in);
|
||||
if (text_addr && dst)
|
||||
{
|
||||
strncpy(dst, text_addr, cnt);
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
|
||||
#define POLLIN 001
|
||||
#define POLLPRI 002
|
||||
#define POLLOUT 004
|
||||
#define POLLNORM POLLIN
|
||||
#define POLLERR 010
|
||||
#define POLLHUP 020
|
||||
#define POLLNVAL 040
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
int fd; /* file descriptor */
|
||||
short events; /* requested events */
|
||||
short revents; /* returned events */
|
||||
};
|
||||
|
||||
int poll(struct pollfd *fds, unsigned long nfds, int timo);
|
||||
int socketpair (int af, int type, int protocol, SOCKET socket[2]);
|
||||
const char * inet_ntop (int af, const void *src, char *dst, size_t cnt);
|
||||
|
||||
#define POLLIN 001
|
||||
#define POLLPRI 002
|
||||
#define POLLOUT 004
|
||||
#define POLLNORM POLLIN
|
||||
#define POLLERR 010
|
||||
#define POLLHUP 020
|
||||
#define POLLNVAL 040
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
int fd; /* file descriptor */
|
||||
short events; /* requested events */
|
||||
short revents; /* returned events */
|
||||
};
|
||||
|
||||
int poll(struct pollfd *fds, unsigned long nfds, int timo);
|
||||
int socketpair (int af, int type, int protocol, SOCKET socket[2]);
|
||||
const char * inet_ntop (int af, const void *src, char *dst, size_t cnt);
|
||||
|
|
Loading…
Reference in a new issue