- 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:
Jérôme Gardou
2011-08-07 16:15:10 +00:00
parent 22227e3f74
commit 4c3406bcd6
27 changed files with 4862 additions and 1791 deletions
+158 -73
View File
@@ -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;
}
+1 -1
View File
@@ -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 );
+9 -9
View File
@@ -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 */
+40 -38
View File
@@ -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;
+20 -6
View File
@@ -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
+18 -16
View File
@@ -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
+7 -7
View File
@@ -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 */
+17 -13
View File
@@ -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;
}
File diff suppressed because it is too large Load Diff
+33 -27
View File
@@ -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;
+21 -9
View File
@@ -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);
+12 -11
View File
@@ -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;
+14 -2
View File
@@ -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);
}
/***********************************************************************
+172 -49
View File
@@ -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);
}
+88 -31
View File
@@ -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
+77 -44
View File
@@ -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
+48 -41
View File
@@ -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
+30 -11
View File
@@ -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
+563 -121
View File
@@ -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.@)
*/
+6 -3
View File
@@ -56,7 +56,7 @@ struct protseq_ops
* new connection was established */
int (*wait_for_new_connection)(RpcServerProtseq *protseq, unsigned int count, void *wait_array);
/* opens the endpoint and optionally begins listening */
RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, 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
+2
View File
@@ -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>
+19 -18
View File
@@ -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()
+44 -33
View File
@@ -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.@]
+26
View File
@@ -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"