mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-30 19:26:05 +00:00
[RPCRT4]
- sync with wine 1.3.26 MAny thanks to Filip Navara for his invaluable help. svn path=/trunk/; revision=53118
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "cpsf.h"
|
||||
#include "ndr_misc.h"
|
||||
#include "ndr_stubless.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
@@ -44,7 +45,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
/* 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;
|
||||
IRpcProxyBuffer IRpcProxyBuffer_iface;
|
||||
LPVOID *PVtbl;
|
||||
LONG RefCount;
|
||||
const IID* piid;
|
||||
@@ -58,47 +59,130 @@ typedef struct {
|
||||
|
||||
static const IRpcProxyBufferVtbl StdProxy_Vtbl;
|
||||
|
||||
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
|
||||
static inline StdProxyImpl *impl_from_IRpcProxyBuffer(IRpcProxyBuffer *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, StdProxyImpl, IRpcProxyBuffer_iface);
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
static inline StdProxyImpl *impl_from_proxy_obj( void *iface )
|
||||
{
|
||||
return CONTAINING_RECORD(iface, StdProxyImpl, PVtbl);
|
||||
}
|
||||
|
||||
#include "pshpack1.h"
|
||||
|
||||
struct thunk {
|
||||
BYTE push;
|
||||
DWORD index;
|
||||
BYTE jmp;
|
||||
LONG handler;
|
||||
};
|
||||
|
||||
#include "poppack.h"
|
||||
#ifdef __i386__
|
||||
|
||||
extern void call_stubless_func(void);
|
||||
__ASM_GLOBAL_FUNC(call_stubless_func,
|
||||
"pushl %esp\n\t" /* pointer to index */
|
||||
"movl 4(%esp),%ecx\n\t" /* This pointer */
|
||||
"movl (%ecx),%ecx\n\t" /* This->lpVtbl */
|
||||
"movl -8(%ecx),%ecx\n\t" /* MIDL_STUBLESS_PROXY_INFO */
|
||||
"movl 8(%ecx),%edx\n\t" /* info->FormatStringOffset */
|
||||
"movzwl (%edx,%eax,2),%edx\n\t" /* FormatStringOffset[index] */
|
||||
"addl 4(%ecx),%edx\n\t" /* info->ProcFormatString + offset */
|
||||
"movzwl 8(%edx),%eax\n\t" /* arguments size */
|
||||
"pushl %eax\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||
"call " __ASM_NAME("ObjectStubless") __ASM_STDCALL(4) "\n\t"
|
||||
"popl %edx\n\t" /* args size */
|
||||
"leal 8(%esp),%eax\n\t" /* &This */
|
||||
"pushl %eax\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||
"pushl %edx\n\t" /* format string */
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||
"pushl (%ecx)\n\t" /* info->pStubDesc */
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||
"call " __ASM_NAME("ndr_client_call") "\n\t"
|
||||
"leal 12(%esp),%esp\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset -12\n\t")
|
||||
"popl %edx\n\t" /* arguments size */
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
|
||||
"movl (%esp),%ecx\n\t" /* return address */
|
||||
"addl %edx,%esp\n\t"
|
||||
"jmp *%ecx" );
|
||||
|
||||
HRESULT WINAPI ObjectStubless(DWORD *args)
|
||||
#include "pshpack1.h"
|
||||
struct thunk
|
||||
{
|
||||
DWORD index = args[0];
|
||||
void **iface = (void **)args[2];
|
||||
const void **vtbl = (const void **)*iface;
|
||||
const MIDL_STUBLESS_PROXY_INFO *stubless = *(const MIDL_STUBLESS_PROXY_INFO **)(vtbl - 2);
|
||||
const PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[index];
|
||||
BYTE mov_eax;
|
||||
DWORD index;
|
||||
BYTE jmp;
|
||||
LONG handler;
|
||||
};
|
||||
#include "poppack.h"
|
||||
|
||||
/* store bytes to remove from stack */
|
||||
args[0] = *(const WORD*)(fs + 8);
|
||||
TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, args[0], args[1]);
|
||||
|
||||
return NdrClientCall2(stubless->pStubDesc, fs, args + 2).Simple;
|
||||
static inline void init_thunk( struct thunk *thunk, unsigned int index )
|
||||
{
|
||||
thunk->mov_eax = 0xb8; /* movl $n,%eax */
|
||||
thunk->index = index;
|
||||
thunk->jmp = 0xe9; /* jmp */
|
||||
thunk->handler = (char *)call_stubless_func - (char *)(&thunk->handler + 1);
|
||||
}
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
|
||||
extern void call_stubless_func(void);
|
||||
__ASM_GLOBAL_FUNC(call_stubless_func,
|
||||
"movq %rcx,0x8(%rsp)\n\t"
|
||||
"movq %rdx,0x10(%rsp)\n\t"
|
||||
"movq %r8,0x18(%rsp)\n\t"
|
||||
"movq %r9,0x20(%rsp)\n\t"
|
||||
"leaq 0x8(%rsp),%r8\n\t" /* &This */
|
||||
"movq (%rcx),%rcx\n\t" /* This->lpVtbl */
|
||||
"movq -0x10(%rcx),%rcx\n\t" /* MIDL_STUBLESS_PROXY_INFO */
|
||||
"movq 0x10(%rcx),%rdx\n\t" /* info->FormatStringOffset */
|
||||
"movzwq (%rdx,%r10,2),%rdx\n\t" /* FormatStringOffset[index] */
|
||||
"addq 8(%rcx),%rdx\n\t" /* info->ProcFormatString + offset */
|
||||
"movq (%rcx),%rcx\n\t" /* info->pStubDesc */
|
||||
"subq $0x38,%rsp\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset 0x38\n\t")
|
||||
"movq %xmm1,0x20(%rsp)\n\t"
|
||||
"movq %xmm2,0x28(%rsp)\n\t"
|
||||
"movq %xmm3,0x30(%rsp)\n\t"
|
||||
"leaq 0x18(%rsp),%r9\n\t" /* fpu_args */
|
||||
"call " __ASM_NAME("ndr_client_call") "\n\t"
|
||||
"addq $0x38,%rsp\n\t"
|
||||
__ASM_CFI(".cfi_adjust_cfa_offset -0x38\n\t")
|
||||
"ret" );
|
||||
|
||||
#include "pshpack1.h"
|
||||
struct thunk
|
||||
{
|
||||
BYTE mov_r10[3];
|
||||
DWORD index;
|
||||
BYTE mov_rax[2];
|
||||
void *call_stubless;
|
||||
BYTE jmp_rax[2];
|
||||
};
|
||||
#include "poppack.h"
|
||||
|
||||
static const struct thunk thunk_template =
|
||||
{
|
||||
{ 0x49, 0xc7, 0xc2 }, 0, /* movq $index,%r10 */
|
||||
{ 0x48, 0xb8 }, 0, /* movq $call_stubless_func,%rax */
|
||||
{ 0xff, 0xe0 } /* jmp *%rax */
|
||||
};
|
||||
|
||||
static inline void init_thunk( struct thunk *thunk, unsigned int index )
|
||||
{
|
||||
*thunk = thunk_template;
|
||||
thunk->index = index;
|
||||
thunk->call_stubless = call_stubless_func;
|
||||
}
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
#warning You must implement stubless proxies for your CPU
|
||||
|
||||
struct thunk
|
||||
{
|
||||
DWORD index;
|
||||
};
|
||||
|
||||
static inline void init_thunk( struct thunk *thunk, unsigned int index )
|
||||
{
|
||||
thunk->index = index;
|
||||
}
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
#define BLOCK_SIZE 1024
|
||||
#define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */
|
||||
|
||||
@@ -113,13 +197,7 @@ static const struct thunk *allocate_block( unsigned int num )
|
||||
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
|
||||
if (!block) return NULL;
|
||||
|
||||
for (i = 0; i < BLOCK_SIZE; i++)
|
||||
{
|
||||
block[i].push = 0x68; /* pushl */
|
||||
block[i].index = BLOCK_SIZE * num + i + 3;
|
||||
block[i].jmp = 0xe9; /* jmp */
|
||||
block[i].handler = (char *)call_stubless_func - (char *)(&block[i].handler + 1);
|
||||
}
|
||||
for (i = 0; i < BLOCK_SIZE; i++) init_thunk( &block[i], BLOCK_SIZE * num + i + 3 );
|
||||
VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL );
|
||||
prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL );
|
||||
if (prev) /* someone beat us to it */
|
||||
@@ -150,16 +228,6 @@ static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num )
|
||||
{
|
||||
ERR("stubless proxies are not supported on this architecture\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
HRESULT StdProxy_Construct(REFIID riid,
|
||||
LPUNKNOWN pUnkOuter,
|
||||
const ProxyFileInfo *ProxyInfo,
|
||||
@@ -191,7 +259,7 @@ HRESULT StdProxy_Construct(REFIID riid,
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
|
||||
if (!pUnkOuter) pUnkOuter = (IUnknown *)This;
|
||||
This->lpVtbl = &StdProxy_Vtbl;
|
||||
This->IRpcProxyBuffer_iface.lpVtbl = &StdProxy_Vtbl;
|
||||
This->PVtbl = vtbl->Vtbl;
|
||||
/* one reference for the proxy */
|
||||
This->RefCount = 1;
|
||||
@@ -214,7 +282,7 @@ HRESULT StdProxy_Construct(REFIID riid,
|
||||
}
|
||||
}
|
||||
|
||||
*ppProxy = (LPRPCPROXYBUFFER)&This->lpVtbl;
|
||||
*ppProxy = &This->IRpcProxyBuffer_iface;
|
||||
*ppvObj = &This->PVtbl;
|
||||
IUnknown_AddRef((IUnknown *)*ppvObj);
|
||||
IPSFactoryBuffer_AddRef(pPSFactory);
|
||||
@@ -224,25 +292,11 @@ HRESULT StdProxy_Construct(REFIID riid,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void StdProxy_Destruct(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
|
||||
if (This->pChannel)
|
||||
IRpcProxyBuffer_Disconnect(iface);
|
||||
|
||||
if (This->base_object) IUnknown_Release( This->base_object );
|
||||
if (This->base_proxy) IRpcProxyBuffer_Release( This->base_proxy );
|
||||
|
||||
IPSFactoryBuffer_Release(This->pPSFactory);
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface);
|
||||
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj);
|
||||
|
||||
if (IsEqualGUID(&IID_IUnknown,riid) ||
|
||||
@@ -253,7 +307,7 @@ static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface,
|
||||
}
|
||||
|
||||
if (IsEqualGUID(&IID_IRpcProxyBuffer,riid)) {
|
||||
*obj = &This->lpVtbl;
|
||||
*obj = &This->IRpcProxyBuffer_iface;
|
||||
InterlockedIncrement(&This->RefCount);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -263,7 +317,7 @@ static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface,
|
||||
|
||||
static ULONG WINAPI StdProxy_AddRef(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface);
|
||||
TRACE("(%p)->AddRef()\n",This);
|
||||
|
||||
return InterlockedIncrement(&This->RefCount);
|
||||
@@ -272,19 +326,29 @@ static ULONG WINAPI StdProxy_AddRef(LPRPCPROXYBUFFER iface)
|
||||
static ULONG WINAPI StdProxy_Release(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ULONG refs;
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface);
|
||||
TRACE("(%p)->Release()\n",This);
|
||||
|
||||
refs = InterlockedDecrement(&This->RefCount);
|
||||
if (!refs)
|
||||
StdProxy_Destruct((LPRPCPROXYBUFFER)&This->lpVtbl);
|
||||
{
|
||||
if (This->pChannel)
|
||||
IRpcProxyBuffer_Disconnect(&This->IRpcProxyBuffer_iface);
|
||||
|
||||
if (This->base_object) IUnknown_Release( This->base_object );
|
||||
if (This->base_proxy) IRpcProxyBuffer_Release( This->base_proxy );
|
||||
|
||||
IPSFactoryBuffer_Release(This->pPSFactory);
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface,
|
||||
LPRPCCHANNELBUFFER pChannel)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface);
|
||||
TRACE("(%p)->Connect(%p)\n",This,pChannel);
|
||||
|
||||
This->pChannel = pChannel;
|
||||
@@ -295,7 +359,7 @@ static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface,
|
||||
|
||||
static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
StdProxyImpl *This = impl_from_IRpcProxyBuffer(iface);
|
||||
TRACE("(%p)->Disconnect()\n",This);
|
||||
|
||||
if (This->base_proxy) IRpcProxyBuffer_Disconnect( This->base_proxy );
|
||||
@@ -316,7 +380,7 @@ static const IRpcProxyBufferVtbl StdProxy_Vtbl =
|
||||
static void StdProxy_GetChannel(LPVOID iface,
|
||||
LPRPCCHANNELBUFFER *ppChannel)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
StdProxyImpl *This = impl_from_proxy_obj( iface );
|
||||
TRACE("(%p)->GetChannel(%p) %s\n",This,ppChannel,This->name);
|
||||
|
||||
*ppChannel = This->pChannel;
|
||||
@@ -325,7 +389,7 @@ static void StdProxy_GetChannel(LPVOID iface,
|
||||
static void StdProxy_GetIID(LPVOID iface,
|
||||
const IID **ppiid)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
StdProxyImpl *This = impl_from_proxy_obj( iface );
|
||||
TRACE("(%p)->GetIID(%p) %s\n",This,ppiid,This->name);
|
||||
|
||||
*ppiid = This->piid;
|
||||
@@ -335,21 +399,21 @@ HRESULT WINAPI IUnknown_QueryInterface_Proxy(LPUNKNOWN iface,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObj)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
StdProxyImpl *This = impl_from_proxy_obj( 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);
|
||||
StdProxyImpl *This = impl_from_proxy_obj( 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);
|
||||
StdProxyImpl *This = impl_from_proxy_obj( iface );
|
||||
TRACE("(%p)->Release() %s\n",This,This->name);
|
||||
return IUnknown_Release(This->pUnkOuter);
|
||||
}
|
||||
@@ -483,3 +547,24 @@ CreateProxyFromTypeInfo( LPTYPEINFO pTypeInfo, LPUNKNOWN pUnkOuter, REFIID riid,
|
||||
}
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI
|
||||
CreateStubFromTypeInfo(ITypeInfo *pTypeInfo, REFIID riid, IUnknown *pUnkServer,
|
||||
IRpcStubBuffer **ppStub )
|
||||
{
|
||||
typedef INT (WINAPI *MessageBoxA)(HWND,LPCSTR,LPCSTR,UINT);
|
||||
HMODULE hUser32 = LoadLibraryA("user32");
|
||||
MessageBoxA pMessageBoxA = (void *)GetProcAddress(hUser32, "MessageBoxA");
|
||||
|
||||
FIXME("%p %s %p %p\n", pTypeInfo, debugstr_guid(riid), pUnkServer, ppStub);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll,
|
||||
TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid));
|
||||
|
||||
//if (!hDll) return E_HANDLE;
|
||||
if (!pProxyFileList || !*pProxyFileList) return E_NOINTERFACE;
|
||||
if (!*pProxyFileList) return E_NOINTERFACE;
|
||||
|
||||
if (pclsid)
|
||||
format_clsid( clsid, pclsid );
|
||||
|
||||
@@ -23,23 +23,23 @@
|
||||
|
||||
HRESULT StdProxy_Construct(REFIID riid, LPUNKNOWN pUnkOuter, const ProxyFileInfo *ProxyInfo,
|
||||
int Index, LPPSFACTORYBUFFER pPSFactory, LPRPCPROXYBUFFER *ppProxy,
|
||||
LPVOID *ppvObj);
|
||||
LPVOID *ppvObj) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT CStdStubBuffer_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name,
|
||||
CInterfaceStubVtbl *vtbl, LPPSFACTORYBUFFER pPSFactory,
|
||||
LPRPCSTUBBUFFER *ppStub);
|
||||
LPRPCSTUBBUFFER *ppStub) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name,
|
||||
CInterfaceStubVtbl *vtbl, REFIID delegating_iid,
|
||||
LPPSFACTORYBUFFER pPSFactory, LPRPCSTUBBUFFER *ppStub);
|
||||
LPPSFACTORYBUFFER pPSFactory, LPRPCSTUBBUFFER *ppStub) DECLSPEC_HIDDEN;
|
||||
|
||||
const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface);
|
||||
const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface) DECLSPEC_HIDDEN;
|
||||
|
||||
const IRpcStubBufferVtbl CStdStubBuffer_Vtbl;
|
||||
const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl;
|
||||
extern const IRpcStubBufferVtbl CStdStubBuffer_Vtbl DECLSPEC_HIDDEN;
|
||||
extern const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl DECLSPEC_HIDDEN;
|
||||
|
||||
BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num);
|
||||
HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv);
|
||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub);
|
||||
BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) DECLSPEC_HIDDEN;
|
||||
HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv) DECLSPEC_HIDDEN;
|
||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_CPSF_H */
|
||||
|
||||
@@ -137,27 +137,54 @@ static ULONG WINAPI delegating_Release(IUnknown *pUnk)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
|
||||
/* The idea here is to replace the first param on the stack
|
||||
ie. This (which will point to cstdstubbuffer_delegating_t)
|
||||
with This->stub_buffer.pvServerObject and then jump to the
|
||||
relevant offset in This->stub_buffer.pvServerObject's vtbl.
|
||||
*/
|
||||
#ifdef __i386__
|
||||
|
||||
#include "pshpack1.h"
|
||||
typedef struct {
|
||||
DWORD mov1; /* mov 0x4(%esp), %eax 8b 44 24 04 */
|
||||
WORD mov2; /* mov 0x10(%eax), %eax 8b 40 */
|
||||
BYTE sixteen; /* 10 */
|
||||
DWORD mov3; /* mov %eax, 0x4(%esp) 89 44 24 04 */
|
||||
WORD mov4; /* mov (%eax), %eax 8b 00 */
|
||||
WORD mov5; /* mov offset(%eax), %eax 8b 80 */
|
||||
DWORD offset; /* xx xx xx xx */
|
||||
WORD jmp; /* jmp *%eax ff e0 */
|
||||
BYTE pad[3]; /* lea 0x0(%esi), %esi 8d 76 00 */
|
||||
BYTE mov1[4]; /* mov 0x4(%esp),%eax 8b 44 24 04 */
|
||||
BYTE mov2[3]; /* mov 0x10(%eax),%eax 8b 40 10 */
|
||||
BYTE mov3[4]; /* mov %eax,0x4(%esp) 89 44 24 04 */
|
||||
BYTE mov4[2]; /* mov (%eax),%eax 8b 00 */
|
||||
BYTE mov5[2]; /* jmp *offset(%eax) ff a0 offset */
|
||||
DWORD offset;
|
||||
BYTE pad[1]; /* nop 90 */
|
||||
} vtbl_method_t;
|
||||
#include "poppack.h"
|
||||
|
||||
static const BYTE opcodes[20] = { 0x8b, 0x44, 0x24, 0x04, 0x8b, 0x40, 0x10, 0x89, 0x44, 0x24, 0x04,
|
||||
0x8b, 0x00, 0xff, 0xa0, 0, 0, 0, 0, 0x90 };
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
|
||||
#include "pshpack1.h"
|
||||
typedef struct
|
||||
{
|
||||
BYTE mov1[4]; /* movq 0x20(%rcx),%rcx 48 8b 49 20 */
|
||||
BYTE mov2[3]; /* movq (%rcx),%rax 48 8b 01 */
|
||||
BYTE jmp[2]; /* jmp *offset(%rax) ff a0 offset */
|
||||
DWORD offset;
|
||||
BYTE pad[3]; /* lea 0x0(%rsi),%rsi 48 8d 36 */
|
||||
} vtbl_method_t;
|
||||
#include "poppack.h"
|
||||
|
||||
static const BYTE opcodes[16] = { 0x48, 0x8b, 0x49, 0x20, 0x48, 0x8b, 0x01,
|
||||
0xff, 0xa0, 0, 0, 0, 0, 0x48, 0x8d, 0x36 };
|
||||
#else
|
||||
|
||||
#warning You must implement delegated proxies/stubs for your CPU
|
||||
typedef struct
|
||||
{
|
||||
DWORD offset;
|
||||
} vtbl_method_t;
|
||||
static const BYTE opcodes[1];
|
||||
|
||||
#endif
|
||||
|
||||
#define BLOCK_SIZE 1024
|
||||
#define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */
|
||||
|
||||
@@ -174,17 +201,8 @@ static const vtbl_method_t *allocate_block( unsigned int num )
|
||||
|
||||
for (i = 0; i < BLOCK_SIZE; i++)
|
||||
{
|
||||
block[i].mov1 = 0x0424448b;
|
||||
block[i].mov2 = 0x408b;
|
||||
block[i].sixteen = 0x10;
|
||||
block[i].mov3 = 0x04244489;
|
||||
block[i].mov4 = 0x008b;
|
||||
block[i].mov5 = 0x808b;
|
||||
block[i].offset = (BLOCK_SIZE * num + i + 3) << 2;
|
||||
block[i].jmp = 0xe0ff;
|
||||
block[i].pad[0] = 0x8d;
|
||||
block[i].pad[1] = 0x76;
|
||||
block[i].pad[2] = 0x00;
|
||||
memcpy( &block[i], opcodes, sizeof(opcodes) );
|
||||
block[i].offset = (BLOCK_SIZE * num + i + 3) * sizeof(void *);
|
||||
}
|
||||
VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL );
|
||||
prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL );
|
||||
@@ -241,22 +259,6 @@ BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num)
|
||||
{
|
||||
ERR("delegated stubs are not supported on this architecture\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num)
|
||||
{
|
||||
ERR("delegated proxies are not supported on this architecture\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
static IUnknownVtbl *get_delegating_vtbl(DWORD num_methods)
|
||||
{
|
||||
IUnknownVtbl *ret;
|
||||
|
||||
@@ -3,16 +3,30 @@
|
||||
|
||||
.code32
|
||||
|
||||
EXTERN _ObjectStubless@4:PROC
|
||||
EXTERN _ndr_client_call:PROC
|
||||
|
||||
PUBLIC _call_stubless_func
|
||||
_call_stubless_func:
|
||||
|
||||
push esp /* pointer to index */
|
||||
call _ObjectStubless@4
|
||||
pop edx /* args size */
|
||||
mov ecx, [esp] /* return address */
|
||||
mov ecx,[esp+4] /* This Pointer */
|
||||
mov ecx,[ecx] /* This->lpVtbl */
|
||||
mov ecx,[ecx-8] /* MIDL_STUBLESS_PROXY_INFO */
|
||||
mov edx,[ecx-8] /* Info->FormatStringOffset */
|
||||
xor edx, edx
|
||||
mov dx,[edx+eax*2] /* FormatStringOffset[index] */
|
||||
add edx,[ecx+4] /* info->ProcFormatString + offset */
|
||||
xor eax, eax
|
||||
mov ax, [edx+8] /* arguments size */
|
||||
push eax
|
||||
lea eax, [esp+8] /* &This */
|
||||
push eax
|
||||
push edx /* format string */
|
||||
push [ecx] /* info->pstubdesc */
|
||||
call _ndr_client_call
|
||||
lea esp, [esp+12]
|
||||
pop edx /* arguments size */
|
||||
mov ecx, [esp] /* return address */
|
||||
add esp, edx
|
||||
jmp ecx
|
||||
|
||||
END
|
||||
END
|
||||
@@ -329,9 +329,10 @@ void WINAPIV NdrMesProcEncodeDecode(handle_t Handle, const MIDL_STUB_DESC * pStu
|
||||
unsigned short stack_size;
|
||||
/* header for procedure string */
|
||||
const NDR_PROC_HEADER *pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0];
|
||||
/* the value to return to the client from the remote procedure */
|
||||
LONG_PTR RetVal = 0;
|
||||
const RPC_CLIENT_INTERFACE *client_interface;
|
||||
__ms_va_list args;
|
||||
unsigned int number_of_params;
|
||||
ULONG_PTR arg_buffer[256];
|
||||
|
||||
TRACE("Handle %p, pStubDesc %p, pFormat %p, ...\n", Handle, pStubDesc, pFormat);
|
||||
|
||||
@@ -396,29 +397,26 @@ void WINAPIV NdrMesProcEncodeDecode(handle_t Handle, const MIDL_STUB_DESC * pStu
|
||||
TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion);
|
||||
|
||||
/* needed for conformance of top-level objects */
|
||||
#ifdef __i386__
|
||||
pEsMsg->StubMsg.StackTop = *(unsigned char **)(&pFormat+1);
|
||||
#else
|
||||
# warning Stack not retrieved for your CPU architecture
|
||||
#endif
|
||||
__ms_va_start( args, pFormat );
|
||||
pEsMsg->StubMsg.StackTop = va_arg( args, unsigned char * );
|
||||
__ms_va_end( args );
|
||||
|
||||
pFormat = convert_old_args( &pEsMsg->StubMsg, pFormat, stack_size, FALSE,
|
||||
arg_buffer, sizeof(arg_buffer), &number_of_params );
|
||||
|
||||
switch (pEsMsg->Operation)
|
||||
{
|
||||
case MES_ENCODE:
|
||||
pEsMsg->StubMsg.BufferLength = mes_proc_header_buffer_size();
|
||||
|
||||
client_do_args_old_format(&pEsMsg->StubMsg, pFormat, PROXY_CALCSIZE,
|
||||
pEsMsg->StubMsg.StackTop, stack_size, (unsigned char *)&RetVal,
|
||||
FALSE /* object_proc */, TRUE /* ignore_retval */);
|
||||
client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_CALCSIZE, NULL, number_of_params, NULL );
|
||||
|
||||
pEsMsg->ByteCount = pEsMsg->StubMsg.BufferLength - mes_proc_header_buffer_size();
|
||||
es_data_alloc(pEsMsg, pEsMsg->StubMsg.BufferLength);
|
||||
|
||||
mes_proc_header_marshal(pEsMsg);
|
||||
|
||||
client_do_args_old_format(&pEsMsg->StubMsg, pFormat, PROXY_MARSHAL,
|
||||
pEsMsg->StubMsg.StackTop, stack_size, (unsigned char *)&RetVal,
|
||||
FALSE /* object_proc */, TRUE /* ignore_retval */);
|
||||
client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_MARSHAL, NULL, number_of_params, NULL );
|
||||
|
||||
es_data_write(pEsMsg, pEsMsg->ByteCount);
|
||||
break;
|
||||
@@ -427,9 +425,7 @@ void WINAPIV NdrMesProcEncodeDecode(handle_t Handle, const MIDL_STUB_DESC * pStu
|
||||
|
||||
es_data_read(pEsMsg, pEsMsg->ByteCount);
|
||||
|
||||
client_do_args_old_format(&pEsMsg->StubMsg, pFormat, PROXY_UNMARSHAL,
|
||||
pEsMsg->StubMsg.StackTop, stack_size, (unsigned char *)&RetVal,
|
||||
FALSE /* object_proc */, TRUE /* ignore_retval */);
|
||||
client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_UNMARSHAL, NULL, number_of_params, NULL );
|
||||
break;
|
||||
default:
|
||||
RpcRaiseException(RPC_S_INTERNAL_ERROR);
|
||||
@@ -446,6 +442,12 @@ void RPC_ENTRY NdrMesTypeDecode2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO
|
||||
FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject);
|
||||
}
|
||||
|
||||
void RPC_ENTRY NdrMesTypeEncode2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo,
|
||||
const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, const void *pObject)
|
||||
{
|
||||
FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject);
|
||||
}
|
||||
|
||||
void RPC_ENTRY NdrMesTypeFree2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo,
|
||||
const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, void *pObject)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,7 +32,7 @@ struct IPSFactoryBuffer;
|
||||
|
||||
PFORMAT_STRING ComputeConformanceOrVariance(
|
||||
MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount);
|
||||
PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline PFORMAT_STRING ComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
@@ -56,12 +56,12 @@ typedef void (WINAPI *NDR_BUFFERSIZE)(PMIDL_STUB_MESSAGE, unsigned cha
|
||||
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[];
|
||||
extern const NDR_MARSHALL NdrMarshaller[] DECLSPEC_HIDDEN;
|
||||
extern const NDR_UNMARSHALL NdrUnmarshaller[] DECLSPEC_HIDDEN;
|
||||
extern const NDR_BUFFERSIZE NdrBufferSizer[] DECLSPEC_HIDDEN;
|
||||
extern const NDR_MEMORYSIZE NdrMemorySizer[] DECLSPEC_HIDDEN;
|
||||
extern const NDR_FREE NdrFreer[] DECLSPEC_HIDDEN;
|
||||
|
||||
ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat);
|
||||
ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_NDR_MISC_H */
|
||||
|
||||
@@ -78,7 +78,7 @@ static HMODULE LoadCOM(void)
|
||||
* (which also implements the MInterfacePointer structure) */
|
||||
typedef struct RpcStreamImpl
|
||||
{
|
||||
const IStreamVtbl *lpVtbl;
|
||||
IStream IStream_iface;
|
||||
LONG RefCount;
|
||||
PMIDL_STUB_MESSAGE pMsg;
|
||||
LPDWORD size;
|
||||
@@ -86,11 +86,16 @@ typedef struct RpcStreamImpl
|
||||
DWORD pos;
|
||||
} RpcStreamImpl;
|
||||
|
||||
static inline RpcStreamImpl *impl_from_IStream(IStream *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, RpcStreamImpl, IStream_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
RpcStreamImpl *This = impl_from_IStream(iface);
|
||||
if (IsEqualGUID(&IID_IUnknown, riid) ||
|
||||
IsEqualGUID(&IID_ISequentialStream, riid) ||
|
||||
IsEqualGUID(&IID_IStream, riid)) {
|
||||
@@ -103,13 +108,13 @@ static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface,
|
||||
|
||||
static ULONG WINAPI RpcStream_AddRef(LPSTREAM iface)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
RpcStreamImpl *This = impl_from_IStream(iface);
|
||||
return InterlockedIncrement( &This->RefCount );
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStream_Release(LPSTREAM iface)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
RpcStreamImpl *This = impl_from_IStream(iface);
|
||||
ULONG ref = InterlockedDecrement( &This->RefCount );
|
||||
if (!ref) {
|
||||
TRACE("size=%d\n", *This->size);
|
||||
@@ -125,7 +130,7 @@ static HRESULT WINAPI RpcStream_Read(LPSTREAM iface,
|
||||
ULONG cb,
|
||||
ULONG *pcbRead)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
RpcStreamImpl *This = impl_from_IStream(iface);
|
||||
HRESULT hr = S_OK;
|
||||
if (This->pos + cb > *This->size)
|
||||
{
|
||||
@@ -145,7 +150,7 @@ static HRESULT WINAPI RpcStream_Write(LPSTREAM iface,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
RpcStreamImpl *This = impl_from_IStream(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);
|
||||
@@ -160,7 +165,7 @@ static HRESULT WINAPI RpcStream_Seek(LPSTREAM iface,
|
||||
DWORD origin,
|
||||
ULARGE_INTEGER *newPos)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
RpcStreamImpl *This = impl_from_IStream(iface);
|
||||
switch (origin) {
|
||||
case STREAM_SEEK_SET:
|
||||
This->pos = move.u.LowPart;
|
||||
@@ -184,7 +189,7 @@ static HRESULT WINAPI RpcStream_Seek(LPSTREAM iface,
|
||||
static HRESULT WINAPI RpcStream_SetSize(LPSTREAM iface,
|
||||
ULARGE_INTEGER newSize)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
RpcStreamImpl *This = impl_from_IStream(iface);
|
||||
*This->size = newSize.u.LowPart;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -212,7 +217,7 @@ 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->IStream_iface.lpVtbl = &RpcStream_Vtbl;
|
||||
This->RefCount = 1;
|
||||
This->pMsg = pStubMsg;
|
||||
This->size = (LPDWORD)pStubMsg->Buffer;
|
||||
@@ -309,13 +314,12 @@ void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
{
|
||||
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);
|
||||
COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory,
|
||||
pStubMsg->dwDestContext, pStubMsg->pvDestContext,
|
||||
MSHLFLAGS_NORMAL);
|
||||
TRACE("size=%d\n", size);
|
||||
pStubMsg->BufferLength += sizeof(DWORD) + size;
|
||||
}
|
||||
|
||||
+1046
-772
File diff suppressed because it is too large
Load Diff
@@ -85,7 +85,7 @@ typedef struct _NDR_PROC_HEADER_RPC
|
||||
* RPCF_Asynchronous = 0x4000 - [async] MIDL attribute
|
||||
* Reserved = 0x8000
|
||||
*/
|
||||
unsigned long rpc_flags;
|
||||
unsigned int rpc_flags;
|
||||
unsigned short proc_num;
|
||||
unsigned short stack_size;
|
||||
|
||||
@@ -141,31 +141,20 @@ typedef struct _NDR_PARAM_OI_OTHER
|
||||
unsigned short type_offset;
|
||||
} NDR_PARAM_OI_OTHER;
|
||||
|
||||
typedef struct _NDR_PARAM_OIF_BASETYPE
|
||||
typedef struct
|
||||
{
|
||||
PARAM_ATTRIBUTES param_attributes;
|
||||
|
||||
PARAM_ATTRIBUTES attr;
|
||||
/* the offset on the calling stack where the parameter is located */
|
||||
unsigned short stack_offset;
|
||||
|
||||
/* see NDR_PARAM_OI_BASETYPE::type_format_char */
|
||||
unsigned char type_format_char;
|
||||
|
||||
/* always FC_PAD */
|
||||
unsigned char unused;
|
||||
} NDR_PARAM_OIF_BASETYPE;
|
||||
|
||||
typedef struct _NDR_PARAM_OIF_OTHER
|
||||
{
|
||||
PARAM_ATTRIBUTES param_attributes;
|
||||
|
||||
/* see NDR_PARAM_OIF_BASETYPE::stack_offset */
|
||||
unsigned short stack_offset;
|
||||
|
||||
/* offset into the provided type format string where the type for this
|
||||
* parameter starts */
|
||||
unsigned short type_offset;
|
||||
} NDR_PARAM_OIF_OTHER;
|
||||
union
|
||||
{
|
||||
/* see NDR_PARAM_OI_BASETYPE::type_format_char */
|
||||
unsigned char type_format_char;
|
||||
/* offset into the provided type format string where the type for this
|
||||
* parameter starts */
|
||||
unsigned short type_offset;
|
||||
} u;
|
||||
} NDR_PARAM_OIF;
|
||||
|
||||
/* explicit handle description for FC_BIND_PRIMITIVE type */
|
||||
typedef struct _NDR_EHD_PRIMITIVE
|
||||
@@ -236,7 +225,24 @@ typedef struct _NDR_EHD_CONTEXT
|
||||
|
||||
#include "poppack.h"
|
||||
|
||||
void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat, int phase, unsigned char *args,
|
||||
unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc,
|
||||
BOOL ignore_retval);
|
||||
enum stubless_phase
|
||||
{
|
||||
STUBLESS_UNMARSHAL,
|
||||
STUBLESS_INITOUT,
|
||||
STUBLESS_CALLSERVER,
|
||||
STUBLESS_CALCSIZE,
|
||||
STUBLESS_GETBUFFER,
|
||||
STUBLESS_MARSHAL,
|
||||
STUBLESS_FREE
|
||||
};
|
||||
|
||||
LONG_PTR CDECL ndr_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat,
|
||||
void **stack_top, void **fpu_stack ) DECLSPEC_HIDDEN;
|
||||
LONG_PTR CDECL ndr_async_client_call( PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat,
|
||||
void **stack_top ) DECLSPEC_HIDDEN;
|
||||
void client_do_args( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, enum stubless_phase phase,
|
||||
void **fpu_args, unsigned short number_of_params, unsigned char *pRetVal ) DECLSPEC_HIDDEN;
|
||||
PFORMAT_STRING convert_old_args( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
|
||||
unsigned int stack_size, BOOL object_proc,
|
||||
void *buffer, unsigned int size, unsigned int *count ) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply) DECLSPEC_HIDDEN;
|
||||
|
||||
@@ -84,6 +84,15 @@ static RPC_STATUS RpcAssoc_Alloc(LPCSTR Protseq, LPCSTR NetworkAddr,
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
static BOOL compare_networkoptions(LPCWSTR opts1, LPCWSTR opts2)
|
||||
{
|
||||
if ((opts1 == NULL) && (opts2 == NULL))
|
||||
return TRUE;
|
||||
if ((opts1 == NULL) || (opts2 == NULL))
|
||||
return FALSE;
|
||||
return !strcmpW(opts1, opts2);
|
||||
}
|
||||
|
||||
RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr,
|
||||
LPCSTR Endpoint, LPCWSTR NetworkOptions,
|
||||
RpcAssoc **assoc_out)
|
||||
@@ -97,7 +106,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr,
|
||||
if (!strcmp(Protseq, assoc->Protseq) &&
|
||||
!strcmp(NetworkAddr, assoc->NetworkAddr) &&
|
||||
!strcmp(Endpoint, assoc->Endpoint) &&
|
||||
((!assoc->NetworkOptions && !NetworkOptions) || !strcmpW(NetworkOptions, assoc->NetworkOptions)))
|
||||
compare_networkoptions(NetworkOptions, assoc->NetworkOptions))
|
||||
{
|
||||
assoc->refs++;
|
||||
*assoc_out = assoc;
|
||||
@@ -125,7 +134,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr,
|
||||
|
||||
RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr,
|
||||
LPCSTR Endpoint, LPCWSTR NetworkOptions,
|
||||
unsigned long assoc_gid,
|
||||
ULONG assoc_gid,
|
||||
RpcAssoc **assoc_out)
|
||||
{
|
||||
RpcAssoc *assoc;
|
||||
@@ -223,7 +232,7 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection *
|
||||
RPC_MESSAGE msg;
|
||||
RPC_STATUS status;
|
||||
unsigned char *auth_data = NULL;
|
||||
unsigned long auth_length;
|
||||
ULONG auth_length;
|
||||
|
||||
TRACE("sending bind request to server\n");
|
||||
|
||||
@@ -254,18 +263,19 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection *
|
||||
{
|
||||
unsigned short remaining = msg.BufferLength -
|
||||
ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4);
|
||||
RpcResults *results = (RpcResults*)((ULONG_PTR)server_address +
|
||||
ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4));
|
||||
if ((results->num_results == 1) && (remaining >= sizeof(*results)))
|
||||
RpcResultList *results = (RpcResultList*)((ULONG_PTR)server_address +
|
||||
ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4));
|
||||
if ((results->num_results == 1) &&
|
||||
(remaining >= FIELD_OFFSET(RpcResultList, results[results->num_results])))
|
||||
{
|
||||
switch (results->results[0].result)
|
||||
{
|
||||
case RESULT_ACCEPT:
|
||||
/* respond to authorization request */
|
||||
if (auth_length > sizeof(RpcAuthVerifier))
|
||||
status = RPCRT4_AuthorizeConnection(conn,
|
||||
auth_data + sizeof(RpcAuthVerifier),
|
||||
auth_length);
|
||||
status = RPCRT4_ClientConnectionAuth(conn,
|
||||
auth_data + sizeof(RpcAuthVerifier),
|
||||
auth_length);
|
||||
if (status == RPC_S_OK)
|
||||
{
|
||||
conn->assoc_group_id = response_hdr->bind_ack.assoc_gid;
|
||||
@@ -394,6 +404,7 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
NewConnection->assoc = assoc;
|
||||
status = RPCRT4_OpenClientConnection(NewConnection);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
@@ -416,6 +427,7 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
|
||||
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection)
|
||||
{
|
||||
assert(!Connection->server);
|
||||
Connection->async_state = NULL;
|
||||
EnterCriticalSection(&assoc->cs);
|
||||
if (!assoc->assoc_group_id) assoc->assoc_group_id = Connection->assoc_group_id;
|
||||
list_add_head(&assoc->free_connection_pool, &Connection->conn_pool_entry);
|
||||
|
||||
@@ -34,6 +34,7 @@ typedef struct _RpcAssoc
|
||||
|
||||
/* id of this association group */
|
||||
ULONG assoc_group_id;
|
||||
UUID http_uuid;
|
||||
|
||||
CRITICAL_SECTION cs;
|
||||
|
||||
@@ -45,14 +46,14 @@ typedef struct _RpcAssoc
|
||||
struct list context_handle_list; /* protected by cs */
|
||||
} RpcAssoc;
|
||||
|
||||
RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAssoc **assoc);
|
||||
RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, RpcConnection **Connection);
|
||||
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection);
|
||||
ULONG RpcAssoc_Release(RpcAssoc *assoc);
|
||||
RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, unsigned long assoc_gid, RpcAssoc **assoc_out);
|
||||
RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext);
|
||||
RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext);
|
||||
RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine);
|
||||
unsigned int RpcServerAssoc_ReleaseContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, BOOL release_lock);
|
||||
void RpcContextHandle_GetUuid(NDR_SCONTEXT SContext, UUID *uuid);
|
||||
BOOL RpcContextHandle_IsGuardCorrect(NDR_SCONTEXT SContext, void *CtxGuard);
|
||||
RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAssoc **assoc) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, RpcConnection **Connection) DECLSPEC_HIDDEN;
|
||||
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection) DECLSPEC_HIDDEN;
|
||||
ULONG RpcAssoc_Release(RpcAssoc *assoc) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, ULONG assoc_gid, RpcAssoc **assoc_out) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine) DECLSPEC_HIDDEN;
|
||||
unsigned int RpcServerAssoc_ReleaseContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, BOOL release_lock) DECLSPEC_HIDDEN;
|
||||
void RpcContextHandle_GetUuid(NDR_SCONTEXT SContext, UUID *uuid) DECLSPEC_HIDDEN;
|
||||
BOOL RpcContextHandle_IsGuardCorrect(NDR_SCONTEXT SContext, void *CtxGuard) DECLSPEC_HIDDEN;
|
||||
|
||||
@@ -29,11 +29,17 @@
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "rpc_message.h"
|
||||
#include "ndr_stubless.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
#define RPC_ASYNC_SIGNATURE 0x43595341
|
||||
|
||||
static inline BOOL valid_async_handle(PRPC_ASYNC_STATE pAsync)
|
||||
{
|
||||
return pAsync->Signature == RPC_ASYNC_SIGNATURE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcAsyncInitializeHandle [RPCRT4.@]
|
||||
*
|
||||
@@ -104,8 +110,14 @@ RPC_STATUS WINAPI RpcAsyncGetCallStatus(PRPC_ASYNC_STATE pAsync)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcAsyncCompleteCall(PRPC_ASYNC_STATE pAsync, void *Reply)
|
||||
{
|
||||
FIXME("(%p, %p): stub\n", pAsync, Reply);
|
||||
return RPC_S_INVALID_ASYNC_HANDLE;
|
||||
TRACE("(%p, %p)\n", pAsync, Reply);
|
||||
|
||||
if (!valid_async_handle(pAsync))
|
||||
return RPC_S_INVALID_ASYNC_HANDLE;
|
||||
|
||||
/* FIXME: check completed */
|
||||
|
||||
return NdrpCompleteAsyncClientCall(pAsync, Reply);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
@@ -661,11 +661,11 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU
|
||||
return RPC_S_OK;
|
||||
|
||||
fail:
|
||||
if (ObjUuid) RpcStringFreeA((unsigned char**)ObjUuid);
|
||||
if (Protseq) RpcStringFreeA((unsigned char**)Protseq);
|
||||
if (NetworkAddr) RpcStringFreeA((unsigned char**)NetworkAddr);
|
||||
if (Endpoint) RpcStringFreeA((unsigned char**)Endpoint);
|
||||
if (Options) RpcStringFreeA((unsigned char**)Options);
|
||||
if (ObjUuid) RpcStringFreeA(ObjUuid);
|
||||
if (Protseq) RpcStringFreeA(Protseq);
|
||||
if (NetworkAddr) RpcStringFreeA(NetworkAddr);
|
||||
if (Endpoint) RpcStringFreeA(Endpoint);
|
||||
if (Options) RpcStringFreeA(Options);
|
||||
return RPC_S_INVALID_STRING_BINDING;
|
||||
}
|
||||
|
||||
@@ -798,13 +798,10 @@ RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding )
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
unsigned long c;
|
||||
ULONG c;
|
||||
|
||||
TRACE("(%p)\n", BindingVector);
|
||||
for (c=0; c<(*BindingVector)->Count; c++) {
|
||||
status = RpcBindingFree(&(*BindingVector)->BindingH[c]);
|
||||
}
|
||||
for (c=0; c<(*BindingVector)->Count; c++) RpcBindingFree(&(*BindingVector)->BindingH[c]);
|
||||
HeapFree(GetProcessHeap(), 0, *BindingVector);
|
||||
*BindingVector = NULL;
|
||||
return RPC_S_OK;
|
||||
@@ -815,7 +812,7 @@ RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector )
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid )
|
||||
{
|
||||
RpcBinding* bind = (RpcBinding*)Binding;
|
||||
RpcBinding* bind = Binding;
|
||||
|
||||
TRACE("(%p,%p) = %s\n", Binding, ObjectUuid, debugstr_guid(&bind->ObjectUuid));
|
||||
*ObjectUuid = bind->ObjectUuid;
|
||||
@@ -827,7 +824,7 @@ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid )
|
||||
{
|
||||
RpcBinding* bind = (RpcBinding*)Binding;
|
||||
RpcBinding* bind = Binding;
|
||||
|
||||
TRACE("(%p,%s)\n", Binding, debugstr_guid(ObjectUuid));
|
||||
if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING;
|
||||
@@ -859,11 +856,11 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BIND
|
||||
if (ret == RPC_S_OK)
|
||||
ret = RPCRT4_CompleteBindingA(bind, (char*)NetworkAddr, (char*)Endpoint, (char*)Options);
|
||||
|
||||
RpcStringFreeA((unsigned char**)&Options);
|
||||
RpcStringFreeA((unsigned char**)&Endpoint);
|
||||
RpcStringFreeA((unsigned char**)&NetworkAddr);
|
||||
RpcStringFreeA((unsigned char**)&Protseq);
|
||||
RpcStringFreeA((unsigned char**)&ObjectUuid);
|
||||
RpcStringFreeA(&Options);
|
||||
RpcStringFreeA(&Endpoint);
|
||||
RpcStringFreeA(&NetworkAddr);
|
||||
RpcStringFreeA(&Protseq);
|
||||
RpcStringFreeA(&ObjectUuid);
|
||||
|
||||
if (ret == RPC_S_OK)
|
||||
*Binding = (RPC_BINDING_HANDLE)bind;
|
||||
@@ -918,7 +915,7 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BIND
|
||||
RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CSTR *StringBinding )
|
||||
{
|
||||
RPC_STATUS ret;
|
||||
RpcBinding* bind = (RpcBinding*)Binding;
|
||||
RpcBinding* bind = Binding;
|
||||
RPC_CSTR ObjectUuid;
|
||||
|
||||
TRACE("(%p,%p)\n", Binding, StringBinding);
|
||||
@@ -949,7 +946,7 @@ RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, RPC_WS
|
||||
TRACE("(%p,%p)\n", Binding, StringBinding);
|
||||
ret = RpcBindingToStringBindingA(Binding, &str);
|
||||
*StringBinding = RPCRT4_strdupAtoW((char*)str);
|
||||
RpcStringFreeA((unsigned char**)&str);
|
||||
RpcStringFreeA(&str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -972,7 +969,7 @@ RPC_STATUS WINAPI I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding, unsi
|
||||
*/
|
||||
RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn)
|
||||
{
|
||||
RpcBinding* bind = (RpcBinding*)Binding;
|
||||
RpcBinding* bind = Binding;
|
||||
|
||||
TRACE( "(%p,%p): stub\n", Binding, BlockingFn );
|
||||
|
||||
@@ -989,7 +986,7 @@ RPC_STATUS RPC_ENTRY RpcBindingCopy(
|
||||
RPC_BINDING_HANDLE* DestinationBinding)
|
||||
{
|
||||
RpcBinding *DestBinding;
|
||||
RpcBinding *SrcBinding = (RpcBinding*)SourceBinding;
|
||||
RpcBinding *SrcBinding = SourceBinding;
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(%p, %p)\n", SourceBinding, DestinationBinding);
|
||||
@@ -1052,9 +1049,17 @@ RPC_STATUS RPC_ENTRY RpcBindingReset(RPC_BINDING_HANDLE Binding)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle)
|
||||
{
|
||||
FIXME("(%p): stub\n", BindingHandle);
|
||||
ImpersonateSelf(SecurityImpersonation);
|
||||
return RPC_S_OK;
|
||||
RpcBinding *bind;
|
||||
|
||||
TRACE("(%p)\n", BindingHandle);
|
||||
|
||||
if (!BindingHandle) BindingHandle = I_RpcGetCurrentCallHandle();
|
||||
if (!BindingHandle) return RPC_S_INVALID_BINDING;
|
||||
|
||||
bind = BindingHandle;
|
||||
if (bind->FromConn)
|
||||
return rpcrt4_conn_impersonate_client(bind->FromConn);
|
||||
return RPC_S_WRONG_KIND_OF_BINDING;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1077,8 +1082,17 @@ RPC_STATUS WINAPI RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle)
|
||||
{
|
||||
FIXME("(%p): stub\n", BindingHandle);
|
||||
return RPC_S_OK;
|
||||
RpcBinding *bind;
|
||||
|
||||
TRACE("(%p)\n", BindingHandle);
|
||||
|
||||
if (!BindingHandle) BindingHandle = I_RpcGetCurrentCallHandle();
|
||||
if (!BindingHandle) return RPC_S_INVALID_BINDING;
|
||||
|
||||
bind = BindingHandle;
|
||||
if (bind->FromConn)
|
||||
return rpcrt4_conn_revert_to_self(bind->FromConn);
|
||||
return RPC_S_WRONG_KIND_OF_BINDING;
|
||||
}
|
||||
|
||||
static inline BOOL has_nt_auth_identity(ULONG AuthnLevel)
|
||||
@@ -1094,11 +1108,11 @@ static inline BOOL has_nt_auth_identity(ULONG AuthnLevel)
|
||||
}
|
||||
}
|
||||
|
||||
static RPC_STATUS RpcAuthInfo_Create(ULONG AuthnLevel, ULONG AuthnSvc,
|
||||
CredHandle cred, TimeStamp exp,
|
||||
ULONG cbMaxToken,
|
||||
RPC_AUTH_IDENTITY_HANDLE identity,
|
||||
RpcAuthInfo **ret)
|
||||
RPC_STATUS RpcAuthInfo_Create(ULONG AuthnLevel, ULONG AuthnSvc,
|
||||
CredHandle cred, TimeStamp exp,
|
||||
ULONG cbMaxToken,
|
||||
RPC_AUTH_IDENTITY_HANDLE identity,
|
||||
RpcAuthInfo **ret)
|
||||
{
|
||||
RpcAuthInfo *AuthInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo));
|
||||
if (!AuthInfo)
|
||||
@@ -1286,7 +1300,7 @@ static RPC_STATUS RpcQualityOfService_Create(const RPC_SECURITY_QOS *qos_src, BO
|
||||
cred_dst->User = HeapAlloc(GetProcessHeap(), 0, cred_dst->UserLength * sizeof(WCHAR));
|
||||
cred_dst->Password = HeapAlloc(GetProcessHeap(), 0, cred_dst->PasswordLength * sizeof(WCHAR));
|
||||
cred_dst->Domain = HeapAlloc(GetProcessHeap(), 0, cred_dst->DomainLength * sizeof(WCHAR));
|
||||
if (!cred_dst || !cred_dst->Password || !cred_dst->Domain) goto error;
|
||||
if (!cred_dst->Password || !cred_dst->Domain) goto error;
|
||||
MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->User, cred_src->UserLength, cred_dst->User, cred_dst->UserLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->Domain, cred_src->DomainLength, cred_dst->Domain, cred_dst->DomainLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->Password, cred_src->PasswordLength, cred_dst->Password, cred_dst->PasswordLength);
|
||||
@@ -1431,9 +1445,8 @@ BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQuali
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcRevertToSelf(void)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
RevertToSelf();
|
||||
return RPC_S_OK;
|
||||
TRACE("\n");
|
||||
return RpcRevertToSelfEx(NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1453,9 +1466,22 @@ RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR *ServerPrincName,
|
||||
ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc,
|
||||
ULONG RpcQosVersion, RPC_SECURITY_QOS *SecurityQOS )
|
||||
{
|
||||
FIXME("%p %p %p %p %p %p %u %p\n", Binding, ServerPrincName, AuthnLevel,
|
||||
RPC_STATUS status;
|
||||
RPC_WSTR principal;
|
||||
|
||||
TRACE("%p %p %p %p %p %p %u %p\n", Binding, ServerPrincName, AuthnLevel,
|
||||
AuthnSvc, AuthIdentity, AuthzSvc, RpcQosVersion, SecurityQOS);
|
||||
return RPC_S_INVALID_BINDING;
|
||||
|
||||
status = RpcBindingInqAuthInfoExW(Binding, ServerPrincName ? &principal : NULL, AuthnLevel,
|
||||
AuthnSvc, AuthIdentity, AuthzSvc, RpcQosVersion, SecurityQOS);
|
||||
if (status == RPC_S_OK && ServerPrincName)
|
||||
{
|
||||
*ServerPrincName = (RPC_CSTR)RPCRT4_strdupWtoA(principal);
|
||||
RpcStringFreeW(&principal);
|
||||
if (!*ServerPrincName) return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1466,9 +1492,38 @@ RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR *ServerPrincName,
|
||||
ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc,
|
||||
ULONG RpcQosVersion, RPC_SECURITY_QOS *SecurityQOS )
|
||||
{
|
||||
FIXME("%p %p %p %p %p %p %u %p\n", Binding, ServerPrincName, AuthnLevel,
|
||||
RpcBinding *bind = Binding;
|
||||
|
||||
TRACE("%p %p %p %p %p %p %u %p\n", Binding, ServerPrincName, AuthnLevel,
|
||||
AuthnSvc, AuthIdentity, AuthzSvc, RpcQosVersion, SecurityQOS);
|
||||
return RPC_S_INVALID_BINDING;
|
||||
|
||||
if (!bind->AuthInfo) return RPC_S_BINDING_HAS_NO_AUTH;
|
||||
|
||||
if (SecurityQOS)
|
||||
{
|
||||
FIXME("QOS not implemented\n");
|
||||
return RPC_S_INVALID_BINDING;
|
||||
}
|
||||
|
||||
if (ServerPrincName)
|
||||
{
|
||||
if (bind->AuthInfo->server_principal_name)
|
||||
{
|
||||
*ServerPrincName = RPCRT4_strdupW(bind->AuthInfo->server_principal_name);
|
||||
if (!*ServerPrincName) return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
else *ServerPrincName = NULL;
|
||||
}
|
||||
if (AuthnLevel) *AuthnLevel = bind->AuthInfo->AuthnLevel;
|
||||
if (AuthnSvc) *AuthnSvc = bind->AuthInfo->AuthnSvc;
|
||||
if (AuthIdentity) *AuthIdentity = bind->AuthInfo->identity;
|
||||
if (AuthzSvc)
|
||||
{
|
||||
FIXME("authorization service not implemented\n");
|
||||
*AuthzSvc = RPC_C_AUTHZ_NONE;
|
||||
}
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1478,9 +1533,8 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
|
||||
RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding, RPC_CSTR *ServerPrincName, ULONG *AuthnLevel,
|
||||
ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc )
|
||||
{
|
||||
FIXME("%p %p %p %p %p %p\n", Binding, ServerPrincName, AuthnLevel,
|
||||
AuthnSvc, AuthIdentity, AuthzSvc);
|
||||
return RPC_S_INVALID_BINDING;
|
||||
return RpcBindingInqAuthInfoExA(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity,
|
||||
AuthzSvc, 0, NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1490,9 +1544,78 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
|
||||
RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR *ServerPrincName, ULONG *AuthnLevel,
|
||||
ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc )
|
||||
{
|
||||
FIXME("%p %p %p %p %p %p\n", Binding, ServerPrincName, AuthnLevel,
|
||||
AuthnSvc, AuthIdentity, AuthzSvc);
|
||||
return RPC_S_INVALID_BINDING;
|
||||
return RpcBindingInqAuthInfoExW(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity,
|
||||
AuthzSvc, 0, NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcBindingInqAuthClientA (RPCRT4.@)
|
||||
*/
|
||||
RPCRTAPI RPC_STATUS RPC_ENTRY
|
||||
RpcBindingInqAuthClientA( RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE *Privs,
|
||||
RPC_CSTR *ServerPrincName, ULONG *AuthnLevel, ULONG *AuthnSvc,
|
||||
ULONG *AuthzSvc )
|
||||
{
|
||||
return RpcBindingInqAuthClientExA(ClientBinding, Privs, ServerPrincName, AuthnLevel,
|
||||
AuthnSvc, AuthzSvc, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcBindingInqAuthClientW (RPCRT4.@)
|
||||
*/
|
||||
RPCRTAPI RPC_STATUS RPC_ENTRY
|
||||
RpcBindingInqAuthClientW( RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE *Privs,
|
||||
RPC_WSTR *ServerPrincName, ULONG *AuthnLevel, ULONG *AuthnSvc,
|
||||
ULONG *AuthzSvc )
|
||||
{
|
||||
return RpcBindingInqAuthClientExW(ClientBinding, Privs, ServerPrincName, AuthnLevel,
|
||||
AuthnSvc, AuthzSvc, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcBindingInqAuthClientExA (RPCRT4.@)
|
||||
*/
|
||||
RPCRTAPI RPC_STATUS RPC_ENTRY
|
||||
RpcBindingInqAuthClientExA( RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE *Privs,
|
||||
RPC_CSTR *ServerPrincName, ULONG *AuthnLevel, ULONG *AuthnSvc,
|
||||
ULONG *AuthzSvc, ULONG Flags )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
RPC_WSTR principal;
|
||||
|
||||
TRACE("%p %p %p %p %p %p 0x%x\n", ClientBinding, Privs, ServerPrincName, AuthnLevel,
|
||||
AuthnSvc, AuthzSvc, Flags);
|
||||
|
||||
status = RpcBindingInqAuthClientExW(ClientBinding, Privs, ServerPrincName ? &principal : NULL,
|
||||
AuthnLevel, AuthnSvc, AuthzSvc, Flags);
|
||||
if (status == RPC_S_OK && ServerPrincName)
|
||||
{
|
||||
*ServerPrincName = (RPC_CSTR)RPCRT4_strdupWtoA(principal);
|
||||
if (!*ServerPrincName && principal) status = ERROR_OUTOFMEMORY;
|
||||
RpcStringFreeW(&principal);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcBindingInqAuthClientExW (RPCRT4.@)
|
||||
*/
|
||||
RPCRTAPI RPC_STATUS RPC_ENTRY
|
||||
RpcBindingInqAuthClientExW( RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE *Privs,
|
||||
RPC_WSTR *ServerPrincName, ULONG *AuthnLevel, ULONG *AuthnSvc,
|
||||
ULONG *AuthzSvc, ULONG Flags )
|
||||
{
|
||||
RpcBinding *bind = ClientBinding;
|
||||
|
||||
TRACE("%p %p %p %p %p %p 0x%x\n", ClientBinding, Privs, ServerPrincName, AuthnLevel,
|
||||
AuthnSvc, AuthzSvc, Flags);
|
||||
|
||||
if (!bind->FromConn) return RPC_S_INVALID_BINDING;
|
||||
|
||||
return rpcrt4_conn_inquire_auth_client(bind->FromConn, Privs,
|
||||
ServerPrincName, AuthnLevel,
|
||||
AuthnSvc, AuthzSvc, Flags);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1504,7 +1627,7 @@ RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName,
|
||||
RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr,
|
||||
RPC_SECURITY_QOS *SecurityQos )
|
||||
{
|
||||
RpcBinding* bind = (RpcBinding*)Binding;
|
||||
RpcBinding* bind = Binding;
|
||||
SECURITY_STATUS r;
|
||||
CredHandle cred;
|
||||
TimeStamp exp;
|
||||
@@ -1634,7 +1757,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName,
|
||||
ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr,
|
||||
RPC_SECURITY_QOS *SecurityQos )
|
||||
{
|
||||
RpcBinding* bind = (RpcBinding*)Binding;
|
||||
RpcBinding* bind = Binding;
|
||||
SECURITY_STATUS r;
|
||||
CredHandle cred;
|
||||
TimeStamp exp;
|
||||
@@ -1643,7 +1766,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName,
|
||||
PSecPkgInfoW packages;
|
||||
ULONG cbMaxToken;
|
||||
|
||||
TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w((const WCHAR*)ServerPrincName),
|
||||
TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w(ServerPrincName),
|
||||
AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos);
|
||||
|
||||
if (SecurityQos)
|
||||
@@ -1775,7 +1898,7 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
|
||||
RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnLevel,
|
||||
ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr )
|
||||
{
|
||||
TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w((const WCHAR*)ServerPrincName),
|
||||
TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w(ServerPrincName),
|
||||
AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr);
|
||||
return RpcBindingSetAuthInfoExW(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, NULL);
|
||||
}
|
||||
|
||||
@@ -24,8 +24,15 @@
|
||||
#include "rpcndr.h"
|
||||
#include "security.h"
|
||||
#include "wine/list.h"
|
||||
#include "rpc_defs.h"
|
||||
|
||||
|
||||
enum secure_packet_direction
|
||||
{
|
||||
SECURE_PACKET_SEND,
|
||||
SECURE_PACKET_RECEIVE
|
||||
};
|
||||
|
||||
typedef struct _RpcAuthInfo
|
||||
{
|
||||
LONG refs;
|
||||
@@ -66,6 +73,7 @@ typedef struct _RpcConnection
|
||||
TimeStamp exp;
|
||||
ULONG attr;
|
||||
RpcAuthInfo *AuthInfo;
|
||||
ULONG auth_context_id;
|
||||
ULONG encryption_auth_len;
|
||||
ULONG signature_auth_len;
|
||||
RpcQualityOfService *QOS;
|
||||
@@ -74,6 +82,7 @@ typedef struct _RpcConnection
|
||||
struct list conn_pool_entry;
|
||||
ULONG assoc_group_id; /* association group returned during binding */
|
||||
RPC_ASYNC_STATE *async_state;
|
||||
struct _RpcAssoc *assoc; /* association this connection is part of */
|
||||
|
||||
/* server-only */
|
||||
/* The active interface bound to server. */
|
||||
@@ -96,6 +105,13 @@ struct connection_ops {
|
||||
int (*wait_for_incoming_data)(RpcConnection *conn);
|
||||
size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint);
|
||||
RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint);
|
||||
RPC_STATUS (*receive_fragment)(RpcConnection *conn, RpcPktHdr **Header, void **Payload);
|
||||
BOOL (*is_authorized)(RpcConnection *conn);
|
||||
RPC_STATUS (*authorize)(RpcConnection *conn, BOOL first_time, unsigned char *in_buffer, unsigned int in_len, unsigned char *out_buffer, unsigned int *out_len);
|
||||
RPC_STATUS (*secure_packet)(RpcConnection *Connection, enum secure_packet_direction dir, RpcPktHdr *hdr, unsigned int hdr_size, unsigned char *stub_data, unsigned int stub_data_size, RpcAuthVerifier *auth_hdr, unsigned char *auth_value, unsigned int auth_value_size);
|
||||
RPC_STATUS (*impersonate_client)(RpcConnection *conn);
|
||||
RPC_STATUS (*revert_to_self)(RpcConnection *conn);
|
||||
RPC_STATUS (*inquire_auth_client)(RpcConnection *, RPC_AUTHZ_HANDLE *, RPC_WSTR *, ULONG *, ULONG *, ULONG *, ULONG);
|
||||
};
|
||||
|
||||
/* don't know what MS's structure looks like */
|
||||
@@ -119,35 +135,36 @@ typedef struct _RpcBinding
|
||||
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);
|
||||
LPSTR RPCRT4_strndupA(LPCSTR src, INT len) DECLSPEC_HIDDEN;
|
||||
LPWSTR RPCRT4_strndupW(LPCWSTR src, INT len) DECLSPEC_HIDDEN;
|
||||
LPSTR RPCRT4_strdupWtoA(LPCWSTR src) DECLSPEC_HIDDEN;
|
||||
LPWSTR RPCRT4_strdupAtoW(LPCSTR src) DECLSPEC_HIDDEN;
|
||||
void RPCRT4_strfree(LPSTR src) DECLSPEC_HIDDEN;
|
||||
|
||||
#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 RpcAuthInfo_Create(ULONG AuthnLevel, ULONG AuthnSvc, CredHandle cred, TimeStamp exp, ULONG cbMaxToken, RPC_AUTH_IDENTITY_HANDLE identity, RpcAuthInfo **ret) DECLSPEC_HIDDEN;
|
||||
ULONG RpcAuthInfo_AddRef(RpcAuthInfo *AuthInfo) DECLSPEC_HIDDEN;
|
||||
ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo) DECLSPEC_HIDDEN;
|
||||
BOOL RpcAuthInfo_IsEqual(const RpcAuthInfo *AuthInfo1, const RpcAuthInfo *AuthInfo2) DECLSPEC_HIDDEN;
|
||||
ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos) DECLSPEC_HIDDEN;
|
||||
ULONG RpcQualityOfService_Release(RpcQualityOfService *qos) DECLSPEC_HIDDEN;
|
||||
BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQualityOfService *qos2) DECLSPEC_HIDDEN;
|
||||
|
||||
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_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_OpenClientConnection(RpcConnection* Connection) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection) DECLSPEC_HIDDEN;
|
||||
|
||||
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);
|
||||
void RPCRT4_AddRefBinding(RpcBinding* Binding);
|
||||
RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding);
|
||||
RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection) DECLSPEC_HIDDEN;
|
||||
void RPCRT4_AddRefBinding(RpcBinding* Binding) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding) DECLSPEC_HIDDEN;
|
||||
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);
|
||||
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection)
|
||||
{
|
||||
@@ -181,15 +198,55 @@ static inline RPC_STATUS rpcrt4_conn_handoff(RpcConnection *old_conn, RpcConnect
|
||||
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);
|
||||
static inline BOOL rpcrt4_conn_is_authorized(RpcConnection *Connection)
|
||||
{
|
||||
return Connection->ops->is_authorized(Connection);
|
||||
}
|
||||
|
||||
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);
|
||||
static inline RPC_STATUS rpcrt4_conn_authorize(
|
||||
RpcConnection *conn, BOOL first_time, unsigned char *in_buffer,
|
||||
unsigned int in_len, unsigned char *out_buffer, unsigned int *out_len)
|
||||
{
|
||||
return conn->ops->authorize(conn, first_time, in_buffer, in_len, out_buffer, out_len);
|
||||
}
|
||||
|
||||
static inline RPC_STATUS rpcrt4_conn_secure_packet(
|
||||
RpcConnection *conn, enum secure_packet_direction dir,
|
||||
RpcPktHdr *hdr, unsigned int hdr_size, unsigned char *stub_data,
|
||||
unsigned int stub_data_size, RpcAuthVerifier *auth_hdr,
|
||||
unsigned char *auth_value, unsigned int auth_value_size)
|
||||
{
|
||||
return conn->ops->secure_packet(conn, dir, hdr, hdr_size, stub_data, stub_data_size, auth_hdr, auth_value, auth_value_size);
|
||||
}
|
||||
|
||||
static inline RPC_STATUS rpcrt4_conn_impersonate_client(
|
||||
RpcConnection *conn)
|
||||
{
|
||||
return conn->ops->impersonate_client(conn);
|
||||
}
|
||||
|
||||
static inline RPC_STATUS rpcrt4_conn_revert_to_self(
|
||||
RpcConnection *conn)
|
||||
{
|
||||
return conn->ops->revert_to_self(conn);
|
||||
}
|
||||
|
||||
static inline RPC_STATUS rpcrt4_conn_inquire_auth_client(
|
||||
RpcConnection *conn, RPC_AUTHZ_HANDLE *privs, RPC_WSTR *server_princ_name,
|
||||
ULONG *authn_level, ULONG *authn_svc, ULONG *authz_svc, ULONG flags)
|
||||
{
|
||||
return conn->ops->inquire_auth_client(conn, privs, server_princ_name, authn_level, authn_svc, authz_svc, flags);
|
||||
}
|
||||
|
||||
/* 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) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RpcTransport_ParseTopOfTower(const unsigned char *tower_data, size_t tower_size, char **protseq, char **networkaddr, char **endpoint) DECLSPEC_HIDDEN;
|
||||
|
||||
void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection) DECLSPEC_HIDDEN;
|
||||
void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding) DECLSPEC_HIDDEN;
|
||||
RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void) DECLSPEC_HIDDEN;
|
||||
void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext) DECLSPEC_HIDDEN;
|
||||
void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext) DECLSPEC_HIDDEN;
|
||||
NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#ifndef __WINE_RPC_DEFS_H
|
||||
#define __WINE_RPC_DEFS_H
|
||||
|
||||
#include "pshpack1.h"
|
||||
typedef struct
|
||||
{
|
||||
unsigned char rpc_ver; /* RPC major version (5) */
|
||||
@@ -31,13 +32,13 @@ typedef struct
|
||||
unsigned char drep[4]; /* Data representation */
|
||||
unsigned short frag_len; /* Data size in bytes including header and tail. */
|
||||
unsigned short auth_len; /* Authentication length */
|
||||
unsigned long call_id; /* Call identifier. */
|
||||
unsigned int call_id; /* Call identifier. */
|
||||
} RpcPktCommonHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */
|
||||
unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */
|
||||
unsigned short context_id; /* Presentation context identifier */
|
||||
unsigned short opnum;
|
||||
} RpcPktRequestHdr;
|
||||
@@ -45,7 +46,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */
|
||||
unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */
|
||||
unsigned short context_id; /* Presentation context identifier */
|
||||
unsigned char cancel_count;
|
||||
unsigned char reserved;
|
||||
@@ -54,58 +55,68 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */
|
||||
unsigned int 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;
|
||||
unsigned int status; /* Runtime fault code (RPC_STATUS) */
|
||||
unsigned int reserved2;
|
||||
} RpcPktFaultHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short context_id; /* Presentation context identifier */
|
||||
unsigned char num_syntaxes; /* Number of syntaxes */
|
||||
unsigned char reserved; /* For alignment */
|
||||
RPC_SYNTAX_IDENTIFIER abstract_syntax;
|
||||
RPC_SYNTAX_IDENTIFIER transfer_syntaxes[ANYSIZE_ARRAY]; /* size_is(num_syntaxes) */
|
||||
} RpcContextElement;
|
||||
|
||||
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 int 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;
|
||||
/*
|
||||
* Following this header are these fields:
|
||||
* RpcContextElement context_elements[num_elements]
|
||||
*/
|
||||
} 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 */
|
||||
char string[ANYSIZE_ARRAY]; /* String data in single byte, null terminated form */
|
||||
} RpcAddressString;
|
||||
#include "poppack.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short result;
|
||||
unsigned short reason;
|
||||
RPC_SYNTAX_IDENTIFIER transfer_syntax;
|
||||
} RpcResult;
|
||||
|
||||
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;
|
||||
RpcResult results[ANYSIZE_ARRAY]; /* size_is(num_results) */
|
||||
} RpcResultList;
|
||||
|
||||
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 int 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;
|
||||
* RpcResultList results;
|
||||
*/
|
||||
} RpcPktBindAckHdr;
|
||||
|
||||
@@ -117,9 +128,24 @@ typedef struct
|
||||
struct {
|
||||
unsigned char rpc_ver;
|
||||
unsigned char rpc_ver_minor;
|
||||
} protocols[1];
|
||||
} protocols[ANYSIZE_ARRAY];
|
||||
} RpcPktBindNAckHdr;
|
||||
|
||||
/* undocumented packet sent during RPC over HTTP */
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned short flags;
|
||||
unsigned short num_data_items;
|
||||
} RpcPktHttpHdr;
|
||||
|
||||
/* AUTH3 packet */
|
||||
typedef struct
|
||||
{
|
||||
RpcPktCommonHdr common;
|
||||
unsigned int pad; /* ignored */
|
||||
} RpcPktAuth3Hdr;
|
||||
|
||||
/* Union representing all possible packet headers */
|
||||
typedef union
|
||||
{
|
||||
@@ -130,6 +156,8 @@ typedef union
|
||||
RpcPktBindHdr bind;
|
||||
RpcPktBindAckHdr bind_ack;
|
||||
RpcPktBindNAckHdr bind_nack;
|
||||
RpcPktHttpHdr http;
|
||||
RpcPktAuth3Hdr auth3;
|
||||
} RpcPktHdr;
|
||||
|
||||
typedef struct
|
||||
@@ -138,8 +166,9 @@ typedef struct
|
||||
unsigned char auth_level; /* RPC_C_AUTHN_LEVEL* */
|
||||
unsigned char auth_pad_length; /* length of padding to restore n % 4 alignment */
|
||||
unsigned char auth_reserved; /* reserved, must be zero */
|
||||
unsigned long auth_context_id; /* unique value for the authenticated connection */
|
||||
unsigned int auth_context_id; /* unique value for the authenticated connection */
|
||||
} RpcAuthVerifier;
|
||||
#include "poppack.h"
|
||||
|
||||
#define RPC_AUTH_VERIFIER_LEN(common_hdr) \
|
||||
((common_hdr)->auth_len ? (common_hdr)->auth_len + sizeof(RpcAuthVerifier) : 0)
|
||||
@@ -154,26 +183,30 @@ typedef struct
|
||||
#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
|
||||
enum rpc_packet_type
|
||||
{
|
||||
PKT_REQUEST = 0,
|
||||
PKT_PING = 1,
|
||||
PKT_RESPONSE = 2,
|
||||
PKT_FAULT = 3,
|
||||
PKT_WORKING = 4,
|
||||
PKT_NOCALL = 5,
|
||||
PKT_REJECT = 6,
|
||||
PKT_ACK = 7,
|
||||
PKT_CL_CANCEL = 8,
|
||||
PKT_FACK = 9,
|
||||
PKT_CANCEL_ACK = 10,
|
||||
PKT_BIND = 11,
|
||||
PKT_BIND_ACK = 12,
|
||||
PKT_BIND_NACK = 13,
|
||||
PKT_ALTER_CONTEXT = 14,
|
||||
PKT_ALTER_CONTEXT_RESP = 15,
|
||||
PKT_AUTH3 = 16,
|
||||
PKT_SHUTDOWN = 17,
|
||||
PKT_CO_CANCEL = 18,
|
||||
PKT_ORPHANED = 19,
|
||||
PKT_HTTP = 20,
|
||||
};
|
||||
|
||||
#define RESULT_ACCEPT 0
|
||||
#define RESULT_USER_REJECTION 1
|
||||
|
||||
@@ -79,30 +79,21 @@ static BOOL start_rpcss(void)
|
||||
{
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFOW si;
|
||||
static WCHAR cmd[6];
|
||||
static const WCHAR rpcss[] = {'r','p','c','s','s',0};
|
||||
WCHAR cmd[MAX_PATH];
|
||||
static const WCHAR rpcss[] = {'\\','r','p','c','s','s','.','e','x','e',0};
|
||||
BOOL rslt;
|
||||
void *redir;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
|
||||
ZeroMemory(&si, sizeof(STARTUPINFOA));
|
||||
si.cb = sizeof(STARTUPINFOA);
|
||||
GetSystemDirectoryW( cmd, MAX_PATH - sizeof(rpcss)/sizeof(WCHAR) );
|
||||
lstrcatW( cmd, rpcss );
|
||||
|
||||
memcpy(cmd, rpcss, sizeof(rpcss));
|
||||
|
||||
rslt = CreateProcessW(
|
||||
NULL, /* executable */
|
||||
cmd, /* command line */
|
||||
NULL, /* process security attributes */
|
||||
NULL, /* primary thread security attributes */
|
||||
FALSE, /* inherit handles */
|
||||
0, /* creation flags */
|
||||
NULL, /* use parent's environment */
|
||||
NULL, /* use parent's current directory */
|
||||
&si, /* STARTUPINFO pointer */
|
||||
&pi /* PROCESS_INFORMATION */
|
||||
);
|
||||
Wow64DisableWow64FsRedirection( &redir );
|
||||
rslt = CreateProcessW( cmd, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
|
||||
Wow64RevertWow64FsRedirection( redir );
|
||||
|
||||
if (rslt)
|
||||
{
|
||||
@@ -116,18 +107,18 @@ static BOOL start_rpcss(void)
|
||||
|
||||
static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle)
|
||||
{
|
||||
RpcBinding *bind = (RpcBinding *)handle;
|
||||
RpcBinding *bind = handle;
|
||||
const char *protseq = bind->Protseq;
|
||||
const char *network_addr = bind->NetworkAddr;
|
||||
|
||||
return ((!strcmp(protseq, "ncalrpc") && !network_addr) ||
|
||||
(!strcmp(protseq, "ncacn_np") &&
|
||||
return (!strcmp(protseq, "ncalrpc") ||
|
||||
(!strcmp(protseq, "ncacn_np") &&
|
||||
(!network_addr || !strcmp(network_addr, "."))));
|
||||
}
|
||||
|
||||
static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_HANDLE *epm_handle)
|
||||
{
|
||||
RpcBinding *bind = (RpcBinding *)handle;
|
||||
RpcBinding *bind = handle;
|
||||
const char * pszEndpoint = NULL;
|
||||
RPC_STATUS status;
|
||||
RpcBinding* epm_bind;
|
||||
@@ -149,7 +140,7 @@ static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_H
|
||||
status = RpcBindingCopy(handle, epm_handle);
|
||||
if (status != RPC_S_OK) return status;
|
||||
|
||||
epm_bind = (RpcBinding*)*epm_handle;
|
||||
epm_bind = *epm_handle;
|
||||
if (epm_bind->AuthInfo)
|
||||
{
|
||||
/* don't bother with authenticating against the EPM by default
|
||||
@@ -187,8 +178,8 @@ static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *__eptr)
|
||||
RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
||||
UUID_VECTOR *UuidVector, RPC_CSTR Annotation )
|
||||
{
|
||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||
unsigned long i;
|
||||
PRPC_SERVER_INTERFACE If = IfSpec;
|
||||
ULONG i;
|
||||
RPC_STATUS status = RPC_S_OK;
|
||||
error_status_t status2;
|
||||
ept_entry_t *entries;
|
||||
@@ -197,13 +188,13 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
|
||||
TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation));
|
||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||
for (i=0; i<BindingVector->Count; i++) {
|
||||
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
|
||||
TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq));
|
||||
TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint));
|
||||
RpcBinding* bind = BindingVector->BindingH[i];
|
||||
TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq));
|
||||
TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint));
|
||||
}
|
||||
if (UuidVector) {
|
||||
for (i=0; i<UuidVector->Count; i++)
|
||||
TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
|
||||
TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
|
||||
}
|
||||
|
||||
if (!BindingVector->Count) return RPC_S_OK;
|
||||
@@ -222,10 +213,9 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
|
||||
for (i = 0; i < BindingVector->Count; i++)
|
||||
{
|
||||
unsigned j;
|
||||
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
|
||||
RpcBinding* bind = BindingVector->BindingH[i];
|
||||
for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++)
|
||||
{
|
||||
int len = strlen((char *)Annotation);
|
||||
status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax,
|
||||
bind->Protseq, bind->Endpoint,
|
||||
bind->NetworkAddr,
|
||||
@@ -236,7 +226,9 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
|
||||
memcpy(&entries[i * UuidVector->Count].object, &UuidVector->Uuid[j], sizeof(GUID));
|
||||
else
|
||||
memset(&entries[i].object, 0, sizeof(entries[i].object));
|
||||
memcpy(entries[i].annotation, Annotation, min(len + 1, ept_max_annotation_size));
|
||||
if (Annotation)
|
||||
memcpy(entries[i].annotation, Annotation,
|
||||
min(strlen((char *)Annotation) + 1, ept_max_annotation_size));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,14 +272,29 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcEpRegisterW (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcEpRegisterW( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
||||
UUID_VECTOR *UuidVector, RPC_WSTR Annotation )
|
||||
{
|
||||
LPSTR annA = RPCRT4_strdupWtoA(Annotation);
|
||||
RPC_STATUS status;
|
||||
|
||||
status = RpcEpRegisterA(IfSpec, BindingVector, UuidVector, (RPC_CSTR)annA);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, annA);
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcEpUnregister (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
||||
UUID_VECTOR *UuidVector )
|
||||
{
|
||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||
unsigned long i;
|
||||
PRPC_SERVER_INTERFACE If = IfSpec;
|
||||
ULONG i;
|
||||
RPC_STATUS status = RPC_S_OK;
|
||||
error_status_t status2;
|
||||
ept_entry_t *entries;
|
||||
@@ -296,13 +303,13 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
|
||||
TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector);
|
||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||
for (i=0; i<BindingVector->Count; i++) {
|
||||
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
|
||||
TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq));
|
||||
TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint));
|
||||
RpcBinding* bind = BindingVector->BindingH[i];
|
||||
TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq));
|
||||
TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint));
|
||||
}
|
||||
if (UuidVector) {
|
||||
for (i=0; i<UuidVector->Count; i++)
|
||||
TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
|
||||
TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
|
||||
}
|
||||
|
||||
entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*entries) * BindingVector->Count * (UuidVector ? UuidVector->Count : 1));
|
||||
@@ -319,7 +326,7 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
|
||||
for (i = 0; i < BindingVector->Count; i++)
|
||||
{
|
||||
unsigned j;
|
||||
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
|
||||
RpcBinding* bind = BindingVector->BindingH[i];
|
||||
for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++)
|
||||
{
|
||||
status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax,
|
||||
@@ -372,8 +379,8 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec )
|
||||
{
|
||||
PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec;
|
||||
RpcBinding* bind = (RpcBinding*)Binding;
|
||||
PRPC_CLIENT_INTERFACE If = IfSpec;
|
||||
RpcBinding* bind = Binding;
|
||||
RPC_STATUS status;
|
||||
error_status_t status2;
|
||||
handle_t handle;
|
||||
@@ -396,7 +403,7 @@ RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE
|
||||
|
||||
status = get_epm_handle_client(Binding, &handle);
|
||||
if (status != RPC_S_OK) return status;
|
||||
|
||||
|
||||
status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax, bind->Protseq,
|
||||
((RpcBinding *)handle)->Endpoint,
|
||||
bind->NetworkAddr, &tower);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,16 +25,35 @@
|
||||
|
||||
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);
|
||||
RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, unsigned long *auth_length_out);
|
||||
NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status);
|
||||
RPC_STATUS RPCRT4_AuthorizeConnection(RpcConnection* conn, BYTE *challenge, ULONG count);
|
||||
RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status) DECLSPEC_HIDDEN;
|
||||
RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength) DECLSPEC_HIDDEN;
|
||||
RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId) DECLSPEC_HIDDEN;
|
||||
RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor, unsigned short RejectReason) DECLSPEC_HIDDEN;
|
||||
RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, LPCSTR ServerAddress, unsigned char ResultCount, const RpcResult *Results) DECLSPEC_HIDDEN;
|
||||
RpcPktHdr *RPCRT4_BuildHttpHeader(ULONG DataRepresentation, unsigned short flags, unsigned short num_data_items, unsigned int payload_size) DECLSPEC_HIDDEN;
|
||||
RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe, const UUID *connection_uuid, const UUID *pipe_uuid, const UUID *association_uuid) DECLSPEC_HIDDEN;
|
||||
RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted, ULONG flow_control_increment, const UUID *pipe_uuid) DECLSPEC_HIDDEN;
|
||||
VOID RPCRT4_FreeHeader(RpcPktHdr *Header) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_SendWithAuth(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength, const void *Auth, unsigned int AuthLength) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, ULONG *auth_length_out) DECLSPEC_HIDDEN;
|
||||
DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) DECLSPEC_HIDDEN;
|
||||
|
||||
BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, unsigned short data_len) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, unsigned char *data, ULONG *field1) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, unsigned char *data, ULONG *field1, ULONG *bytes_until_next_packet, ULONG *field3) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, unsigned char *data, BOOL server, ULONG *bytes_transmitted, ULONG *flow_control_increment, UUID *pipe_uuid) DECLSPEC_HIDDEN;
|
||||
NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_ClientConnectionAuth(RpcConnection* conn, BYTE *challenge, ULONG count) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_ServerConnectionAuth(RpcConnection* conn, BOOL start, RpcAuthVerifier *auth_data_in, ULONG auth_length_in, unsigned char **auth_data_out, ULONG *auth_length_out) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_AuthorizeConnection(RpcConnection* conn, BYTE *challenge, ULONG count) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_ServerGetRegisteredAuthInfo(USHORT auth_type, CredHandle *cred, TimeStamp *exp, ULONG *max_token) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_default_authorize(RpcConnection *conn, BOOL first_time, unsigned char *in_buffer, unsigned int in_size, unsigned char *out_buffer, unsigned int *out_size) DECLSPEC_HIDDEN;
|
||||
BOOL RPCRT4_default_is_authorized(RpcConnection *Connection) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_default_secure_packet(RpcConnection *Connection, enum secure_packet_direction dir, RpcPktHdr *hdr, unsigned int hdr_size, unsigned char *stub_data, unsigned int stub_data_size, RpcAuthVerifier *auth_hdr, unsigned char *auth_value, unsigned int auth_value_size) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_default_impersonate_client(RpcConnection *conn) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_default_revert_to_self(RpcConnection *conn) DECLSPEC_HIDDEN;
|
||||
RPC_STATUS RPCRT4_default_inquire_auth_client(RpcConnection *conn, RPC_AUTHZ_HANDLE *privs, RPC_WSTR *server_princ_name, ULONG *authn_level, ULONG *authn_svc, ULONG *authz_svc, ULONG flags) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -52,6 +52,8 @@ typedef struct _RpcPacket
|
||||
struct _RpcConnection* conn;
|
||||
RpcPktHdr* hdr;
|
||||
RPC_MESSAGE* msg;
|
||||
unsigned char *auth_data;
|
||||
ULONG auth_length;
|
||||
} RpcPacket;
|
||||
|
||||
typedef struct _RpcObjTypeMap
|
||||
@@ -67,6 +69,7 @@ static RpcObjTypeMap *RpcObjTypeMaps;
|
||||
/* list of type RpcServerProtseq */
|
||||
static struct list protseqs = LIST_INIT(protseqs);
|
||||
static struct list server_interfaces = LIST_INIT(server_interfaces);
|
||||
static struct list server_registered_auth_info = LIST_INIT(server_registered_auth_info);
|
||||
|
||||
static CRITICAL_SECTION server_cs;
|
||||
static CRITICAL_SECTION_DEBUG server_cs_debug =
|
||||
@@ -86,12 +89,23 @@ static CRITICAL_SECTION_DEBUG listen_cs_debug =
|
||||
};
|
||||
static CRITICAL_SECTION listen_cs = { &listen_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
static CRITICAL_SECTION server_auth_info_cs;
|
||||
static CRITICAL_SECTION_DEBUG server_auth_info_cs_debug =
|
||||
{
|
||||
0, 0, &server_auth_info_cs,
|
||||
{ &server_auth_info_cs_debug.ProcessLocksList, &server_auth_info_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": server_auth_info_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION server_auth_info_cs = { &server_auth_info_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
/* whether the server is currently listening */
|
||||
static BOOL std_listen;
|
||||
/* number of manual listeners (calls to RpcServerListen) */
|
||||
static LONG manual_listen_count;
|
||||
/* total listeners including auto listeners */
|
||||
static LONG listen_count;
|
||||
/* event set once all listening is finished */
|
||||
static HANDLE listen_done_event;
|
||||
|
||||
static UUID uuid_nil;
|
||||
|
||||
@@ -118,7 +132,8 @@ static inline UUID *LookupObjType(UUID *ObjUuid)
|
||||
}
|
||||
|
||||
static RpcServerInterface* RPCRT4_find_interface(UUID* object,
|
||||
const RPC_SYNTAX_IDENTIFIER* if_id,
|
||||
const RPC_SYNTAX_IDENTIFIER *if_id,
|
||||
const RPC_SYNTAX_IDENTIFIER *transfer_syntax,
|
||||
BOOL check_object)
|
||||
{
|
||||
UUID* MgrType = NULL;
|
||||
@@ -130,6 +145,7 @@ static RpcServerInterface* RPCRT4_find_interface(UUID* object,
|
||||
EnterCriticalSection(&server_cs);
|
||||
LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) {
|
||||
if (!memcmp(if_id, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)) &&
|
||||
(!transfer_syntax || !memcmp(transfer_syntax, &cif->If->TransferSyntax, sizeof(RPC_SYNTAX_IDENTIFIER))) &&
|
||||
(check_object == FALSE || UuidEqual(MgrType, &cif->MgrTypeUuid, &status)) &&
|
||||
std_listen) {
|
||||
InterlockedIncrement(&cif->CurrentCalls);
|
||||
@@ -156,64 +172,197 @@ static void RPCRT4_release_server_interface(RpcServerInterface *sif)
|
||||
}
|
||||
}
|
||||
|
||||
static RPC_STATUS process_bind_packet(RpcConnection *conn, RpcPktBindHdr *hdr, RPC_MESSAGE *msg)
|
||||
static RpcPktHdr *handle_bind_error(RpcConnection *conn, RPC_STATUS error)
|
||||
{
|
||||
unsigned int reject_reason;
|
||||
switch (error)
|
||||
{
|
||||
case RPC_S_SERVER_TOO_BUSY:
|
||||
reject_reason = REJECT_TEMPORARY_CONGESTION;
|
||||
break;
|
||||
case ERROR_OUTOFMEMORY:
|
||||
case RPC_S_OUT_OF_RESOURCES:
|
||||
reject_reason = REJECT_LOCAL_LIMIT_EXCEEDED;
|
||||
break;
|
||||
case RPC_S_PROTOCOL_ERROR:
|
||||
reject_reason = REJECT_PROTOCOL_VERSION_NOT_SUPPORTED;
|
||||
break;
|
||||
case RPC_S_UNKNOWN_AUTHN_SERVICE:
|
||||
reject_reason = REJECT_UNKNOWN_AUTHN_SERVICE;
|
||||
break;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
reject_reason = REJECT_INVALID_CHECKSUM;
|
||||
break;
|
||||
default:
|
||||
FIXME("unexpected status value %d\n", error);
|
||||
/* fall through */
|
||||
case RPC_S_INVALID_BOUND:
|
||||
reject_reason = REJECT_REASON_NOT_SPECIFIED;
|
||||
break;
|
||||
}
|
||||
return RPCRT4_BuildBindNackHeader(NDR_LOCAL_DATA_REPRESENTATION,
|
||||
RPC_VER_MAJOR, RPC_VER_MINOR,
|
||||
reject_reason);
|
||||
}
|
||||
|
||||
static RPC_STATUS process_bind_packet_no_send(
|
||||
RpcConnection *conn, RpcPktBindHdr *hdr, RPC_MESSAGE *msg,
|
||||
unsigned char *auth_data, ULONG auth_length, RpcPktHdr **ack_response,
|
||||
unsigned char **auth_data_out, ULONG *auth_length_out)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
RpcServerInterface* sif;
|
||||
RpcPktHdr *response = NULL;
|
||||
RpcContextElement *ctxt_elem;
|
||||
unsigned int i;
|
||||
RpcResult *results;
|
||||
|
||||
/* validate data */
|
||||
for (i = 0, ctxt_elem = msg->Buffer;
|
||||
i < hdr->num_elements;
|
||||
i++, ctxt_elem = (RpcContextElement *)&ctxt_elem->transfer_syntaxes[ctxt_elem->num_syntaxes])
|
||||
{
|
||||
if (((char *)ctxt_elem - (char *)msg->Buffer) > msg->BufferLength ||
|
||||
((char *)&ctxt_elem->transfer_syntaxes[ctxt_elem->num_syntaxes] - (char *)msg->Buffer) > msg->BufferLength)
|
||||
{
|
||||
ERR("inconsistent data in packet - packet length %d, num elements %d\n",
|
||||
msg->BufferLength, hdr->num_elements);
|
||||
return RPC_S_INVALID_BOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: do more checks! */
|
||||
if (hdr->max_tsize < RPC_MIN_PACKET_SIZE ||
|
||||
!UuidIsNil(&conn->ActiveInterface.SyntaxGUID, &status) ||
|
||||
conn->server_binding) {
|
||||
conn->server_binding)
|
||||
{
|
||||
TRACE("packet size less than min size, or active interface syntax guid non-null\n");
|
||||
sif = NULL;
|
||||
} else {
|
||||
/* create temporary binding */
|
||||
if (RPCRT4_MakeBinding(&conn->server_binding, conn) == RPC_S_OK &&
|
||||
RpcServerAssoc_GetAssociation(rpcrt4_conn_get_name(conn),
|
||||
conn->NetworkAddr, conn->Endpoint,
|
||||
conn->NetworkOptions,
|
||||
hdr->assoc_gid,
|
||||
&conn->server_binding->Assoc) == RPC_S_OK)
|
||||
sif = RPCRT4_find_interface(NULL, &hdr->abstract, FALSE);
|
||||
else
|
||||
sif = NULL;
|
||||
}
|
||||
if (sif == NULL) {
|
||||
TRACE("rejecting bind request on connection %p\n", conn);
|
||||
/* Report failure to client. */
|
||||
response = RPCRT4_BuildBindNackHeader(NDR_LOCAL_DATA_REPRESENTATION,
|
||||
RPC_VER_MAJOR, RPC_VER_MINOR);
|
||||
} else {
|
||||
TRACE("accepting bind request on connection %p for %s\n", conn,
|
||||
debugstr_guid(&hdr->abstract.SyntaxGUID));
|
||||
|
||||
/* accept. */
|
||||
response = RPCRT4_BuildBindAckHeader(NDR_LOCAL_DATA_REPRESENTATION,
|
||||
RPC_MAX_PACKET_SIZE,
|
||||
RPC_MAX_PACKET_SIZE,
|
||||
conn->server_binding->Assoc->assoc_group_id,
|
||||
conn->Endpoint,
|
||||
RESULT_ACCEPT, REASON_NONE,
|
||||
&sif->If->TransferSyntax);
|
||||
|
||||
/* save the interface for later use */
|
||||
conn->ActiveInterface = hdr->abstract;
|
||||
conn->MaxTransmissionSize = hdr->max_tsize;
|
||||
|
||||
RPCRT4_release_server_interface(sif);
|
||||
return RPC_S_INVALID_BOUND;
|
||||
}
|
||||
|
||||
if (response)
|
||||
status = RPCRT4_Send(conn, response, NULL, 0);
|
||||
results = HeapAlloc(GetProcessHeap(), 0,
|
||||
hdr->num_elements * sizeof(*results));
|
||||
if (!results)
|
||||
return RPC_S_OUT_OF_RESOURCES;
|
||||
|
||||
for (i = 0, ctxt_elem = (RpcContextElement *)msg->Buffer;
|
||||
i < hdr->num_elements;
|
||||
i++, ctxt_elem = (RpcContextElement *)&ctxt_elem->transfer_syntaxes[ctxt_elem->num_syntaxes])
|
||||
{
|
||||
RpcServerInterface* sif = NULL;
|
||||
unsigned int j;
|
||||
|
||||
for (j = 0; !sif && j < ctxt_elem->num_syntaxes; j++)
|
||||
{
|
||||
sif = RPCRT4_find_interface(NULL, &ctxt_elem->abstract_syntax,
|
||||
&ctxt_elem->transfer_syntaxes[j], FALSE);
|
||||
if (sif)
|
||||
break;
|
||||
}
|
||||
if (sif)
|
||||
{
|
||||
RPCRT4_release_server_interface(sif);
|
||||
TRACE("accepting bind request on connection %p for %s\n", conn,
|
||||
debugstr_guid(&ctxt_elem->abstract_syntax.SyntaxGUID));
|
||||
results[i].result = RESULT_ACCEPT;
|
||||
results[i].reason = REASON_NONE;
|
||||
results[i].transfer_syntax = ctxt_elem->transfer_syntaxes[j];
|
||||
|
||||
/* save the interface for later use */
|
||||
/* FIXME: save linked list */
|
||||
conn->ActiveInterface = ctxt_elem->abstract_syntax;
|
||||
}
|
||||
else if ((sif = RPCRT4_find_interface(NULL, &ctxt_elem->abstract_syntax,
|
||||
NULL, FALSE)) != NULL)
|
||||
{
|
||||
RPCRT4_release_server_interface(sif);
|
||||
TRACE("not accepting bind request on connection %p for %s - no transfer syntaxes supported\n",
|
||||
conn, debugstr_guid(&ctxt_elem->abstract_syntax.SyntaxGUID));
|
||||
results[i].result = RESULT_PROVIDER_REJECTION;
|
||||
results[i].reason = REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
|
||||
memset(&results[i].transfer_syntax, 0, sizeof(results[i].transfer_syntax));
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("not accepting bind request on connection %p for %s - abstract syntax not supported\n",
|
||||
conn, debugstr_guid(&ctxt_elem->abstract_syntax.SyntaxGUID));
|
||||
results[i].result = RESULT_PROVIDER_REJECTION;
|
||||
results[i].reason = REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
|
||||
memset(&results[i].transfer_syntax, 0, sizeof(results[i].transfer_syntax));
|
||||
}
|
||||
}
|
||||
|
||||
/* create temporary binding */
|
||||
status = RPCRT4_MakeBinding(&conn->server_binding, conn);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, results);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = RpcServerAssoc_GetAssociation(rpcrt4_conn_get_name(conn),
|
||||
conn->NetworkAddr, conn->Endpoint,
|
||||
conn->NetworkOptions,
|
||||
hdr->assoc_gid,
|
||||
&conn->server_binding->Assoc);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, results);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (auth_length)
|
||||
{
|
||||
status = RPCRT4_ServerConnectionAuth(conn, TRUE,
|
||||
(RpcAuthVerifier *)auth_data,
|
||||
auth_length, auth_data_out,
|
||||
auth_length_out);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, results);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
*ack_response = RPCRT4_BuildBindAckHeader(NDR_LOCAL_DATA_REPRESENTATION,
|
||||
RPC_MAX_PACKET_SIZE,
|
||||
RPC_MAX_PACKET_SIZE,
|
||||
conn->server_binding->Assoc->assoc_group_id,
|
||||
conn->Endpoint, hdr->num_elements,
|
||||
results);
|
||||
HeapFree(GetProcessHeap(), 0, results);
|
||||
|
||||
if (*ack_response)
|
||||
conn->MaxTransmissionSize = hdr->max_tsize;
|
||||
else
|
||||
status = ERROR_OUTOFMEMORY;
|
||||
RPCRT4_FreeHeader(response);
|
||||
status = RPC_S_OUT_OF_RESOURCES;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static RPC_STATUS process_bind_packet(RpcConnection *conn, RpcPktBindHdr *hdr,
|
||||
RPC_MESSAGE *msg,
|
||||
unsigned char *auth_data,
|
||||
ULONG auth_length)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
RpcPktHdr *response = NULL;
|
||||
unsigned char *auth_data_out = NULL;
|
||||
ULONG auth_length_out = 0;
|
||||
|
||||
status = process_bind_packet_no_send(conn, hdr, msg, auth_data, auth_length,
|
||||
&response, &auth_data_out,
|
||||
&auth_length_out);
|
||||
if (status != RPC_S_OK)
|
||||
response = handle_bind_error(conn, status);
|
||||
if (response)
|
||||
status = RPCRT4_SendWithAuth(conn, response, NULL, 0, auth_data_out, auth_length_out);
|
||||
else
|
||||
status = ERROR_OUTOFMEMORY;
|
||||
RPCRT4_FreeHeader(response);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static RPC_STATUS process_request_packet(RpcConnection *conn, RpcPktRequestHdr *hdr, RPC_MESSAGE *msg)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
@@ -242,7 +391,7 @@ static RPC_STATUS process_request_packet(RpcConnection *conn, RpcPktRequestHdr *
|
||||
object_uuid = NULL;
|
||||
}
|
||||
|
||||
sif = RPCRT4_find_interface(object_uuid, &conn->ActiveInterface, TRUE);
|
||||
sif = RPCRT4_find_interface(object_uuid, &conn->ActiveInterface, NULL, TRUE);
|
||||
if (!sif) {
|
||||
WARN("interface %s no longer registered, returning fault packet\n", debugstr_guid(&conn->ActiveInterface.SyntaxGUID));
|
||||
response = RPCRT4_BuildFaultHeader(NDR_LOCAL_DATA_REPRESENTATION,
|
||||
@@ -327,25 +476,52 @@ static RPC_STATUS process_request_packet(RpcConnection *conn, RpcPktRequestHdr *
|
||||
return status;
|
||||
}
|
||||
|
||||
static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSAGE* msg)
|
||||
static RPC_STATUS process_auth3_packet(RpcConnection *conn,
|
||||
RpcPktCommonHdr *hdr,
|
||||
RPC_MESSAGE *msg,
|
||||
unsigned char *auth_data,
|
||||
ULONG auth_length)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
RPC_STATUS status;
|
||||
|
||||
if (UuidIsNil(&conn->ActiveInterface.SyntaxGUID, &status) ||
|
||||
!auth_length || msg->BufferLength != 0)
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
else
|
||||
{
|
||||
status = RPCRT4_ServerConnectionAuth(conn, FALSE,
|
||||
(RpcAuthVerifier *)auth_data,
|
||||
auth_length, NULL, NULL);
|
||||
}
|
||||
|
||||
/* FIXME: client doesn't expect a response to this message so must store
|
||||
* status in connection so that fault packet can be returned when next
|
||||
* packet is received */
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr,
|
||||
RPC_MESSAGE* msg, unsigned char *auth_data,
|
||||
ULONG auth_length)
|
||||
{
|
||||
msg->Handle = (RPC_BINDING_HANDLE)conn->server_binding;
|
||||
|
||||
switch (hdr->common.ptype) {
|
||||
case PKT_BIND:
|
||||
TRACE("got bind packet\n");
|
||||
|
||||
status = process_bind_packet(conn, &hdr->bind, msg);
|
||||
process_bind_packet(conn, &hdr->bind, msg, auth_data, auth_length);
|
||||
break;
|
||||
|
||||
case PKT_REQUEST:
|
||||
TRACE("got request packet\n");
|
||||
|
||||
status = process_request_packet(conn, &hdr->request, msg);
|
||||
process_request_packet(conn, &hdr->request, msg);
|
||||
break;
|
||||
|
||||
case PKT_AUTH3:
|
||||
TRACE("got auth3 packet\n");
|
||||
process_auth3_packet(conn, &hdr->common, msg, auth_data, auth_length);
|
||||
break;
|
||||
default:
|
||||
FIXME("unhandled packet type %u\n", hdr->common.ptype);
|
||||
break;
|
||||
@@ -355,57 +531,96 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
||||
I_RpcFree(msg->Buffer);
|
||||
RPCRT4_FreeHeader(hdr);
|
||||
HeapFree(GetProcessHeap(), 0, msg);
|
||||
HeapFree(GetProcessHeap(), 0, auth_data);
|
||||
}
|
||||
|
||||
static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg)
|
||||
{
|
||||
RpcPacket *pkt = the_arg;
|
||||
RPCRT4_process_packet(pkt->conn, pkt->hdr, pkt->msg);
|
||||
RPCRT4_process_packet(pkt->conn, pkt->hdr, pkt->msg, pkt->auth_data,
|
||||
pkt->auth_length);
|
||||
HeapFree(GetProcessHeap(), 0, pkt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
|
||||
{
|
||||
RpcConnection* conn = (RpcConnection*)the_arg;
|
||||
RpcConnection* conn = the_arg;
|
||||
RpcPktHdr *hdr;
|
||||
RPC_MESSAGE *msg;
|
||||
RPC_STATUS status;
|
||||
RpcPacket *packet;
|
||||
unsigned char *auth_data;
|
||||
ULONG auth_length;
|
||||
|
||||
TRACE("(%p)\n", conn);
|
||||
|
||||
for (;;) {
|
||||
msg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RPC_MESSAGE));
|
||||
if (!msg) break;
|
||||
|
||||
status = RPCRT4_Receive(conn, &hdr, msg);
|
||||
status = RPCRT4_ReceiveWithAuth(conn, &hdr, msg, &auth_data, &auth_length);
|
||||
if (status != RPC_S_OK) {
|
||||
WARN("receive failed with error %x\n", status);
|
||||
HeapFree(GetProcessHeap(), 0, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
packet = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcPacket));
|
||||
if (!packet) {
|
||||
I_RpcFree(msg->Buffer);
|
||||
RPCRT4_FreeHeader(hdr);
|
||||
HeapFree(GetProcessHeap(), 0, msg);
|
||||
switch (hdr->common.ptype) {
|
||||
case PKT_BIND:
|
||||
TRACE("got bind packet\n");
|
||||
|
||||
status = process_bind_packet(conn, &hdr->bind, msg, auth_data,
|
||||
auth_length);
|
||||
break;
|
||||
}
|
||||
packet->conn = conn;
|
||||
packet->hdr = hdr;
|
||||
packet->msg = msg;
|
||||
if (!QueueUserWorkItem(RPCRT4_worker_thread, packet, WT_EXECUTELONGFUNCTION)) {
|
||||
ERR("couldn't queue work item for worker thread, error was %d\n", GetLastError());
|
||||
I_RpcFree(msg->Buffer);
|
||||
RPCRT4_FreeHeader(hdr);
|
||||
HeapFree(GetProcessHeap(), 0, msg);
|
||||
HeapFree(GetProcessHeap(), 0, packet);
|
||||
|
||||
case PKT_REQUEST:
|
||||
TRACE("got request packet\n");
|
||||
|
||||
packet = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcPacket));
|
||||
if (!packet) {
|
||||
I_RpcFree(msg->Buffer);
|
||||
RPCRT4_FreeHeader(hdr);
|
||||
HeapFree(GetProcessHeap(), 0, msg);
|
||||
HeapFree(GetProcessHeap(), 0, auth_data);
|
||||
goto exit;
|
||||
}
|
||||
packet->conn = conn;
|
||||
packet->hdr = hdr;
|
||||
packet->msg = msg;
|
||||
packet->auth_data = auth_data;
|
||||
packet->auth_length = auth_length;
|
||||
if (!QueueUserWorkItem(RPCRT4_worker_thread, packet, WT_EXECUTELONGFUNCTION)) {
|
||||
ERR("couldn't queue work item for worker thread, error was %d\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, packet);
|
||||
status = RPC_S_OUT_OF_RESOURCES;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case PKT_AUTH3:
|
||||
TRACE("got auth3 packet\n");
|
||||
|
||||
status = process_auth3_packet(conn, &hdr->common, msg, auth_data,
|
||||
auth_length);
|
||||
break;
|
||||
default:
|
||||
FIXME("unhandled packet type %u\n", hdr->common.ptype);
|
||||
break;
|
||||
}
|
||||
|
||||
msg = NULL;
|
||||
I_RpcFree(msg->Buffer);
|
||||
RPCRT4_FreeHeader(hdr);
|
||||
HeapFree(GetProcessHeap(), 0, msg);
|
||||
HeapFree(GetProcessHeap(), 0, auth_data);
|
||||
|
||||
if (status != RPC_S_OK) {
|
||||
WARN("processing packet failed with error %u\n", status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
exit:
|
||||
RPCRT4_DestroyConnection(conn);
|
||||
return 0;
|
||||
}
|
||||
@@ -449,27 +664,23 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
|
||||
|
||||
/* start waiting */
|
||||
res = cps->ops->wait_for_new_connection(cps, count, objs);
|
||||
if (res == -1)
|
||||
break;
|
||||
else if (res == 0)
|
||||
|
||||
if (res == -1 || (res == 0 && !std_listen))
|
||||
{
|
||||
if (!std_listen)
|
||||
{
|
||||
/* cleanup */
|
||||
cps->ops->free_wait_array(cps, objs);
|
||||
EnterCriticalSection(&cps->cs);
|
||||
for (conn = cps->conn; conn; conn = conn->Next)
|
||||
RPCRT4_CloseConnection(conn);
|
||||
LeaveCriticalSection(&cps->cs);
|
||||
|
||||
if (res == 0 && !std_listen)
|
||||
SetEvent(cps->server_ready_event);
|
||||
break;
|
||||
}
|
||||
set_ready_event = TRUE;
|
||||
break;
|
||||
}
|
||||
else if (res == 0)
|
||||
set_ready_event = TRUE;
|
||||
}
|
||||
cps->ops->free_wait_array(cps, objs);
|
||||
EnterCriticalSection(&cps->cs);
|
||||
/* close connections */
|
||||
conn = cps->conn;
|
||||
while (conn) {
|
||||
RPCRT4_CloseConnection(conn);
|
||||
conn = conn->Next;
|
||||
}
|
||||
LeaveCriticalSection(&cps->cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -563,6 +774,10 @@ static void RPCRT4_stop_listen(BOOL auto_listen)
|
||||
LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
|
||||
RPCRT4_sync_with_server_thread(cps);
|
||||
|
||||
EnterCriticalSection(&listen_cs);
|
||||
if (listen_done_event) SetEvent( listen_done_event );
|
||||
listen_done_event = 0;
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
return;
|
||||
}
|
||||
assert(listen_count >= 0);
|
||||
@@ -570,11 +785,32 @@ static void RPCRT4_stop_listen(BOOL auto_listen)
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
}
|
||||
|
||||
static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, LPSTR endpoint)
|
||||
static BOOL RPCRT4_protseq_is_endpoint_registered(RpcServerProtseq *protseq, const char *endpoint)
|
||||
{
|
||||
RpcConnection *conn;
|
||||
EnterCriticalSection(&protseq->cs);
|
||||
for (conn = protseq->conn; conn; conn = conn->Next)
|
||||
{
|
||||
if (!endpoint || !strcmp(endpoint, conn->Endpoint))
|
||||
break;
|
||||
}
|
||||
LeaveCriticalSection(&protseq->cs);
|
||||
return (conn != NULL);
|
||||
}
|
||||
|
||||
static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, const char *endpoint)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
status = ps->ops->open_endpoint(ps, endpoint);
|
||||
EnterCriticalSection(&ps->cs);
|
||||
|
||||
if (RPCRT4_protseq_is_endpoint_registered(ps, endpoint))
|
||||
status = RPC_S_OK;
|
||||
else
|
||||
status = ps->ops->open_endpoint(ps, endpoint);
|
||||
|
||||
LeaveCriticalSection(&ps->cs);
|
||||
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
@@ -608,11 +844,8 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
|
||||
count = 0;
|
||||
LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
|
||||
EnterCriticalSection(&ps->cs);
|
||||
conn = ps->conn;
|
||||
while (conn) {
|
||||
for (conn = ps->conn; conn; conn = conn->Next)
|
||||
count++;
|
||||
conn = conn->Next;
|
||||
}
|
||||
LeaveCriticalSection(&ps->cs);
|
||||
}
|
||||
if (count) {
|
||||
@@ -624,12 +857,10 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
|
||||
count = 0;
|
||||
LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
|
||||
EnterCriticalSection(&ps->cs);
|
||||
conn = ps->conn;
|
||||
while (conn) {
|
||||
for (conn = ps->conn; conn; conn = conn->Next) {
|
||||
RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count],
|
||||
conn);
|
||||
count++;
|
||||
conn = conn->Next;
|
||||
}
|
||||
LeaveCriticalSection(&ps->cs);
|
||||
}
|
||||
@@ -681,7 +912,7 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_W
|
||||
*
|
||||
* Must be called with server_cs held.
|
||||
*/
|
||||
static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps)
|
||||
static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps)
|
||||
{
|
||||
const struct protseq_ops *ops = rpcrt4_get_protseq_ops(Protseq);
|
||||
|
||||
@@ -695,7 +926,7 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerPr
|
||||
if (!*ps)
|
||||
return RPC_S_OUT_OF_RESOURCES;
|
||||
(*ps)->MaxCalls = MaxCalls;
|
||||
(*ps)->Protseq = Protseq;
|
||||
(*ps)->Protseq = RPCRT4_strdupA(Protseq);
|
||||
(*ps)->ops = ops;
|
||||
(*ps)->MaxCalls = 0;
|
||||
(*ps)->conn = NULL;
|
||||
@@ -711,8 +942,19 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerPr
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/* must be called with server_cs held */
|
||||
static void destroy_serverprotoseq(RpcServerProtseq *ps)
|
||||
{
|
||||
RPCRT4_strfree(ps->Protseq);
|
||||
DeleteCriticalSection(&ps->cs);
|
||||
CloseHandle(ps->mgr_mutex);
|
||||
CloseHandle(ps->server_ready_event);
|
||||
list_remove(&ps->entry);
|
||||
HeapFree(GetProcessHeap(), 0, ps);
|
||||
}
|
||||
|
||||
/* Finds a given protseq or creates a new one if one doesn't already exist */
|
||||
static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps)
|
||||
static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
RpcServerProtseq *cps;
|
||||
@@ -741,19 +983,18 @@ static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protse
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqEpExA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor,
|
||||
PRPC_POLICY lpPolicy )
|
||||
{
|
||||
char *szps = (char*)Protseq, *szep = (char*)Endpoint;
|
||||
RpcServerProtseq* ps;
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a(szps), MaxCalls,
|
||||
debugstr_a(szep), SecurityDescriptor,
|
||||
TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a((const char *)Protseq),
|
||||
MaxCalls, debugstr_a((const char *)Endpoint), SecurityDescriptor,
|
||||
lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
|
||||
|
||||
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupA(szps), &ps);
|
||||
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps);
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
return RPCRT4_use_protseq(ps, szep);
|
||||
return RPCRT4_use_protseq(ps, (const char *)Endpoint);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -764,13 +1005,16 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC
|
||||
{
|
||||
RpcServerProtseq* ps;
|
||||
RPC_STATUS status;
|
||||
LPSTR ProtseqA;
|
||||
LPSTR EndpointA;
|
||||
|
||||
TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_w( Protseq ), MaxCalls,
|
||||
debugstr_w( Endpoint ), SecurityDescriptor,
|
||||
lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
|
||||
|
||||
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps);
|
||||
ProtseqA = RPCRT4_strdupWtoA(Protseq);
|
||||
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps);
|
||||
RPCRT4_strfree(ProtseqA);
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
@@ -785,8 +1029,16 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
RpcServerProtseq* ps;
|
||||
|
||||
TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_a((char*)Protseq), MaxCalls, SecurityDescriptor);
|
||||
return RpcServerUseProtseqEpA(Protseq, MaxCalls, NULL, SecurityDescriptor);
|
||||
|
||||
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps);
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
return RPCRT4_use_protseq(ps, NULL);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -794,8 +1046,36 @@ RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls,
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
RpcServerProtseq* ps;
|
||||
LPSTR ProtseqA;
|
||||
|
||||
TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_w(Protseq), MaxCalls, SecurityDescriptor);
|
||||
return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor);
|
||||
|
||||
ProtseqA = RPCRT4_strdupWtoA(Protseq);
|
||||
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps);
|
||||
RPCRT4_strfree(ProtseqA);
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
return RPCRT4_use_protseq(ps, NULL);
|
||||
}
|
||||
|
||||
void RPCRT4_destroy_all_protseqs(void)
|
||||
{
|
||||
RpcServerProtseq *cps, *cursor2;
|
||||
|
||||
if (listen_count != 0)
|
||||
std_listen = FALSE;
|
||||
|
||||
EnterCriticalSection(&server_cs);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(cps, cursor2, &protseqs, RpcServerProtseq, entry)
|
||||
{
|
||||
if (listen_count != 0)
|
||||
RPCRT4_sync_with_server_thread(cps);
|
||||
destroy_serverprotoseq(cps);
|
||||
}
|
||||
LeaveCriticalSection(&server_cs);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -823,7 +1103,7 @@ RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid
|
||||
RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
|
||||
UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn )
|
||||
{
|
||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||
PRPC_SERVER_INTERFACE If = IfSpec;
|
||||
RpcServerInterface* sif;
|
||||
unsigned int i;
|
||||
|
||||
@@ -876,7 +1156,7 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid,
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete )
|
||||
{
|
||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||
PRPC_SERVER_INTERFACE If = IfSpec;
|
||||
HANDLE event = NULL;
|
||||
BOOL found = FALSE;
|
||||
BOOL completed = TRUE;
|
||||
@@ -944,7 +1224,7 @@ RPC_STATUS WINAPI RpcServerUnregisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUu
|
||||
* RPC_S_INVALID_OBJECT The provided object (nil) is not valid
|
||||
* RPC_S_ALREADY_REGISTERED The provided object is already registered
|
||||
*
|
||||
* Maps "Object" UUIDs to "Type" UUID's. Passing the nil UUID as the type
|
||||
* Maps "Object" UUIDs to "Type" UUIDs. Passing the nil UUID as the type
|
||||
* resets the mapping for the specified object UUID to nil (the default).
|
||||
* The nil object is always associated with the nil type and cannot be
|
||||
* reassigned. Servers can support multiple implementations on the same
|
||||
@@ -996,15 +1276,114 @@ RPC_STATUS WINAPI RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid )
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
struct rpc_server_registered_auth_info
|
||||
{
|
||||
struct list entry;
|
||||
TimeStamp exp;
|
||||
CredHandle cred;
|
||||
ULONG max_token;
|
||||
USHORT auth_type;
|
||||
};
|
||||
|
||||
RPC_STATUS RPCRT4_ServerGetRegisteredAuthInfo(
|
||||
USHORT auth_type, CredHandle *cred, TimeStamp *exp, ULONG *max_token)
|
||||
{
|
||||
RPC_STATUS status = RPC_S_UNKNOWN_AUTHN_SERVICE;
|
||||
struct rpc_server_registered_auth_info *auth_info;
|
||||
|
||||
EnterCriticalSection(&server_auth_info_cs);
|
||||
LIST_FOR_EACH_ENTRY(auth_info, &server_registered_auth_info, struct rpc_server_registered_auth_info, entry)
|
||||
{
|
||||
if (auth_info->auth_type == auth_type)
|
||||
{
|
||||
*cred = auth_info->cred;
|
||||
*exp = auth_info->exp;
|
||||
*max_token = auth_info->max_token;
|
||||
status = RPC_S_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&server_auth_info_cs);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void RPCRT4_ServerFreeAllRegisteredAuthInfo(void)
|
||||
{
|
||||
struct rpc_server_registered_auth_info *auth_info, *cursor2;
|
||||
|
||||
EnterCriticalSection(&server_auth_info_cs);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(auth_info, cursor2, &server_registered_auth_info, struct rpc_server_registered_auth_info, entry)
|
||||
{
|
||||
FreeCredentialsHandle(&auth_info->cred);
|
||||
HeapFree(GetProcessHeap(), 0, auth_info);
|
||||
}
|
||||
LeaveCriticalSection(&server_auth_info_cs);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcServerRegisterAuthInfoA (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( RPC_CSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
|
||||
LPVOID Arg )
|
||||
{
|
||||
FIXME( "(%s,%u,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg );
|
||||
|
||||
return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
|
||||
SECURITY_STATUS sec_status;
|
||||
CredHandle cred;
|
||||
TimeStamp exp;
|
||||
ULONG package_count;
|
||||
ULONG i;
|
||||
PSecPkgInfoA packages;
|
||||
ULONG max_token;
|
||||
struct rpc_server_registered_auth_info *auth_info;
|
||||
|
||||
TRACE("(%s,%u,%p,%p)\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg);
|
||||
|
||||
sec_status = EnumerateSecurityPackagesA(&package_count, &packages);
|
||||
if (sec_status != SEC_E_OK)
|
||||
{
|
||||
ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n",
|
||||
sec_status);
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < package_count; i++)
|
||||
if (packages[i].wRPCID == AuthnSvc)
|
||||
break;
|
||||
|
||||
if (i == package_count)
|
||||
{
|
||||
WARN("unsupported AuthnSvc %u\n", AuthnSvc);
|
||||
FreeContextBuffer(packages);
|
||||
return RPC_S_UNKNOWN_AUTHN_SERVICE;
|
||||
}
|
||||
TRACE("found package %s for service %u\n", packages[i].Name,
|
||||
AuthnSvc);
|
||||
sec_status = AcquireCredentialsHandleA((SEC_CHAR *)ServerPrincName,
|
||||
packages[i].Name,
|
||||
SECPKG_CRED_INBOUND, NULL, NULL,
|
||||
NULL, NULL, &cred, &exp);
|
||||
max_token = packages[i].cbMaxToken;
|
||||
FreeContextBuffer(packages);
|
||||
if (sec_status != SEC_E_OK)
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
|
||||
auth_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*auth_info));
|
||||
if (!auth_info)
|
||||
{
|
||||
FreeCredentialsHandle(&cred);
|
||||
return RPC_S_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
auth_info->exp = exp;
|
||||
auth_info->cred = cred;
|
||||
auth_info->max_token = max_token;
|
||||
auth_info->auth_type = AuthnSvc;
|
||||
|
||||
EnterCriticalSection(&server_auth_info_cs);
|
||||
list_add_tail(&server_registered_auth_info, &auth_info->entry);
|
||||
LeaveCriticalSection(&server_auth_info_cs);
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1013,9 +1392,63 @@ RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( RPC_CSTR ServerPrincName, ULONG Au
|
||||
RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( RPC_WSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
|
||||
LPVOID Arg )
|
||||
{
|
||||
FIXME( "(%s,%u,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg );
|
||||
|
||||
return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
|
||||
SECURITY_STATUS sec_status;
|
||||
CredHandle cred;
|
||||
TimeStamp exp;
|
||||
ULONG package_count;
|
||||
ULONG i;
|
||||
PSecPkgInfoW packages;
|
||||
ULONG max_token;
|
||||
struct rpc_server_registered_auth_info *auth_info;
|
||||
|
||||
TRACE("(%s,%u,%p,%p)\n", debugstr_w(ServerPrincName), AuthnSvc, GetKeyFn, Arg);
|
||||
|
||||
sec_status = EnumerateSecurityPackagesW(&package_count, &packages);
|
||||
if (sec_status != SEC_E_OK)
|
||||
{
|
||||
ERR("EnumerateSecurityPackagesW failed with error 0x%08x\n",
|
||||
sec_status);
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < package_count; i++)
|
||||
if (packages[i].wRPCID == AuthnSvc)
|
||||
break;
|
||||
|
||||
if (i == package_count)
|
||||
{
|
||||
WARN("unsupported AuthnSvc %u\n", AuthnSvc);
|
||||
FreeContextBuffer(packages);
|
||||
return RPC_S_UNKNOWN_AUTHN_SERVICE;
|
||||
}
|
||||
TRACE("found package %s for service %u\n", debugstr_w(packages[i].Name),
|
||||
AuthnSvc);
|
||||
sec_status = AcquireCredentialsHandleW((SEC_WCHAR *)ServerPrincName,
|
||||
packages[i].Name,
|
||||
SECPKG_CRED_INBOUND, NULL, NULL,
|
||||
NULL, NULL, &cred, &exp);
|
||||
max_token = packages[i].cbMaxToken;
|
||||
FreeContextBuffer(packages);
|
||||
if (sec_status != SEC_E_OK)
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
|
||||
auth_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*auth_info));
|
||||
if (!auth_info)
|
||||
{
|
||||
FreeCredentialsHandle(&cred);
|
||||
return RPC_S_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
auth_info->exp = exp;
|
||||
auth_info->cred = cred;
|
||||
auth_info->max_token = max_token;
|
||||
auth_info->auth_type = AuthnSvc;
|
||||
|
||||
EnterCriticalSection(&server_auth_info_cs);
|
||||
list_add_tail(&server_registered_auth_info, &auth_info->entry);
|
||||
LeaveCriticalSection(&server_auth_info_cs);
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1044,23 +1477,23 @@ RPC_STATUS WINAPI RpcMgmtWaitServerListen( void )
|
||||
{
|
||||
RpcServerProtseq *cps;
|
||||
|
||||
TRACE("()\n");
|
||||
|
||||
EnterCriticalSection(&listen_cs);
|
||||
|
||||
if (!std_listen) {
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
return RPC_S_NOT_LISTENING;
|
||||
}
|
||||
|
||||
do {
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
|
||||
WaitForSingleObject(cps->server_ready_event, INFINITE);
|
||||
|
||||
|
||||
EnterCriticalSection(&listen_cs);
|
||||
} while (!std_listen);
|
||||
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
@@ -1183,6 +1616,15 @@ RPC_STATUS WINAPI RpcMgmtIsServerListening(RPC_BINDING_HANDLE Binding)
|
||||
return RPC_S_INVALID_BINDING;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcMgmtSetAuthorizationFn (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcMgmtSetAuthorizationFn(RPC_MGMT_AUTHORIZATION_FN fn)
|
||||
{
|
||||
FIXME("(%p): stub\n", fn);
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcMgmtSetServerStackSize (RPCRT4.@)
|
||||
*/
|
||||
|
||||
@@ -56,7 +56,7 @@ struct protseq_ops
|
||||
* new connection was established */
|
||||
int (*wait_for_new_connection)(RpcServerProtseq *protseq, unsigned int count, void *wait_array);
|
||||
/* opens the endpoint and optionally begins listening */
|
||||
RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, LPSTR endpoint);
|
||||
RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, const char *endpoint);
|
||||
};
|
||||
|
||||
typedef struct _RpcServerInterface
|
||||
@@ -76,7 +76,10 @@ typedef struct _RpcServerInterface
|
||||
BOOL Delete; /* delete when the last call finishes */
|
||||
} RpcServerInterface;
|
||||
|
||||
void RPCRT4_new_client(RpcConnection* conn);
|
||||
const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq);
|
||||
void RPCRT4_new_client(RpcConnection* conn) DECLSPEC_HIDDEN;
|
||||
const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq) DECLSPEC_HIDDEN;
|
||||
|
||||
void RPCRT4_destroy_all_protseqs(void) DECLSPEC_HIDDEN;
|
||||
void RPCRT4_ServerFreeAllRegisteredAuthInfo(void) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_RPC_SERVER_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,8 @@
|
||||
<library>user32</library>
|
||||
<library>advapi32</library>
|
||||
<library>secur32</library>
|
||||
<library delayimport="true">wininet</library>
|
||||
<library>delayimp</library>
|
||||
<library>iphlpapi</library>
|
||||
<library>ws2_32</library>
|
||||
<library>ntdll</library>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@ stdcall CreateProxyFromTypeInfo(ptr ptr ptr ptr ptr)
|
||||
@ stub CreateStubFromTypeInfo
|
||||
@ stdcall CreateStubFromTypeInfo(ptr ptr ptr ptr)
|
||||
@ stdcall CStdStubBuffer_AddRef(ptr)
|
||||
@ stdcall CStdStubBuffer_Connect(ptr ptr)
|
||||
@ stdcall CStdStubBuffer_CountRefs(ptr)
|
||||
@@ -53,7 +53,7 @@
|
||||
@ stub I_RpcIfInqTransferSyntaxes
|
||||
@ stub I_RpcLogEvent
|
||||
@ stdcall I_RpcMapWin32Status(long)
|
||||
@ stdcall I_RpcNegotiateTransferSyntax(ptr) # wxp
|
||||
@ stdcall I_RpcNegotiateTransferSyntax(ptr)
|
||||
@ stub I_RpcNsBindingSetEntryName
|
||||
@ stub I_RpcNsBindingSetEntryNameA
|
||||
@ stub I_RpcNsBindingSetEntryNameW
|
||||
@@ -116,8 +116,9 @@
|
||||
@ stdcall NDRSContextUnmarshallEx(ptr ptr ptr)
|
||||
@ stub NDRcopy
|
||||
@ stdcall NdrAllocate(ptr long)
|
||||
@ stub NdrAsyncClientCall
|
||||
@ varargs NdrAsyncClientCall(ptr ptr)
|
||||
@ stub NdrAsyncServerCall
|
||||
@ stdcall NdrAsyncStubCall(ptr ptr ptr ptr)
|
||||
@ stdcall NdrByteCountPointerBufferSize(ptr ptr ptr)
|
||||
@ stdcall NdrByteCountPointerFree(ptr ptr ptr)
|
||||
@ stdcall NdrByteCountPointerMarshall(ptr ptr ptr)
|
||||
@@ -126,7 +127,7 @@
|
||||
@ stdcall NdrCStdStubBuffer_Release(ptr ptr)
|
||||
@ stdcall NdrClearOutParameters(ptr ptr ptr)
|
||||
@ varargs NdrClientCall2(ptr ptr)
|
||||
@ varargs NdrClientCall(ptr ptr) NdrClientCall2
|
||||
@ varargs -arch=i386 NdrClientCall(ptr ptr) NdrClientCall2
|
||||
@ stdcall NdrClientContextMarshall(ptr ptr long)
|
||||
@ stdcall NdrClientContextUnmarshall(ptr ptr ptr)
|
||||
@ stub NdrClientInitialize
|
||||
@@ -194,7 +195,7 @@
|
||||
@ stdcall NdrFullPointerQueryPointer(ptr ptr long ptr)
|
||||
@ stdcall NdrFullPointerQueryRefId(ptr long long ptr)
|
||||
@ stdcall NdrFullPointerXlatFree(ptr)
|
||||
@ stdcall NdrFullPointerXlatInit(long long)
|
||||
@ stdcall NdrFullPointerXlatInit(long long)
|
||||
@ stdcall NdrGetBuffer(ptr long ptr)
|
||||
@ stub NdrGetDcomProtocolVersion
|
||||
@ stub NdrGetPartialBuffer
|
||||
@@ -226,7 +227,7 @@
|
||||
@ stub NdrMesTypeAlignSize
|
||||
@ stdcall NdrMesTypeDecode2(ptr ptr ptr ptr ptr)
|
||||
@ stub NdrMesTypeDecode
|
||||
@ stub NdrMesTypeEncode2
|
||||
@ stdcall NdrMesTypeEncode2(ptr ptr ptr ptr ptr)
|
||||
@ stub NdrMesTypeEncode
|
||||
@ stdcall NdrMesTypeFree2(ptr ptr ptr ptr ptr)
|
||||
@ stdcall NdrNonConformantStringBufferSize(ptr ptr ptr)
|
||||
@@ -272,7 +273,7 @@
|
||||
@ stub NdrRpcSsEnableAllocate
|
||||
@ stdcall NdrSendReceive(ptr ptr)
|
||||
@ stdcall NdrServerCall2(ptr)
|
||||
@ stub NdrServerCall
|
||||
@ stdcall NdrServerCall(ptr)
|
||||
@ stdcall NdrServerContextMarshall(ptr ptr long)
|
||||
@ stdcall NdrServerContextNewMarshall(ptr ptr ptr ptr) # wxp
|
||||
@ stdcall NdrServerContextNewUnmarshall(ptr ptr) # wxp
|
||||
@@ -292,7 +293,7 @@
|
||||
@ stdcall NdrSimpleTypeMarshall(ptr ptr long)
|
||||
@ stdcall NdrSimpleTypeUnmarshall(ptr ptr long)
|
||||
@ stdcall NdrStubCall2(ptr ptr ptr ptr)
|
||||
@ stub NdrStubCall
|
||||
@ stdcall NdrStubCall(ptr ptr ptr ptr)
|
||||
@ stdcall NdrStubForwardingFunction(ptr ptr ptr ptr)
|
||||
@ stdcall NdrStubGetBuffer(ptr ptr ptr)
|
||||
@ stdcall NdrStubInitialize(ptr ptr ptr ptr)
|
||||
@@ -340,10 +341,10 @@
|
||||
@ stdcall RpcBindingFree(ptr)
|
||||
@ stdcall RpcBindingFromStringBindingA(str ptr)
|
||||
@ stdcall RpcBindingFromStringBindingW(wstr ptr)
|
||||
@ stub RpcBindingInqAuthClientA
|
||||
@ stub RpcBindingInqAuthClientExA
|
||||
@ stub RpcBindingInqAuthClientExW
|
||||
@ stub RpcBindingInqAuthClientW
|
||||
@ stdcall RpcBindingInqAuthClientA(ptr ptr ptr ptr ptr ptr)
|
||||
@ stdcall RpcBindingInqAuthClientExA(ptr ptr ptr ptr ptr ptr long)
|
||||
@ stdcall RpcBindingInqAuthClientExW(ptr ptr ptr ptr ptr ptr long)
|
||||
@ stdcall RpcBindingInqAuthClientW(ptr ptr ptr ptr ptr ptr)
|
||||
@ stdcall RpcBindingInqAuthInfoA(ptr ptr ptr ptr ptr ptr)
|
||||
@ stdcall RpcBindingInqAuthInfoExA(ptr ptr ptr ptr ptr ptr long ptr)
|
||||
@ stdcall RpcBindingInqAuthInfoExW(ptr ptr ptr ptr ptr ptr long ptr)
|
||||
@@ -370,7 +371,7 @@
|
||||
@ stdcall RpcEpRegisterA(ptr ptr ptr str)
|
||||
@ stub RpcEpRegisterNoReplaceA
|
||||
@ stub RpcEpRegisterNoReplaceW
|
||||
@ stub RpcEpRegisterW
|
||||
@ stdcall RpcEpRegisterW(ptr ptr ptr wstr)
|
||||
@ stdcall RpcEpResolveBinding(ptr ptr)
|
||||
@ stdcall RpcEpUnregister(ptr ptr ptr)
|
||||
@ stub RpcErrorAddRecord # wxp
|
||||
@@ -401,15 +402,15 @@
|
||||
@ stub RpcMgmtInqServerPrincNameW
|
||||
@ stdcall RpcMgmtInqStats(ptr ptr)
|
||||
@ stdcall RpcMgmtIsServerListening(ptr)
|
||||
@ stub RpcMgmtSetAuthorizationFn
|
||||
@ stdcall RpcMgmtSetAuthorizationFn(ptr)
|
||||
@ stdcall RpcMgmtSetCancelTimeout(long)
|
||||
@ stdcall RpcMgmtSetComTimeout(ptr long)
|
||||
@ stdcall RpcMgmtSetServerStackSize(long)
|
||||
@ stdcall RpcMgmtStatsVectorFree(ptr)
|
||||
@ stdcall RpcMgmtStopServerListening(ptr)
|
||||
@ stdcall RpcMgmtWaitServerListen()
|
||||
@ stub RpcNetworkInqProtseqsA
|
||||
@ stub RpcNetworkInqProtseqsW
|
||||
@ stdcall RpcNetworkInqProtseqsA(ptr)
|
||||
@ stdcall RpcNetworkInqProtseqsW(ptr)
|
||||
@ stdcall RpcNetworkIsProtseqValidA(ptr)
|
||||
@ stdcall RpcNetworkIsProtseqValidW(ptr)
|
||||
@ stub RpcNsBindingInqEntryNameA
|
||||
@@ -417,8 +418,8 @@
|
||||
@ stub RpcObjectInqType
|
||||
@ stub RpcObjectSetInqFn
|
||||
@ stdcall RpcObjectSetType(ptr ptr)
|
||||
@ stub RpcProtseqVectorFreeA
|
||||
@ stub RpcProtseqVectorFreeW
|
||||
@ stdcall RpcProtseqVectorFreeA(ptr)
|
||||
@ stdcall RpcProtseqVectorFreeW(ptr)
|
||||
@ stdcall RpcRaiseException(long)
|
||||
@ stub RpcRegisterAsyncInfo
|
||||
@ stdcall RpcRevertToSelf()
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "winuser.h"
|
||||
#include "winnt.h"
|
||||
#include "winternl.h"
|
||||
#include "ntsecapi.h"
|
||||
#include "iptypes.h"
|
||||
#include "iphlpapi.h"
|
||||
#include "wine/unicode.h"
|
||||
@@ -53,6 +54,7 @@
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "rpc_server.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
@@ -135,6 +137,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
RPCRT4_destroy_all_protseqs();
|
||||
RPCRT4_ServerFreeAllRegisteredAuthInfo();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -280,6 +284,38 @@ RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid)
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* UuidCreate [RPCRT4.@]
|
||||
*
|
||||
* Creates a 128bit UUID.
|
||||
*
|
||||
* RETURNS
|
||||
*
|
||||
* RPC_S_OK if successful.
|
||||
* RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique.
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
* Follows RFC 4122, section 4.4 (Algorithms for Creating a UUID from
|
||||
* Truly Random or Pseudo-Random Numbers)
|
||||
*/
|
||||
RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
|
||||
{
|
||||
RtlGenRandom(Uuid, sizeof(*Uuid));
|
||||
/* Clear the version bits and set the version (4) */
|
||||
Uuid->Data3 &= 0x0fff;
|
||||
Uuid->Data3 |= (4 << 12);
|
||||
/* Set the topmost bits of Data4 (clock_seq_hi_and_reserved) as
|
||||
* specified in RFC 4122, section 4.4.
|
||||
*/
|
||||
Uuid->Data4[0] &= 0x3f;
|
||||
Uuid->Data4[0] |= 0x80;
|
||||
|
||||
TRACE("%s\n", debugstr_guid(Uuid));
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/* Number of 100ns ticks per clock tick. To be safe, assume that the clock
|
||||
resolution is at least 1000 * 100 * (1/1000000) = 1/10 of a second */
|
||||
#define TICKS_PER_CLOCK_TICK 1000
|
||||
@@ -299,7 +335,7 @@ static void RPC_UuidGetSystemTime(ULONGLONG *time)
|
||||
*time += TICKS_15_OCT_1582_TO_1601;
|
||||
}
|
||||
|
||||
/* Assume that a hardware address is at least 6 bytes long */
|
||||
/* Assume that a hardware address is at least 6 bytes long */
|
||||
#define ADDRESS_BYTES_NEEDED 6
|
||||
|
||||
static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address)
|
||||
@@ -323,10 +359,7 @@ static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address)
|
||||
/* We can't get a hardware address, just use random numbers.
|
||||
Set the multicast bit to prevent conflicts with real cards. */
|
||||
else {
|
||||
for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) {
|
||||
address[i] = rand() & 0xff;
|
||||
}
|
||||
|
||||
RtlGenRandom(address, ADDRESS_BYTES_NEEDED);
|
||||
address[0] |= 0x01;
|
||||
status = RPC_S_UUID_LOCAL_ONLY;
|
||||
}
|
||||
@@ -336,7 +369,7 @@ static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* UuidCreate [RPCRT4.@]
|
||||
* UuidCreateSequential [RPCRT4.@]
|
||||
*
|
||||
* Creates a 128bit UUID.
|
||||
*
|
||||
@@ -346,12 +379,12 @@ static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address)
|
||||
* RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique.
|
||||
*
|
||||
* FIXME: No compensation for changes across reloading
|
||||
* this dll or across reboots (e.g. clock going
|
||||
* this dll or across reboots (e.g. clock going
|
||||
* backwards and swapped network cards). The RFC
|
||||
* suggests using NVRAM for storing persistent
|
||||
* suggests using NVRAM for storing persistent
|
||||
* values.
|
||||
*/
|
||||
RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
|
||||
RPC_STATUS WINAPI UuidCreateSequential(UUID *Uuid)
|
||||
{
|
||||
static int initialised, count;
|
||||
|
||||
@@ -399,7 +432,7 @@ RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
|
||||
|
||||
/* Pack the information into the UUID structure. */
|
||||
|
||||
Uuid->Data1 = (unsigned long)(time & 0xffffffff);
|
||||
Uuid->Data1 = (ULONG)(time & 0xffffffff);
|
||||
Uuid->Data2 = (unsigned short)((time >> 32) & 0xffff);
|
||||
Uuid->Data3 = (unsigned short)((time >> 48) & 0x0fff);
|
||||
|
||||
@@ -409,13 +442,7 @@ RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
|
||||
Uuid->Data4[0] = sequence & 0xff;
|
||||
Uuid->Data4[1] = (sequence & 0x3f00) >> 8;
|
||||
Uuid->Data4[1] |= 0x80;
|
||||
|
||||
Uuid->Data4[2] = address[0];
|
||||
Uuid->Data4[3] = address[1];
|
||||
Uuid->Data4[4] = address[2];
|
||||
Uuid->Data4[5] = address[3];
|
||||
Uuid->Data4[6] = address[4];
|
||||
Uuid->Data4[7] = address[5];
|
||||
memcpy(&Uuid->Data4[2], address, ADDRESS_BYTES_NEEDED);
|
||||
|
||||
LeaveCriticalSection(&uuid_cs);
|
||||
|
||||
@@ -424,22 +451,6 @@ RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
|
||||
return status;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* UuidCreateSequential [RPCRT4.@]
|
||||
*
|
||||
* Creates a 128bit UUID.
|
||||
*
|
||||
* RETURNS
|
||||
*
|
||||
* RPC_S_OK if successful.
|
||||
* RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique.
|
||||
*
|
||||
*/
|
||||
RPC_STATUS WINAPI UuidCreateSequential(UUID *Uuid)
|
||||
{
|
||||
return UuidCreate(Uuid);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* UuidHash [RPCRT4.@]
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Alexandre Julliard
|
||||
*
|
||||
* 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 WINE_FILEDESCRIPTION_STR "Wine rpcrt4"
|
||||
#define WINE_FILENAME_STR "rpcrt4.dll"
|
||||
#define WINE_FILEVERSION 5,1,2600,2180
|
||||
#define WINE_FILEVERSION_STR "5.1.2600.2180"
|
||||
#define WINE_PRODUCTVERSION 5,1,2600,2180
|
||||
#define WINE_PRODUCTVERSION_STR "5.1.2600.2180"
|
||||
|
||||
#include "wine/wine_common_ver.rc"
|
||||
Reference in New Issue
Block a user