diff --git a/reactos/dll/win32/rpcrt4/cproxy.c b/reactos/dll/win32/rpcrt4/cproxy.c index 9ce555f7146..6c26d181978 100644 --- a/reactos/dll/win32/rpcrt4/cproxy.c +++ b/reactos/dll/win32/rpcrt4/cproxy.c @@ -2,7 +2,6 @@ * COM proxy implementation * * Copyright 2001 Ove Kåven, TransGaming Technologies - * Copyright 2009 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,9 +20,6 @@ * TODO: Handle non-i386 architectures */ -#include "config.h" -#include "wine/port.h" - #include #define COBJMACROS @@ -41,19 +37,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); +struct StublessThunk; + /* I don't know what MS's std proxy structure looks like, so this probably doesn't match, but that shouldn't matter */ typedef struct { const IRpcProxyBufferVtbl *lpVtbl; LPVOID *PVtbl; LONG RefCount; + const MIDL_STUBLESS_PROXY_INFO *stubless; const IID* piid; LPUNKNOWN pUnkOuter; - IUnknown *base_object; /* must be at offset 0x10 from PVtbl */ - IRpcProxyBuffer *base_proxy; PCInterfaceName name; LPPSFACTORYBUFFER pPSFactory; LPRPCCHANNELBUFFER pChannel; + struct StublessThunk *thunks; } StdProxyImpl; static const IRpcProxyBufferVtbl StdProxy_Vtbl; @@ -64,111 +62,66 @@ static const IRpcProxyBufferVtbl StdProxy_Vtbl; #include "pshpack1.h" -struct thunk { +struct StublessThunk { BYTE push; DWORD index; - BYTE jmp; + BYTE call; LONG handler; + BYTE ret; + WORD bytes; + BYTE pad[3]; }; #include "poppack.h" -extern void call_stubless_func(void); -__ASM_GLOBAL_FUNC(call_stubless_func, - "pushl %esp\n\t" /* pointer to index */ - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - "call " __ASM_NAME("ObjectStubless") __ASM_STDCALL(4) "\n\t" - "popl %edx\n\t" /* args size */ - __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") - "movl (%esp),%ecx\n\t" /* return address */ - "addl %edx,%esp\n\t" - "jmp *%ecx" ); +/* adjust the stack size since we don't use Windows's method */ +#define STACK_ADJUST sizeof(DWORD) -HRESULT WINAPI ObjectStubless(DWORD *args) +#define FILL_STUBLESS(x,idx,stk) \ + x->push = 0x68; /* pushl [immediate] */ \ + x->index = (idx); \ + x->call = 0xe8; /* call [near] */ \ + x->handler = (char*)ObjectStubless - (char*)&x->ret; \ + x->ret = 0xc2; /* ret [immediate] */ \ + x->bytes = stk; \ + x->pad[0] = 0x8d; /* leal (%esi),%esi */ \ + x->pad[1] = 0x76; \ + x->pad[2] = 0x00; + +static HRESULT WINAPI ObjectStubless(DWORD index) { - DWORD index = args[0]; - void **iface = (void **)args[2]; - const void **vtbl = (const void **)*iface; - const MIDL_STUBLESS_PROXY_INFO *stubless = *(const MIDL_STUBLESS_PROXY_INFO **)(vtbl - 2); - const PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[index]; + char *args = (char*)(&index + 2); + LPVOID iface = *(LPVOID*)args; - /* store bytes to remove from stack */ - args[0] = *(const WORD*)(fs + 8); - TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, args[0], args[1]); + ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); - return NdrClientCall2(stubless->pStubDesc, fs, args + 2); -} + PFORMAT_STRING fs = This->stubless->ProcFormatString + This->stubless->FormatStringOffset[index]; + unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; + TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, bytes, *(DWORD*)(args+bytes)); -#define BLOCK_SIZE 1024 -#define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */ - -static const struct thunk *method_blocks[MAX_BLOCKS]; - -static const struct thunk *allocate_block( unsigned int num ) -{ - unsigned int i; - struct thunk *prev, *block; - - block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block), - MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); - if (!block) return NULL; - - for (i = 0; i < BLOCK_SIZE; i++) - { - block[i].push = 0x68; /* pushl */ - block[i].index = BLOCK_SIZE * num + i + 3; - block[i].jmp = 0xe9; /* jmp */ - block[i].handler = (char *)call_stubless_func - (char *)(&block[i].handler + 1); - } - VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL ); - prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL ); - if (prev) /* someone beat us to it */ - { - VirtualFree( block, 0, MEM_RELEASE ); - block = prev; - } - return block; -} - -static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num ) -{ - const void **entry = (const void **)(vtbl + 1); - DWORD i, j; - - if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) - { - FIXME( "%u methods not supported\n", num ); - return FALSE; - } - for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) - { - const struct thunk *block = method_blocks[i]; - if (!block && !(block = allocate_block( i ))) return FALSE; - for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++) - if (*entry == (LPVOID)-1) *entry = &block[j]; - } - return TRUE; + return NdrClientCall2(This->stubless->pStubDesc, fs, args); } #else /* __i386__ */ -static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num ) -{ - ERR("stubless proxies are not supported on this architecture\n"); - return FALSE; -} +/* can't do that on this arch */ +struct StublessThunk { int dummy; }; +#define FILL_STUBLESS(x,idx,stk) \ + ERR("stubless proxies are not supported on this architecture\n"); +#define STACK_ADJUST 0 #endif /* __i386__ */ -HRESULT StdProxy_Construct(REFIID riid, - LPUNKNOWN pUnkOuter, - const ProxyFileInfo *ProxyInfo, - int Index, - LPPSFACTORYBUFFER pPSFactory, - LPRPCPROXYBUFFER *ppProxy, - LPVOID *ppvObj) +HRESULT WINAPI StdProxy_Construct(REFIID riid, + LPUNKNOWN pUnkOuter, + const ProxyFileInfo *ProxyInfo, + int Index, + LPPSFACTORYBUFFER pPSFactory, + LPRPCPROXYBUFFER *ppProxy, + LPVOID *ppvObj) { StdProxyImpl *This; + const MIDL_STUBLESS_PROXY_INFO *stubless = NULL; PCInterfaceName name = ProxyInfo->pNamesArray[Index]; CInterfaceProxyVtbl *vtbl = ProxyInfo->pProxyVtblList[Index]; @@ -176,12 +129,14 @@ HRESULT StdProxy_Construct(REFIID riid, /* TableVersion = 2 means it is the stubless version of CInterfaceProxyVtbl */ if (ProxyInfo->TableVersion > 1) { - ULONG count = ProxyInfo->pStubVtblList[Index]->header.DispatchTableCount; + stubless = *(const void **)vtbl; vtbl = (CInterfaceProxyVtbl *)((const void **)vtbl + 1); - TRACE("stubless vtbl %p: count=%d\n", vtbl->Vtbl, count ); - fill_stubless_table( (IUnknownVtbl *)vtbl->Vtbl, count ); + TRACE("stubless=%p\n", stubless); } + TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid)); + TRACE("vtbl=%p\n", vtbl->Vtbl); + if (!IsEqualGUID(vtbl->header.piid, riid)) { ERR("IID mismatch during proxy creation\n"); return RPC_E_UNEXPECTED; @@ -190,37 +145,51 @@ HRESULT StdProxy_Construct(REFIID riid, This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(StdProxyImpl)); if (!This) return E_OUTOFMEMORY; - if (!pUnkOuter) pUnkOuter = (IUnknown *)This; + if (stubless) { + CInterfaceStubVtbl *svtbl = ProxyInfo->pStubVtblList[Index]; + unsigned long i, count = svtbl->header.DispatchTableCount; + /* Maybe the original vtbl is just modified directly to point at + * ObjectStublessClientXXX thunks in real Windows, but I don't like it + */ + TRACE("stubless thunks: count=%ld\n", count); + This->thunks = HeapAlloc(GetProcessHeap(),0,sizeof(struct StublessThunk)*count); + This->PVtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID)*count); + for (i=0; ithunks[i]; + if (vtbl->Vtbl[i] == (LPVOID)-1) { + PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[i]; + unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; + TRACE("method %ld: stacksize=%d\n", i, bytes); + FILL_STUBLESS(thunk, i, bytes) + This->PVtbl[i] = thunk; + } + else { + memset(thunk, 0, sizeof(struct StublessThunk)); + This->PVtbl[i] = vtbl->Vtbl[i]; + } + } + } + else + This->PVtbl = vtbl->Vtbl; + This->lpVtbl = &StdProxy_Vtbl; - This->PVtbl = vtbl->Vtbl; /* one reference for the proxy */ This->RefCount = 1; + This->stubless = stubless; This->piid = vtbl->header.piid; - This->base_object = NULL; - This->base_proxy = NULL; This->pUnkOuter = pUnkOuter; This->name = name; This->pPSFactory = pPSFactory; This->pChannel = NULL; - - if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index]) - { - HRESULT r = create_proxy( ProxyInfo->pDelegatedIIDs[Index], NULL, - &This->base_proxy, (void **)&This->base_object ); - if (FAILED(r)) - { - HeapFree( GetProcessHeap(), 0, This ); - return r; - } - } - *ppProxy = (LPRPCPROXYBUFFER)&This->lpVtbl; *ppvObj = &This->PVtbl; - IUnknown_AddRef((IUnknown *)*ppvObj); + /* if there is no outer unknown then the caller will control the lifetime + * of the proxy object through the proxy buffer, so no need to increment the + * ref count of the proxy object */ + if (pUnkOuter) + IUnknown_AddRef((IUnknown *)*ppvObj); IPSFactoryBuffer_AddRef(pPSFactory); - TRACE( "iid=%s this %p proxy %p obj %p vtbl %p base proxy %p base obj %p\n", - debugstr_guid(riid), This, *ppProxy, *ppvObj, This->PVtbl, This->base_proxy, This->base_object ); return S_OK; } @@ -231,10 +200,11 @@ static void StdProxy_Destruct(LPRPCPROXYBUFFER iface) if (This->pChannel) IRpcProxyBuffer_Disconnect(iface); - if (This->base_object) IUnknown_Release( This->base_object ); - if (This->base_proxy) IRpcProxyBuffer_Release( This->base_proxy ); - IPSFactoryBuffer_Release(This->pPSFactory); + if (This->thunks) { + HeapFree(GetProcessHeap(),0,This->PVtbl); + HeapFree(GetProcessHeap(),0,This->thunks); + } HeapFree(GetProcessHeap(),0,This); } @@ -289,7 +259,6 @@ static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface, This->pChannel = pChannel; IRpcChannelBuffer_AddRef(pChannel); - if (This->base_proxy) IRpcProxyBuffer_Connect( This->base_proxy, pChannel ); return S_OK; } @@ -298,8 +267,6 @@ static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface) ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); TRACE("(%p)->Disconnect()\n",This); - if (This->base_proxy) IRpcProxyBuffer_Disconnect( This->base_proxy ); - IRpcChannelBuffer_Release(This->pChannel); This->pChannel = NULL; } diff --git a/reactos/dll/win32/rpcrt4/cpsf.c b/reactos/dll/win32/rpcrt4/cpsf.c index ac1eccf56fa..bece899d964 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.c +++ b/reactos/dll/win32/rpcrt4/cpsf.c @@ -145,41 +145,6 @@ static const IPSFactoryBufferVtbl CStdPSFactory_Vtbl = CStdPSFactory_CreateStub }; - -static void init_psfactory( CStdPSFactoryBuffer *psfac, const ProxyFileInfo **file_list ) -{ - DWORD i, j, k; - - psfac->lpVtbl = &CStdPSFactory_Vtbl; - psfac->RefCount = 0; - psfac->pProxyFileList = file_list; - for (i = 0; file_list[i]; i++) - { - const PCInterfaceProxyVtblList *proxies = file_list[i]->pProxyVtblList; - const PCInterfaceStubVtblList *stubs = file_list[i]->pStubVtblList; - - for (j = 0; j < file_list[i]->TableSize; j++) - { - /* FIXME: i think that different vtables should be copied for - * async interfaces */ - void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl; - void **pRpcStubVtbl = (void **)&stubs[j]->Vtbl; - - if (file_list[i]->pDelegatedIIDs && file_list[i]->pDelegatedIIDs[j]) - { - void **vtbl = proxies[j]->Vtbl; - if (file_list[i]->TableVersion > 1) vtbl++; - fill_delegated_proxy_table( (IUnknownVtbl *)vtbl, stubs[j]->header.DispatchTableCount ); - pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl; - } - - for (k = 0; k < sizeof(IRpcStubBufferVtbl)/sizeof(void *); k++) - if (!pRpcStubVtbl[k]) pRpcStubVtbl[k] = pSrcRpcStubVtbl[k]; - } - } -} - - /*********************************************************************** * NdrDllGetClassObject [RPCRT4.@] */ @@ -193,8 +158,35 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, pPSFactoryBuffer); *ppv = NULL; - if (!pPSFactoryBuffer->lpVtbl) init_psfactory( pPSFactoryBuffer, pProxyFileList ); + if (!pPSFactoryBuffer->lpVtbl) { + const ProxyFileInfo **pProxyFileList2; + DWORD max_delegating_vtbl_size = 0; + pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl; + pPSFactoryBuffer->RefCount = 0; + pPSFactoryBuffer->pProxyFileList = pProxyFileList; + for (pProxyFileList2 = pProxyFileList; *pProxyFileList2; pProxyFileList2++) { + int i; + for (i = 0; i < (*pProxyFileList2)->TableSize; i++) { + /* FIXME: i think that different vtables should be copied for + * async interfaces */ + void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl; + void **pRpcStubVtbl = (void **)&(*pProxyFileList2)->pStubVtblList[i]->Vtbl; + unsigned int j; + if ((*pProxyFileList2)->pDelegatedIIDs && (*pProxyFileList2)->pDelegatedIIDs[i]) { + pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl; + if ((*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount > max_delegating_vtbl_size) + max_delegating_vtbl_size = (*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount; + } + + for (j = 0; j < sizeof(IRpcStubBufferVtbl)/sizeof(void *); j++) + if (!pRpcStubVtbl[j]) + pRpcStubVtbl[j] = pSrcRpcStubVtbl[j]; + } + } + if(max_delegating_vtbl_size > 0) + create_delegating_vtbl(max_delegating_vtbl_size); + } if (pclsid && IsEqualGUID(rclsid, pclsid)) return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); else { @@ -215,7 +207,7 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, */ HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer) { - return pPSFactoryBuffer->RefCount != 0 ? S_FALSE : S_OK; + return !(pPSFactoryBuffer->RefCount); } @@ -274,7 +266,7 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll, if (len && len < sizeof(module)) { TRACE("registering CLSID %s => %s\n", debugstr_w(clsid), debugstr_w(module)); if (RegCreateKeyW(HKEY_CLASSES_ROOT, keyname, &key) == ERROR_SUCCESS) { - RegSetValueExW(key, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW)); + RegSetValueExW(subkey, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW)); if (RegCreateKeyW(key, inprocserverW, &subkey) == ERROR_SUCCESS) { RegSetValueExW(subkey, NULL, 0, REG_SZ, (LPBYTE)module, (strlenW(module)+1)*sizeof(WCHAR)); RegSetValueExW(subkey, threadingmodelW, 0, REG_SZ, (const BYTE *)bothW, sizeof(bothW)); diff --git a/reactos/dll/win32/rpcrt4/cpsf.h b/reactos/dll/win32/rpcrt4/cpsf.h index 9cc046ff7ca..d8867d40e60 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.h +++ b/reactos/dll/win32/rpcrt4/cpsf.h @@ -21,25 +21,36 @@ #ifndef __WINE_CPSF_H #define __WINE_CPSF_H -HRESULT StdProxy_Construct(REFIID riid, LPUNKNOWN pUnkOuter, const ProxyFileInfo *ProxyInfo, - int Index, LPPSFACTORYBUFFER pPSFactory, LPRPCPROXYBUFFER *ppProxy, - LPVOID *ppvObj); +HRESULT WINAPI StdProxy_Construct(REFIID riid, + LPUNKNOWN pUnkOuter, + const ProxyFileInfo *ProxyInfo, + int Index, + LPPSFACTORYBUFFER pPSFactory, + LPRPCPROXYBUFFER *ppProxy, + LPVOID *ppvObj); -HRESULT CStdStubBuffer_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name, - CInterfaceStubVtbl *vtbl, LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub); +HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub); -HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name, - CInterfaceStubVtbl *vtbl, REFIID delegating_iid, - LPPSFACTORYBUFFER pPSFactory, LPRPCSTUBBUFFER *ppStub); +HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + REFIID delegating_iid, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub); const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface); const IRpcStubBufferVtbl CStdStubBuffer_Vtbl; const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl; -BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num); -HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv); +void create_delegating_vtbl(DWORD num_methods); + HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub); #endif /* __WINE_CPSF_H */ diff --git a/reactos/dll/win32/rpcrt4/cstub.c b/reactos/dll/win32/rpcrt4/cstub.c index 95ac1d89af2..85411cd81e9 100644 --- a/reactos/dll/win32/rpcrt4/cstub.c +++ b/reactos/dll/win32/rpcrt4/cstub.c @@ -2,7 +2,6 @@ * COM stub (CStdStubBuffer) implementation * * Copyright 2001 Ove Kåven, TransGaming Technologies - * Copyright 2009 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -62,12 +61,12 @@ static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer return (cstdstubbuffer_delegating_t*)((char *)iface - FIELD_OFFSET(cstdstubbuffer_delegating_t, stub_buffer)); } -HRESULT CStdStubBuffer_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub) +HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub) { CStdStubBuffer *This; IUnknown *pvServer; @@ -114,16 +113,20 @@ typedef struct { DWORD ref; DWORD size; + void **methods; IUnknownVtbl vtbl; /* remaining entries in vtbl */ } ref_counted_vtbl; -static ref_counted_vtbl *current_vtbl; +static struct +{ + ref_counted_vtbl *table; +} current_vtbl; static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv) { - *ppv = pUnk; + *ppv = (void *)pUnk; return S_OK; } @@ -158,137 +161,87 @@ typedef struct { } vtbl_method_t; #include "poppack.h" -#define BLOCK_SIZE 1024 -#define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */ - -static const vtbl_method_t *method_blocks[MAX_BLOCKS]; - -static const vtbl_method_t *allocate_block( unsigned int num ) +static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num) { - unsigned int i; - vtbl_method_t *prev, *block; + vtbl_method_t *method; + void **entry; + DWORD i; - block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block), - MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); - if (!block) return NULL; - - for (i = 0; i < BLOCK_SIZE; i++) - { - block[i].mov1 = 0x0424448b; - block[i].mov2 = 0x408b; - block[i].sixteen = 0x10; - block[i].mov3 = 0x04244489; - block[i].mov4 = 0x008b; - block[i].mov5 = 0x808b; - block[i].offset = (BLOCK_SIZE * num + i + 3) << 2; - block[i].jmp = 0xe0ff; - block[i].pad[0] = 0x8d; - block[i].pad[1] = 0x76; - block[i].pad[2] = 0x00; - } - VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL ); - prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL ); - if (prev) /* someone beat us to it */ - { - VirtualFree( block, 0, MEM_RELEASE ); - block = prev; - } - return block; -} - -static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num) -{ - const void **entry = (const void **)(vtbl + 1); - DWORD i, j; - - if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) - { - FIXME( "%u methods not supported\n", num ); - return FALSE; - } vtbl->QueryInterface = delegating_QueryInterface; vtbl->AddRef = delegating_AddRef; vtbl->Release = delegating_Release; - for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) - { - const vtbl_method_t *block = method_blocks[i]; - if (!block && !(block = allocate_block( i ))) return FALSE; - for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++) *entry++ = &block[j]; - } - return TRUE; -} -BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) -{ - const void **entry = (const void **)(vtbl + 1); - DWORD i, j; + method = (vtbl_method_t*)methods; + entry = (void**)(vtbl + 1); - if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) + for(i = 3; i < num; i++) { - FIXME( "%u methods not supported\n", num ); - return FALSE; + *entry = method; + method->mov1 = 0x0424448b; + method->mov2 = 0x408b; + method->sixteen = 0x10; + method->mov3 = 0x04244489; + method->mov4 = 0x008b; + method->mov5 = 0x808b; + method->offset = i << 2; + method->jmp = 0xe0ff; + method->pad[0] = 0x8d; + method->pad[1] = 0x76; + method->pad[2] = 0x00; + + method++; + entry++; } - vtbl->QueryInterface = IUnknown_QueryInterface_Proxy; - vtbl->AddRef = IUnknown_AddRef_Proxy; - vtbl->Release = IUnknown_Release_Proxy; - for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) - { - const vtbl_method_t *block = method_blocks[i]; - if (!block && !(block = allocate_block( i ))) return FALSE; - for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++) - if (!*entry) *entry = &block[j]; - } - return TRUE; } #else /* __i386__ */ -static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num) +typedef struct {int dummy;} vtbl_method_t; +static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num) { ERR("delegated stubs are not supported on this architecture\n"); - return FALSE; -} - -BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) -{ - ERR("delegated proxies are not supported on this architecture\n"); - return FALSE; } #endif /* __i386__ */ -static IUnknownVtbl *get_delegating_vtbl(DWORD num_methods) +void create_delegating_vtbl(DWORD num_methods) +{ + TRACE("%d\n", num_methods); + if(num_methods <= 3) + { + ERR("should have more than %d methods\n", num_methods); + return; + } + + EnterCriticalSection(&delegating_vtbl_section); + if(!current_vtbl.table || num_methods > current_vtbl.table->size) + { + DWORD size; + DWORD old_protect; + if(current_vtbl.table && current_vtbl.table->ref == 0) + { + TRACE("freeing old table\n"); + VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE); + HeapFree(GetProcessHeap(), 0, current_vtbl.table); + } + size = (num_methods - 3) * sizeof(vtbl_method_t); + current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*)); + current_vtbl.table->ref = 0; + current_vtbl.table->size = num_methods; + current_vtbl.table->methods = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + fill_table(¤t_vtbl.table->vtbl, current_vtbl.table->methods, num_methods); + VirtualProtect(current_vtbl.table->methods, size, PAGE_EXECUTE_READ, &old_protect); + } + LeaveCriticalSection(&delegating_vtbl_section); +} + +static IUnknownVtbl *get_delegating_vtbl(void) { IUnknownVtbl *ret; - if (num_methods < 256) num_methods = 256; /* avoid frequent reallocations */ - EnterCriticalSection(&delegating_vtbl_section); - - if(!current_vtbl || num_methods > current_vtbl->size) - { - ref_counted_vtbl *table = HeapAlloc(GetProcessHeap(), 0, - FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*)); - if (!table) - { - LeaveCriticalSection(&delegating_vtbl_section); - return NULL; - } - - table->ref = 0; - table->size = num_methods; - fill_delegated_stub_table(&table->vtbl, num_methods); - - if (current_vtbl && current_vtbl->ref == 0) - { - TRACE("freeing old table\n"); - HeapFree(GetProcessHeap(), 0, current_vtbl); - } - current_vtbl = table; - } - - current_vtbl->ref++; - ret = ¤t_vtbl->vtbl; + current_vtbl.table->ref++; + ret = ¤t_vtbl.table->vtbl; LeaveCriticalSection(&delegating_vtbl_section); return ret; } @@ -300,21 +253,22 @@ static void release_delegating_vtbl(IUnknownVtbl *vtbl) EnterCriticalSection(&delegating_vtbl_section); table->ref--; TRACE("ref now %d\n", table->ref); - if(table->ref == 0 && table != current_vtbl) + if(table->ref == 0 && table != current_vtbl.table) { TRACE("... and we're not current so free'ing\n"); + VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE); HeapFree(GetProcessHeap(), 0, table); } LeaveCriticalSection(&delegating_vtbl_section); } -HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - REFIID delegating_iid, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub) +HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + REFIID delegating_iid, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub) { cstdstubbuffer_delegating_t *This; IUnknown *pvServer; @@ -340,7 +294,7 @@ HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, return E_OUTOFMEMORY; } - This->base_obj = get_delegating_vtbl( vtbl->header.DispatchTableCount ); + This->base_obj = get_delegating_vtbl(); r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub); if(FAILED(r)) { diff --git a/reactos/dll/win32/rpcrt4/epm_towers.h b/reactos/dll/win32/rpcrt4/epm_towers.h index 3eec37aa228..1afd3eb3376 100644 --- a/reactos/dll/win32/rpcrt4/epm_towers.h +++ b/reactos/dll/win32/rpcrt4/epm_towers.h @@ -19,7 +19,7 @@ * */ -#include "epm.h" +#include "epm_c.h" #define EPM_PROTOCOL_DNET_NSP 0x04 #define EPM_PROTOCOL_OSI_TP4 0x05 diff --git a/reactos/dll/win32/rpcrt4/ndr_contexthandle.c b/reactos/dll/win32/rpcrt4/ndr_contexthandle.c index cab0fc5d86e..15192a72878 100644 --- a/reactos/dll/win32/rpcrt4/ndr_contexthandle.c +++ b/reactos/dll/win32/rpcrt4/ndr_contexthandle.c @@ -59,7 +59,7 @@ static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 }; static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext) { - struct context_handle_entry *che = CContext; + struct context_handle_entry *che = (struct context_handle_entry*) CContext; if (che->magic != NDR_CONTEXT_HANDLE_MAGIC) return NULL; @@ -111,7 +111,7 @@ void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff) } else { - ndr_context_handle *wire_data = pBuff; + ndr_context_handle *wire_data = (ndr_context_handle *)pBuff; wire_data->attributes = 0; wire_data->uuid = GUID_NULL; } diff --git a/reactos/dll/win32/rpcrt4/ndr_misc.h b/reactos/dll/win32/rpcrt4/ndr_misc.h index b0150c3a2eb..c3beff4d725 100644 --- a/reactos/dll/win32/rpcrt4/ndr_misc.h +++ b/reactos/dll/win32/rpcrt4/ndr_misc.h @@ -62,6 +62,6 @@ extern const NDR_BUFFERSIZE NdrBufferSizer[]; extern const NDR_MEMORYSIZE NdrMemorySizer[]; extern const NDR_FREE NdrFreer[]; -ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat); +unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat); #endif /* __WINE_NDR_MISC_H */ diff --git a/reactos/dll/win32/rpcrt4/ndr_ole.c b/reactos/dll/win32/rpcrt4/ndr_ole.c index a4c23c2c5c2..a3264e70122 100644 --- a/reactos/dll/win32/rpcrt4/ndr_ole.c +++ b/reactos/dll/win32/rpcrt4/ndr_ole.c @@ -369,30 +369,6 @@ void WINAPI NdrOleFree(void *NodeToFree) COM_MemFree(NodeToFree); } -/*********************************************************************** - * Helper function to create a proxy. - * Probably similar to NdrpCreateProxy. - */ -HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv) -{ - CLSID clsid; - IPSFactoryBuffer *psfac; - HRESULT r; - - if(!LoadCOM()) return E_FAIL; - - r = COM_GetPSClsid( iid, &clsid ); - if(FAILED(r)) return r; - - r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac ); - if(FAILED(r)) return r; - - r = IPSFactoryBuffer_CreateProxy(psfac, pUnkOuter, iid, pproxy, ppv); - - IPSFactoryBuffer_Release(psfac); - return r; -} - /*********************************************************************** * Helper function to create a stub. * This probably looks very much like NdrpCreateStub. diff --git a/reactos/dll/win32/rpcrt4/ndr_stubless.c b/reactos/dll/win32/rpcrt4/ndr_stubless.c index 8cb5f2b5e45..645a0ca4729 100644 --- a/reactos/dll/win32/rpcrt4/ndr_stubless.c +++ b/reactos/dll/win32/rpcrt4/ndr_stubless.c @@ -173,7 +173,7 @@ static PFORMAT_STRING client_get_handle( if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); else - pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); + pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; *phBinding = pGenPair->pfnBind(pObject); @@ -256,7 +256,7 @@ static void client_free_handle( if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); else - pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); + pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; pGenPair->pfnUnbind(pObject, hBinding); @@ -867,14 +867,9 @@ __declspec(naked) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigne LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size); __ASM_GLOBAL_FUNC(call_server_func, "pushl %ebp\n\t" - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") - "movl %esp,%ebp\n\t" - __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") + "movl %esp, %ebp\n\t" "pushl %edi\n\t" /* Save registers */ - __ASM_CFI(".cfi_rel_offset %edi,-4\n\t") "pushl %esi\n\t" - __ASM_CFI(".cfi_rel_offset %esi,-8\n\t") "movl 16(%ebp), %eax\n\t" /* Get stack size */ "subl %eax, %esp\n\t" /* Make room in stack for arguments */ "andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for Mac OS X */ @@ -887,13 +882,9 @@ __ASM_GLOBAL_FUNC(call_server_func, "call *8(%ebp)\n\t" /* Call function */ "leal -8(%ebp), %esp\n\t" /* Restore stack */ "popl %esi\n\t" /* Restore registers */ - __ASM_CFI(".cfi_same_value %esi\n\t") "popl %edi\n\t" - __ASM_CFI(".cfi_same_value %edi\n\t") "popl %ebp\n\t" - __ASM_CFI(".cfi_def_cfa %esp,4\n\t") - __ASM_CFI(".cfi_same_value %ebp\n\t") - "ret" ) + "ret\n" ) #else #warning call_server_func not implemented for your architecture LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size) @@ -1531,339 +1522,3 @@ void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg) DWORD dwPhase; NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase); } - -struct async_call_data -{ - MIDL_STUB_MESSAGE *pStubMsg; - const NDR_PROC_HEADER *pProcHeader; - PFORMAT_STRING pHandleFormat; - PFORMAT_STRING pParamFormat; - RPC_BINDING_HANDLE hBinding; - /* size of stack */ - unsigned short stack_size; - /* number of parameters. optional for client to give it to us */ - unsigned char number_of_params; - /* correlation cache */ - unsigned long NdrCorrCache[256]; -}; - -LONG_PTR WINAPIV NdrAsyncClientCall(PMIDL_STUB_DESC pStubDesc, - PFORMAT_STRING pFormat, ...) -{ - /* pointer to start of stack where arguments start */ - PRPC_MESSAGE pRpcMsg; - PMIDL_STUB_MESSAGE pStubMsg; - RPC_ASYNC_STATE *pAsync; - struct async_call_data *async_call_data; - /* procedure number */ - unsigned short procedure_number; - /* cache of Oif_flags from v2 procedure header */ - INTERPRETER_OPT_FLAGS Oif_flags = { 0 }; - /* cache of extension flags from NDR_PROC_HEADER_EXTS */ - INTERPRETER_OPT_FLAGS2 ext_flags = { 0 }; - /* the type of pass we are currently doing */ - int phase; - /* header for procedure string */ - const NDR_PROC_HEADER * pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; - /* -Oif or -Oicf generated format */ - BOOL bV2Format = FALSE; - - TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat); - - /* Later NDR language versions probably won't be backwards compatible */ - if (pStubDesc->Version > 0x50002) - { - FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version); - RpcRaiseException(RPC_X_WRONG_STUB_VERSION); - } - - async_call_data = I_RpcAllocate(sizeof(*async_call_data) + sizeof(MIDL_STUB_MESSAGE) + sizeof(RPC_MESSAGE)); - if (!async_call_data) RpcRaiseException(ERROR_OUTOFMEMORY); - async_call_data->number_of_params = ~0; - async_call_data->pProcHeader = pProcHeader; - - async_call_data->pStubMsg = pStubMsg = (PMIDL_STUB_MESSAGE)(async_call_data + 1); - pRpcMsg = (PRPC_MESSAGE)(pStubMsg + 1); - - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) - { - const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; - async_call_data->stack_size = pProcHeader->stack_size; - procedure_number = pProcHeader->proc_num; - pFormat += sizeof(NDR_PROC_HEADER_RPC); - } - else - { - async_call_data->stack_size = pProcHeader->stack_size; - procedure_number = pProcHeader->proc_num; - pFormat += sizeof(NDR_PROC_HEADER); - } - TRACE("stack size: 0x%x\n", async_call_data->stack_size); - TRACE("proc num: %d\n", procedure_number); - - /* create the full pointer translation tables, if requested */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) - pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); - - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - { - ERR("objects not supported\n"); - I_RpcFree(async_call_data); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDesc, procedure_number); - - TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); - TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion); - - /* needed for conformance of top-level objects */ -#ifdef __i386__ - pStubMsg->StackTop = I_RpcAllocate(async_call_data->stack_size); - /* FIXME: this may read one more DWORD than is necessary, but it shouldn't hurt */ - memcpy(pStubMsg->StackTop, *(unsigned char **)(&pFormat+1), async_call_data->stack_size); -#else -# warning Stack not retrieved for your CPU architecture -#endif - - pAsync = *(RPC_ASYNC_STATE **)pStubMsg->StackTop; - pAsync->StubInfo = async_call_data; - async_call_data->pHandleFormat = pFormat; - - pFormat = client_get_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, &async_call_data->hBinding); - if (!pFormat) return 0; - - bV2Format = (pStubDesc->Version >= 0x20000); - - if (bV2Format) - { - const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader = - (const NDR_PROC_PARTIAL_OIF_HEADER *)pFormat; - - Oif_flags = pOIFHeader->Oi2Flags; - async_call_data->number_of_params = pOIFHeader->number_of_params; - - pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); - } - - TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags); - - if (Oif_flags.HasExtensions) - { - const NDR_PROC_HEADER_EXTS *pExtensions = - (const NDR_PROC_HEADER_EXTS *)pFormat; - ext_flags = pExtensions->Flags2; - pFormat += pExtensions->Size; - } - - async_call_data->pParamFormat = pFormat; - - pStubMsg->BufferLength = 0; - - /* store the RPC flags away */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) - pRpcMsg->RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; - - /* use alternate memory allocation routines */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC) - NdrRpcSmSetClientToOsf(pStubMsg); - - if (Oif_flags.HasPipes) - { - FIXME("pipes not supported yet\n"); - RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ - /* init pipes package */ - /* NdrPipesInitialize(...) */ - } - if (ext_flags.HasNewCorrDesc) - { - /* initialize extra correlation package */ - NdrCorrelationInitialize(pStubMsg, async_call_data->NdrCorrCache, sizeof(async_call_data->NdrCorrCache), 0); - } - - /* order of phases: - * 1. PROXY_CALCSIZE - calculate the buffer size - * 2. PROXY_GETBUFFER - allocate the buffer - * 3. PROXY_MARHSAL - marshal [in] params into the buffer - * 4. PROXY_SENDRECEIVE - send buffer - * Then in NdrpCompleteAsyncClientCall: - * 1. PROXY_SENDRECEIVE - receive buffer - * 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer - */ - for (phase = PROXY_CALCSIZE; phase <= PROXY_SENDRECEIVE; phase++) - { - RPC_STATUS status; - TRACE("phase = %d\n", phase); - switch (phase) - { - case PROXY_GETBUFFER: - /* allocate the buffer */ - if (Oif_flags.HasPipes) - /* NdrGetPipeBuffer(...) */ - FIXME("pipes not supported yet\n"); - else - { - if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) -#if 0 - NdrNsGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding); -#else - FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n"); -#endif - else - NdrGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding); - } - pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC; - status = I_RpcAsyncSetHandle(pRpcMsg, pAsync); - if (status != RPC_S_OK) - RpcRaiseException(status); - break; - case PROXY_SENDRECEIVE: - pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC; - /* send the [in] params only */ - if (Oif_flags.HasPipes) - /* NdrPipesSend(...) */ - FIXME("pipes not supported yet\n"); - else - { - if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) -#if 0 - NdrNsSend(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle); -#else - FIXME("using auto handle - call NdrNsSend when it gets implemented\n"); -#endif - else - { - pStubMsg->RpcMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer; - status = I_RpcSend(pStubMsg->RpcMsg); - if (status != RPC_S_OK) - RpcRaiseException(status); - } - } - - break; - case PROXY_CALCSIZE: - case PROXY_MARSHAL: - if (bV2Format) - client_do_args(pStubMsg, pFormat, phase, pStubMsg->StackTop, - async_call_data->number_of_params, NULL); - else - client_do_args_old_format(pStubMsg, pFormat, phase, - pStubMsg->StackTop, async_call_data->stack_size, NULL, - (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT), FALSE); - break; - default: - ERR("shouldn't reach here. phase %d\n", phase); - break; - } - } - - TRACE("returning 0\n"); - return 0; -} - -RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply) -{ - /* pointer to start of stack where arguments start */ - PMIDL_STUB_MESSAGE pStubMsg; - struct async_call_data *async_call_data; - /* the type of pass we are currently doing */ - int phase; - /* header for procedure string */ - const NDR_PROC_HEADER * pProcHeader; - /* -Oif or -Oicf generated format */ - BOOL bV2Format; - RPC_STATUS status = RPC_S_OK; - - if (!pAsync->StubInfo) - return RPC_S_INVALID_ASYNC_HANDLE; - - async_call_data = pAsync->StubInfo; - pStubMsg = async_call_data->pStubMsg; - pProcHeader = async_call_data->pProcHeader; - - bV2Format = (pStubMsg->StubDesc->Version >= 0x20000); - - /* order of phases: - * 1. PROXY_CALCSIZE - calculate the buffer size - * 2. PROXY_GETBUFFER - allocate the buffer - * 3. PROXY_MARHSAL - marshal [in] params into the buffer - * 4. PROXY_SENDRECEIVE - send buffer - * Then in NdrpCompleteAsyncClientCall: - * 1. PROXY_SENDRECEIVE - receive buffer - * 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer - */ - for (phase = PROXY_SENDRECEIVE; phase <= PROXY_UNMARSHAL; phase++) - { - switch (phase) - { - case PROXY_SENDRECEIVE: - pStubMsg->RpcMsg->RpcFlags |= RPC_BUFFER_ASYNC; - /* receive the [out] params */ - if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) -#if 0 - NdrNsReceive(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle); -#else - FIXME("using auto handle - call NdrNsReceive when it gets implemented\n"); -#endif - else - { - status = I_RpcReceive(pStubMsg->RpcMsg); - if (status != RPC_S_OK) - goto cleanup; - pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength; - pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; - pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; - pStubMsg->Buffer = pStubMsg->BufferStart; - } - - /* convert strings, floating point values and endianess into our - * preferred format */ -#if 0 - if ((pStubMsg->RpcMsg.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION) - NdrConvert(pStubMsg, pFormat); -#endif - - break; - case PROXY_UNMARSHAL: - if (bV2Format) - client_do_args(pStubMsg, async_call_data->pParamFormat, phase, pStubMsg->StackTop, - async_call_data->number_of_params, Reply); - else - client_do_args_old_format(pStubMsg, async_call_data->pParamFormat, phase, - pStubMsg->StackTop, async_call_data->stack_size, Reply, FALSE, FALSE); - break; - default: - ERR("shouldn't reach here. phase %d\n", phase); - break; - } - } - -cleanup: - if (pStubMsg->fHasNewCorrDesc) - { - /* free extra correlation package */ - NdrCorrelationFree(pStubMsg); - } - - /* free the full pointer translation tables */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) - NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables); - - /* free marshalling buffer */ - NdrFreeBuffer(pStubMsg); - client_free_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, async_call_data->hBinding); - - I_RpcFree(pStubMsg->StackTop); - I_RpcFree(async_call_data); - - TRACE("-- 0x%x\n", status); - return status; -} - -RPCRTAPI LONG RPC_ENTRY NdrAsyncStubCall(struct IRpcStubBuffer* pThis, - struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, - DWORD * pdwStubPhase) -{ - FIXME("unimplemented, expect crash!\n"); - return 0; -} diff --git a/reactos/dll/win32/rpcrt4/ndr_stubless.h b/reactos/dll/win32/rpcrt4/ndr_stubless.h index 87f603b6065..9a6fb444783 100644 --- a/reactos/dll/win32/rpcrt4/ndr_stubless.h +++ b/reactos/dll/win32/rpcrt4/ndr_stubless.h @@ -85,7 +85,7 @@ typedef struct _NDR_PROC_HEADER_RPC * RPCF_Asynchronous = 0x4000 - [async] MIDL attribute * Reserved = 0x8000 */ - unsigned int rpc_flags; + unsigned long rpc_flags; unsigned short proc_num; unsigned short stack_size; @@ -240,4 +240,3 @@ void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, int phase, unsigned char *args, unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc, BOOL ignore_retval); -RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply); diff --git a/reactos/dll/win32/rpcrt4/rpc_assoc.c b/reactos/dll/win32/rpcrt4/rpc_assoc.c index 117301f42c0..32e951a929a 100644 --- a/reactos/dll/win32/rpcrt4/rpc_assoc.c +++ b/reactos/dll/win32/rpcrt4/rpc_assoc.c @@ -125,7 +125,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, - ULONG assoc_gid, + unsigned long assoc_gid, RpcAssoc **assoc_out) { RpcAssoc *assoc; @@ -223,7 +223,7 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection * RPC_MESSAGE msg; RPC_STATUS status; unsigned char *auth_data = NULL; - ULONG auth_length; + unsigned long auth_length; TRACE("sending bind request to server\n"); @@ -394,7 +394,6 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, if (status != RPC_S_OK) return status; - NewConnection->assoc = assoc; status = RPCRT4_OpenClientConnection(NewConnection); if (status != RPC_S_OK) { @@ -417,7 +416,6 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection) { assert(!Connection->server); - Connection->async_state = NULL; EnterCriticalSection(&assoc->cs); if (!assoc->assoc_group_id) assoc->assoc_group_id = Connection->assoc_group_id; list_add_head(&assoc->free_connection_pool, &Connection->conn_pool_entry); diff --git a/reactos/dll/win32/rpcrt4/rpc_assoc.h b/reactos/dll/win32/rpcrt4/rpc_assoc.h index 70fb664e31d..1ce1f135638 100644 --- a/reactos/dll/win32/rpcrt4/rpc_assoc.h +++ b/reactos/dll/win32/rpcrt4/rpc_assoc.h @@ -34,7 +34,6 @@ typedef struct _RpcAssoc /* id of this association group */ ULONG assoc_group_id; - UUID http_uuid; CRITICAL_SECTION cs; @@ -50,7 +49,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endp RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, RpcConnection **Connection); void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection); ULONG RpcAssoc_Release(RpcAssoc *assoc); -RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, ULONG assoc_gid, RpcAssoc **assoc_out); +RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, unsigned long assoc_gid, RpcAssoc **assoc_out); RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext); RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext); RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine); diff --git a/reactos/dll/win32/rpcrt4/rpc_async.c b/reactos/dll/win32/rpcrt4/rpc_async.c index 891fc5ad725..33fdc774304 100644 --- a/reactos/dll/win32/rpcrt4/rpc_async.c +++ b/reactos/dll/win32/rpcrt4/rpc_async.c @@ -29,17 +29,11 @@ #include "rpc_binding.h" #include "rpc_message.h" -#include "ndr_stubless.h" WINE_DEFAULT_DEBUG_CHANNEL(rpc); #define RPC_ASYNC_SIGNATURE 0x43595341 -static inline BOOL valid_async_handle(PRPC_ASYNC_STATE pAsync) -{ - return pAsync->Signature == RPC_ASYNC_SIGNATURE; -} - /*********************************************************************** * RpcAsyncInitializeHandle [RPCRT4.@] * @@ -110,14 +104,8 @@ RPC_STATUS WINAPI RpcAsyncGetCallStatus(PRPC_ASYNC_STATE pAsync) */ RPC_STATUS WINAPI RpcAsyncCompleteCall(PRPC_ASYNC_STATE pAsync, void *Reply) { - TRACE("(%p, %p)\n", pAsync, Reply); - - if (!valid_async_handle(pAsync)) - return RPC_S_INVALID_ASYNC_HANDLE; - - /* FIXME: check completed */ - - return NdrpCompleteAsyncClientCall(pAsync, Reply); + FIXME("(%p, %p): stub\n", pAsync, Reply); + return RPC_S_INVALID_ASYNC_HANDLE; } /*********************************************************************** diff --git a/reactos/dll/win32/rpcrt4/rpc_binding.c b/reactos/dll/win32/rpcrt4/rpc_binding.c index 29e0709e54f..696887cb7b3 100644 --- a/reactos/dll/win32/rpcrt4/rpc_binding.c +++ b/reactos/dll/win32/rpcrt4/rpc_binding.c @@ -661,11 +661,11 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU return RPC_S_OK; fail: - if (ObjUuid) RpcStringFreeA(ObjUuid); - if (Protseq) RpcStringFreeA(Protseq); - if (NetworkAddr) RpcStringFreeA(NetworkAddr); - if (Endpoint) RpcStringFreeA(Endpoint); - if (Options) RpcStringFreeA(Options); + if (ObjUuid) RpcStringFreeA((unsigned char**)ObjUuid); + if (Protseq) RpcStringFreeA((unsigned char**)Protseq); + if (NetworkAddr) RpcStringFreeA((unsigned char**)NetworkAddr); + if (Endpoint) RpcStringFreeA((unsigned char**)Endpoint); + if (Options) RpcStringFreeA((unsigned char**)Options); return RPC_S_INVALID_STRING_BINDING; } @@ -796,7 +796,7 @@ RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding ) RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ) { RPC_STATUS status; - ULONG c; + unsigned long c; TRACE("(%p)\n", BindingVector); for (c=0; c<(*BindingVector)->Count; c++) { @@ -812,7 +812,7 @@ RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ) */ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ) { - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; TRACE("(%p,%p) = %s\n", Binding, ObjectUuid, debugstr_guid(&bind->ObjectUuid)); *ObjectUuid = bind->ObjectUuid; @@ -824,7 +824,7 @@ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU */ RPC_STATUS WINAPI RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ) { - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; TRACE("(%p,%s)\n", Binding, debugstr_guid(ObjectUuid)); if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING; @@ -856,11 +856,11 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BIND if (ret == RPC_S_OK) ret = RPCRT4_CompleteBindingA(bind, (char*)NetworkAddr, (char*)Endpoint, (char*)Options); - RpcStringFreeA(&Options); - RpcStringFreeA(&Endpoint); - RpcStringFreeA(&NetworkAddr); - RpcStringFreeA(&Protseq); - RpcStringFreeA(&ObjectUuid); + RpcStringFreeA((unsigned char**)&Options); + RpcStringFreeA((unsigned char**)&Endpoint); + RpcStringFreeA((unsigned char**)&NetworkAddr); + RpcStringFreeA((unsigned char**)&Protseq); + RpcStringFreeA((unsigned char**)&ObjectUuid); if (ret == RPC_S_OK) *Binding = (RPC_BINDING_HANDLE)bind; @@ -915,7 +915,7 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BIND RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CSTR *StringBinding ) { RPC_STATUS ret; - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; RPC_CSTR ObjectUuid; TRACE("(%p,%p)\n", Binding, StringBinding); @@ -946,7 +946,7 @@ RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, RPC_WS TRACE("(%p,%p)\n", Binding, StringBinding); ret = RpcBindingToStringBindingA(Binding, &str); *StringBinding = RPCRT4_strdupAtoW((char*)str); - RpcStringFreeA(&str); + RpcStringFreeA((unsigned char**)&str); return ret; } @@ -969,7 +969,7 @@ RPC_STATUS WINAPI I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding, unsi */ RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn) { - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; TRACE( "(%p,%p): stub\n", Binding, BlockingFn ); @@ -986,7 +986,7 @@ RPC_STATUS RPC_ENTRY RpcBindingCopy( RPC_BINDING_HANDLE* DestinationBinding) { RpcBinding *DestBinding; - RpcBinding *SrcBinding = SourceBinding; + RpcBinding *SrcBinding = (RpcBinding*)SourceBinding; RPC_STATUS status; TRACE("(%p, %p)\n", SourceBinding, DestinationBinding); @@ -1501,7 +1501,7 @@ RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr, RPC_SECURITY_QOS *SecurityQos ) { - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; SECURITY_STATUS r; CredHandle cred; TimeStamp exp; @@ -1631,7 +1631,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr, RPC_SECURITY_QOS *SecurityQos ) { - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; SECURITY_STATUS r; CredHandle cred; TimeStamp exp; @@ -1640,7 +1640,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, PSecPkgInfoW packages; ULONG cbMaxToken; - TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w(ServerPrincName), + TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w((const WCHAR*)ServerPrincName), AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos); if (SecurityQos) @@ -1772,7 +1772,7 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnLevel, ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr ) { - TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w(ServerPrincName), + TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w((const WCHAR*)ServerPrincName), AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr); return RpcBindingSetAuthInfoExW(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, NULL); } diff --git a/reactos/dll/win32/rpcrt4/rpc_binding.h b/reactos/dll/win32/rpcrt4/rpc_binding.h index 036b59a5567..5aa83079d51 100644 --- a/reactos/dll/win32/rpcrt4/rpc_binding.h +++ b/reactos/dll/win32/rpcrt4/rpc_binding.h @@ -24,7 +24,6 @@ #include "rpcndr.h" #include "security.h" #include "wine/list.h" -#include "rpc_defs.h" typedef struct _RpcAuthInfo @@ -67,7 +66,6 @@ typedef struct _RpcConnection TimeStamp exp; ULONG attr; RpcAuthInfo *AuthInfo; - ULONG auth_context_id; ULONG encryption_auth_len; ULONG signature_auth_len; RpcQualityOfService *QOS; @@ -76,7 +74,6 @@ typedef struct _RpcConnection struct list conn_pool_entry; ULONG assoc_group_id; /* association group returned during binding */ RPC_ASYNC_STATE *async_state; - struct _RpcAssoc *assoc; /* association this connection is part of */ /* server-only */ /* The active interface bound to server. */ @@ -99,7 +96,6 @@ struct connection_ops { int (*wait_for_incoming_data)(RpcConnection *conn); size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint); RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint); - RPC_STATUS (*receive_fragment)(RpcConnection *conn, RpcPktHdr **Header, void **Payload); }; /* don't know what MS's structure looks like */ diff --git a/reactos/dll/win32/rpcrt4/rpc_defs.h b/reactos/dll/win32/rpcrt4/rpc_defs.h index e70731a3818..cae77c4f356 100644 --- a/reactos/dll/win32/rpcrt4/rpc_defs.h +++ b/reactos/dll/win32/rpcrt4/rpc_defs.h @@ -31,13 +31,13 @@ typedef struct unsigned char drep[4]; /* Data representation */ unsigned short frag_len; /* Data size in bytes including header and tail. */ unsigned short auth_len; /* Authentication length */ - unsigned int call_id; /* Call identifier. */ + unsigned long call_id; /* Call identifier. */ } RpcPktCommonHdr; typedef struct { RpcPktCommonHdr common; - unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */ + unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ unsigned short context_id; /* Presentation context identifier */ unsigned short opnum; } RpcPktRequestHdr; @@ -45,7 +45,7 @@ typedef struct typedef struct { RpcPktCommonHdr common; - unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */ + unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ unsigned short context_id; /* Presentation context identifier */ unsigned char cancel_count; unsigned char reserved; @@ -54,12 +54,12 @@ typedef struct typedef struct { RpcPktCommonHdr common; - unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */ + unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ unsigned short context_id; /* Presentation context identifier */ unsigned char cancel_count; /* Received cancel count */ unsigned char reserved; /* Force alignment! */ - unsigned int status; /* Runtime fault code (RPC_STATUS) */ - unsigned int reserved2; + unsigned long status; /* Runtime fault code (RPC_STATUS) */ + unsigned long reserved2; } RpcPktFaultHdr; typedef struct @@ -67,7 +67,7 @@ typedef struct RpcPktCommonHdr common; unsigned short max_tsize; /* Maximum transmission fragment size */ unsigned short max_rsize; /* Maximum receive fragment size */ - unsigned int assoc_gid; /* Associated group id */ + unsigned long assoc_gid; /* Associated group id */ unsigned char num_elements; /* Number of elements */ unsigned char padding[3]; /* Force alignment! */ unsigned short context_id; /* Presentation context identifier */ @@ -99,7 +99,7 @@ typedef struct RpcPktCommonHdr common; unsigned short max_tsize; /* Maximum transmission fragment size */ unsigned short max_rsize; /* Maximum receive fragment size */ - unsigned int assoc_gid; /* Associated group id */ + unsigned long assoc_gid; /* Associated group id */ /* * Following this header are these fields: * RpcAddressString server_address; @@ -120,14 +120,6 @@ typedef struct } protocols[1]; } RpcPktBindNAckHdr; -/* undocumented packet sent during RPC over HTTP */ -typedef struct -{ - RpcPktCommonHdr common; - unsigned short flags; - unsigned short num_data_items; -} RpcPktHttpHdr; - /* Union representing all possible packet headers */ typedef union { @@ -138,7 +130,6 @@ typedef union RpcPktBindHdr bind; RpcPktBindAckHdr bind_ack; RpcPktBindNAckHdr bind_nack; - RpcPktHttpHdr http; } RpcPktHdr; typedef struct @@ -147,7 +138,7 @@ typedef struct unsigned char auth_level; /* RPC_C_AUTHN_LEVEL* */ unsigned char auth_pad_length; /* length of padding to restore n % 4 alignment */ unsigned char auth_reserved; /* reserved, must be zero */ - unsigned int auth_context_id; /* unique value for the authenticated connection */ + unsigned long auth_context_id; /* unique value for the authenticated connection */ } RpcAuthVerifier; #define RPC_AUTH_VERIFIER_LEN(common_hdr) \ @@ -183,7 +174,6 @@ typedef struct #define PKT_SHUTDOWN 17 #define PKT_CO_CANCEL 18 #define PKT_ORPHANED 19 -#define PKT_HTTP 20 #define RESULT_ACCEPT 0 #define RESULT_USER_REJECTION 1 diff --git a/reactos/dll/win32/rpcrt4/rpc_epmap.c b/reactos/dll/win32/rpcrt4/rpc_epmap.c index 60c425550ad..286ffbf9973 100644 --- a/reactos/dll/win32/rpcrt4/rpc_epmap.c +++ b/reactos/dll/win32/rpcrt4/rpc_epmap.c @@ -32,7 +32,7 @@ #include "wine/exception.h" #include "rpc_binding.h" -#include "epm.h" +#include "epm_c.h" #include "epm_towers.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -116,7 +116,7 @@ static BOOL start_rpcss(void) static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle) { - RpcBinding *bind = handle; + RpcBinding *bind = (RpcBinding *)handle; const char *protseq = bind->Protseq; const char *network_addr = bind->NetworkAddr; @@ -127,7 +127,7 @@ static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle) static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_HANDLE *epm_handle) { - RpcBinding *bind = handle; + RpcBinding *bind = (RpcBinding *)handle; const char * pszEndpoint = NULL; RPC_STATUS status; RpcBinding* epm_bind; @@ -149,7 +149,7 @@ static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_H status = RpcBindingCopy(handle, epm_handle); if (status != RPC_S_OK) return status; - epm_bind = *epm_handle; + epm_bind = (RpcBinding*)*epm_handle; if (epm_bind->AuthInfo) { /* don't bother with authenticating against the EPM by default @@ -187,8 +187,8 @@ static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *__eptr) RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, UUID_VECTOR *UuidVector, RPC_CSTR Annotation ) { - PRPC_SERVER_INTERFACE If = IfSpec; - ULONG i; + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; + unsigned long i; RPC_STATUS status = RPC_S_OK; error_status_t status2; ept_entry_t *entries; @@ -197,13 +197,13 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation)); TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); for (i=0; iCount; i++) { - RpcBinding* bind = BindingVector->BindingH[i]; - TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq)); - TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint)); + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); + TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq)); + TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint)); } if (UuidVector) { for (i=0; iCount; i++) - TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); + TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); } if (!BindingVector->Count) return RPC_S_OK; @@ -222,9 +222,10 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind for (i = 0; i < BindingVector->Count; i++) { unsigned j; - RpcBinding* bind = BindingVector->BindingH[i]; + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++) { + int len = strlen((char *)Annotation); status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax, bind->Protseq, bind->Endpoint, bind->NetworkAddr, @@ -235,9 +236,7 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind memcpy(&entries[i * UuidVector->Count].object, &UuidVector->Uuid[j], sizeof(GUID)); else memset(&entries[i].object, 0, sizeof(entries[i].object)); - if (Annotation) - memcpy(entries[i].annotation, Annotation, - min(strlen((char *)Annotation) + 1, ept_max_annotation_size)); + memcpy(entries[i].annotation, Annotation, min(len + 1, ept_max_annotation_size)); } } @@ -281,29 +280,14 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind return status; } -/*********************************************************************** - * RpcEpRegisterW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcEpRegisterW( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, - UUID_VECTOR *UuidVector, RPC_WSTR Annotation ) -{ - LPSTR annA = RPCRT4_strdupWtoA(Annotation); - RPC_STATUS status; - - status = RpcEpRegisterA(IfSpec, BindingVector, UuidVector, (RPC_CSTR)annA); - - HeapFree(GetProcessHeap(), 0, annA); - return status; -} - /*********************************************************************** * RpcEpUnregister (RPCRT4.@) */ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, UUID_VECTOR *UuidVector ) { - PRPC_SERVER_INTERFACE If = IfSpec; - ULONG i; + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; + unsigned long i; RPC_STATUS status = RPC_S_OK; error_status_t status2; ept_entry_t *entries; @@ -312,13 +296,13 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector); TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); for (i=0; iCount; i++) { - RpcBinding* bind = BindingVector->BindingH[i]; - TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq)); - TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint)); + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); + TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq)); + TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint)); } if (UuidVector) { for (i=0; iCount; i++) - TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); + TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); } entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*entries) * BindingVector->Count * (UuidVector ? UuidVector->Count : 1)); @@ -335,7 +319,7 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin for (i = 0; i < BindingVector->Count; i++) { unsigned j; - RpcBinding* bind = BindingVector->BindingH[i]; + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++) { status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax, @@ -388,8 +372,8 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin */ RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec ) { - PRPC_CLIENT_INTERFACE If = IfSpec; - RpcBinding* bind = Binding; + PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec; + RpcBinding* bind = (RpcBinding*)Binding; RPC_STATUS status; error_status_t status2; handle_t handle; diff --git a/reactos/dll/win32/rpcrt4/rpc_message.c b/reactos/dll/win32/rpcrt4/rpc_message.c index 5e7c857acdd..e4f96a9179e 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.c +++ b/reactos/dll/win32/rpcrt4/rpc_message.c @@ -59,13 +59,13 @@ enum secure_packet_direction static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg); -DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) +static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) { static const DWORD header_sizes[] = { sizeof(Header->request), 0, sizeof(Header->response), sizeof(Header->fault), 0, 0, 0, 0, 0, 0, 0, sizeof(Header->bind), sizeof(Header->bind_ack), sizeof(Header->bind_nack), - 0, 0, 0, 0, 0, 0, sizeof(Header->http) + 0, 0, 0, 0, 0 }; ULONG ret = 0; @@ -76,7 +76,7 @@ DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) if (Header->common.flags & RPC_FLG_OBJECT_UUID) ret += sizeof(UUID); } else { - WARN("invalid packet type %u\n", Header->common.ptype); + TRACE("invalid packet type\n"); } return ret; @@ -96,7 +96,7 @@ static int packet_has_auth_verifier(const RpcPktHdr *Header) } static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType, - ULONG DataRepresentation) + unsigned long DataRepresentation) { Header->common.rpc_ver = RPC_VER_MAJOR; Header->common.rpc_ver_minor = RPC_VER_MINOR; @@ -111,8 +111,8 @@ static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType /* Flags and fragment length are computed in RPCRT4_Send. */ } -static RpcPktHdr *RPCRT4_BuildRequestHeader(ULONG DataRepresentation, - ULONG BufferLength, +static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation, + unsigned long BufferLength, unsigned short ProcNum, UUID *ObjectUuid) { @@ -141,7 +141,8 @@ static RpcPktHdr *RPCRT4_BuildRequestHeader(ULONG DataRepresentation, return header; } -RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength) +RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, + unsigned long BufferLength) { RpcPktHdr *header; @@ -157,7 +158,8 @@ RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLeng return header; } -RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status) +RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, + RPC_STATUS Status) { RpcPktHdr *header; @@ -173,10 +175,10 @@ RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status) return header; } -RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation, +RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, - ULONG AssocGroupId, + unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId) { @@ -200,7 +202,7 @@ RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation, return header; } -static RpcPktHdr *RPCRT4_BuildAuthHeader(ULONG DataRepresentation) +static RpcPktHdr *RPCRT4_BuildAuthHeader(unsigned long DataRepresentation) { RpcPktHdr *header; @@ -216,7 +218,7 @@ static RpcPktHdr *RPCRT4_BuildAuthHeader(ULONG DataRepresentation) return header; } -RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, +RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor) { @@ -237,17 +239,17 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, return header; } -RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, +RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, - ULONG AssocGroupId, + unsigned long AssocGroupId, LPCSTR ServerAddress, - unsigned short Result, - unsigned short Reason, + unsigned long Result, + unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId) { RpcPktHdr *header; - ULONG header_size; + unsigned long header_size; RpcAddressString *server_address; RpcResults *results; RPC_SYNTAX_IDENTIFIER *transfer_id; @@ -281,118 +283,6 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, return header; } -RpcPktHdr *RPCRT4_BuildHttpHeader(ULONG DataRepresentation, - unsigned short flags, - unsigned short num_data_items, - unsigned int payload_size) -{ - RpcPktHdr *header; - - header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->http) + payload_size); - if (header == NULL) { - ERR("failed to allocate memory\n"); - return NULL; - } - - RPCRT4_BuildCommonHeader(header, PKT_HTTP, DataRepresentation); - /* since the packet isn't current sent using RPCRT4_Send, set the flags - * manually here */ - header->common.flags = RPC_FLG_FIRST|RPC_FLG_LAST; - header->common.call_id = 0; - header->common.frag_len = sizeof(header->http) + payload_size; - header->http.flags = flags; - header->http.num_data_items = num_data_items; - - return header; -} - -#define WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, type, value) \ - do { \ - *(unsigned int *)(payload) = (type); \ - (payload) += 4; \ - *(unsigned int *)(payload) = (value); \ - (payload) += 4; \ - } while (0) - -#define WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, type, uuid) \ - do { \ - *(unsigned int *)(payload) = (type); \ - (payload) += 4; \ - *(UUID *)(payload) = (uuid); \ - (payload) += sizeof(UUID); \ - } while (0) - -#define WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted, flow_control_increment, uuid) \ - do { \ - *(unsigned int *)(payload) = 0x00000001; \ - (payload) += 4; \ - *(unsigned int *)(payload) = (bytes_transmitted); \ - (payload) += 4; \ - *(unsigned int *)(payload) = (flow_control_increment); \ - (payload) += 4; \ - *(UUID *)(payload) = (uuid); \ - (payload) += sizeof(UUID); \ - } while (0) - -RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe, - const UUID *connection_uuid, - const UUID *pipe_uuid, - const UUID *association_uuid) -{ - RpcPktHdr *header; - unsigned int size; - char *payload; - - size = 8 + 4 + sizeof(UUID) + 4 + sizeof(UUID) + 8; - if (!out_pipe) - size += 8 + 4 + sizeof(UUID); - - header = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, flags, - out_pipe ? 4 : 6, size); - if (!header) return NULL; - payload = (char *)(&header->http+1); - - /* FIXME: what does this part of the payload do? */ - WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000006, 0x00000001); - - WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *connection_uuid); - WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *pipe_uuid); - - if (out_pipe) - /* FIXME: what does this part of the payload do? */ - WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000000, 0x00010000); - else - { - /* FIXME: what does this part of the payload do? */ - WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000004, 0x40000000); - /* FIXME: what does this part of the payload do? */ - WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000005, 0x000493e0); - - WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x0000000c, *association_uuid); - } - - return header; -} - -RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted, - ULONG flow_control_increment, - const UUID *pipe_uuid) -{ - RpcPktHdr *header; - char *payload; - - header = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, 0x2, 2, - 5 * sizeof(ULONG) + sizeof(UUID)); - if (!header) return NULL; - payload = (char *)(&header->http+1); - - WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x0000000d, (server ? 0x0 : 0x3)); - - WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted, - flow_control_increment, *pipe_uuid); - return header; -} - VOID RPCRT4_FreeHeader(RpcPktHdr *Header) { HeapFree(GetProcessHeap(), 0, Header); @@ -472,206 +362,6 @@ static RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status) } } -/* assumes the common header fields have already been validated */ -BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, - unsigned short data_len) -{ - unsigned short i; - BYTE *p = data; - - for (i = 0; i < hdr->http.num_data_items; i++) - { - ULONG type; - - if (data_len < sizeof(ULONG)) - return FALSE; - - type = *(ULONG *)p; - p += sizeof(ULONG); - data_len -= sizeof(ULONG); - - switch (type) - { - case 0x3: - case 0xc: - if (data_len < sizeof(GUID)) - return FALSE; - p += sizeof(GUID); - data_len -= sizeof(GUID); - break; - case 0x0: - case 0x2: - case 0x4: - case 0x5: - case 0x6: - case 0xd: - if (data_len < sizeof(ULONG)) - return FALSE; - p += sizeof(ULONG); - data_len -= sizeof(ULONG); - break; - case 0x1: - if (data_len < 24) - return FALSE; - p += 24; - data_len -= 24; - break; - default: - FIXME("unimplemented type 0x%x\n", type); - break; - } - } - return TRUE; -} - -/* assumes the HTTP packet has been validated */ -static unsigned char *RPCRT4_NextHttpHeaderField(unsigned char *data) -{ - ULONG type; - - type = *(ULONG *)data; - data += sizeof(ULONG); - - switch (type) - { - case 0x3: - case 0xc: - return data + sizeof(GUID); - case 0x0: - case 0x2: - case 0x4: - case 0x5: - case 0x6: - case 0xd: - return data + sizeof(ULONG); - case 0x1: - return data + 24; - default: - FIXME("unimplemented type 0x%x\n", type); - return data; - } -} - -#define READ_HTTP_PAYLOAD_FIELD_TYPE(data) *(ULONG *)(data) -#define GET_HTTP_PAYLOAD_FIELD_DATA(data) ((data) + sizeof(ULONG)) - -/* assumes the HTTP packet has been validated */ -RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, - unsigned char *data, ULONG *field1) -{ - ULONG type; - if (header->http.flags != 0x0) - { - ERR("invalid flags 0x%x\n", header->http.flags); - return RPC_S_PROTOCOL_ERROR; - } - if (header->http.num_data_items != 1) - { - ERR("invalid number of data items %d\n", header->http.num_data_items); - return RPC_S_PROTOCOL_ERROR; - } - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x00000002) - { - ERR("invalid type 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - *field1 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); - return RPC_S_OK; -} - -/* assumes the HTTP packet has been validated */ -RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, - unsigned char *data, ULONG *field1, - ULONG *bytes_until_next_packet, - ULONG *field3) -{ - ULONG type; - if (header->http.flags != 0x0) - { - ERR("invalid flags 0x%x\n", header->http.flags); - return RPC_S_PROTOCOL_ERROR; - } - if (header->http.num_data_items != 3) - { - ERR("invalid number of data items %d\n", header->http.num_data_items); - return RPC_S_PROTOCOL_ERROR; - } - - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x00000006) - { - ERR("invalid type for field 1: 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - *field1 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); - data = RPCRT4_NextHttpHeaderField(data); - - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x00000000) - { - ERR("invalid type for field 2: 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - *bytes_until_next_packet = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); - data = RPCRT4_NextHttpHeaderField(data); - - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x00000002) - { - ERR("invalid type for field 3: 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - *field3 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); - - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, - unsigned char *data, BOOL server, - ULONG *bytes_transmitted, - ULONG *flow_control_increment, - UUID *pipe_uuid) -{ - ULONG type; - if (header->http.flags != 0x2) - { - ERR("invalid flags 0x%x\n", header->http.flags); - return RPC_S_PROTOCOL_ERROR; - } - if (header->http.num_data_items != 2) - { - ERR("invalid number of data items %d\n", header->http.num_data_items); - return RPC_S_PROTOCOL_ERROR; - } - - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x0000000d) - { - ERR("invalid type for field 1: 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - if (*(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data) != (server ? 0x3 : 0x0)) - { - ERR("invalid type for 0xd field data: 0x%08x\n", *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data)); - return RPC_S_PROTOCOL_ERROR; - } - data = RPCRT4_NextHttpHeaderField(data); - - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x00000001) - { - ERR("invalid type for field 2: 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - *bytes_transmitted = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); - *flow_control_increment = *(ULONG *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 4); - *pipe_uuid = *(UUID *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 8); - - return RPC_S_OK; -} - - static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection, enum secure_packet_direction dir, RpcPktHdr *hdr, unsigned int hdr_size, @@ -819,7 +509,7 @@ static RPC_STATUS RPCRT4_SendWithAuth(RpcConnection *Connection, RpcPktHdr *Head auth_hdr->auth_pad_length = auth_pad_len; auth_hdr->auth_reserved = 0; /* a unique number... */ - auth_hdr->auth_context_id = Connection->auth_context_id; + auth_hdr->auth_context_id = (unsigned long)Connection; if (AuthLength) memcpy(auth_hdr + 1, Auth, AuthLength); @@ -997,7 +687,7 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, } /* validates version and frag_len fields */ -RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) +static RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) { DWORD hdr_length; @@ -1026,11 +716,11 @@ RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) } /*********************************************************************** - * RPCRT4_default_receive_fragment (internal) + * RPCRT4_receive_fragment (internal) * * Receive a fragment from a connection. */ -static RPC_STATUS RPCRT4_default_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) +static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) { RPC_STATUS status; DWORD hdr_length; @@ -1104,14 +794,6 @@ fail: return status; } -static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) -{ - if (Connection->ops->receive_fragment) - return Connection->ops->receive_fragment(Connection, Header, Payload); - else - return RPCRT4_default_receive_fragment(Connection, Header, Payload); -} - /*********************************************************************** * RPCRT4_ReceiveWithAuth (internal) * @@ -1121,14 +803,14 @@ static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr * RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, - ULONG *auth_length_out) + unsigned long *auth_length_out) { RPC_STATUS status; DWORD hdr_length; unsigned short first_flag; - ULONG data_length; - ULONG buffer_length; - ULONG auth_length = 0; + unsigned long data_length; + unsigned long buffer_length; + unsigned long auth_length = 0; unsigned char *auth_data = NULL; RpcPktHdr *CurrentHeader = NULL; void *payload = NULL; @@ -1192,7 +874,7 @@ RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, } if (CurrentHeader->common.auth_len != auth_length) { - WARN("auth_len header field changed from %d to %d\n", + WARN("auth_len header field changed from %ld to %d\n", auth_length, CurrentHeader->common.auth_len); status = RPC_S_PROTOCOL_ERROR; goto fail; @@ -1206,7 +888,7 @@ RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, data_length = CurrentHeader->common.frag_len - hdr_length - header_auth_len; if (data_length + buffer_length > pMsg->BufferLength) { - TRACE("allocation hint exceeded, new buffer length = %d\n", + TRACE("allocation hint exceeded, new buffer length = %ld\n", data_length + buffer_length); pMsg->BufferLength = data_length + buffer_length; status = I_RpcReAllocateBuffer(pMsg); @@ -1316,7 +998,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, */ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg) { - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcConnection* conn; RPC_STATUS status = RPC_S_OK; @@ -1381,7 +1063,7 @@ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg) RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg) { RPC_STATUS status; - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength); @@ -1438,7 +1120,7 @@ static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg) */ RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg) { - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer); @@ -1532,7 +1214,7 @@ static DWORD WINAPI async_notifier_proc(LPVOID p) */ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) { - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcConnection* conn; RPC_STATUS status; RpcPktHdr *hdr; @@ -1586,7 +1268,7 @@ static inline BOOL is_hard_error(RPC_STATUS status) */ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) { - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; RPC_STATUS status; RpcPktHdr *hdr = NULL; RpcConnection *conn; @@ -1605,7 +1287,7 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) case PKT_RESPONSE: break; case PKT_FAULT: - ERR ("we got fault packet with status 0x%x\n", hdr->fault.status); + ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status); status = NCA2RPC_STATUS(hdr->fault.status); if (is_hard_error(status)) goto fail; @@ -1678,7 +1360,7 @@ RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg) */ RPC_STATUS WINAPI I_RpcAsyncSetHandle(PRPC_MESSAGE pMsg, PRPC_ASYNC_STATE pAsync) { - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcConnection *conn; TRACE("(%p, %p)\n", pMsg, pAsync); diff --git a/reactos/dll/win32/rpcrt4/rpc_message.h b/reactos/dll/win32/rpcrt4/rpc_message.h index aeeef0773e5..e4033882feb 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.h +++ b/reactos/dll/win32/rpcrt4/rpc_message.h @@ -25,25 +25,15 @@ typedef unsigned int NCA_STATUS; -RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status); -RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength); -RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId); -RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor); -RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, LPCSTR ServerAddress, unsigned short Result, unsigned short Reason, const RPC_SYNTAX_IDENTIFIER *TransferId); -RpcPktHdr *RPCRT4_BuildHttpHeader(ULONG DataRepresentation, unsigned short flags, unsigned short num_data_items, unsigned int payload_size); -RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe, const UUID *connection_uuid, const UUID *pipe_uuid, const UUID *association_uuid); -RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted, ULONG flow_control_increment, const UUID *pipe_uuid); +RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS Status); +RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength); +RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId); +RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor); +RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId); VOID RPCRT4_FreeHeader(RpcPktHdr *Header); RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength); RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg); -RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, ULONG *auth_length_out); -DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header); -RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr); - -BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, unsigned short data_len); -RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, unsigned char *data, ULONG *field1); -RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, unsigned char *data, ULONG *field1, ULONG *bytes_until_next_packet, ULONG *field3); -RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, unsigned char *data, BOOL server, ULONG *bytes_transmitted, ULONG *flow_control_increment, UUID *pipe_uuid); +RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, unsigned long *auth_length_out); NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status); RPC_STATUS RPCRT4_AuthorizeConnection(RpcConnection* conn, BYTE *challenge, ULONG count); diff --git a/reactos/dll/win32/rpcrt4/rpc_server.c b/reactos/dll/win32/rpcrt4/rpc_server.c index 34006396220..473c7ba9328 100644 --- a/reactos/dll/win32/rpcrt4/rpc_server.c +++ b/reactos/dll/win32/rpcrt4/rpc_server.c @@ -367,7 +367,7 @@ static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg) static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) { - RpcConnection* conn = the_arg; + RpcConnection* conn = (RpcConnection*)the_arg; RpcPktHdr *hdr; RPC_MESSAGE *msg; RPC_STATUS status; @@ -449,23 +449,27 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg) /* start waiting */ res = cps->ops->wait_for_new_connection(cps, count, objs); - - if (res == -1 || (res == 0 && !std_listen)) - { - /* cleanup */ - cps->ops->free_wait_array(cps, objs); - EnterCriticalSection(&cps->cs); - for (conn = cps->conn; conn; conn = conn->Next) - RPCRT4_CloseConnection(conn); - LeaveCriticalSection(&cps->cs); - - if (res == 0 && !std_listen) - SetEvent(cps->server_ready_event); + if (res == -1) break; - } else if (res == 0) + { + if (!std_listen) + { + SetEvent(cps->server_ready_event); + break; + } set_ready_event = TRUE; + } } + cps->ops->free_wait_array(cps, objs); + EnterCriticalSection(&cps->cs); + /* close connections */ + conn = cps->conn; + while (conn) { + RPCRT4_CloseConnection(conn); + conn = conn->Next; + } + LeaveCriticalSection(&cps->cs); return 0; } @@ -566,32 +570,11 @@ static void RPCRT4_stop_listen(BOOL auto_listen) LeaveCriticalSection(&listen_cs); } -static BOOL RPCRT4_protseq_is_endpoint_registered(RpcServerProtseq *protseq, const char *endpoint) -{ - RpcConnection *conn; - EnterCriticalSection(&protseq->cs); - for (conn = protseq->conn; conn; conn = conn->Next) - { - if (!endpoint || !strcmp(endpoint, conn->Endpoint)) - break; - } - LeaveCriticalSection(&protseq->cs); - return (conn != NULL); -} - -static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, const char *endpoint) +static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, LPSTR endpoint) { RPC_STATUS status; - EnterCriticalSection(&ps->cs); - - if (RPCRT4_protseq_is_endpoint_registered(ps, endpoint)) - status = RPC_S_OK; - else - status = ps->ops->open_endpoint(ps, endpoint); - - LeaveCriticalSection(&ps->cs); - + status = ps->ops->open_endpoint(ps, endpoint); if (status != RPC_S_OK) return status; @@ -625,8 +608,11 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) count = 0; LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) { EnterCriticalSection(&ps->cs); - for (conn = ps->conn; conn; conn = conn->Next) + conn = ps->conn; + while (conn) { count++; + conn = conn->Next; + } LeaveCriticalSection(&ps->cs); } if (count) { @@ -638,10 +624,12 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) count = 0; LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) { EnterCriticalSection(&ps->cs); - for (conn = ps->conn; conn; conn = conn->Next) { + conn = ps->conn; + while (conn) { RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count], conn); count++; + conn = conn->Next; } LeaveCriticalSection(&ps->cs); } @@ -693,7 +681,7 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_W * * Must be called with server_cs held. */ -static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps) +static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps) { const struct protseq_ops *ops = rpcrt4_get_protseq_ops(Protseq); @@ -707,7 +695,7 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcSe if (!*ps) return RPC_S_OUT_OF_RESOURCES; (*ps)->MaxCalls = MaxCalls; - (*ps)->Protseq = RPCRT4_strdupA(Protseq); + (*ps)->Protseq = Protseq; (*ps)->ops = ops; (*ps)->MaxCalls = 0; (*ps)->conn = NULL; @@ -723,19 +711,8 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcSe return RPC_S_OK; } -/* must be called with server_cs held */ -static void destroy_serverprotoseq(RpcServerProtseq *ps) -{ - RPCRT4_strfree(ps->Protseq); - DeleteCriticalSection(&ps->cs); - CloseHandle(ps->mgr_mutex); - CloseHandle(ps->server_ready_event); - list_remove(&ps->entry); - HeapFree(GetProcessHeap(), 0, ps); -} - /* Finds a given protseq or creates a new one if one doesn't already exist */ -static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps) +static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps) { RPC_STATUS status; RpcServerProtseq *cps; @@ -764,18 +741,19 @@ static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, const char * RPC_STATUS WINAPI RpcServerUseProtseqEpExA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor, PRPC_POLICY lpPolicy ) { + char *szps = (char*)Protseq, *szep = (char*)Endpoint; RpcServerProtseq* ps; RPC_STATUS status; - TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a((const char *)Protseq), - MaxCalls, debugstr_a((const char *)Endpoint), SecurityDescriptor, + TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a(szps), MaxCalls, + debugstr_a(szep), SecurityDescriptor, lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps); + status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupA(szps), &ps); if (status != RPC_S_OK) return status; - return RPCRT4_use_protseq(ps, (const char *)Endpoint); + return RPCRT4_use_protseq(ps, szep); } /*********************************************************************** @@ -786,16 +764,13 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC { RpcServerProtseq* ps; RPC_STATUS status; - LPSTR ProtseqA; LPSTR EndpointA; TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor, lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - ProtseqA = RPCRT4_strdupWtoA(Protseq); - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps); - RPCRT4_strfree(ProtseqA); + status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps); if (status != RPC_S_OK) return status; @@ -810,16 +785,8 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC */ RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) { - RPC_STATUS status; - RpcServerProtseq* ps; - TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_a((char*)Protseq), MaxCalls, SecurityDescriptor); - - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps); - if (status != RPC_S_OK) - return status; - - return RPCRT4_use_protseq(ps, NULL); + return RpcServerUseProtseqEpA(Protseq, MaxCalls, NULL, SecurityDescriptor); } /*********************************************************************** @@ -827,36 +794,8 @@ RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, */ RPC_STATUS WINAPI RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) { - RPC_STATUS status; - RpcServerProtseq* ps; - LPSTR ProtseqA; - TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_w(Protseq), MaxCalls, SecurityDescriptor); - - ProtseqA = RPCRT4_strdupWtoA(Protseq); - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps); - RPCRT4_strfree(ProtseqA); - if (status != RPC_S_OK) - return status; - - return RPCRT4_use_protseq(ps, NULL); -} - -void RPCRT4_destroy_all_protseqs(void) -{ - RpcServerProtseq *cps, *cursor2; - - if (listen_count != 0) - std_listen = FALSE; - - EnterCriticalSection(&server_cs); - LIST_FOR_EACH_ENTRY_SAFE(cps, cursor2, &protseqs, RpcServerProtseq, entry) - { - if (listen_count != 0) - RPCRT4_sync_with_server_thread(cps); - destroy_serverprotoseq(cps); - } - LeaveCriticalSection(&server_cs); + return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor); } /*********************************************************************** @@ -884,7 +823,7 @@ RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn ) { - PRPC_SERVER_INTERFACE If = IfSpec; + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; RpcServerInterface* sif; unsigned int i; @@ -937,7 +876,7 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, */ RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete ) { - PRPC_SERVER_INTERFACE If = IfSpec; + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; HANDLE event = NULL; BOOL found = FALSE; BOOL completed = TRUE; diff --git a/reactos/dll/win32/rpcrt4/rpc_server.h b/reactos/dll/win32/rpcrt4/rpc_server.h index cacce794e34..ffd5b016e4b 100644 --- a/reactos/dll/win32/rpcrt4/rpc_server.h +++ b/reactos/dll/win32/rpcrt4/rpc_server.h @@ -56,7 +56,7 @@ struct protseq_ops * new connection was established */ int (*wait_for_new_connection)(RpcServerProtseq *protseq, unsigned int count, void *wait_array); /* opens the endpoint and optionally begins listening */ - RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, const char *endpoint); + RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, LPSTR endpoint); }; typedef struct _RpcServerInterface @@ -79,6 +79,4 @@ typedef struct _RpcServerInterface void RPCRT4_new_client(RpcConnection* conn); const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq); -void RPCRT4_destroy_all_protseqs(void); - #endif /* __WINE_RPC_SERVER_H */ diff --git a/reactos/dll/win32/rpcrt4/rpc_transport.c b/reactos/dll/win32/rpcrt4/rpc_transport.c index dddc5135c9d..735a19df648 100644 --- a/reactos/dll/win32/rpcrt4/rpc_transport.c +++ b/reactos/dll/win32/rpcrt4/rpc_transport.c @@ -40,8 +40,6 @@ # ifndef EAGAIN # define EAGAIN WSAEWOULDBLOCK # endif -# undef errno -# define errno WSAGetLastError() #else # include # ifdef HAVE_UNISTD_H @@ -66,21 +64,16 @@ # ifdef HAVE_SYS_POLL_H # include # endif -# ifdef HAVE_SYS_FILIO_H -# include -# endif -# ifdef HAVE_SYS_IOCTL_H -# include -# endif # define closesocket close -# define ioctlsocket ioctl #endif /* defined(__MINGW32__) || defined (_MSC_VER) */ +#include +#include + #include "windef.h" #include "winbase.h" #include "winnls.h" #include "winerror.h" -#include "wininet.h" #include "winternl.h" #include "wine/unicode.h" @@ -90,17 +83,16 @@ #include "wine/debug.h" #include "rpc_binding.h" -#include "rpc_assoc.h" #include "rpc_message.h" #include "rpc_server.h" #include "epm_towers.h" +#include "unix_func.h" + #ifndef SOL_TCP # define SOL_TCP IPPROTO_TCP #endif -#define DEFAULT_NCACN_HTTP_TIMEOUT (60 * 1000) - WINE_DEFAULT_DEBUG_CHANNEL(rpc); static RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection); @@ -266,23 +258,12 @@ static RPC_STATUS rpcrt4_ncalrpc_open(RpcConnection* Connection) return r; } -static RPC_STATUS rpcrt4_protseq_ncalrpc_open_endpoint(RpcServerProtseq* protseq, const char *endpoint) +static RPC_STATUS rpcrt4_protseq_ncalrpc_open_endpoint(RpcServerProtseq* protseq, LPSTR endpoint) { static const char prefix[] = "\\\\.\\pipe\\lrpc\\"; RPC_STATUS r; LPSTR pname; RpcConnection *Connection; - char generated_endpoint[22]; - - if (!endpoint) - { - static LONG lrpc_nameless_id; - DWORD process_id = GetCurrentProcessId(); - ULONG id = InterlockedIncrement(&lrpc_nameless_id); - snprintf(generated_endpoint, sizeof(generated_endpoint), - "LRPC%08x.%08x", process_id, id); - endpoint = generated_endpoint; - } r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL, endpoint, NULL, NULL, NULL); @@ -324,23 +305,12 @@ static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection) return r; } -static RPC_STATUS rpcrt4_protseq_ncacn_np_open_endpoint(RpcServerProtseq *protseq, const char *endpoint) +static RPC_STATUS rpcrt4_protseq_ncacn_np_open_endpoint(RpcServerProtseq *protseq, LPSTR endpoint) { static const char prefix[] = "\\\\."; RPC_STATUS r; LPSTR pname; RpcConnection *Connection; - char generated_endpoint[21]; - - if (!endpoint) - { - static LONG np_nameless_id; - DWORD process_id = GetCurrentProcessId(); - ULONG id = InterlockedExchangeAdd(&np_nameless_id, 1 ); - snprintf(generated_endpoint, sizeof(generated_endpoint), - "\\\\pipe\\\\%08x.%03x", process_id, id); - endpoint = generated_endpoint; - } r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL, endpoint, NULL, NULL, NULL); @@ -370,7 +340,7 @@ static void rpcrt4_conn_np_handoff(RpcConnection_np *old_npc, RpcConnection_np * new_npc->ovl[0] = old_npc->ovl[0]; new_npc->ovl[1] = old_npc->ovl[1]; old_npc->pipe = 0; - memset(&old_npc->ovl[0], 0, sizeof(old_npc->ovl)); + memset(&old_npc->ovl, 0, sizeof(old_npc->ovl)); old_npc->listening = FALSE; } @@ -422,11 +392,11 @@ static int rpcrt4_conn_np_read(RpcConnection *Connection, ret = ReadFile(npc->pipe, buf, bytes_left, &bytes_read, &npc->ovl[0]); if ((!ret || !bytes_read) && (GetLastError() != ERROR_IO_PENDING)) break; + ret = GetOverlappedResult(npc->pipe, &npc->ovl[0], &bytes_read, TRUE); - if (!ret && GetLastError() == ERROR_MORE_DATA) - ret = TRUE; - if (!ret || !bytes_read) + if (!ret && (GetLastError() != ERROR_MORE_DATA)) break; + bytes_left -= bytes_read; buf += bytes_read; } @@ -447,11 +417,11 @@ static int rpcrt4_conn_np_write(RpcConnection *Connection, ret = WriteFile(npc->pipe, buf, bytes_left, &bytes_written, &npc->ovl[1]); if ((!ret || !bytes_written) && (GetLastError() != ERROR_IO_PENDING)) break; + ret = GetOverlappedResult(npc->pipe, &npc->ovl[1], &bytes_written, TRUE); - if (!ret && GetLastError() == ERROR_MORE_DATA) - ret = TRUE; - if (!ret || !bytes_written) + if (!ret && (GetLastError() != ERROR_MORE_DATA)) break; + bytes_left -= bytes_written; buf += bytes_written; } @@ -786,10 +756,377 @@ static RPC_STATUS rpcrt4_ncalrpc_parse_top_of_tower(const unsigned char *tower_d /**** ncacn_ip_tcp support ****/ -static size_t rpcrt4_ip_tcp_get_top_of_tower(unsigned char *tower_data, - const char *networkaddr, - unsigned char tcp_protid, - const char *endpoint) +#ifdef HAVE_SOCKETPAIR + +typedef struct _RpcConnection_tcp +{ + RpcConnection common; + int sock; + int cancel_fds[2]; +} RpcConnection_tcp; + +static RpcConnection *rpcrt4_conn_tcp_alloc(void) +{ + RpcConnection_tcp *tcpc; + tcpc = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcConnection_tcp)); + if (tcpc == NULL) + return NULL; + tcpc->sock = -1; + if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0) + { + ERR("socketpair() failed: %s\n", strerror(errno)); + HeapFree(GetProcessHeap(), 0, tcpc); + return NULL; + } + return &tcpc->common; +} + +static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + int sock; + int ret; + struct addrinfo *ai; + struct addrinfo *ai_cur; + struct addrinfo hints; + + TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint); + + if (tcpc->sock != -1) + return RPC_S_OK; + + hints.ai_flags = 0; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; + + ret = getaddrinfo(Connection->NetworkAddr, Connection->Endpoint, &hints, &ai); + if (ret) + { + ERR("getaddrinfo for %s:%s failed: %s\n", Connection->NetworkAddr, + Connection->Endpoint, gai_strerror(ret)); + return RPC_S_SERVER_UNAVAILABLE; + } + + for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) + { + int val; + + if (TRACE_ON(rpc)) + { + char host[256]; + char service[256]; + getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, + host, sizeof(host), service, sizeof(service), + NI_NUMERICHOST | NI_NUMERICSERV); + TRACE("trying %s:%s\n", host, service); + } + + sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); + if (sock == -1) + { + WARN("socket() failed: %s\n", strerror(errno)); + continue; + } + + if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen)) + { + WARN("connect() failed: %s\n", strerror(errno)); + closesocket(sock); + continue; + } + + /* RPC depends on having minimal latency so disable the Nagle algorithm */ + val = 1; + setsockopt(sock, SOL_TCP, TCP_NODELAY, &val, sizeof(val)); + fcntl(sock, F_SETFL, O_NONBLOCK); /* make socket nonblocking */ + + tcpc->sock = sock; + + freeaddrinfo(ai); + TRACE("connected\n"); + return RPC_S_OK; + } + + freeaddrinfo(ai); + ERR("couldn't connect to %s:%s\n", Connection->NetworkAddr, Connection->Endpoint); + return RPC_S_SERVER_UNAVAILABLE; +} + +static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *protseq, LPSTR endpoint) +{ + RPC_STATUS status = RPC_S_CANT_CREATE_ENDPOINT; + int sock; + int ret; + struct addrinfo *ai; + struct addrinfo *ai_cur; + struct addrinfo hints; + RpcConnection *first_connection = NULL; + + TRACE("(%p, %s)\n", protseq, endpoint); + + hints.ai_flags = AI_PASSIVE /* for non-localhost addresses */; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; + + ret = getaddrinfo(NULL, endpoint, &hints, &ai); + if (ret) + { + ERR("getaddrinfo for port %s failed: %s\n", endpoint, + gai_strerror(ret)); + if ((ret == EAI_SERVICE) || (ret == EAI_NONAME)) + return RPC_S_INVALID_ENDPOINT_FORMAT; + return RPC_S_CANT_CREATE_ENDPOINT; + } + + for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) + { + RpcConnection_tcp *tcpc; + RPC_STATUS create_status; + + if (TRACE_ON(rpc)) + { + char host[256]; + char service[256]; + getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, + host, sizeof(host), service, sizeof(service), + NI_NUMERICHOST | NI_NUMERICSERV); + TRACE("trying %s:%s\n", host, service); + } + + sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); + if (sock == -1) + { + WARN("socket() failed: %s\n", strerror(errno)); + status = RPC_S_CANT_CREATE_ENDPOINT; + continue; + } + + ret = bind(sock, ai_cur->ai_addr, ai_cur->ai_addrlen); + if (ret < 0) + { + WARN("bind failed: %s\n", strerror(errno)); + closesocket(sock); + if (errno == EADDRINUSE) + status = RPC_S_DUPLICATE_ENDPOINT; + else + status = RPC_S_CANT_CREATE_ENDPOINT; + continue; + } + create_status = RPCRT4_CreateConnection((RpcConnection **)&tcpc, TRUE, + protseq->Protseq, NULL, + endpoint, NULL, NULL, NULL); + if (create_status != RPC_S_OK) + { + closesocket(sock); + status = create_status; + continue; + } + + tcpc->sock = sock; + ret = listen(sock, protseq->MaxCalls); + if (ret < 0) + { + WARN("listen failed: %s\n", strerror(errno)); + RPCRT4_DestroyConnection(&tcpc->common); + status = RPC_S_OUT_OF_RESOURCES; + continue; + } + /* need a non-blocking socket, otherwise accept() has a potential + * race-condition (poll() says it is readable, connection drops, + * and accept() blocks until the next connection comes...) + */ + ret = fcntl(sock, F_SETFL, O_NONBLOCK); + if (ret < 0) + { + WARN("couldn't make socket non-blocking, error %d\n", ret); + RPCRT4_DestroyConnection(&tcpc->common); + status = RPC_S_OUT_OF_RESOURCES; + continue; + } + + tcpc->common.Next = first_connection; + first_connection = &tcpc->common; + } + + freeaddrinfo(ai); + + /* if at least one connection was created for an endpoint then + * return success */ + if (first_connection) + { + RpcConnection *conn; + + /* find last element in list */ + for (conn = first_connection; conn->Next; conn = conn->Next) + ; + + EnterCriticalSection(&protseq->cs); + conn->Next = protseq->conn; + protseq->conn = first_connection; + LeaveCriticalSection(&protseq->cs); + + TRACE("listening on %s\n", endpoint); + return RPC_S_OK; + } + + ERR("couldn't listen on port %s\n", endpoint); + return status; +} + +static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection *new_conn) +{ + int ret; + struct sockaddr_in address; + socklen_t addrsize; + RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn; + RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn; + + addrsize = sizeof(address); + ret = accept(server->sock, (struct sockaddr*) &address, &addrsize); + if (ret < 0) + { + ERR("Failed to accept a TCP connection: error %d\n", ret); + return RPC_S_OUT_OF_RESOURCES; + } + /* reset to blocking behaviour */ + fcntl(ret, F_SETFL, 0); + client->sock = ret; + TRACE("Accepted a new TCP connection\n"); + return RPC_S_OK; +} + +static int rpcrt4_conn_tcp_read(RpcConnection *Connection, + void *buffer, unsigned int count) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + int bytes_read = 0; + do + { + int r = recv(tcpc->sock, (char *)buffer + bytes_read, count - bytes_read, 0); + if (!r) + return -1; + else if (r > 0) + bytes_read += r; + else if (errno != EAGAIN) + { + WARN("recv() failed: %s\n", strerror(errno)); + return -1; + } + else + { + struct pollfd pfds[2]; + pfds[0].fd = tcpc->sock; + pfds[0].events = POLLIN; + pfds[1].fd = tcpc->cancel_fds[0]; + pfds[1].events = POLLIN; + if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR) + { + ERR("poll() failed: %s\n", strerror(errno)); + return -1; + } + if (pfds[1].revents & POLLIN) /* canceled */ + { + char dummy; + read(pfds[1].fd, &dummy, sizeof(dummy)); + return -1; + } + } + } while (bytes_read != count); + TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_read); + return bytes_read; +} + +static int rpcrt4_conn_tcp_write(RpcConnection *Connection, + const void *buffer, unsigned int count) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + int bytes_written = 0; + do + { + int r = send(tcpc->sock, (const char *)buffer + bytes_written, count - bytes_written, 0); + if (r >= 0) + bytes_written += r; + else if (errno != EAGAIN) + return -1; + else + { + struct pollfd pfd; + pfd.fd = tcpc->sock; + pfd.events = POLLOUT; + if (poll(&pfd, 1, -1 /* infinite */) == -1 && errno != EINTR) + { + ERR("poll() failed: %s\n", strerror(errno)); + return -1; + } + } + } while (bytes_written != count); + TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_written); + return bytes_written; +} + +static int rpcrt4_conn_tcp_close(RpcConnection *Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + + TRACE("%d\n", tcpc->sock); + + if (tcpc->sock != -1) + closesocket(tcpc->sock); + tcpc->sock = -1; + close(tcpc->cancel_fds[0]); + close(tcpc->cancel_fds[1]); + return 0; +} + +static void rpcrt4_conn_tcp_cancel_call(RpcConnection *Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + char dummy = 1; + + TRACE("%p\n", Connection); + + write(tcpc->cancel_fds[1], &dummy, 1); +} + +static int rpcrt4_conn_tcp_wait_for_incoming_data(RpcConnection *Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + struct pollfd pfds[2]; + + TRACE("%p\n", Connection); + + pfds[0].fd = tcpc->sock; + pfds[0].events = POLLIN; + pfds[1].fd = tcpc->cancel_fds[0]; + pfds[1].events = POLLIN; + if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR) + { + ERR("poll() failed: %s\n", strerror(errno)); + return -1; + } + if (pfds[1].revents & POLLIN) /* canceled */ + { + char dummy; + read(pfds[1].fd, &dummy, sizeof(dummy)); + return -1; + } + + return 0; +} + +static size_t rpcrt4_ncacn_ip_tcp_get_top_of_tower(unsigned char *tower_data, + const char *networkaddr, + const char *endpoint) { twr_tcp_floor_t *tcp_floor; twr_ipv4_floor_t *ipv4_floor; @@ -809,7 +1146,7 @@ static size_t rpcrt4_ip_tcp_get_top_of_tower(unsigned char *tower_data, ipv4_floor = (twr_ipv4_floor_t *)tower_data; tcp_floor->count_lhs = sizeof(tcp_floor->protid); - tcp_floor->protid = tcp_protid; + tcp_floor->protid = EPM_PROTOCOL_TCP; tcp_floor->count_rhs = sizeof(tcp_floor->port); ipv4_floor->count_lhs = sizeof(ipv4_floor->protid); @@ -854,11 +1191,10 @@ static size_t rpcrt4_ip_tcp_get_top_of_tower(unsigned char *tower_data, return size; } -static RPC_STATUS rpcrt4_ip_tcp_parse_top_of_tower(const unsigned char *tower_data, - size_t tower_size, - char **networkaddr, - unsigned char tcp_protid, - char **endpoint) +static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *tower_data, + size_t tower_size, + char **networkaddr, + char **endpoint) { const twr_tcp_floor_t *tcp_floor = (const twr_tcp_floor_t *)tower_data; const twr_ipv4_floor_t *ipv4_floor; @@ -878,7 +1214,7 @@ static RPC_STATUS rpcrt4_ip_tcp_parse_top_of_tower(const unsigned char *tower_da ipv4_floor = (const twr_ipv4_floor_t *)tower_data; if ((tcp_floor->count_lhs != sizeof(tcp_floor->protid)) || - (tcp_floor->protid != tcp_protid) || + (tcp_floor->protid != EPM_PROTOCOL_TCP) || (tcp_floor->count_rhs != sizeof(tcp_floor->port)) || (ipv4_floor->count_lhs != sizeof(ipv4_floor->protid)) || (ipv4_floor->protid != EPM_PROTOCOL_IP) || @@ -923,528 +1259,6 @@ static RPC_STATUS rpcrt4_ip_tcp_parse_top_of_tower(const unsigned char *tower_da return RPC_S_OK; } -typedef struct _RpcConnection_tcp -{ - RpcConnection common; - int sock; -#ifdef HAVE_SOCKETPAIR - int cancel_fds[2]; -#else - HANDLE sock_event; - HANDLE cancel_event; -#endif -} RpcConnection_tcp; - -#ifdef HAVE_SOCKETPAIR - -static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc) -{ - if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0) - { - ERR("socketpair() failed: %s\n", strerror(errno)); - return FALSE; - } - return TRUE; -} - -static BOOL rpcrt4_sock_wait_for_recv(RpcConnection_tcp *tcpc) -{ - struct pollfd pfds[2]; - pfds[0].fd = tcpc->sock; - pfds[0].events = POLLIN; - pfds[1].fd = tcpc->cancel_fds[0]; - pfds[1].events = POLLIN; - if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR) - { - ERR("poll() failed: %s\n", strerror(errno)); - return FALSE; - } - if (pfds[1].revents & POLLIN) /* canceled */ - { - char dummy; - read(pfds[1].fd, &dummy, sizeof(dummy)); - return FALSE; - } - return TRUE; -} - -static BOOL rpcrt4_sock_wait_for_send(RpcConnection_tcp *tcpc) -{ - struct pollfd pfd; - pfd.fd = tcpc->sock; - pfd.events = POLLOUT; - if (poll(&pfd, 1, -1 /* infinite */) == -1 && errno != EINTR) - { - ERR("poll() failed: %s\n", strerror(errno)); - return FALSE; - } - return TRUE; -} - -static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc) -{ - char dummy = 1; - - write(tcpc->cancel_fds[1], &dummy, 1); -} - -static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc) -{ - close(tcpc->cancel_fds[0]); - close(tcpc->cancel_fds[1]); -} - -#else /* HAVE_SOCKETPAIR */ - -static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc) -{ - static BOOL wsa_inited; - if (!wsa_inited) - { - WSADATA wsadata; - WSAStartup(MAKEWORD(2, 2), &wsadata); - /* Note: WSAStartup can be called more than once so we don't bother with - * making accesses to wsa_inited thread-safe */ - wsa_inited = TRUE; - } - tcpc->sock_event = CreateEventW(NULL, FALSE, FALSE, NULL); - tcpc->cancel_event = CreateEventW(NULL, FALSE, FALSE, NULL); - if (!tcpc->sock_event || !tcpc->cancel_event) - { - ERR("event creation failed\n"); - if (tcpc->sock_event) CloseHandle(tcpc->sock_event); - return FALSE; - } - return TRUE; -} - -static BOOL rpcrt4_sock_wait_for_recv(RpcConnection_tcp *tcpc) -{ - HANDLE wait_handles[2]; - DWORD res; - if (WSAEventSelect(tcpc->sock, tcpc->sock_event, FD_READ | FD_CLOSE) == SOCKET_ERROR) - { - ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError()); - return FALSE; - } - wait_handles[0] = tcpc->sock_event; - wait_handles[1] = tcpc->cancel_event; - res = WaitForMultipleObjects(2, wait_handles, FALSE, INFINITE); - switch (res) - { - case WAIT_OBJECT_0: - return TRUE; - case WAIT_OBJECT_0 + 1: - return FALSE; - default: - ERR("WaitForMultipleObjects() failed with error %d\n", GetLastError()); - return FALSE; - } -} - -static BOOL rpcrt4_sock_wait_for_send(RpcConnection_tcp *tcpc) -{ - DWORD res; - if (WSAEventSelect(tcpc->sock, tcpc->sock_event, FD_WRITE | FD_CLOSE) == SOCKET_ERROR) - { - ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError()); - return FALSE; - } - res = WaitForSingleObject(tcpc->sock_event, INFINITE); - switch (res) - { - case WAIT_OBJECT_0: - return TRUE; - default: - ERR("WaitForMultipleObjects() failed with error %d\n", GetLastError()); - return FALSE; - } -} - -static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc) -{ - SetEvent(tcpc->cancel_event); -} - -static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc) -{ - CloseHandle(tcpc->sock_event); - CloseHandle(tcpc->cancel_event); -} - -#endif - -static RpcConnection *rpcrt4_conn_tcp_alloc(void) -{ - RpcConnection_tcp *tcpc; - tcpc = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcConnection_tcp)); - if (tcpc == NULL) - return NULL; - tcpc->sock = -1; - if (!rpcrt4_sock_wait_init(tcpc)) - { - HeapFree(GetProcessHeap(), 0, tcpc); - return NULL; - } - return &tcpc->common; -} - -static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - int sock; - int ret; - struct addrinfo *ai; - struct addrinfo *ai_cur; - struct addrinfo hints; - - TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint); - - if (tcpc->sock != -1) - return RPC_S_OK; - - hints.ai_flags = 0; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_addrlen = 0; - hints.ai_addr = NULL; - hints.ai_canonname = NULL; - hints.ai_next = NULL; - - ret = getaddrinfo(Connection->NetworkAddr, Connection->Endpoint, &hints, &ai); - if (ret) - { - ERR("getaddrinfo for %s:%s failed: %s\n", Connection->NetworkAddr, - Connection->Endpoint, gai_strerror(ret)); - return RPC_S_SERVER_UNAVAILABLE; - } - - for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) - { - int val; - u_long nonblocking; - - if (ai_cur->ai_family != AF_INET && ai_cur->ai_family != AF_INET6) - { - TRACE("skipping non-IP/IPv6 address family\n"); - continue; - } - - if (TRACE_ON(rpc)) - { - char host[256]; - char service[256]; - getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, - host, sizeof(host), service, sizeof(service), - NI_NUMERICHOST | NI_NUMERICSERV); - TRACE("trying %s:%s\n", host, service); - } - - sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); - if (sock == -1) - { - WARN("socket() failed: %s\n", strerror(errno)); - continue; - } - - if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen)) - { - WARN("connect() failed: %s\n", strerror(errno)); - closesocket(sock); - continue; - } - - /* RPC depends on having minimal latency so disable the Nagle algorithm */ - val = 1; - setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); - nonblocking = 1; - ioctlsocket(sock, FIONBIO, &nonblocking); - - tcpc->sock = sock; - - freeaddrinfo(ai); - TRACE("connected\n"); - return RPC_S_OK; - } - - freeaddrinfo(ai); - ERR("couldn't connect to %s:%s\n", Connection->NetworkAddr, Connection->Endpoint); - return RPC_S_SERVER_UNAVAILABLE; -} - -static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *protseq, const char *endpoint) -{ - RPC_STATUS status = RPC_S_CANT_CREATE_ENDPOINT; - int sock; - int ret; - struct addrinfo *ai; - struct addrinfo *ai_cur; - struct addrinfo hints; - RpcConnection *first_connection = NULL; - - TRACE("(%p, %s)\n", protseq, endpoint); - - hints.ai_flags = AI_PASSIVE /* for non-localhost addresses */; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_addrlen = 0; - hints.ai_addr = NULL; - hints.ai_canonname = NULL; - hints.ai_next = NULL; - - ret = getaddrinfo(NULL, endpoint ? endpoint : "0", &hints, &ai); - if (ret) - { - ERR("getaddrinfo for port %s failed: %s\n", endpoint, - gai_strerror(ret)); - if ((ret == EAI_SERVICE) || (ret == EAI_NONAME)) - return RPC_S_INVALID_ENDPOINT_FORMAT; - return RPC_S_CANT_CREATE_ENDPOINT; - } - - for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) - { - RpcConnection_tcp *tcpc; - RPC_STATUS create_status; - struct sockaddr_storage sa; - socklen_t sa_len; - char service[NI_MAXSERV]; - u_long nonblocking; - - if (ai_cur->ai_family != AF_INET && ai_cur->ai_family != AF_INET6) - { - TRACE("skipping non-IP/IPv6 address family\n"); - continue; - } - - if (TRACE_ON(rpc)) - { - char host[256]; - getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, - host, sizeof(host), service, sizeof(service), - NI_NUMERICHOST | NI_NUMERICSERV); - TRACE("trying %s:%s\n", host, service); - } - - sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); - if (sock == -1) - { - WARN("socket() failed: %s\n", strerror(errno)); - status = RPC_S_CANT_CREATE_ENDPOINT; - continue; - } - - ret = bind(sock, ai_cur->ai_addr, ai_cur->ai_addrlen); - if (ret < 0) - { - WARN("bind failed: %s\n", strerror(errno)); - closesocket(sock); - if (errno == EADDRINUSE) - status = RPC_S_DUPLICATE_ENDPOINT; - else - status = RPC_S_CANT_CREATE_ENDPOINT; - continue; - } - - sa_len = sizeof(sa); - if (getsockname(sock, (struct sockaddr *)&sa, &sa_len)) - { - WARN("getsockname() failed: %s\n", strerror(errno)); - status = RPC_S_CANT_CREATE_ENDPOINT; - continue; - } - - ret = getnameinfo((struct sockaddr *)&sa, sa_len, - NULL, 0, service, sizeof(service), - NI_NUMERICSERV); - if (ret) - { - WARN("getnameinfo failed: %s\n", gai_strerror(ret)); - status = RPC_S_CANT_CREATE_ENDPOINT; - continue; - } - - create_status = RPCRT4_CreateConnection((RpcConnection **)&tcpc, TRUE, - protseq->Protseq, NULL, - service, NULL, NULL, NULL); - if (create_status != RPC_S_OK) - { - closesocket(sock); - status = create_status; - continue; - } - - tcpc->sock = sock; - ret = listen(sock, protseq->MaxCalls); - if (ret < 0) - { - WARN("listen failed: %s\n", strerror(errno)); - RPCRT4_DestroyConnection(&tcpc->common); - status = RPC_S_OUT_OF_RESOURCES; - continue; - } - /* need a non-blocking socket, otherwise accept() has a potential - * race-condition (poll() says it is readable, connection drops, - * and accept() blocks until the next connection comes...) - */ - nonblocking = 1; - ret = ioctlsocket(sock, FIONBIO, &nonblocking); - if (ret < 0) - { - WARN("couldn't make socket non-blocking, error %d\n", ret); - RPCRT4_DestroyConnection(&tcpc->common); - status = RPC_S_OUT_OF_RESOURCES; - continue; - } - - tcpc->common.Next = first_connection; - first_connection = &tcpc->common; - - /* since IPv4 and IPv6 share the same port space, we only need one - * successful bind to listen for both */ - break; - } - - freeaddrinfo(ai); - - /* if at least one connection was created for an endpoint then - * return success */ - if (first_connection) - { - RpcConnection *conn; - - /* find last element in list */ - for (conn = first_connection; conn->Next; conn = conn->Next) - ; - - EnterCriticalSection(&protseq->cs); - conn->Next = protseq->conn; - protseq->conn = first_connection; - LeaveCriticalSection(&protseq->cs); - - TRACE("listening on %s\n", endpoint); - return RPC_S_OK; - } - - ERR("couldn't listen on port %s\n", endpoint); - return status; -} - -static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection *new_conn) -{ - int ret; - struct sockaddr_in address; - socklen_t addrsize; - RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn; - RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn; - u_long nonblocking; - - addrsize = sizeof(address); - ret = accept(server->sock, (struct sockaddr*) &address, &addrsize); - if (ret < 0) - { - ERR("Failed to accept a TCP connection: error %d\n", ret); - return RPC_S_OUT_OF_RESOURCES; - } - nonblocking = 1; - ioctlsocket(ret, FIONBIO, &nonblocking); - client->sock = ret; - TRACE("Accepted a new TCP connection\n"); - return RPC_S_OK; -} - -static int rpcrt4_conn_tcp_read(RpcConnection *Connection, - void *buffer, unsigned int count) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - int bytes_read = 0; - do - { - int r = recv(tcpc->sock, (char *)buffer + bytes_read, count - bytes_read, 0); - if (!r) - return -1; - else if (r > 0) - bytes_read += r; - else if (errno != EAGAIN) - { - WARN("recv() failed: %s\n", strerror(errno)); - return -1; - } - else - { - if (!rpcrt4_sock_wait_for_recv(tcpc)) - return -1; - } - } while (bytes_read != count); - TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_read); - return bytes_read; -} - -static int rpcrt4_conn_tcp_write(RpcConnection *Connection, - const void *buffer, unsigned int count) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - int bytes_written = 0; - do - { - int r = send(tcpc->sock, (const char *)buffer + bytes_written, count - bytes_written, 0); - if (r >= 0) - bytes_written += r; - else if (errno != EAGAIN) - return -1; - else - { - if (!rpcrt4_sock_wait_for_send(tcpc)) - return -1; - } - } while (bytes_written != count); - TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_written); - return bytes_written; -} - -static int rpcrt4_conn_tcp_close(RpcConnection *Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - - TRACE("%d\n", tcpc->sock); - - if (tcpc->sock != -1) - closesocket(tcpc->sock); - tcpc->sock = -1; - rpcrt4_sock_wait_destroy(tcpc); - return 0; -} - -static void rpcrt4_conn_tcp_cancel_call(RpcConnection *Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - TRACE("%p\n", Connection); - rpcrt4_sock_wait_cancel(tcpc); -} - -static int rpcrt4_conn_tcp_wait_for_incoming_data(RpcConnection *Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - - TRACE("%p\n", Connection); - - if (!rpcrt4_sock_wait_for_recv(tcpc)) - return -1; - return 0; -} - -static size_t rpcrt4_ncacn_ip_tcp_get_top_of_tower(unsigned char *tower_data, - const char *networkaddr, - const char *endpoint) -{ - return rpcrt4_ip_tcp_get_top_of_tower(tower_data, networkaddr, - EPM_PROTOCOL_TCP, endpoint); -} - -#ifdef HAVE_SOCKETPAIR - typedef struct _RpcServerProtseq_sock { RpcServerProtseq common; @@ -1584,1100 +1398,8 @@ static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq return 1; } -#else /* HAVE_SOCKETPAIR */ - -typedef struct _RpcServerProtseq_sock -{ - RpcServerProtseq common; - HANDLE mgr_event; -} RpcServerProtseq_sock; - -static RpcServerProtseq *rpcrt4_protseq_sock_alloc(void) -{ - RpcServerProtseq_sock *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps)); - if (ps) - { - static BOOL wsa_inited; - if (!wsa_inited) - { - WSADATA wsadata; - WSAStartup(MAKEWORD(2, 2), &wsadata); - /* Note: WSAStartup can be called more than once so we don't bother with - * making accesses to wsa_inited thread-safe */ - wsa_inited = TRUE; - } - ps->mgr_event = CreateEventW(NULL, FALSE, FALSE, NULL); - } - return &ps->common; -} - -static void rpcrt4_protseq_sock_signal_state_changed(RpcServerProtseq *protseq) -{ - RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, RpcServerProtseq_sock, common); - SetEvent(sockps->mgr_event); -} - -static void *rpcrt4_protseq_sock_get_wait_array(RpcServerProtseq *protseq, void *prev_array, unsigned int *count) -{ - HANDLE *objs = prev_array; - RpcConnection_tcp *conn; - RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, RpcServerProtseq_sock, common); - - EnterCriticalSection(&protseq->cs); - - /* open and count connections */ - *count = 1; - conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common); - while (conn) - { - if (conn->sock != -1) - (*count)++; - conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common); - } - - /* make array of connections */ - if (objs) - objs = HeapReAlloc(GetProcessHeap(), 0, objs, *count*sizeof(HANDLE)); - else - objs = HeapAlloc(GetProcessHeap(), 0, *count*sizeof(HANDLE)); - if (!objs) - { - ERR("couldn't allocate objs\n"); - LeaveCriticalSection(&protseq->cs); - return NULL; - } - - objs[0] = sockps->mgr_event; - *count = 1; - conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common); - while (conn) - { - if (conn->sock != -1) - { - int res = WSAEventSelect(conn->sock, conn->sock_event, FD_ACCEPT); - if (res == SOCKET_ERROR) - ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError()); - else - { - objs[*count] = conn->sock_event; - (*count)++; - } - } - conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common); - } - LeaveCriticalSection(&protseq->cs); - return objs; -} - -static void rpcrt4_protseq_sock_free_wait_array(RpcServerProtseq *protseq, void *array) -{ - HeapFree(GetProcessHeap(), 0, array); -} - -static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq, unsigned int count, void *wait_array) -{ - HANDLE b_handle; - HANDLE *objs = wait_array; - DWORD res; - RpcConnection *cconn; - RpcConnection_tcp *conn; - - if (!objs) - return -1; - - do - { - /* an alertable wait isn't strictly necessary, but due to our - * overlapped I/O implementation in Wine we need to free some memory - * by the file user APC being called, even if no completion routine was - * specified at the time of starting the async operation */ - res = WaitForMultipleObjectsEx(count, objs, FALSE, INFINITE, TRUE); - } while (res == WAIT_IO_COMPLETION); - - if (res == WAIT_OBJECT_0) - return 0; - else if (res == WAIT_FAILED) - { - ERR("wait failed with error %d\n", GetLastError()); - return -1; - } - else - { - b_handle = objs[res - WAIT_OBJECT_0]; - /* find which connection got a RPC */ - EnterCriticalSection(&protseq->cs); - conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common); - while (conn) - { - if (b_handle == conn->sock_event) break; - conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common); - } - cconn = NULL; - if (conn) - RPCRT4_SpawnConnection(&cconn, &conn->common); - else - ERR("failed to locate connection for handle %p\n", b_handle); - LeaveCriticalSection(&protseq->cs); - if (cconn) - { - RPCRT4_new_client(cconn); - return 1; - } - else return -1; - } -} - #endif /* HAVE_SOCKETPAIR */ -static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *tower_data, - size_t tower_size, - char **networkaddr, - char **endpoint) -{ - return rpcrt4_ip_tcp_parse_top_of_tower(tower_data, tower_size, - networkaddr, EPM_PROTOCOL_TCP, - endpoint); -} - -/**** ncacn_http support ****/ -#if 0 -/* 60 seconds is the period native uses */ -#define HTTP_IDLE_TIME 60000 - -/* reference counted to avoid a race between a cancelled call's connection - * being destroyed and the asynchronous InternetReadFileEx call being - * completed */ -typedef struct _RpcHttpAsyncData -{ - LONG refs; - HANDLE completion_event; - INTERNET_BUFFERSA inet_buffers; - void *destination_buffer; /* the address that inet_buffers.lpvBuffer will be - * copied into when the call completes */ - CRITICAL_SECTION cs; -} RpcHttpAsyncData; - -static ULONG RpcHttpAsyncData_AddRef(RpcHttpAsyncData *data) -{ - return InterlockedIncrement(&data->refs); -} - -static ULONG RpcHttpAsyncData_Release(RpcHttpAsyncData *data) -{ - ULONG refs = InterlockedDecrement(&data->refs); - if (!refs) - { - TRACE("destroying async data %p\n", data); - CloseHandle(data->completion_event); - HeapFree(GetProcessHeap(), 0, data->inet_buffers.lpvBuffer); - DeleteCriticalSection(&data->cs); - HeapFree(GetProcessHeap(), 0, data); - } - return refs; -} - -typedef struct _RpcConnection_http -{ - RpcConnection common; - HINTERNET app_info; - HINTERNET session; - HINTERNET in_request; - HINTERNET out_request; - HANDLE timer_cancelled; - HANDLE cancel_event; - DWORD last_sent_time; - ULONG bytes_received; - ULONG flow_control_mark; /* send a control packet to the server when this many bytes received */ - ULONG flow_control_increment; /* number of bytes to increment flow_control_mark by */ - UUID connection_uuid; - UUID in_pipe_uuid; - UUID out_pipe_uuid; - RpcHttpAsyncData *async_data; -} RpcConnection_http; - -static RpcConnection *rpcrt4_ncacn_http_alloc(void) -{ - RpcConnection_http *httpc; - httpc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*httpc)); - if (!httpc) return NULL; - httpc->async_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcHttpAsyncData)); - if (!httpc->async_data) - { - HeapFree(GetProcessHeap(), 0, httpc); - return NULL; - } - TRACE("async data = %p\n", httpc->async_data); - httpc->cancel_event = CreateEventW(NULL, FALSE, FALSE, NULL); - httpc->async_data->refs = 1; - httpc->async_data->inet_buffers.dwStructSize = sizeof(INTERNET_BUFFERSA); - httpc->async_data->inet_buffers.lpvBuffer = NULL; - httpc->async_data->destination_buffer = NULL; - InitializeCriticalSection(&httpc->async_data->cs); - return &httpc->common; -} - -typedef struct _HttpTimerThreadData -{ - PVOID timer_param; - DWORD *last_sent_time; - HANDLE timer_cancelled; -} HttpTimerThreadData; - -static VOID rpcrt4_http_keep_connection_active_timer_proc(PVOID param, BOOLEAN dummy) -{ - HINTERNET in_request = param; - RpcPktHdr *idle_pkt; - - idle_pkt = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, 0x0001, - 0, 0); - if (idle_pkt) - { - DWORD bytes_written; - InternetWriteFile(in_request, idle_pkt, idle_pkt->common.frag_len, &bytes_written); - RPCRT4_FreeHeader(idle_pkt); - } -} - -static inline DWORD rpcrt4_http_timer_calc_timeout(DWORD *last_sent_time) -{ - DWORD cur_time = GetTickCount(); - DWORD cached_last_sent_time = *last_sent_time; - return HTTP_IDLE_TIME - (cur_time - cached_last_sent_time > HTTP_IDLE_TIME ? 0 : cur_time - cached_last_sent_time); -} - -static DWORD CALLBACK rpcrt4_http_timer_thread(PVOID param) -{ - HttpTimerThreadData *data_in = param; - HttpTimerThreadData data; - DWORD timeout; - - data = *data_in; - HeapFree(GetProcessHeap(), 0, data_in); - - for (timeout = HTTP_IDLE_TIME; - WaitForSingleObject(data.timer_cancelled, timeout) == WAIT_TIMEOUT; - timeout = rpcrt4_http_timer_calc_timeout(data.last_sent_time)) - { - /* are we too soon after last send? */ - if (GetTickCount() - HTTP_IDLE_TIME < *data.last_sent_time) - continue; - rpcrt4_http_keep_connection_active_timer_proc(data.timer_param, TRUE); - } - - CloseHandle(data.timer_cancelled); - return 0; -} - -static VOID WINAPI rpcrt4_http_internet_callback( - HINTERNET hInternet, - DWORD_PTR dwContext, - DWORD dwInternetStatus, - LPVOID lpvStatusInformation, - DWORD dwStatusInformationLength) -{ - RpcHttpAsyncData *async_data = (RpcHttpAsyncData *)dwContext; - - switch (dwInternetStatus) - { - case INTERNET_STATUS_REQUEST_COMPLETE: - TRACE("INTERNET_STATUS_REQUEST_COMPLETED\n"); - if (async_data) - { - if (async_data->inet_buffers.lpvBuffer) - { - EnterCriticalSection(&async_data->cs); - if (async_data->destination_buffer) - { - memcpy(async_data->destination_buffer, - async_data->inet_buffers.lpvBuffer, - async_data->inet_buffers.dwBufferLength); - async_data->destination_buffer = NULL; - } - LeaveCriticalSection(&async_data->cs); - } - HeapFree(GetProcessHeap(), 0, async_data->inet_buffers.lpvBuffer); - async_data->inet_buffers.lpvBuffer = NULL; - SetEvent(async_data->completion_event); - RpcHttpAsyncData_Release(async_data); - } - break; - } -} - -static RPC_STATUS rpcrt4_http_check_response(HINTERNET hor) -{ - BOOL ret; - DWORD status_code; - DWORD size; - DWORD index; - WCHAR buf[32]; - WCHAR *status_text = buf; - TRACE("\n"); - - index = 0; - size = sizeof(status_code); - ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status_code, &size, &index); - if (!ret) - return GetLastError(); - if (status_code < 400) - return RPC_S_OK; - index = 0; - size = sizeof(buf); - ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_TEXT, status_text, &size, &index); - if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - status_text = HeapAlloc(GetProcessHeap(), 0, size); - ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_TEXT, status_text, &size, &index); - } - - ERR("server returned: %d %s\n", status_code, ret ? debugstr_w(status_text) : ""); - if(status_text != buf) HeapFree(GetProcessHeap(), 0, status_text); - - if (status_code == HTTP_STATUS_DENIED) - return ERROR_ACCESS_DENIED; - return RPC_S_SERVER_UNAVAILABLE; -} - -static RPC_STATUS rpcrt4_http_internet_connect(RpcConnection_http *httpc) -{ - static const WCHAR wszUserAgent[] = {'M','S','R','P','C',0}; - LPWSTR proxy = NULL; - LPWSTR user = NULL; - LPWSTR password = NULL; - LPWSTR servername = NULL; - const WCHAR *option; - INTERNET_PORT port = INTERNET_INVALID_PORT_NUMBER; /* use default port */ - - if (httpc->common.QOS && - (httpc->common.QOS->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP)) - { - const RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_cred = httpc->common.QOS->qos->u.HttpCredentials; - if (http_cred->TransportCredentials) - { - WCHAR *p; - const SEC_WINNT_AUTH_IDENTITY_W *cred = http_cred->TransportCredentials; - ULONG len = cred->DomainLength + 1 + cred->UserLength; - user = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); - if (!user) - return RPC_S_OUT_OF_RESOURCES; - p = user; - if (cred->DomainLength) - { - memcpy(p, cred->Domain, cred->DomainLength * sizeof(WCHAR)); - p += cred->DomainLength; - *p = '\\'; - p++; - } - memcpy(p, cred->User, cred->UserLength * sizeof(WCHAR)); - p[cred->UserLength] = 0; - - password = RPCRT4_strndupW(cred->Password, cred->PasswordLength); - } - } - - for (option = httpc->common.NetworkOptions; option; - option = (strchrW(option, ',') ? strchrW(option, ',')+1 : NULL)) - { - static const WCHAR wszRpcProxy[] = {'R','p','c','P','r','o','x','y','=',0}; - static const WCHAR wszHttpProxy[] = {'H','t','t','p','P','r','o','x','y','=',0}; - - if (!strncmpiW(option, wszRpcProxy, sizeof(wszRpcProxy)/sizeof(wszRpcProxy[0])-1)) - { - const WCHAR *value_start = option + sizeof(wszRpcProxy)/sizeof(wszRpcProxy[0])-1; - const WCHAR *value_end; - const WCHAR *p; - - value_end = strchrW(option, ','); - if (!value_end) - value_end = value_start + strlenW(value_start); - for (p = value_start; p < value_end; p++) - if (*p == ':') - { - port = atoiW(p+1); - value_end = p; - break; - } - TRACE("RpcProxy value is %s\n", debugstr_wn(value_start, value_end-value_start)); - servername = RPCRT4_strndupW(value_start, value_end-value_start); - } - else if (!strncmpiW(option, wszHttpProxy, sizeof(wszHttpProxy)/sizeof(wszHttpProxy[0])-1)) - { - const WCHAR *value_start = option + sizeof(wszHttpProxy)/sizeof(wszHttpProxy[0])-1; - const WCHAR *value_end; - - value_end = strchrW(option, ','); - if (!value_end) - value_end = value_start + strlenW(value_start); - TRACE("HttpProxy value is %s\n", debugstr_wn(value_start, value_end-value_start)); - proxy = RPCRT4_strndupW(value_start, value_end-value_start); - } - else - FIXME("unhandled option %s\n", debugstr_w(option)); - } - - httpc->app_info = InternetOpenW(wszUserAgent, proxy ? INTERNET_OPEN_TYPE_PROXY : INTERNET_OPEN_TYPE_PRECONFIG, - NULL, NULL, INTERNET_FLAG_ASYNC); - if (!httpc->app_info) - { - HeapFree(GetProcessHeap(), 0, password); - HeapFree(GetProcessHeap(), 0, user); - ERR("InternetOpenW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - InternetSetStatusCallbackW(httpc->app_info, rpcrt4_http_internet_callback); - - /* if no RpcProxy option specified, set the HTTP server address to the - * RPC server address */ - if (!servername) - { - servername = HeapAlloc(GetProcessHeap(), 0, (strlen(httpc->common.NetworkAddr) + 1)*sizeof(WCHAR)); - if (!servername) - { - HeapFree(GetProcessHeap(), 0, password); - HeapFree(GetProcessHeap(), 0, user); - return RPC_S_OUT_OF_RESOURCES; - } - MultiByteToWideChar(CP_ACP, 0, httpc->common.NetworkAddr, -1, servername, strlen(httpc->common.NetworkAddr) + 1); - } - - httpc->session = InternetConnectW(httpc->app_info, servername, port, user, password, - INTERNET_SERVICE_HTTP, 0, 0); - - HeapFree(GetProcessHeap(), 0, password); - HeapFree(GetProcessHeap(), 0, user); - HeapFree(GetProcessHeap(), 0, servername); - - if (!httpc->session) - { - ERR("InternetConnectW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - - return RPC_S_OK; -} - -/* prepare the in pipe for use by RPC packets */ -static RPC_STATUS rpcrt4_http_prepare_in_pipe(HINTERNET in_request, RpcHttpAsyncData *async_data, - const UUID *connection_uuid, - const UUID *in_pipe_uuid, - const UUID *association_uuid) -{ - BYTE packet[44]; - BOOL ret; - RPC_STATUS status; - RpcPktHdr *hdr; - INTERNET_BUFFERSW buffers_in; - DWORD bytes_read, bytes_written; - - /* prepare in pipe */ - ResetEvent(async_data->completion_event); - RpcHttpAsyncData_AddRef(async_data); - ret = HttpSendRequestW(in_request, NULL, 0, NULL, 0); - if (!ret) - { - if (GetLastError() == ERROR_IO_PENDING) - WaitForSingleObject(async_data->completion_event, INFINITE); - else - { - RpcHttpAsyncData_Release(async_data); - ERR("HttpSendRequestW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - } - status = rpcrt4_http_check_response(in_request); - if (status != RPC_S_OK) return status; - - InternetReadFile(in_request, packet, 20, &bytes_read); - /* FIXME: do something with retrieved data */ - - memset(&buffers_in, 0, sizeof(buffers_in)); - buffers_in.dwStructSize = sizeof(buffers_in); - /* FIXME: get this from the registry */ - buffers_in.dwBufferTotal = 1024 * 1024 * 1024; /* 1Gb */ - ResetEvent(async_data->completion_event); - RpcHttpAsyncData_AddRef(async_data); - ret = HttpSendRequestExW(in_request, &buffers_in, NULL, 0, 0); - if (!ret) - { - if (GetLastError() == ERROR_IO_PENDING) - WaitForSingleObject(async_data->completion_event, INFINITE); - else - { - RpcHttpAsyncData_Release(async_data); - ERR("HttpSendRequestExW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - } - - TRACE("sending HTTP connect header to server\n"); - hdr = RPCRT4_BuildHttpConnectHeader(0, FALSE, connection_uuid, in_pipe_uuid, association_uuid); - if (!hdr) return RPC_S_OUT_OF_RESOURCES; - ret = InternetWriteFile(in_request, hdr, hdr->common.frag_len, &bytes_written); - RPCRT4_FreeHeader(hdr); - if (!ret) - { - ERR("InternetWriteFile failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - - return RPC_S_OK; -} - -static RPC_STATUS rpcrt4_http_read_http_packet(HINTERNET request, RpcPktHdr *hdr, BYTE **data) -{ - BOOL ret; - DWORD bytes_read; - unsigned short data_len; - - ret = InternetReadFile(request, hdr, sizeof(hdr->common), &bytes_read); - if (!ret) - return RPC_S_SERVER_UNAVAILABLE; - if (hdr->common.ptype != PKT_HTTP || hdr->common.frag_len < sizeof(hdr->http)) - { - ERR("wrong packet type received %d or wrong frag_len %d\n", - hdr->common.ptype, hdr->common.frag_len); - return RPC_S_PROTOCOL_ERROR; - } - - ret = InternetReadFile(request, &hdr->common + 1, sizeof(hdr->http) - sizeof(hdr->common), &bytes_read); - if (!ret) - return RPC_S_SERVER_UNAVAILABLE; - - data_len = hdr->common.frag_len - sizeof(hdr->http); - if (data_len) - { - *data = HeapAlloc(GetProcessHeap(), 0, data_len); - if (!*data) - return RPC_S_OUT_OF_RESOURCES; - ret = InternetReadFile(request, *data, data_len, &bytes_read); - if (!ret) - { - HeapFree(GetProcessHeap(), 0, *data); - return RPC_S_SERVER_UNAVAILABLE; - } - } - else - *data = NULL; - - if (!RPCRT4_IsValidHttpPacket(hdr, *data, data_len)) - { - ERR("invalid http packet\n"); - return RPC_S_PROTOCOL_ERROR; - } - - return RPC_S_OK; -} - -/* prepare the out pipe for use by RPC packets */ -static RPC_STATUS rpcrt4_http_prepare_out_pipe(HINTERNET out_request, - RpcHttpAsyncData *async_data, - const UUID *connection_uuid, - const UUID *out_pipe_uuid, - ULONG *flow_control_increment) -{ - BYTE packet[20]; - BOOL ret; - RPC_STATUS status; - RpcPktHdr *hdr; - DWORD bytes_read; - BYTE *data_from_server; - RpcPktHdr pkt_from_server; - ULONG field1, field3; - - ResetEvent(async_data->completion_event); - RpcHttpAsyncData_AddRef(async_data); - ret = HttpSendRequestW(out_request, NULL, 0, NULL, 0); - if (!ret) - { - if (GetLastError() == ERROR_IO_PENDING) - WaitForSingleObject(async_data->completion_event, INFINITE); - else - { - RpcHttpAsyncData_Release(async_data); - ERR("HttpSendRequestW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - } - status = rpcrt4_http_check_response(out_request); - if (status != RPC_S_OK) return status; - - InternetReadFile(out_request, packet, 20, &bytes_read); - /* FIXME: do something with retrieved data */ - - hdr = RPCRT4_BuildHttpConnectHeader(0, TRUE, connection_uuid, out_pipe_uuid, NULL); - if (!hdr) return RPC_S_OUT_OF_RESOURCES; - ResetEvent(async_data->completion_event); - RpcHttpAsyncData_AddRef(async_data); - ret = HttpSendRequestW(out_request, NULL, 0, hdr, hdr->common.frag_len); - if (!ret) - { - if (GetLastError() == ERROR_IO_PENDING) - WaitForSingleObject(async_data->completion_event, INFINITE); - else - { - RpcHttpAsyncData_Release(async_data); - ERR("HttpSendRequestW failed with error %d\n", GetLastError()); - RPCRT4_FreeHeader(hdr); - return RPC_S_SERVER_UNAVAILABLE; - } - } - RPCRT4_FreeHeader(hdr); - status = rpcrt4_http_check_response(out_request); - if (status != RPC_S_OK) return status; - - status = rpcrt4_http_read_http_packet(out_request, &pkt_from_server, - &data_from_server); - if (status != RPC_S_OK) return status; - status = RPCRT4_ParseHttpPrepareHeader1(&pkt_from_server, data_from_server, - &field1); - HeapFree(GetProcessHeap(), 0, data_from_server); - if (status != RPC_S_OK) return status; - TRACE("received (%d) from first prepare header\n", field1); - - status = rpcrt4_http_read_http_packet(out_request, &pkt_from_server, - &data_from_server); - if (status != RPC_S_OK) return status; - status = RPCRT4_ParseHttpPrepareHeader2(&pkt_from_server, data_from_server, - &field1, flow_control_increment, - &field3); - HeapFree(GetProcessHeap(), 0, data_from_server); - if (status != RPC_S_OK) return status; - TRACE("received (0x%08x 0x%08x %d) from second prepare header\n", field1, *flow_control_increment, field3); - - return RPC_S_OK; -} - -static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection) -{ - RpcConnection_http *httpc = (RpcConnection_http *)Connection; - static const WCHAR wszVerbIn[] = {'R','P','C','_','I','N','_','D','A','T','A',0}; - static const WCHAR wszVerbOut[] = {'R','P','C','_','O','U','T','_','D','A','T','A',0}; - static const WCHAR wszRpcProxyPrefix[] = {'/','r','p','c','/','r','p','c','p','r','o','x','y','.','d','l','l','?',0}; - static const WCHAR wszColon[] = {':',0}; - static const WCHAR wszAcceptType[] = {'a','p','p','l','i','c','a','t','i','o','n','/','r','p','c',0}; - LPCWSTR wszAcceptTypes[] = { wszAcceptType, NULL }; - WCHAR *url; - RPC_STATUS status; - BOOL secure; - HttpTimerThreadData *timer_data; - HANDLE thread; - - TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint); - - if (Connection->server) - { - ERR("ncacn_http servers not supported yet\n"); - return RPC_S_SERVER_UNAVAILABLE; - } - - if (httpc->in_request) - return RPC_S_OK; - - httpc->async_data->completion_event = CreateEventW(NULL, FALSE, FALSE, NULL); - - status = UuidCreate(&httpc->connection_uuid); - status = UuidCreate(&httpc->in_pipe_uuid); - status = UuidCreate(&httpc->out_pipe_uuid); - - status = rpcrt4_http_internet_connect(httpc); - if (status != RPC_S_OK) - return status; - - url = HeapAlloc(GetProcessHeap(), 0, sizeof(wszRpcProxyPrefix) + (strlen(Connection->NetworkAddr) + 1 + strlen(Connection->Endpoint))*sizeof(WCHAR)); - if (!url) - return RPC_S_OUT_OF_MEMORY; - memcpy(url, wszRpcProxyPrefix, sizeof(wszRpcProxyPrefix)); - MultiByteToWideChar(CP_ACP, 0, Connection->NetworkAddr, -1, url+sizeof(wszRpcProxyPrefix)/sizeof(wszRpcProxyPrefix[0])-1, strlen(Connection->NetworkAddr)+1); - strcatW(url, wszColon); - MultiByteToWideChar(CP_ACP, 0, Connection->Endpoint, -1, url+strlenW(url), strlen(Connection->Endpoint)+1); - - secure = httpc->common.QOS && - (httpc->common.QOS->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) && - (httpc->common.QOS->qos->u.HttpCredentials->Flags & RPC_C_HTTP_FLAG_USE_SSL); - - httpc->in_request = HttpOpenRequestW(httpc->session, wszVerbIn, url, NULL, NULL, - wszAcceptTypes, - (secure ? INTERNET_FLAG_SECURE : 0)|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_PRAGMA_NOCACHE, - (DWORD_PTR)httpc->async_data); - if (!httpc->in_request) - { - ERR("HttpOpenRequestW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - httpc->out_request = HttpOpenRequestW(httpc->session, wszVerbOut, url, NULL, NULL, - wszAcceptTypes, - (secure ? INTERNET_FLAG_SECURE : 0)|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_PRAGMA_NOCACHE, - (DWORD_PTR)httpc->async_data); - if (!httpc->out_request) - { - ERR("HttpOpenRequestW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - - status = rpcrt4_http_prepare_in_pipe(httpc->in_request, - httpc->async_data, - &httpc->connection_uuid, - &httpc->in_pipe_uuid, - &Connection->assoc->http_uuid); - if (status != RPC_S_OK) - return status; - - status = rpcrt4_http_prepare_out_pipe(httpc->out_request, - httpc->async_data, - &httpc->connection_uuid, - &httpc->out_pipe_uuid, - &httpc->flow_control_increment); - if (status != RPC_S_OK) - return status; - - httpc->flow_control_mark = httpc->flow_control_increment / 2; - httpc->last_sent_time = GetTickCount(); - httpc->timer_cancelled = CreateEventW(NULL, FALSE, FALSE, NULL); - - timer_data = HeapAlloc(GetProcessHeap(), 0, sizeof(*timer_data)); - if (!timer_data) - return ERROR_OUTOFMEMORY; - timer_data->timer_param = httpc->in_request; - timer_data->last_sent_time = &httpc->last_sent_time; - timer_data->timer_cancelled = httpc->timer_cancelled; - /* FIXME: should use CreateTimerQueueTimer when implemented */ - thread = CreateThread(NULL, 0, rpcrt4_http_timer_thread, timer_data, 0, NULL); - if (!thread) - { - HeapFree(GetProcessHeap(), 0, timer_data); - return GetLastError(); - } - CloseHandle(thread); - - return RPC_S_OK; -} - -static RPC_STATUS rpcrt4_ncacn_http_handoff(RpcConnection *old_conn, RpcConnection *new_conn) -{ - assert(0); - return RPC_S_SERVER_UNAVAILABLE; -} - -static int rpcrt4_ncacn_http_read(RpcConnection *Connection, - void *buffer, unsigned int count) -{ - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - char *buf = buffer; - BOOL ret = TRUE; - unsigned int bytes_left = count; - - ResetEvent(httpc->async_data->completion_event); - while (bytes_left) - { - RpcHttpAsyncData_AddRef(httpc->async_data); - httpc->async_data->inet_buffers.dwBufferLength = bytes_left; - httpc->async_data->inet_buffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, bytes_left); - httpc->async_data->destination_buffer = buf; - ret = InternetReadFileExA(httpc->out_request, &httpc->async_data->inet_buffers, IRF_ASYNC, 0); - if (ret) - { - /* INTERNET_STATUS_REQUEST_COMPLETED won't be sent, so release our - * async ref now */ - RpcHttpAsyncData_Release(httpc->async_data); - memcpy(buf, httpc->async_data->inet_buffers.lpvBuffer, - httpc->async_data->inet_buffers.dwBufferLength); - HeapFree(GetProcessHeap(), 0, httpc->async_data->inet_buffers.lpvBuffer); - httpc->async_data->inet_buffers.lpvBuffer = NULL; - httpc->async_data->destination_buffer = NULL; - } - else - { - if (GetLastError() == ERROR_IO_PENDING) - { - HANDLE handles[2] = { httpc->async_data->completion_event, httpc->cancel_event }; - DWORD result = WaitForMultipleObjects(2, handles, FALSE, DEFAULT_NCACN_HTTP_TIMEOUT); - if (result == WAIT_OBJECT_0) - ret = TRUE; - else - { - TRACE("call cancelled\n"); - EnterCriticalSection(&httpc->async_data->cs); - httpc->async_data->destination_buffer = NULL; - LeaveCriticalSection(&httpc->async_data->cs); - break; - } - } - else - { - HeapFree(GetProcessHeap(), 0, httpc->async_data->inet_buffers.lpvBuffer); - httpc->async_data->inet_buffers.lpvBuffer = NULL; - httpc->async_data->destination_buffer = NULL; - RpcHttpAsyncData_Release(httpc->async_data); - break; - } - } - if (!httpc->async_data->inet_buffers.dwBufferLength) - break; - bytes_left -= httpc->async_data->inet_buffers.dwBufferLength; - buf += httpc->async_data->inet_buffers.dwBufferLength; - } - TRACE("%p %p %u -> %s\n", httpc->out_request, buffer, count, ret ? "TRUE" : "FALSE"); - return ret ? count : -1; -} - -static RPC_STATUS rpcrt4_ncacn_http_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) -{ - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - RPC_STATUS status; - DWORD hdr_length; - LONG dwRead; - RpcPktCommonHdr common_hdr; - - *Header = NULL; - - TRACE("(%p, %p, %p)\n", Connection, Header, Payload); - -again: - /* read packet common header */ - dwRead = rpcrt4_ncacn_http_read(Connection, &common_hdr, sizeof(common_hdr)); - if (dwRead != sizeof(common_hdr)) { - WARN("Short read of header, %d bytes\n", dwRead); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - if (!memcmp(&common_hdr, "HTTP/1.1", sizeof("HTTP/1.1")) || - !memcmp(&common_hdr, "HTTP/1.0", sizeof("HTTP/1.0"))) - { - FIXME("server returned %s\n", debugstr_a((const char *)&common_hdr)); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - status = RPCRT4_ValidateCommonHeader(&common_hdr); - if (status != RPC_S_OK) goto fail; - - hdr_length = RPCRT4_GetHeaderSize((RpcPktHdr*)&common_hdr); - if (hdr_length == 0) { - WARN("header length == 0\n"); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - *Header = HeapAlloc(GetProcessHeap(), 0, hdr_length); - if (!*Header) - { - status = RPC_S_OUT_OF_RESOURCES; - goto fail; - } - memcpy(*Header, &common_hdr, sizeof(common_hdr)); - - /* read the rest of packet header */ - dwRead = rpcrt4_ncacn_http_read(Connection, &(*Header)->common + 1, hdr_length - sizeof(common_hdr)); - if (dwRead != hdr_length - sizeof(common_hdr)) { - WARN("bad header length, %d bytes, hdr_length %d\n", dwRead, hdr_length); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - if (common_hdr.frag_len - hdr_length) - { - *Payload = HeapAlloc(GetProcessHeap(), 0, common_hdr.frag_len - hdr_length); - if (!*Payload) - { - status = RPC_S_OUT_OF_RESOURCES; - goto fail; - } - - dwRead = rpcrt4_ncacn_http_read(Connection, *Payload, common_hdr.frag_len - hdr_length); - if (dwRead != common_hdr.frag_len - hdr_length) - { - WARN("bad data length, %d/%d\n", dwRead, common_hdr.frag_len - hdr_length); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - } - else - *Payload = NULL; - - if ((*Header)->common.ptype == PKT_HTTP) - { - if (!RPCRT4_IsValidHttpPacket(*Header, *Payload, common_hdr.frag_len - hdr_length)) - { - ERR("invalid http packet of length %d bytes\n", (*Header)->common.frag_len); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - if ((*Header)->http.flags == 0x0001) - { - TRACE("http idle packet, waiting for real packet\n"); - if ((*Header)->http.num_data_items != 0) - { - ERR("HTTP idle packet should have no data items instead of %d\n", (*Header)->http.num_data_items); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - } - else if ((*Header)->http.flags == 0x0002) - { - ULONG bytes_transmitted; - ULONG flow_control_increment; - UUID pipe_uuid; - status = RPCRT4_ParseHttpFlowControlHeader(*Header, *Payload, - Connection->server, - &bytes_transmitted, - &flow_control_increment, - &pipe_uuid); - if (status != RPC_S_OK) - goto fail; - TRACE("received http flow control header (0x%x, 0x%x, %s)\n", - bytes_transmitted, flow_control_increment, debugstr_guid(&pipe_uuid)); - /* FIXME: do something with parsed data */ - } - else - { - FIXME("unrecognised http packet with flags 0x%04x\n", (*Header)->http.flags); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - RPCRT4_FreeHeader(*Header); - *Header = NULL; - HeapFree(GetProcessHeap(), 0, *Payload); - *Payload = NULL; - goto again; - } - - /* success */ - status = RPC_S_OK; - - httpc->bytes_received += common_hdr.frag_len; - - TRACE("httpc->bytes_received = 0x%x\n", httpc->bytes_received); - - if (httpc->bytes_received > httpc->flow_control_mark) - { - RpcPktHdr *hdr = RPCRT4_BuildHttpFlowControlHeader(httpc->common.server, - httpc->bytes_received, - httpc->flow_control_increment, - &httpc->out_pipe_uuid); - if (hdr) - { - DWORD bytes_written; - BOOL ret2; - TRACE("sending flow control packet at 0x%x\n", httpc->bytes_received); - ret2 = InternetWriteFile(httpc->in_request, hdr, hdr->common.frag_len, &bytes_written); - RPCRT4_FreeHeader(hdr); - if (ret2) - httpc->flow_control_mark = httpc->bytes_received + httpc->flow_control_increment / 2; - } - } - -fail: - if (status != RPC_S_OK) { - RPCRT4_FreeHeader(*Header); - *Header = NULL; - HeapFree(GetProcessHeap(), 0, *Payload); - *Payload = NULL; - } - return status; -} - -static int rpcrt4_ncacn_http_write(RpcConnection *Connection, - const void *buffer, unsigned int count) -{ - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - DWORD bytes_written; - BOOL ret; - - httpc->last_sent_time = ~0U; /* disable idle packet sending */ - ret = InternetWriteFile(httpc->in_request, buffer, count, &bytes_written); - httpc->last_sent_time = GetTickCount(); - TRACE("%p %p %u -> %s\n", httpc->in_request, buffer, count, ret ? "TRUE" : "FALSE"); - return ret ? bytes_written : -1; -} - -static int rpcrt4_ncacn_http_close(RpcConnection *Connection) -{ - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - - TRACE("\n"); - - SetEvent(httpc->timer_cancelled); - if (httpc->in_request) - InternetCloseHandle(httpc->in_request); - httpc->in_request = NULL; - if (httpc->out_request) - InternetCloseHandle(httpc->out_request); - httpc->out_request = NULL; - if (httpc->app_info) - InternetCloseHandle(httpc->app_info); - httpc->app_info = NULL; - if (httpc->session) - InternetCloseHandle(httpc->session); - httpc->session = NULL; - RpcHttpAsyncData_Release(httpc->async_data); - if (httpc->cancel_event) - CloseHandle(httpc->cancel_event); - - return 0; -} - -static void rpcrt4_ncacn_http_cancel_call(RpcConnection *Connection) -{ - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - - SetEvent(httpc->cancel_event); -} - -static int rpcrt4_ncacn_http_wait_for_incoming_data(RpcConnection *Connection) -{ - BOOL ret; - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - - RpcHttpAsyncData_AddRef(httpc->async_data); - ret = InternetQueryDataAvailable(httpc->out_request, - &httpc->async_data->inet_buffers.dwBufferLength, IRF_ASYNC, 0); - if (ret) - { - /* INTERNET_STATUS_REQUEST_COMPLETED won't be sent, so release our - * async ref now */ - RpcHttpAsyncData_Release(httpc->async_data); - } - else - { - if (GetLastError() == ERROR_IO_PENDING) - { - HANDLE handles[2] = { httpc->async_data->completion_event, httpc->cancel_event }; - DWORD result = WaitForMultipleObjects(2, handles, FALSE, DEFAULT_NCACN_HTTP_TIMEOUT); - if (result != WAIT_OBJECT_0) - { - TRACE("call cancelled\n"); - return -1; - } - } - else - { - RpcHttpAsyncData_Release(httpc->async_data); - return -1; - } - } - - /* success */ - return 0; -} - -static size_t rpcrt4_ncacn_http_get_top_of_tower(unsigned char *tower_data, - const char *networkaddr, - const char *endpoint) -{ - return rpcrt4_ip_tcp_get_top_of_tower(tower_data, networkaddr, - EPM_PROTOCOL_HTTP, endpoint); -} - -static RPC_STATUS rpcrt4_ncacn_http_parse_top_of_tower(const unsigned char *tower_data, - size_t tower_size, - char **networkaddr, - char **endpoint) -{ - return rpcrt4_ip_tcp_parse_top_of_tower(tower_data, tower_size, - networkaddr, EPM_PROTOCOL_HTTP, - endpoint); -} -#endif static const struct connection_ops conn_protseq_list[] = { { "ncacn_np", { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_SMB }, @@ -2691,7 +1413,6 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_np_wait_for_incoming_data, rpcrt4_ncacn_np_get_top_of_tower, rpcrt4_ncacn_np_parse_top_of_tower, - NULL, }, { "ncalrpc", { EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_PIPE }, @@ -2705,8 +1426,8 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_np_wait_for_incoming_data, rpcrt4_ncalrpc_get_top_of_tower, rpcrt4_ncalrpc_parse_top_of_tower, - NULL, }, +#ifdef HAVE_SOCKETPAIR { "ncacn_ip_tcp", { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_TCP }, rpcrt4_conn_tcp_alloc, @@ -2719,23 +1440,7 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_tcp_wait_for_incoming_data, rpcrt4_ncacn_ip_tcp_get_top_of_tower, rpcrt4_ncacn_ip_tcp_parse_top_of_tower, - NULL, - }, -#if 0 - { "ncacn_http", - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_HTTP }, - rpcrt4_ncacn_http_alloc, - rpcrt4_ncacn_http_open, - rpcrt4_ncacn_http_handoff, - rpcrt4_ncacn_http_read, - rpcrt4_ncacn_http_write, - rpcrt4_ncacn_http_close, - rpcrt4_ncacn_http_cancel_call, - rpcrt4_ncacn_http_wait_for_incoming_data, - rpcrt4_ncacn_http_get_top_of_tower, - rpcrt4_ncacn_http_parse_top_of_tower, - rpcrt4_ncacn_http_receive_fragment, - }, + } #endif }; @@ -2760,6 +1465,7 @@ static const struct protseq_ops protseq_list[] = rpcrt4_protseq_np_wait_for_new_connection, rpcrt4_protseq_ncalrpc_open_endpoint, }, +#ifdef HAVE_SOCKETPAIR { "ncacn_ip_tcp", rpcrt4_protseq_sock_alloc, @@ -2769,6 +1475,7 @@ static const struct protseq_ops protseq_list[] = rpcrt4_protseq_sock_wait_for_new_connection, rpcrt4_protseq_ncacn_ip_tcp_open_endpoint, }, +#endif }; #define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) @@ -2817,7 +1524,6 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS) { - static LONG next_id; const struct connection_ops *ops; RpcConnection* NewConnection; @@ -2845,7 +1551,6 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, NewConnection->attr = 0; if (AuthInfo) RpcAuthInfo_AddRef(AuthInfo); NewConnection->AuthInfo = AuthInfo; - NewConnection->auth_context_id = InterlockedIncrement( &next_id ); NewConnection->encryption_auth_len = 0; NewConnection->signature_auth_len = 0; if (QOS) RpcQualityOfService_AddRef(QOS); diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.rbuild b/reactos/dll/win32/rpcrt4/rpcrt4.rbuild index 59f9fe29ea4..67f05aebcfb 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.rbuild +++ b/reactos/dll/win32/rpcrt4/rpcrt4.rbuild @@ -14,7 +14,6 @@ user32 advapi32 secur32 - iphlpapi ws2_32 ntdll diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.spec b/reactos/dll/win32/rpcrt4/rpcrt4.spec index 0a047691822..4550889f62a 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.spec +++ b/reactos/dll/win32/rpcrt4/rpcrt4.spec @@ -116,9 +116,8 @@ @ stdcall NDRSContextUnmarshallEx(ptr ptr ptr) @ stub NDRcopy @ stdcall NdrAllocate(ptr long) -@ varargs NdrAsyncClientCall(ptr ptr) +@ stub NdrAsyncClientCall @ stub NdrAsyncServerCall -@ stdcall NdrAsyncStubCall(ptr ptr ptr ptr) @ stdcall NdrByteCountPointerBufferSize(ptr ptr ptr) @ stdcall NdrByteCountPointerFree(ptr ptr ptr) @ stdcall NdrByteCountPointerMarshall(ptr ptr ptr) @@ -371,7 +370,7 @@ @ stdcall RpcEpRegisterA(ptr ptr ptr str) @ stub RpcEpRegisterNoReplaceA @ stub RpcEpRegisterNoReplaceW -@ stdcall RpcEpRegisterW(ptr ptr ptr wstr) +@ stub RpcEpRegisterW @ stdcall RpcEpResolveBinding(ptr ptr) @ stdcall RpcEpUnregister(ptr ptr ptr) @ stub RpcErrorAddRecord # wxp diff --git a/reactos/dll/win32/rpcrt4/rpcrt4_main.c b/reactos/dll/win32/rpcrt4/rpcrt4_main.c index 2cc7429bf29..537a00537bc 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4_main.c +++ b/reactos/dll/win32/rpcrt4/rpcrt4_main.c @@ -43,10 +43,8 @@ #include "winuser.h" #include "winnt.h" #include "winternl.h" -#define _NTDEF_ -typedef NTSTATUS *PNTSTATUS; -#include "ntsecapi.h" -#undef _NTDEF_ +#include "iptypes.h" +#include "iphlpapi.h" #include "wine/unicode.h" #include "rpc.h" @@ -55,7 +53,6 @@ typedef NTSTATUS *PNTSTATUS; #include "rpcproxy.h" #include "rpc_binding.h" -#include "rpc_server.h" #include "wine/debug.h" @@ -63,6 +60,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(rpc); static UUID uuid_nil; +static CRITICAL_SECTION uuid_cs; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &uuid_cs, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": uuid_cs") } +}; +static CRITICAL_SECTION uuid_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; + static CRITICAL_SECTION threaddata_cs; static CRITICAL_SECTION_DEBUG threaddata_cs_debug = { @@ -129,7 +135,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) break; case DLL_PROCESS_DETACH: - RPCRT4_destroy_all_protseqs(); break; } @@ -275,6 +280,61 @@ RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid) return RPC_S_OK; } +/* Number of 100ns ticks per clock tick. To be safe, assume that the clock + resolution is at least 1000 * 100 * (1/1000000) = 1/10 of a second */ +#define TICKS_PER_CLOCK_TICK 1000 +#define SECSPERDAY 86400 +#define TICKSPERSEC 10000000 +/* UUID system time starts at October 15, 1582 */ +#define SECS_15_OCT_1582_TO_1601 ((17 + 30 + 31 + 365 * 18 + 5) * SECSPERDAY) +#define TICKS_15_OCT_1582_TO_1601 ((ULONGLONG)SECS_15_OCT_1582_TO_1601 * TICKSPERSEC) + +static void RPC_UuidGetSystemTime(ULONGLONG *time) +{ + FILETIME ft; + + GetSystemTimeAsFileTime(&ft); + + *time = ((ULONGLONG)ft.dwHighDateTime << 32) | ft.dwLowDateTime; + *time += TICKS_15_OCT_1582_TO_1601; +} + +/* Assume that a hardware address is at least 6 bytes long */ +#define ADDRESS_BYTES_NEEDED 6 + +static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address) +{ + int i; + DWORD status = RPC_S_OK; + + ULONG buflen = sizeof(IP_ADAPTER_INFO); + PIP_ADAPTER_INFO adapter = HeapAlloc(GetProcessHeap(), 0, buflen); + + if (GetAdaptersInfo(adapter, &buflen) == ERROR_BUFFER_OVERFLOW) { + HeapFree(GetProcessHeap(), 0, adapter); + adapter = HeapAlloc(GetProcessHeap(), 0, buflen); + } + + if (GetAdaptersInfo(adapter, &buflen) == NO_ERROR) { + for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { + address[i] = adapter->Address[i]; + } + } + /* We can't get a hardware address, just use random numbers. + Set the multicast bit to prevent conflicts with real cards. */ + else { + for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { + address[i] = rand() & 0xff; + } + + address[0] |= 0x01; + status = RPC_S_UUID_LOCAL_ONLY; + } + + HeapFree(GetProcessHeap(), 0, adapter); + return status; +} + /************************************************************************* * UuidCreate [RPCRT4.@] * @@ -285,26 +345,83 @@ RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid) * RPC_S_OK if successful. * RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique. * - * NOTES - * - * Follows RFC 4122, section 4.4 (Algorithms for Creating a UUID from - * Truly Random or Pseudo-Random Numbers) + * FIXME: No compensation for changes across reloading + * this dll or across reboots (e.g. clock going + * backwards and swapped network cards). The RFC + * suggests using NVRAM for storing persistent + * values. */ RPC_STATUS WINAPI UuidCreate(UUID *Uuid) { - RtlGenRandom(Uuid, sizeof(*Uuid)); - /* Clear the version bits and set the version (4) */ - Uuid->Data3 &= 0x0fff; - Uuid->Data3 |= (4 << 12); - /* Set the topmost bits of Data4 (clock_seq_hi_and_reserved) as - * specified in RFC 4122, section 4.4. - */ - Uuid->Data4[0] &= 0x3f; - Uuid->Data4[0] |= 0x80; + static int initialised, count; + + ULONGLONG time; + static ULONGLONG timelast; + static WORD sequence; + + static DWORD status; + static BYTE address[MAX_ADAPTER_ADDRESS_LENGTH]; + + EnterCriticalSection(&uuid_cs); + + if (!initialised) { + RPC_UuidGetSystemTime(&timelast); + count = TICKS_PER_CLOCK_TICK; + + sequence = ((rand() & 0xff) << 8) + (rand() & 0xff); + sequence &= 0x1fff; + + status = RPC_UuidGetNodeAddress(address); + initialised = 1; + } + + /* Generate time element of the UUID. Account for going faster + than our clock as well as the clock going backwards. */ + while (1) { + RPC_UuidGetSystemTime(&time); + if (time > timelast) { + count = 0; + break; + } + if (time < timelast) { + sequence = (sequence + 1) & 0x1fff; + count = 0; + break; + } + if (count < TICKS_PER_CLOCK_TICK) { + count++; + break; + } + } + + timelast = time; + time += count; + + /* Pack the information into the UUID structure. */ + + Uuid->Data1 = (unsigned long)(time & 0xffffffff); + Uuid->Data2 = (unsigned short)((time >> 32) & 0xffff); + Uuid->Data3 = (unsigned short)((time >> 48) & 0x0fff); + + /* This is a version 1 UUID */ + Uuid->Data3 |= (1 << 12); + + Uuid->Data4[0] = sequence & 0xff; + Uuid->Data4[1] = (sequence & 0x3f00) >> 8; + Uuid->Data4[1] |= 0x80; + + Uuid->Data4[2] = address[0]; + Uuid->Data4[3] = address[1]; + Uuid->Data4[4] = address[2]; + Uuid->Data4[5] = address[3]; + Uuid->Data4[6] = address[4]; + Uuid->Data4[7] = address[5]; + + LeaveCriticalSection(&uuid_cs); TRACE("%s\n", debugstr_guid(Uuid)); - return RPC_S_OK; + return status; } /*************************************************************************