mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
- Revert rpcrt4 update, too buggy for now. My apologizes.
svn path=/trunk/; revision=26792
This commit is contained in:
parent
3d1bf7d14e
commit
149c5b1cae
32 changed files with 2760 additions and 7763 deletions
|
@ -17,17 +17,14 @@
|
|||
<library>kernel32</library>
|
||||
<pch>advapi32.h</pch>
|
||||
<directory name="crypt">
|
||||
<compilationunit name="crypt_unit.c">
|
||||
<file>crypt.c</file>
|
||||
<file>crypt_des.c</file>
|
||||
<file>crypt_lmhash.c</file>
|
||||
<file>crypt_md4.c</file>
|
||||
<file>crypt_md5.c</file>
|
||||
<file>crypt_sha.c</file>
|
||||
</compilationunit>
|
||||
</directory>
|
||||
<directory name="misc">
|
||||
<compilationunit name="misc.c">
|
||||
<file>dllmain.c</file>
|
||||
<file>hwprofiles.c</file>
|
||||
<file>logon.c</file>
|
||||
|
@ -35,13 +32,11 @@
|
|||
<file>shutdown.c</file>
|
||||
<file>sysfunc.c</file>
|
||||
<file>trace.c</file>
|
||||
</compilationunit>
|
||||
</directory>
|
||||
<directory name="reg">
|
||||
<file>reg.c</file>
|
||||
</directory>
|
||||
<directory name="sec">
|
||||
<compilationunit name="sec_unit.c">
|
||||
<file>ac.c</file>
|
||||
<file>audit.c</file>
|
||||
<file>lsa.c</file>
|
||||
|
@ -49,21 +44,16 @@
|
|||
<file>sec.c</file>
|
||||
<file>sid.c</file>
|
||||
<file>trustee.c</file>
|
||||
</compilationunit>
|
||||
</directory>
|
||||
<directory name="service">
|
||||
<compilationunit name="service.c">
|
||||
<file>eventlog.c</file>
|
||||
<file>scm.c</file>
|
||||
<file>sctrl.c</file>
|
||||
<file>undoc.c</file>
|
||||
</compilationunit>
|
||||
</directory>
|
||||
<directory name="token">
|
||||
<compilationunit name="token_unit.c">
|
||||
<file>privilege.c</file>
|
||||
<file>token.c</file>
|
||||
</compilationunit>
|
||||
</directory>
|
||||
<file>advapi32.rc</file>
|
||||
</module>
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
|
||||
#include <advapi32.h>
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
#undef NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* TODO: Handle non-i386 architectures
|
||||
* Get rid of #if 0'ed code.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -44,7 +45,7 @@ struct StublessThunk;
|
|||
typedef struct {
|
||||
const IRpcProxyBufferVtbl *lpVtbl;
|
||||
LPVOID *PVtbl;
|
||||
LONG RefCount;
|
||||
DWORD RefCount;
|
||||
const MIDL_STUBLESS_PROXY_INFO *stubless;
|
||||
const IID* piid;
|
||||
LPUNKNOWN pUnkOuter;
|
||||
|
@ -101,7 +102,7 @@ static HRESULT WINAPI ObjectStubless(DWORD index)
|
|||
|
||||
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));
|
||||
TRACE("(%p)->(%ld)([%d bytes]) ret=%08lx\n", iface, index, bytes, *(DWORD*)(args+bytes));
|
||||
|
||||
return NdrClientCall2(This->stubless->pStubDesc, fs, args);
|
||||
}
|
||||
|
@ -222,13 +223,13 @@ static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface,
|
|||
if (IsEqualGUID(&IID_IUnknown,riid) ||
|
||||
IsEqualGUID(This->piid,riid)) {
|
||||
*obj = &This->PVtbl;
|
||||
InterlockedIncrement(&This->RefCount);
|
||||
This->RefCount++;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (IsEqualGUID(&IID_IRpcProxyBuffer,riid)) {
|
||||
*obj = &This->lpVtbl;
|
||||
InterlockedIncrement(&This->RefCount);
|
||||
This->RefCount++;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -240,19 +241,19 @@ static ULONG WINAPI StdProxy_AddRef(LPRPCPROXYBUFFER iface)
|
|||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->AddRef()\n",This);
|
||||
|
||||
return InterlockedIncrement(&This->RefCount);
|
||||
return ++(This->RefCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI StdProxy_Release(LPRPCPROXYBUFFER iface)
|
||||
{
|
||||
ULONG refs;
|
||||
ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface);
|
||||
TRACE("(%p)->Release()\n",This);
|
||||
|
||||
refs = InterlockedDecrement(&This->RefCount);
|
||||
if (!refs)
|
||||
if (!--(This->RefCount)) {
|
||||
StdProxy_Destruct((LPRPCPROXYBUFFER)&This->lpVtbl);
|
||||
return refs;
|
||||
return 0;
|
||||
}
|
||||
return This->RefCount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface,
|
||||
|
@ -284,22 +285,24 @@ static const IRpcProxyBufferVtbl StdProxy_Vtbl =
|
|||
StdProxy_Disconnect
|
||||
};
|
||||
|
||||
static void StdProxy_GetChannel(LPVOID iface,
|
||||
LPRPCCHANNELBUFFER *ppChannel)
|
||||
HRESULT WINAPI StdProxy_GetChannel(LPVOID iface,
|
||||
LPRPCCHANNELBUFFER *ppChannel)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->GetChannel(%p) %s\n",This,ppChannel,This->name);
|
||||
|
||||
*ppChannel = This->pChannel;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void StdProxy_GetIID(LPVOID iface,
|
||||
const IID **ppiid)
|
||||
HRESULT WINAPI StdProxy_GetIID(LPVOID iface,
|
||||
const IID **ppiid)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->GetIID(%p) %s\n",This,ppiid,This->name);
|
||||
|
||||
*ppiid = This->piid;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IUnknown_QueryInterface_Proxy(LPUNKNOWN iface,
|
||||
|
@ -315,136 +318,32 @@ ULONG WINAPI IUnknown_AddRef_Proxy(LPUNKNOWN iface)
|
|||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->AddRef() %s\n",This,This->name);
|
||||
#if 0 /* interface refcounting */
|
||||
return ++(This->RefCount);
|
||||
#else /* object refcounting */
|
||||
return IUnknown_AddRef(This->pUnkOuter);
|
||||
#endif
|
||||
}
|
||||
|
||||
ULONG WINAPI IUnknown_Release_Proxy(LPUNKNOWN iface)
|
||||
{
|
||||
ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface);
|
||||
TRACE("(%p)->Release() %s\n",This,This->name);
|
||||
#if 0 /* interface refcounting */
|
||||
if (!--(This->RefCount)) {
|
||||
StdProxy_Destruct((LPRPCPROXYBUFFER)&This->lpVtbl);
|
||||
return 0;
|
||||
}
|
||||
return This->RefCount;
|
||||
#else /* object refcounting */
|
||||
return IUnknown_Release(This->pUnkOuter);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyInitialize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyInitialize(void *This,
|
||||
PRPC_MESSAGE pRpcMsg,
|
||||
PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDescriptor,
|
||||
unsigned int ProcNum)
|
||||
{
|
||||
TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
|
||||
NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
|
||||
StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer);
|
||||
IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
|
||||
&pStubMsg->dwDestContext,
|
||||
&pStubMsg->pvDestContext);
|
||||
TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyGetBuffer(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
HRESULT hr;
|
||||
const IID *riid = NULL;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
|
||||
pStubMsg->dwStubPhase = PROXY_GETBUFFER;
|
||||
StdProxy_GetIID(This, &riid);
|
||||
hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg,
|
||||
riid);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RpcRaiseException(hr);
|
||||
return;
|
||||
}
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
pStubMsg->dwStubPhase = PROXY_MARSHAL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxySendReceive [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxySendReceive(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
ULONG Status = 0;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
|
||||
if (!pStubMsg->pRpcChannelBuffer)
|
||||
{
|
||||
WARN("Trying to use disconnected proxy %p\n", This);
|
||||
RpcRaiseException(RPC_E_DISCONNECTED);
|
||||
}
|
||||
|
||||
pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
|
||||
hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg,
|
||||
&Status);
|
||||
pStubMsg->dwStubPhase = PROXY_UNMARSHAL;
|
||||
pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
|
||||
/* raise exception if call failed */
|
||||
if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer);
|
||||
else if (FAILED(hr)) RpcRaiseException(hr);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyFreeBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyFreeBuffer(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
hr = IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyErrorHandler [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode)
|
||||
{
|
||||
WARN("(0x%08x): a proxy call failed\n", dwExceptionCode);
|
||||
|
||||
if (FAILED(dwExceptionCode))
|
||||
return dwExceptionCode;
|
||||
else
|
||||
return HRESULT_FROM_WIN32(dwExceptionCode);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT WINAPI
|
||||
CreateProxyFromTypeInfo( LPTYPEINFO pTypeInfo, LPUNKNOWN pUnkOuter, REFIID riid,
|
||||
LPRPCPROXYBUFFER *ppProxy, LPVOID *ppv )
|
||||
{
|
||||
typedef INT (WINAPI *MessageBoxA)(HWND,LPCSTR,LPCSTR,UINT);
|
||||
HMODULE hUser32 = LoadLibraryA("user32");
|
||||
MessageBoxA pMessageBoxA = GetProcAddress(hUser32, "MessageBoxA");
|
||||
|
||||
FIXME("%p %p %s %p %p\n", pTypeInfo, pUnkOuter, debugstr_guid(riid), ppProxy, ppv);
|
||||
if (pMessageBoxA)
|
||||
{
|
||||
pMessageBoxA(NULL,
|
||||
"The native implementation of OLEAUT32.DLL cannot be used "
|
||||
"with Wine's RPCRT4.DLL. Remove OLEAUT32.DLL and try again.\n",
|
||||
"Wine: Unimplemented CreateProxyFromTypeInfo",
|
||||
0x10);
|
||||
ExitProcess(1);
|
||||
}
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -110,12 +110,6 @@ static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface,
|
|||
pUnkServer,ppStub);
|
||||
if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index))
|
||||
return E_NOINTERFACE;
|
||||
|
||||
if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index])
|
||||
return CStdStubBuffer_Delegating_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index],
|
||||
ProxyInfo->pStubVtblList[Index], ProxyInfo->pDelegatedIIDs[Index],
|
||||
iface, ppStub);
|
||||
|
||||
return CStdStubBuffer_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index],
|
||||
ProxyInfo->pStubVtblList[Index], iface, ppStub);
|
||||
}
|
||||
|
@ -144,7 +138,6 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
|
|||
*ppv = NULL;
|
||||
if (!pPSFactoryBuffer->lpVtbl) {
|
||||
const ProxyFileInfo **pProxyFileList2;
|
||||
int max_delegating_vtbl_size = 0;
|
||||
pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl;
|
||||
pPSFactoryBuffer->RefCount = 0;
|
||||
pPSFactoryBuffer->pProxyFileList = pProxyFileList;
|
||||
|
@ -157,19 +150,11 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
|
|||
void **pRpcStubVtbl = (void **)&(*pProxyFileList2)->pStubVtblList[i]->Vtbl;
|
||||
int j;
|
||||
|
||||
if ((*pProxyFileList2)->pDelegatedIIDs && (*pProxyFileList2)->pDelegatedIIDs[i]) {
|
||||
pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl;
|
||||
if ((*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount > max_delegating_vtbl_size)
|
||||
max_delegating_vtbl_size = (*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount;
|
||||
}
|
||||
|
||||
for (j = 0; j < sizeof(IRpcStubBufferVtbl)/sizeof(void *); j++)
|
||||
if (!pRpcStubVtbl[j])
|
||||
pRpcStubVtbl[j] = pSrcRpcStubVtbl[j];
|
||||
}
|
||||
}
|
||||
if(max_delegating_vtbl_size > 0)
|
||||
create_delegating_vtbl(max_delegating_vtbl_size);
|
||||
}
|
||||
if (IsEqualGUID(rclsid, pclsid))
|
||||
return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
|
||||
|
@ -225,7 +210,7 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll,
|
|||
if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
|
||||
if (name)
|
||||
RegSetValueExA(key, NULL, 0, REG_SZ, (const BYTE *)name, strlen(name));
|
||||
RegSetValueExA(key, NULL, 0, REG_SZ, (LPBYTE)name, strlen(name));
|
||||
if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) {
|
||||
snprintf(module, sizeof(module), "{%s}", clsid);
|
||||
|
@ -245,11 +230,9 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll,
|
|||
TRACE("registering CLSID %s => %s\n", clsid, module);
|
||||
if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
|
||||
RegSetValueExA(subkey, NULL, 0, REG_SZ, (const BYTE *)"PSFactoryBuffer", strlen("PSFactoryBuffer"));
|
||||
if (RegCreateKeyExA(key, "InProcServer32", 0, NULL, 0,
|
||||
KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) {
|
||||
RegSetValueExA(subkey, NULL, 0, REG_SZ, (LPBYTE)module, strlen(module));
|
||||
RegSetValueExA(subkey, "ThreadingModel", 0, REG_SZ, (const BYTE *)"Both", strlen("Both"));
|
||||
RegCloseKey(subkey);
|
||||
}
|
||||
RegCloseKey(key);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_CPSF_H
|
||||
|
@ -28,6 +28,10 @@ HRESULT WINAPI StdProxy_Construct(REFIID riid,
|
|||
LPPSFACTORYBUFFER pPSFactory,
|
||||
LPRPCPROXYBUFFER *ppProxy,
|
||||
LPVOID *ppvObj);
|
||||
HRESULT WINAPI StdProxy_GetChannel(LPVOID iface,
|
||||
LPRPCCHANNELBUFFER *ppChannel);
|
||||
HRESULT WINAPI StdProxy_GetIID(LPVOID iface,
|
||||
const IID **piid);
|
||||
|
||||
HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
|
||||
LPUNKNOWN pUnkServer,
|
||||
|
@ -36,21 +40,8 @@ HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
|
|||
LPPSFACTORYBUFFER pPSFactory,
|
||||
LPRPCSTUBBUFFER *ppStub);
|
||||
|
||||
HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid,
|
||||
LPUNKNOWN pUnkServer,
|
||||
PCInterfaceName name,
|
||||
CInterfaceStubVtbl *vtbl,
|
||||
REFIID delegating_iid,
|
||||
LPPSFACTORYBUFFER pPSFactory,
|
||||
LPRPCSTUBBUFFER *ppStub);
|
||||
|
||||
const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface);
|
||||
|
||||
const IRpcStubBufferVtbl CStdStubBuffer_Vtbl;
|
||||
const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl;
|
||||
|
||||
void create_delegating_vtbl(DWORD num_methods);
|
||||
|
||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub);
|
||||
|
||||
#endif /* __WINE_CPSF_H */
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -25,38 +25,18 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "excpt.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/exception.h"
|
||||
|
||||
#include "cpsf.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
#define STUB_HEADER(This) (((const CInterfaceStubHeader*)((This)->lpVtbl))[-1])
|
||||
|
||||
static WINE_EXCEPTION_FILTER(stub_filter)
|
||||
{
|
||||
if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IUnknownVtbl *base_obj;
|
||||
IRpcStubBuffer *base_stub;
|
||||
CStdStubBuffer stub_buffer;
|
||||
} cstdstubbuffer_delegating_t;
|
||||
|
||||
static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer *iface )
|
||||
{
|
||||
return (cstdstubbuffer_delegating_t*)((char *)iface - FIELD_OFFSET(cstdstubbuffer_delegating_t, stub_buffer));
|
||||
}
|
||||
#define STUB_HEADER(This) (((CInterfaceStubHeader*)((This)->lpVtbl))[-1])
|
||||
|
||||
HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
|
||||
LPUNKNOWN pUnkServer,
|
||||
|
@ -66,8 +46,7 @@ HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
|
|||
LPRPCSTUBBUFFER *ppStub)
|
||||
{
|
||||
CStdStubBuffer *This;
|
||||
IUnknown *pvServer;
|
||||
HRESULT r;
|
||||
|
||||
TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name);
|
||||
TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid));
|
||||
TRACE("vtbl=%p\n", &vtbl->Vtbl);
|
||||
|
@ -77,233 +56,20 @@ HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
|
|||
return RPC_E_UNEXPECTED;
|
||||
}
|
||||
|
||||
r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer);
|
||||
if(FAILED(r))
|
||||
return r;
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CStdStubBuffer));
|
||||
if (!This) {
|
||||
IUnknown_Release(pvServer);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
|
||||
This->lpVtbl = &vtbl->Vtbl;
|
||||
This->RefCount = 1;
|
||||
This->pvServerObject = pvServer;
|
||||
This->pvServerObject = pUnkServer;
|
||||
This->pPSFactory = pPSFactory;
|
||||
*ppStub = (LPRPCSTUBBUFFER)This;
|
||||
|
||||
IUnknown_AddRef(This->pvServerObject);
|
||||
IPSFactoryBuffer_AddRef(pPSFactory);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static CRITICAL_SECTION delegating_vtbl_section;
|
||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
{
|
||||
0, 0, &delegating_vtbl_section,
|
||||
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": delegating_vtbl_section") }
|
||||
};
|
||||
static CRITICAL_SECTION delegating_vtbl_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD ref;
|
||||
IUnknownVtbl vtbl;
|
||||
} ref_counted_vtbl;
|
||||
|
||||
static struct
|
||||
{
|
||||
ref_counted_vtbl *table;
|
||||
DWORD size;
|
||||
} current_vtbl;
|
||||
|
||||
|
||||
static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv)
|
||||
{
|
||||
*ppv = (void *)pUnk;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI delegating_AddRef(IUnknown *pUnk)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ULONG WINAPI delegating_Release(IUnknown *pUnk)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
|
||||
/* The idea here is to replace the first param on the stack
|
||||
ie. This (which will point to cstdstubbuffer_delegating_t)
|
||||
with This->stub_buffer.pvServerObject and then jump to the
|
||||
relevant offset in This->stub_buffer.pvServerObject's vtbl.
|
||||
*/
|
||||
#include "pshpack1.h"
|
||||
typedef struct {
|
||||
DWORD mov1; /* mov 0x4(%esp), %eax 8b 44 24 04 */
|
||||
WORD mov2; /* mov 0x10(%eax), %eax 8b 40 */
|
||||
BYTE sixteen; /* 10 */
|
||||
DWORD mov3; /* mov %eax, 0x4(%esp) 89 44 24 04 */
|
||||
WORD mov4; /* mov (%eax), %eax 8b 00 */
|
||||
WORD mov5; /* mov offset(%eax), %eax 8b 80 */
|
||||
DWORD offset; /* xx xx xx xx */
|
||||
WORD jmp; /* jmp *%eax ff e0 */
|
||||
BYTE pad[3]; /* lea 0x0(%esi), %esi 8d 76 00 */
|
||||
} vtbl_method_t;
|
||||
#include "poppack.h"
|
||||
|
||||
static void fill_table(IUnknownVtbl *vtbl, DWORD num)
|
||||
{
|
||||
vtbl_method_t *method;
|
||||
void **entry;
|
||||
DWORD i;
|
||||
|
||||
vtbl->QueryInterface = delegating_QueryInterface;
|
||||
vtbl->AddRef = delegating_AddRef;
|
||||
vtbl->Release = delegating_Release;
|
||||
|
||||
method = (vtbl_method_t*)((void **)vtbl + num);
|
||||
entry = (void**)(vtbl + 1);
|
||||
|
||||
for(i = 3; i < num; i++)
|
||||
{
|
||||
*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++;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
typedef struct {int dummy;} vtbl_method_t;
|
||||
static void fill_table(IUnknownVtbl *vtbl, DWORD num)
|
||||
{
|
||||
ERR("delegated stubs are not supported on this architecture\n");
|
||||
}
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
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(num_methods > current_vtbl.size)
|
||||
{
|
||||
DWORD size;
|
||||
if(current_vtbl.table && current_vtbl.table->ref == 0)
|
||||
{
|
||||
TRACE("freeing old table\n");
|
||||
HeapFree(GetProcessHeap(), 0, current_vtbl.table);
|
||||
}
|
||||
size = sizeof(DWORD) + num_methods * sizeof(void*) + (num_methods - 3) * sizeof(vtbl_method_t);
|
||||
current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
fill_table(¤t_vtbl.table->vtbl, num_methods);
|
||||
current_vtbl.table->ref = 0;
|
||||
current_vtbl.size = num_methods;
|
||||
}
|
||||
LeaveCriticalSection(&delegating_vtbl_section);
|
||||
}
|
||||
|
||||
static IUnknownVtbl *get_delegating_vtbl(void)
|
||||
{
|
||||
IUnknownVtbl *ret;
|
||||
|
||||
EnterCriticalSection(&delegating_vtbl_section);
|
||||
current_vtbl.table->ref++;
|
||||
ret = ¤t_vtbl.table->vtbl;
|
||||
LeaveCriticalSection(&delegating_vtbl_section);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void release_delegating_vtbl(IUnknownVtbl *vtbl)
|
||||
{
|
||||
ref_counted_vtbl *table = (ref_counted_vtbl*)((DWORD *)vtbl - 1);
|
||||
|
||||
EnterCriticalSection(&delegating_vtbl_section);
|
||||
table->ref--;
|
||||
TRACE("ref now %d\n", table->ref);
|
||||
if(table->ref == 0 && table != current_vtbl.table)
|
||||
{
|
||||
TRACE("... and we're not current so free'ing\n");
|
||||
HeapFree(GetProcessHeap(), 0, table);
|
||||
}
|
||||
LeaveCriticalSection(&delegating_vtbl_section);
|
||||
}
|
||||
|
||||
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;
|
||||
HRESULT r;
|
||||
|
||||
TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name);
|
||||
TRACE("iid=%s delegating to %s\n", debugstr_guid(vtbl->header.piid), debugstr_guid(delegating_iid));
|
||||
TRACE("vtbl=%p\n", &vtbl->Vtbl);
|
||||
|
||||
if (!IsEqualGUID(vtbl->header.piid, riid))
|
||||
{
|
||||
ERR("IID mismatch during stub creation\n");
|
||||
return RPC_E_UNEXPECTED;
|
||||
}
|
||||
|
||||
r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer);
|
||||
if(FAILED(r)) return r;
|
||||
|
||||
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
|
||||
if (!This)
|
||||
{
|
||||
IUnknown_Release(pvServer);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
This->base_obj = get_delegating_vtbl();
|
||||
r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub);
|
||||
if(FAILED(r))
|
||||
{
|
||||
release_delegating_vtbl(This->base_obj);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
IUnknown_Release(pvServer);
|
||||
return r;
|
||||
}
|
||||
|
||||
This->stub_buffer.lpVtbl = &vtbl->Vtbl;
|
||||
This->stub_buffer.RefCount = 1;
|
||||
This->stub_buffer.pvServerObject = pvServer;
|
||||
This->stub_buffer.pPSFactory = pPSFactory;
|
||||
*ppStub = (LPRPCSTUBBUFFER)&This->stub_buffer;
|
||||
|
||||
IPSFactoryBuffer_AddRef(pPSFactory);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CStdStubBuffer_QueryInterface(LPRPCSTUBBUFFER iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
|
@ -311,14 +77,12 @@ HRESULT WINAPI CStdStubBuffer_QueryInterface(LPRPCSTUBBUFFER iface,
|
|||
CStdStubBuffer *This = (CStdStubBuffer *)iface;
|
||||
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj);
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown, riid) ||
|
||||
IsEqualIID(&IID_IRpcStubBuffer, riid))
|
||||
{
|
||||
IUnknown_AddRef(iface);
|
||||
*obj = iface;
|
||||
if (IsEqualGUID(&IID_IUnknown,riid) ||
|
||||
IsEqualGUID(&IID_IRpcStubBuffer,riid)) {
|
||||
*obj = This;
|
||||
This->RefCount++;
|
||||
return S_OK;
|
||||
}
|
||||
*obj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -326,81 +90,50 @@ ULONG WINAPI CStdStubBuffer_AddRef(LPRPCSTUBBUFFER iface)
|
|||
{
|
||||
CStdStubBuffer *This = (CStdStubBuffer *)iface;
|
||||
TRACE("(%p)->AddRef()\n",This);
|
||||
return InterlockedIncrement(&This->RefCount);
|
||||
return ++(This->RefCount);
|
||||
}
|
||||
|
||||
ULONG WINAPI NdrCStdStubBuffer_Release(LPRPCSTUBBUFFER iface,
|
||||
LPPSFACTORYBUFFER pPSF)
|
||||
{
|
||||
CStdStubBuffer *This = (CStdStubBuffer *)iface;
|
||||
ULONG refs;
|
||||
|
||||
TRACE("(%p)->Release()\n",This);
|
||||
|
||||
refs = InterlockedDecrement(&This->RefCount);
|
||||
if (!refs)
|
||||
{
|
||||
/* test_Release shows that native doesn't call Disconnect here.
|
||||
We'll leave it in for the time being. */
|
||||
if (!--(This->RefCount)) {
|
||||
IRpcStubBuffer_Disconnect(iface);
|
||||
|
||||
IPSFactoryBuffer_Release(pPSF);
|
||||
if(This->pPSFactory)
|
||||
IPSFactoryBuffer_Release(This->pPSFactory);
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return 0;
|
||||
}
|
||||
return refs;
|
||||
return This->RefCount;
|
||||
}
|
||||
|
||||
ULONG WINAPI NdrCStdStubBuffer2_Release(LPRPCSTUBBUFFER iface,
|
||||
LPPSFACTORYBUFFER pPSF)
|
||||
{
|
||||
cstdstubbuffer_delegating_t *This = impl_from_delegating( iface );
|
||||
ULONG refs;
|
||||
|
||||
TRACE("(%p)->Release()\n", This);
|
||||
|
||||
refs = InterlockedDecrement(&This->stub_buffer.RefCount);
|
||||
if (!refs)
|
||||
{
|
||||
/* Just like NdrCStdStubBuffer_Release, we shouldn't call
|
||||
Disconnect here */
|
||||
IRpcStubBuffer_Disconnect((IRpcStubBuffer *)&This->stub_buffer);
|
||||
|
||||
IRpcStubBuffer_Release(This->base_stub);
|
||||
release_delegating_vtbl(This->base_obj);
|
||||
|
||||
IPSFactoryBuffer_Release(pPSF);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return refs;
|
||||
FIXME("Not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CStdStubBuffer_Connect(LPRPCSTUBBUFFER iface,
|
||||
LPUNKNOWN lpUnkServer)
|
||||
{
|
||||
CStdStubBuffer *This = (CStdStubBuffer *)iface;
|
||||
HRESULT r;
|
||||
IUnknown *new = NULL;
|
||||
|
||||
TRACE("(%p)->Connect(%p)\n",This,lpUnkServer);
|
||||
|
||||
r = IUnknown_QueryInterface(lpUnkServer, STUB_HEADER(This).piid, (void**)&new);
|
||||
new = InterlockedExchangePointer((void**)&This->pvServerObject, new);
|
||||
if(new)
|
||||
IUnknown_Release(new);
|
||||
return r;
|
||||
CStdStubBuffer *This = (CStdStubBuffer *)iface;
|
||||
TRACE("(%p)->Connect(%p)\n",This,lpUnkServer);
|
||||
This->pvServerObject = lpUnkServer;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void WINAPI CStdStubBuffer_Disconnect(LPRPCSTUBBUFFER iface)
|
||||
{
|
||||
CStdStubBuffer *This = (CStdStubBuffer *)iface;
|
||||
IUnknown *old;
|
||||
TRACE("(%p)->Disconnect()\n",This);
|
||||
|
||||
old = InterlockedExchangePointer((void**)&This->pvServerObject, NULL);
|
||||
|
||||
if(old)
|
||||
IUnknown_Release(old);
|
||||
CStdStubBuffer *This = (CStdStubBuffer *)iface;
|
||||
TRACE("(%p)->Disconnect()\n",This);
|
||||
if (This->pvServerObject)
|
||||
{
|
||||
IUnknown_Release(This->pvServerObject);
|
||||
This->pvServerObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface,
|
||||
|
@ -409,29 +142,13 @@ HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface,
|
|||
{
|
||||
CStdStubBuffer *This = (CStdStubBuffer *)iface;
|
||||
DWORD dwPhase = STUB_UNMARSHAL;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
TRACE("(%p)->Invoke(%p,%p)\n",This,pMsg,pChannel);
|
||||
|
||||
__TRY
|
||||
{
|
||||
if (STUB_HEADER(This).pDispatchTable)
|
||||
STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase);
|
||||
else /* pure interpreted */
|
||||
NdrStubCall2(iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase);
|
||||
}
|
||||
__EXCEPT(stub_filter)
|
||||
{
|
||||
DWORD dwExceptionCode = GetExceptionCode();
|
||||
WARN("a stub call failed with exception 0x%08x (%d)\n", dwExceptionCode, dwExceptionCode);
|
||||
if (FAILED(dwExceptionCode))
|
||||
hr = dwExceptionCode;
|
||||
else
|
||||
hr = HRESULT_FROM_WIN32(dwExceptionCode);
|
||||
}
|
||||
__ENDTRY
|
||||
|
||||
return hr;
|
||||
if (STUB_HEADER(This).pDispatchTable)
|
||||
STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase);
|
||||
else /* pure interpreted */
|
||||
NdrStubCall2(iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LPRPCSTUBBUFFER WINAPI CStdStubBuffer_IsIIDSupported(LPRPCSTUBBUFFER iface,
|
||||
|
@ -478,110 +195,8 @@ const IRpcStubBufferVtbl CStdStubBuffer_Vtbl =
|
|||
CStdStubBuffer_DebugServerRelease
|
||||
};
|
||||
|
||||
static HRESULT WINAPI CStdStubBuffer_Delegating_Connect(LPRPCSTUBBUFFER iface,
|
||||
LPUNKNOWN lpUnkServer)
|
||||
{
|
||||
cstdstubbuffer_delegating_t *This = impl_from_delegating(iface);
|
||||
HRESULT r;
|
||||
TRACE("(%p)->Connect(%p)\n", This, lpUnkServer);
|
||||
|
||||
r = CStdStubBuffer_Connect(iface, lpUnkServer);
|
||||
if(SUCCEEDED(r))
|
||||
r = IRpcStubBuffer_Connect(This->base_stub, (IUnknown*)&This->base_obj);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void WINAPI CStdStubBuffer_Delegating_Disconnect(LPRPCSTUBBUFFER iface)
|
||||
{
|
||||
cstdstubbuffer_delegating_t *This = impl_from_delegating(iface);
|
||||
TRACE("(%p)->Disconnect()\n", This);
|
||||
|
||||
IRpcStubBuffer_Disconnect(This->base_stub);
|
||||
CStdStubBuffer_Disconnect(iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI CStdStubBuffer_Delegating_CountRefs(LPRPCSTUBBUFFER iface)
|
||||
{
|
||||
cstdstubbuffer_delegating_t *This = impl_from_delegating(iface);
|
||||
ULONG ret;
|
||||
TRACE("(%p)->CountRefs()\n", This);
|
||||
|
||||
ret = CStdStubBuffer_CountRefs(iface);
|
||||
ret += IRpcStubBuffer_CountRefs(This->base_stub);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl =
|
||||
{
|
||||
CStdStubBuffer_QueryInterface,
|
||||
CStdStubBuffer_AddRef,
|
||||
NULL,
|
||||
CStdStubBuffer_Delegating_Connect,
|
||||
CStdStubBuffer_Delegating_Disconnect,
|
||||
CStdStubBuffer_Invoke,
|
||||
CStdStubBuffer_IsIIDSupported,
|
||||
CStdStubBuffer_Delegating_CountRefs,
|
||||
CStdStubBuffer_DebugServerQueryInterface,
|
||||
CStdStubBuffer_DebugServerRelease
|
||||
};
|
||||
|
||||
const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface)
|
||||
{
|
||||
CStdStubBuffer *This = (CStdStubBuffer *)iface;
|
||||
return STUB_HEADER(This).pServerInfo;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrStubForwardingFunction [RPCRT4.@]
|
||||
*/
|
||||
void __RPC_STUB NdrStubForwardingFunction( IRpcStubBuffer *iface, IRpcChannelBuffer *pChannel,
|
||||
PRPC_MESSAGE pMsg, DWORD *pdwStubPhase )
|
||||
{
|
||||
/* Note pMsg is passed intact since RPCOLEMESSAGE is basically a RPC_MESSAGE. */
|
||||
|
||||
cstdstubbuffer_delegating_t *This = impl_from_delegating(iface);
|
||||
HRESULT r = IRpcStubBuffer_Invoke(This->base_stub, (RPCOLEMESSAGE*)pMsg, pChannel);
|
||||
if(FAILED(r)) RpcRaiseException(r);
|
||||
return;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrStubInitialize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg,
|
||||
PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDescriptor,
|
||||
LPRPCCHANNELBUFFER pRpcChannelBuffer)
|
||||
{
|
||||
TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer);
|
||||
NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor);
|
||||
pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrStubGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER iface,
|
||||
LPRPCCHANNELBUFFER pRpcChannelBuffer,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
CStdStubBuffer *This = (CStdStubBuffer *)iface;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p, %p, %p)\n", This, pRpcChannelBuffer, pStubMsg);
|
||||
|
||||
pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
|
||||
hr = IRpcChannelBuffer_GetBuffer(pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE *)pStubMsg->RpcMsg, STUB_HEADER(This).piid);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RpcRaiseException(hr);
|
||||
return;
|
||||
}
|
||||
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
}
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* Endpoint Mapper Tower Definitions
|
||||
*
|
||||
* Copyright 2006 Robert Shearman (for CodeWeavers)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define EPM_PROTOCOL_DNET_NSP 0x04
|
||||
#define EPM_PROTOCOL_OSI_TP4 0x05
|
||||
#define EPM_PROTOCOL_OSI_CLNS 0x06
|
||||
#define EPM_PROTOCOL_TCP 0x07
|
||||
#define EPM_PROTOCOL_UDP 0x08
|
||||
#define EPM_PROTOCOL_IP 0x09
|
||||
#define EPM_PROTOCOL_NCADG 0x0a /* Connectionless RPC */
|
||||
#define EPM_PROTOCOL_NCACN 0x0b
|
||||
#define EPM_PROTOCOL_NCALRPC 0x0c /* Local RPC */
|
||||
#define EPM_PROTOCOL_UUID 0x0d
|
||||
#define EPM_PROTOCOL_IPX 0x0e
|
||||
#define EPM_PROTOCOL_SMB 0x0f
|
||||
#define EPM_PROTOCOL_PIPE 0x10
|
||||
#define EPM_PROTOCOL_NETBIOS 0x11
|
||||
#define EPM_PROTOCOL_NETBEUI 0x12
|
||||
#define EPM_PROTOCOL_SPX 0x13
|
||||
#define EPM_PROTOCOL_NB_IPX 0x14 /* NetBIOS over IPX */
|
||||
#define EPM_PROTOCOL_DSP 0x16 /* AppleTalk Data Stream Protocol */
|
||||
#define EPM_PROTOCOL_DDP 0x17 /* AppleTalk Data Datagram Protocol */
|
||||
#define EPM_PROTOCOL_APPLETALK 0x18 /* AppleTalk */
|
||||
#define EPM_PROTOCOL_VINES_SPP 0x1a
|
||||
#define EPM_PROTOCOL_VINES_IPC 0x1b /* Inter Process Communication */
|
||||
#define EPM_PROTOCOL_STREETTALK 0x1c /* Vines Streettalk */
|
||||
#define EPM_PROTOCOL_HTTP 0x1f
|
||||
#define EPM_PROTOCOL_UNIX_DS 0x20 /* Unix domain socket */
|
||||
#define EPM_PROTOCOL_NULL 0x21
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
typedef unsigned char u_int8;
|
||||
typedef unsigned short u_int16;
|
||||
typedef unsigned int u_int32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
GUID uuid;
|
||||
u_int16 major_version;
|
||||
u_int16 count_rhs;
|
||||
u_int16 minor_version;
|
||||
} twr_uuid_floor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
u_int16 count_rhs;
|
||||
u_int16 port;
|
||||
} twr_tcp_floor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
u_int16 count_rhs;
|
||||
u_int32 ipv4addr;
|
||||
} twr_ipv4_floor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u_int16 count_lhs;
|
||||
u_int8 protid;
|
||||
u_int16 count_rhs;
|
||||
} twr_empty_floor_t;
|
||||
|
||||
#include <poppack.h>
|
|
@ -1,208 +0,0 @@
|
|||
/*
|
||||
* MIDL proxy/stub stuff
|
||||
*
|
||||
* Copyright 2002 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - figure out whether we *really* got this right
|
||||
* - check for errors and throw exceptions
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
/************************************************************************
|
||||
* NdrClientInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum )
|
||||
{
|
||||
TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n",
|
||||
pRpcMessage, pStubMsg, pStubDesc, ProcNum);
|
||||
|
||||
assert( pRpcMessage && pStubMsg && pStubDesc );
|
||||
|
||||
pRpcMessage->Handle = NULL;
|
||||
pRpcMessage->ProcNum = ProcNum;
|
||||
pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
|
||||
pRpcMessage->RpcFlags = 0;
|
||||
pRpcMessage->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
|
||||
|
||||
pStubMsg->RpcMsg = pRpcMessage;
|
||||
pStubMsg->BufferStart = NULL;
|
||||
pStubMsg->BufferEnd = NULL;
|
||||
pStubMsg->BufferLength = 0;
|
||||
pStubMsg->IsClient = TRUE;
|
||||
pStubMsg->ReuseBuffer = FALSE;
|
||||
pStubMsg->pAllocAllNodesContext = NULL;
|
||||
pStubMsg->pPointerQueueState = NULL;
|
||||
pStubMsg->IgnoreEmbeddedPointers = 0;
|
||||
pStubMsg->PointerBufferMark = NULL;
|
||||
pStubMsg->fBufferValid = 0;
|
||||
pStubMsg->uFlags = 0;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->StackTop = NULL;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->FullPtrRefId = 0;
|
||||
pStubMsg->PointerLength = 0;
|
||||
pStubMsg->fInDontFree = 0;
|
||||
pStubMsg->fDontCallFreeInst = 0;
|
||||
pStubMsg->fInOnlyParam = 0;
|
||||
pStubMsg->fHasReturn = 0;
|
||||
pStubMsg->fHasExtensions = 0;
|
||||
pStubMsg->fHasNewCorrDesc = 0;
|
||||
pStubMsg->fUnused = 0;
|
||||
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
|
||||
pStubMsg->pvDestContext = NULL;
|
||||
pStubMsg->pRpcChannelBuffer = NULL;
|
||||
pStubMsg->pArrayInfo = NULL;
|
||||
pStubMsg->dwStubPhase = 0;
|
||||
/* FIXME: LowStackMark */
|
||||
pStubMsg->pAsyncMsg = NULL;
|
||||
pStubMsg->pCorrInfo = NULL;
|
||||
pStubMsg->pCorrMemory = NULL;
|
||||
pStubMsg->pMemoryList = NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrServerInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc )
|
||||
{
|
||||
TRACE("(pRpcMsg == ^%p, pStubMsg == ^%p, pStubDesc == ^%p)\n", pRpcMsg, pStubMsg, pStubDesc);
|
||||
|
||||
assert( pRpcMsg && pStubMsg && pStubDesc );
|
||||
|
||||
/* not everyone allocates stack space for w2kReserved */
|
||||
memset(pStubMsg, 0, FIELD_OFFSET(MIDL_STUB_MESSAGE,pCSInfo));
|
||||
|
||||
pStubMsg->ReuseBuffer = TRUE;
|
||||
pStubMsg->IsClient = FALSE;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->RpcMsg = pRpcMsg;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart = pRpcMsg->Buffer;
|
||||
pStubMsg->BufferLength = pRpcMsg->BufferLength;
|
||||
pStubMsg->BufferEnd = pStubMsg->Buffer + pStubMsg->BufferLength;
|
||||
|
||||
/* FIXME: determine the proper return value */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrGetBuffer(PMIDL_STUB_MESSAGE stubmsg, ULONG buflen, RPC_BINDING_HANDLE handle)
|
||||
{
|
||||
TRACE("(stubmsg == ^%p, buflen == %u, handle == %p): wild guess.\n", stubmsg, buflen, handle);
|
||||
|
||||
assert( stubmsg && stubmsg->RpcMsg );
|
||||
|
||||
/* I guess this is our chance to put the binding handle into the RPC_MESSAGE */
|
||||
stubmsg->RpcMsg->Handle = handle;
|
||||
|
||||
stubmsg->RpcMsg->BufferLength = buflen;
|
||||
if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK)
|
||||
return NULL;
|
||||
|
||||
stubmsg->Buffer = stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
stubmsg->BufferEnd = stubmsg->Buffer + stubmsg->BufferLength;
|
||||
return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer);
|
||||
}
|
||||
/***********************************************************************
|
||||
* NdrFreeBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrFreeBuffer(PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
TRACE("(pStubMsg == ^%p): wild guess.\n", pStubMsg);
|
||||
I_RpcFreeBuffer(pStubMsg->RpcMsg);
|
||||
pStubMsg->BufferLength = 0;
|
||||
pStubMsg->Buffer = pStubMsg->BufferEnd = (unsigned char *)(pStubMsg->RpcMsg->Buffer = NULL);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrSendReceive [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrSendReceive( PMIDL_STUB_MESSAGE stubmsg, unsigned char *buffer )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);
|
||||
|
||||
/* FIXME: how to handle errors? (raise exception?) */
|
||||
if (!stubmsg) {
|
||||
ERR("NULL stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!stubmsg->RpcMsg) {
|
||||
ERR("RPC Message not present in stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stubmsg->RpcMsg->BufferLength = buffer - (unsigned char *)stubmsg->RpcMsg->Buffer;
|
||||
status = I_RpcSendReceive(stubmsg->RpcMsg);
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->BufferEnd = stubmsg->BufferStart + stubmsg->BufferLength;
|
||||
stubmsg->Buffer = stubmsg->BufferStart;
|
||||
|
||||
/* FIXME: is this the right return value? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrMapCommAndFaultStatus [RPCRT4.@]
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY NdrMapCommAndFaultStatus( PMIDL_STUB_MESSAGE pStubMsg,
|
||||
ULONG *pCommStatus,
|
||||
ULONG *pFaultStatus,
|
||||
RPC_STATUS Status )
|
||||
{
|
||||
FIXME("(%p, %p, %p, %ld): stub\n", pStubMsg, pCommStatus, pFaultStatus, Status);
|
||||
|
||||
*pCommStatus = 0;
|
||||
*pFaultStatus = 0;
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
371
reactos/dll/win32/rpcrt4/ndr_contexth.c
Normal file
371
reactos/dll/win32/rpcrt4/ndr_contexth.c
Normal file
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* Context Handle Functions
|
||||
*
|
||||
* Copyright 2006 Saveliy Tretiakov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "ndr_contexth.h"
|
||||
|
||||
static SContextHandle *CtxList = NULL;
|
||||
|
||||
static CRITICAL_SECTION CtxList_cs;
|
||||
static CRITICAL_SECTION_DEBUG CtxList_cs_debug =
|
||||
{
|
||||
0, 0, &CtxList_cs,
|
||||
{ &CtxList_cs_debug.ProcessLocksList, &CtxList_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": CtxList_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION CtxList_cs = { &CtxList_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
SContextHandle* RPCRT4_SrvAllocCtxHdl()
|
||||
{
|
||||
SContextHandle *Hdl, *Tmp;
|
||||
|
||||
if((Hdl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(SContextHandle)))==NULL) return NULL;
|
||||
|
||||
EnterCriticalSection(&CtxList_cs);
|
||||
|
||||
if(!CtxList) CtxList = Hdl;
|
||||
else
|
||||
{
|
||||
for(Tmp = CtxList; Tmp->Next; Tmp = Tmp->Next);
|
||||
Tmp->Next = Hdl;
|
||||
Hdl->Prev = Tmp;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&CtxList_cs);
|
||||
|
||||
return Hdl;
|
||||
}
|
||||
|
||||
void RPCRT4_SrvFreeCtxHdl(SContextHandle *Hdl)
|
||||
{
|
||||
EnterCriticalSection(&CtxList_cs);
|
||||
|
||||
if(Hdl->Prev && Hdl->Next)
|
||||
{
|
||||
((SContextHandle*)Hdl->Prev)->Next = Hdl->Next;
|
||||
((SContextHandle*)Hdl->Next)->Prev = Hdl->Prev;
|
||||
}
|
||||
else if(Hdl->Next)
|
||||
{
|
||||
((SContextHandle*)Hdl->Next)->Prev = NULL;
|
||||
CtxList = (SContextHandle*)Hdl->Next;
|
||||
}
|
||||
else if(Hdl->Prev)
|
||||
((SContextHandle*)Hdl->Prev)->Next = NULL;
|
||||
else CtxList = NULL;
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, Hdl);
|
||||
LeaveCriticalSection(&CtxList_cs);
|
||||
}
|
||||
|
||||
SContextHandle* RPCRT4_SrvFindCtxHdl(ContextHandleNdr *CtxNdr)
|
||||
{
|
||||
SContextHandle *Hdl, *Ret=NULL;
|
||||
RPC_STATUS status;
|
||||
EnterCriticalSection(&CtxList_cs);
|
||||
|
||||
for(Hdl = CtxList; Hdl; Hdl = Hdl->Next)
|
||||
if(UuidCompare(&Hdl->Ndr.uuid, &CtxNdr->uuid, &status)==0)
|
||||
{
|
||||
Ret = Hdl;
|
||||
break;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&CtxList_cs);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
SContextHandle* RPCRT4_SrvUnmarshallCtxHdl(ContextHandleNdr *Ndr)
|
||||
{
|
||||
SContextHandle *Hdl = NULL;
|
||||
RPC_STATUS status;
|
||||
|
||||
if(!Ndr)
|
||||
{
|
||||
if((Hdl = RPCRT4_SrvAllocCtxHdl())==NULL)
|
||||
RpcRaiseException(ERROR_OUTOFMEMORY);
|
||||
|
||||
UuidCreate(&Hdl->Ndr.uuid);
|
||||
}
|
||||
else if(!UuidIsNil(&Ndr->uuid, &status))
|
||||
Hdl = RPCRT4_SrvFindCtxHdl(Ndr);
|
||||
|
||||
return Hdl;
|
||||
}
|
||||
|
||||
void RPCRT4_SrvMarshallCtxHdl(SContextHandle *Hdl, ContextHandleNdr *Ndr)
|
||||
{
|
||||
if(!Hdl->Value)
|
||||
{
|
||||
RPCRT4_SrvFreeCtxHdl(Hdl);
|
||||
ZeroMemory(Ndr, sizeof(ContextHandleNdr));
|
||||
}
|
||||
else memcpy(Ndr, &Hdl->Ndr, sizeof(ContextHandleNdr));
|
||||
}
|
||||
|
||||
void RPCRT4_DoContextRundownIfNeeded(RpcConnection *Conn)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRCContextBinding
|
||||
*/
|
||||
RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
|
||||
{
|
||||
if(!CContext)
|
||||
RpcRaiseException(ERROR_INVALID_HANDLE);
|
||||
|
||||
return (RPC_BINDING_HANDLE)((CContextHandle*)CContext)->Binding;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRCContextMarshall
|
||||
*/
|
||||
void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff )
|
||||
{
|
||||
CContextHandle *ctx = (CContextHandle*)CContext;
|
||||
memcpy(pBuff, &ctx->Ndr, sizeof(ContextHandleNdr));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrClientContextMarshall
|
||||
*/
|
||||
void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
NDR_CCONTEXT ContextHandle,
|
||||
int fCheck)
|
||||
{
|
||||
if(!ContextHandle)
|
||||
RpcRaiseException(ERROR_INVALID_HANDLE);
|
||||
|
||||
NDRCContextMarshall(ContextHandle, pStubMsg->Buffer);
|
||||
|
||||
pStubMsg->Buffer += sizeof(ContextHandleNdr);
|
||||
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRCContextUnmarshall
|
||||
*/
|
||||
void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *pCContext,
|
||||
RPC_BINDING_HANDLE hBinding,
|
||||
void *pBuff,
|
||||
unsigned long DataRepresentation )
|
||||
{
|
||||
CContextHandle *ctx = (CContextHandle*)*pCContext;
|
||||
ContextHandleNdr *ndr = (ContextHandleNdr*)pBuff;
|
||||
RPC_STATUS status;
|
||||
|
||||
if(UuidIsNil(&ndr->uuid, &status))
|
||||
{
|
||||
if(ctx)
|
||||
{
|
||||
RPCRT4_DestroyBinding(ctx->Binding);
|
||||
HeapFree(GetProcessHeap(), 0, ctx);
|
||||
}
|
||||
*pCContext = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx = HeapAlloc(GetProcessHeap(), 0, sizeof(CContextHandle));
|
||||
if(!ctx) RpcRaiseException(ERROR_OUTOFMEMORY);
|
||||
|
||||
status = RpcBindingCopy(hBinding, (RPC_BINDING_HANDLE*) &ctx->Binding);
|
||||
if(status != RPC_S_OK) RpcRaiseException(status);
|
||||
|
||||
memcpy(&ctx->Ndr, ndr, sizeof(ContextHandleNdr));
|
||||
*pCContext = (NDR_CCONTEXT)ctx;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrClientContextUnmarshall
|
||||
*/
|
||||
void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
NDR_CCONTEXT * pContextHandle,
|
||||
RPC_BINDING_HANDLE BindHandle)
|
||||
{
|
||||
|
||||
if(!pContextHandle || !BindHandle)
|
||||
RpcRaiseException(ERROR_INVALID_HANDLE);
|
||||
|
||||
NDRCContextUnmarshall(pContextHandle,
|
||||
(CContextHandle*)BindHandle,
|
||||
pStubMsg->Buffer,
|
||||
pStubMsg->RpcMsg->DataRepresentation);
|
||||
|
||||
pStubMsg->Buffer += sizeof(ContextHandleNdr);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcSmDestroyClientContext
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcSmDestroyClientContext(void** ContextHandle)
|
||||
{
|
||||
CContextHandle *ctx = (CContextHandle*)ContextHandle;
|
||||
|
||||
if(!ctx)
|
||||
return RPC_X_SS_CONTEXT_MISMATCH;
|
||||
|
||||
RPCRT4_DestroyBinding(ctx->Binding);
|
||||
HeapFree(GetProcessHeap(), 0, ctx);
|
||||
*ContextHandle = NULL;
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcSsDestroyClientContext
|
||||
*/
|
||||
void WINAPI RpcSsDestroyClientContext(void** ContextHandle)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
status = RpcSmDestroyClientContext(ContextHandle);
|
||||
|
||||
if(status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrContextHandleSize
|
||||
*/
|
||||
void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char* pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrContextHandleInitialize
|
||||
*/
|
||||
NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrServerContextMarshall
|
||||
*/
|
||||
void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
NDR_SCONTEXT ContextHandle,
|
||||
NDR_RUNDOWN RundownRoutine)
|
||||
{
|
||||
SContextHandle *Hdl;
|
||||
RpcBinding *Binding;
|
||||
|
||||
if(!ContextHandle)
|
||||
RpcRaiseException(ERROR_INVALID_HANDLE);
|
||||
|
||||
Hdl = (SContextHandle*)ContextHandle;
|
||||
Binding = (RpcBinding*)pStubMsg->RpcMsg->Handle;
|
||||
Hdl->Rundown = RundownRoutine;
|
||||
Hdl->Conn = Binding->FromConn;
|
||||
RPCRT4_SrvMarshallCtxHdl(Hdl, (ContextHandleNdr*)pStubMsg->Buffer);
|
||||
pStubMsg->Buffer += sizeof(ContextHandleNdr);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrServerContextUnmarshall
|
||||
*/
|
||||
NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
SContextHandle *Hdl;
|
||||
|
||||
Hdl = RPCRT4_SrvUnmarshallCtxHdl((ContextHandleNdr*)pStubMsg->Buffer);
|
||||
return (NDR_SCONTEXT)Hdl;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrServerContextNewMarshall
|
||||
*/
|
||||
void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
NDR_SCONTEXT ContextHandle,
|
||||
NDR_RUNDOWN RundownRoutine,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrServerContextNewUnmarshall
|
||||
*/
|
||||
NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRSContextMarshall
|
||||
*/
|
||||
void WINAPI NDRSContextMarshall(IN NDR_SCONTEXT CContext,
|
||||
OUT void *pBuff,
|
||||
IN NDR_RUNDOWN userRunDownIn)
|
||||
{
|
||||
SContextHandle *Hdl;
|
||||
|
||||
if(!CContext)
|
||||
RpcRaiseException(ERROR_INVALID_HANDLE);
|
||||
|
||||
Hdl = (SContextHandle*)CContext;
|
||||
Hdl->Rundown = userRunDownIn;
|
||||
RPCRT4_SrvMarshallCtxHdl(Hdl, (ContextHandleNdr*)pBuff);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRSContextUnmarshall
|
||||
*/
|
||||
NDR_SCONTEXT WINAPI NDRSContextUnmarshall(IN void *pBuff,
|
||||
IN unsigned long DataRepresentation)
|
||||
{
|
||||
return (NDR_SCONTEXT) RPCRT4_SrvUnmarshallCtxHdl((ContextHandleNdr*)pBuff);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRSContextMarshallEx
|
||||
*/
|
||||
void WINAPI NDRSContextMarshallEx(IN RPC_BINDING_HANDLE BindingHandle,
|
||||
IN NDR_SCONTEXT CContext,
|
||||
OUT void *pBuff,
|
||||
IN NDR_RUNDOWN userRunDownIn)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRSContextUnmarshallEx
|
||||
*/
|
||||
NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(IN RPC_BINDING_HANDLE BindingHandle,
|
||||
IN void *pBuff,
|
||||
IN unsigned long DataRepresentation)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
return NULL;
|
||||
}
|
60
reactos/dll/win32/rpcrt4/ndr_contexth.h
Normal file
60
reactos/dll/win32/rpcrt4/ndr_contexth.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Context Handle Functions
|
||||
*
|
||||
* Copyright 2006 Saveliy Tretiakov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __WINE_NDR_CONTEXTH_H
|
||||
#define __WINE_NDR_CONTEXTH_H
|
||||
|
||||
#include "wine/rpcss_shared.h"
|
||||
|
||||
typedef struct _ContextHandleNdr
|
||||
{
|
||||
UINT attributes;
|
||||
UUID uuid;
|
||||
} ContextHandleNdr;
|
||||
|
||||
typedef struct _CContextHandle
|
||||
{
|
||||
RpcBinding *Binding;
|
||||
ContextHandleNdr Ndr;
|
||||
} CContextHandle;
|
||||
|
||||
/*
|
||||
Keep this structure compatible with public rpcndr.h
|
||||
declaration, otherwise NDRSContextValue macro won't work.
|
||||
typedef struct {
|
||||
void *pad[2];
|
||||
void *userContext;
|
||||
} *NDR_SCONTEXT;
|
||||
*/
|
||||
|
||||
typedef struct _SContextHandle
|
||||
{
|
||||
PVOID Prev;
|
||||
PVOID Next;
|
||||
PVOID Value;
|
||||
NDR_RUNDOWN Rundown;
|
||||
RpcConnection *Conn;
|
||||
ContextHandleNdr Ndr;
|
||||
} SContextHandle;
|
||||
|
||||
void RPCRT4_DoContextRundownIfNeeded(RpcConnection *Conn);
|
||||
|
||||
#endif //__WINE_NDR_CONTEXTH_H
|
|
@ -1,233 +0,0 @@
|
|||
/*
|
||||
* Full Pointer Translation Routines
|
||||
*
|
||||
* Copyright 2006 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
PFULL_PTR_XLAT_TABLES WINAPI NdrFullPointerXlatInit(ULONG NumberOfPointers,
|
||||
XLAT_SIDE XlatSide)
|
||||
{
|
||||
ULONG NumberOfBuckets;
|
||||
PFULL_PTR_XLAT_TABLES pXlatTables = HeapAlloc(GetProcessHeap(), 0, sizeof(*pXlatTables));
|
||||
|
||||
TRACE("(%d, %d)\n", NumberOfPointers, XlatSide);
|
||||
|
||||
if (!NumberOfPointers) NumberOfPointers = 512;
|
||||
NumberOfBuckets = ((NumberOfPointers + 3) & ~3) - 1;
|
||||
|
||||
pXlatTables->RefIdToPointer.XlatTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(void *) * NumberOfPointers);
|
||||
pXlatTables->RefIdToPointer.StateTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(unsigned char) * NumberOfPointers);
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = NumberOfPointers;
|
||||
|
||||
TRACE("NumberOfBuckets = %d\n", NumberOfBuckets);
|
||||
pXlatTables->PointerToRefId.XlatTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(PFULL_PTR_TO_REFID_ELEMENT) * NumberOfBuckets);
|
||||
pXlatTables->PointerToRefId.NumberOfBuckets = NumberOfBuckets;
|
||||
pXlatTables->PointerToRefId.HashMask = NumberOfBuckets - 1;
|
||||
|
||||
pXlatTables->NextRefId = 1;
|
||||
pXlatTables->XlatSide = XlatSide;
|
||||
|
||||
return pXlatTables;
|
||||
}
|
||||
|
||||
void WINAPI NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables)
|
||||
{
|
||||
TRACE("(%p)\n", pXlatTables);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable);
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.StateTable);
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->PointerToRefId.XlatTable);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables);
|
||||
}
|
||||
|
||||
static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId)
|
||||
{
|
||||
if (RefId >= pXlatTables->RefIdToPointer.NumberOfEntries)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = RefId * 2;
|
||||
pXlatTables->RefIdToPointer.XlatTable =
|
||||
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
pXlatTables->RefIdToPointer.XlatTable,
|
||||
sizeof(void *) * pXlatTables->RefIdToPointer.NumberOfEntries);
|
||||
pXlatTables->RefIdToPointer.StateTable =
|
||||
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
pXlatTables->RefIdToPointer.StateTable,
|
||||
sizeof(unsigned char) * pXlatTables->RefIdToPointer.NumberOfEntries);
|
||||
|
||||
if (!pXlatTables->RefIdToPointer.XlatTable || !pXlatTables->RefIdToPointer.StateTable)
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
void *pPointer, unsigned char QueryType,
|
||||
ULONG *pRefId )
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
|
||||
TRACE("(%p, %p, %d, %p)\n", pXlatTables, pPointer, QueryType, pRefId);
|
||||
|
||||
if (!pPointer)
|
||||
{
|
||||
*pRefId = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(pPointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
|
||||
|
||||
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
|
||||
if (pPointer == XlatTableEntry->Pointer)
|
||||
{
|
||||
*pRefId = XlatTableEntry->RefId;
|
||||
if (XlatTableEntry->State & QueryType)
|
||||
return 1;
|
||||
XlatTableEntry->State |= QueryType;
|
||||
return 0;
|
||||
}
|
||||
|
||||
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
|
||||
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
XlatTableEntry->Pointer = pPointer;
|
||||
XlatTableEntry->RefId = *pRefId = pXlatTables->NextRefId++;
|
||||
XlatTableEntry->State = QueryType;
|
||||
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
|
||||
|
||||
/* insert pointer into mapping table */
|
||||
expand_pointer_table_if_necessary(pXlatTables, XlatTableEntry->RefId);
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > XlatTableEntry->RefId)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
|
||||
pXlatTables->RefIdToPointer.StateTable[XlatTableEntry->RefId] = QueryType;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
ULONG RefId, unsigned char QueryType,
|
||||
void **ppPointer)
|
||||
{
|
||||
TRACE("(%p, 0x%x, %d, %p)\n", pXlatTables, RefId, QueryType, ppPointer);
|
||||
|
||||
expand_pointer_table_if_necessary(pXlatTables, RefId);
|
||||
|
||||
pXlatTables->NextRefId = max(RefId + 1, pXlatTables->NextRefId);
|
||||
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
{
|
||||
*ppPointer = pXlatTables->RefIdToPointer.XlatTable[RefId];
|
||||
if (QueryType)
|
||||
{
|
||||
if (pXlatTables->RefIdToPointer.StateTable[RefId] & QueryType)
|
||||
return 1;
|
||||
pXlatTables->RefIdToPointer.StateTable[RefId] |= QueryType;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
*ppPointer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WINAPI NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
ULONG RefId, void *pPointer)
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
|
||||
TRACE("(%p, 0x%x, %p)\n", pXlatTables, RefId, pPointer);
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(pPointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
|
||||
|
||||
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
|
||||
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
XlatTableEntry->Pointer = pPointer;
|
||||
XlatTableEntry->RefId = RefId;
|
||||
XlatTableEntry->State = 0;
|
||||
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
|
||||
|
||||
/* insert pointer into mapping table */
|
||||
expand_pointer_table_if_necessary(pXlatTables, RefId);
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables, void *Pointer)
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
ULONG RefId = 0;
|
||||
|
||||
TRACE("(%p, %p)\n", pXlatTables, Pointer);
|
||||
|
||||
if (!Pointer)
|
||||
return 1;
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(Pointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&Pointer)[i];
|
||||
|
||||
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
|
||||
if (Pointer == XlatTableEntry->Pointer)
|
||||
{
|
||||
if (XlatTableEntry->State & 0x20)
|
||||
return 0;
|
||||
XlatTableEntry->State |= 0x20;
|
||||
RefId = XlatTableEntry->RefId;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!XlatTableEntry)
|
||||
return 0;
|
||||
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.StateTable[RefId] |= 0x20;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load diff
327
reactos/dll/win32/rpcrt4/ndr_midl.c
Normal file
327
reactos/dll/win32/rpcrt4/ndr_midl.c
Normal file
|
@ -0,0 +1,327 @@
|
|||
/*
|
||||
* MIDL proxy/stub stuff
|
||||
*
|
||||
* Copyright 2002 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* TODO:
|
||||
* - figure out whether we *really* got this right
|
||||
* - check for errors and throw exceptions
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "cpsf.h"
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyInitialize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyInitialize(void *This,
|
||||
PRPC_MESSAGE pRpcMsg,
|
||||
PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDescriptor,
|
||||
unsigned int ProcNum)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
|
||||
NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor, ProcNum);
|
||||
if (This) StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer);
|
||||
if (pStubMsg->pRpcChannelBuffer) {
|
||||
hr = IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
|
||||
&pStubMsg->dwDestContext,
|
||||
&pStubMsg->pvDestContext);
|
||||
}
|
||||
TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyGetBuffer(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
HRESULT hr;
|
||||
const IID *riid = NULL;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
|
||||
pStubMsg->dwStubPhase = PROXY_GETBUFFER;
|
||||
hr = StdProxy_GetIID(This, &riid);
|
||||
hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg,
|
||||
riid);
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
pStubMsg->dwStubPhase = PROXY_MARSHAL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxySendReceive [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxySendReceive(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
ULONG Status = 0;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
|
||||
if (!pStubMsg->pRpcChannelBuffer)
|
||||
{
|
||||
WARN("Trying to use disconnected proxy %p\n", This);
|
||||
RpcRaiseException(RPC_E_DISCONNECTED);
|
||||
}
|
||||
|
||||
pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
|
||||
hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg,
|
||||
&Status);
|
||||
pStubMsg->dwStubPhase = PROXY_UNMARSHAL;
|
||||
pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
|
||||
/* raise exception if call failed */
|
||||
if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer);
|
||||
else if (FAILED(hr)) RpcRaiseException(hr);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyFreeBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrProxyFreeBuffer(void *This,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
hr = IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer,
|
||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrProxyErrorHandler [RPCRT4.@]
|
||||
*/
|
||||
HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode)
|
||||
{
|
||||
WARN("(0x%08lx): a proxy call failed\n", dwExceptionCode);
|
||||
|
||||
if (FAILED(dwExceptionCode))
|
||||
return dwExceptionCode;
|
||||
else
|
||||
return HRESULT_FROM_WIN32(dwExceptionCode);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrStubInitialize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg,
|
||||
PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDescriptor,
|
||||
LPRPCCHANNELBUFFER pRpcChannelBuffer)
|
||||
{
|
||||
TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer);
|
||||
NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor);
|
||||
pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrStubGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER This,
|
||||
LPRPCCHANNELBUFFER pRpcChannelBuffer,
|
||||
PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
TRACE("(%p,%p)\n", This, pStubMsg);
|
||||
pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
|
||||
pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength;
|
||||
I_RpcGetBuffer(pStubMsg->RpcMsg); /* ? */
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrClientInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum )
|
||||
{
|
||||
TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n",
|
||||
pRpcMessage, pStubMsg, pStubDesc, ProcNum);
|
||||
|
||||
assert( pRpcMessage && pStubMsg && pStubDesc );
|
||||
|
||||
memset(pRpcMessage, 0, sizeof(RPC_MESSAGE));
|
||||
pRpcMessage->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
|
||||
|
||||
/* not everyone allocates stack space for w2kReserved */
|
||||
memset(pStubMsg, 0, FIELD_OFFSET(MIDL_STUB_MESSAGE,pCSInfo));
|
||||
|
||||
pStubMsg->ReuseBuffer = FALSE;
|
||||
pStubMsg->IsClient = TRUE;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->RpcMsg = pRpcMessage;
|
||||
|
||||
pRpcMessage->ProcNum = ProcNum;
|
||||
pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrServerInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc )
|
||||
{
|
||||
TRACE("(pRpcMsg == ^%p, pStubMsg == ^%p, pStubDesc == ^%p)\n", pRpcMsg, pStubMsg, pStubDesc);
|
||||
|
||||
assert( pRpcMsg && pStubMsg && pStubDesc );
|
||||
|
||||
/* not everyone allocates stack space for w2kReserved */
|
||||
memset(pStubMsg, 0, FIELD_OFFSET(MIDL_STUB_MESSAGE,pCSInfo));
|
||||
|
||||
pStubMsg->ReuseBuffer = TRUE;
|
||||
pStubMsg->IsClient = FALSE;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->RpcMsg = pRpcMsg;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart = pRpcMsg->Buffer;
|
||||
pStubMsg->BufferLength = pRpcMsg->BufferLength;
|
||||
pStubMsg->BufferEnd = pStubMsg->Buffer + pStubMsg->BufferLength;
|
||||
|
||||
/* FIXME: determine the proper return value */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buflen, RPC_BINDING_HANDLE handle)
|
||||
{
|
||||
TRACE("(stubmsg == ^%p, buflen == %lu, handle == %p): wild guess.\n", stubmsg, buflen, handle);
|
||||
|
||||
assert( stubmsg && stubmsg->RpcMsg );
|
||||
|
||||
/* I guess this is our chance to put the binding handle into the RPC_MESSAGE */
|
||||
stubmsg->RpcMsg->Handle = handle;
|
||||
|
||||
stubmsg->RpcMsg->BufferLength = buflen;
|
||||
if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK)
|
||||
return NULL;
|
||||
|
||||
stubmsg->Buffer = stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
stubmsg->BufferEnd = stubmsg->Buffer + stubmsg->BufferLength;
|
||||
return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer);
|
||||
}
|
||||
/***********************************************************************
|
||||
* NdrFreeBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrFreeBuffer(MIDL_STUB_MESSAGE *pStubMsg)
|
||||
{
|
||||
TRACE("(pStubMsg == ^%p): wild guess.\n", pStubMsg);
|
||||
I_RpcFreeBuffer(pStubMsg->RpcMsg);
|
||||
pStubMsg->BufferLength = 0;
|
||||
pStubMsg->Buffer = pStubMsg->BufferEnd = (unsigned char *)(pStubMsg->RpcMsg->Buffer = NULL);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrSendReceive [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *stubmsg, unsigned char *buffer )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);
|
||||
|
||||
/* FIXME: how to handle errors? (raise exception?) */
|
||||
if (!stubmsg) {
|
||||
ERR("NULL stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!stubmsg->RpcMsg) {
|
||||
ERR("RPC Message not present in stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = I_RpcSendReceive(stubmsg->RpcMsg);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
WARN("I_RpcSendReceive did not return success.\n");
|
||||
/* FIXME: raise exception? */
|
||||
//RpcRaiseException(status);
|
||||
}
|
||||
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->BufferEnd = stubmsg->BufferStart + stubmsg->BufferLength;
|
||||
stubmsg->Buffer = stubmsg->BufferStart;
|
||||
|
||||
/* FIXME: is this the right return value? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrMapCommAndFaultStatus [RPCRT4.@]
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY NdrMapCommAndFaultStatus( PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned long *pCommStatus,
|
||||
unsigned long *pFaultStatus,
|
||||
RPC_STATUS Status )
|
||||
{
|
||||
FIXME("(%p, %p, %p, %ld): stub\n", pStubMsg, pCommStatus, pFaultStatus, Status);
|
||||
|
||||
*pCommStatus = 0;
|
||||
*pFaultStatus = 0;
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrStubForwardingFunction [RPCRT4.@]
|
||||
*/
|
||||
void __RPC_STUB NdrStubForwardingFunction( IRpcStubBuffer *This, IRpcChannelBuffer *pChannel,
|
||||
PRPC_MESSAGE pMsg, DWORD *pdwStubPhase )
|
||||
{
|
||||
FIXME("Not implemented\n");
|
||||
return;
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_NDR_MISC_H
|
||||
|
@ -30,36 +30,22 @@
|
|||
|
||||
struct IPSFactoryBuffer;
|
||||
|
||||
#define ComputeConformance(pStubMsg, pMemory, pFormat, def) ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount)
|
||||
#define ComputeVariance(pStubMsg, pMemory, pFormat, def) ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->ActualCount)
|
||||
PFORMAT_STRING ComputeConformanceOrVariance(
|
||||
MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount);
|
||||
|
||||
static inline PFORMAT_STRING ComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
return ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount);
|
||||
}
|
||||
|
||||
static inline PFORMAT_STRING ComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
PFORMAT_STRING ret;
|
||||
ULONG_PTR ActualCount = pStubMsg->ActualCount;
|
||||
|
||||
pStubMsg->Offset = 0;
|
||||
ret = ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &ActualCount);
|
||||
pStubMsg->ActualCount = (ULONG)ActualCount;
|
||||
return ret;
|
||||
}
|
||||
PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount);
|
||||
|
||||
typedef unsigned char* (WINAPI *NDR_MARSHALL) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
typedef unsigned char* (WINAPI *NDR_UNMARSHALL)(PMIDL_STUB_MESSAGE, unsigned char**,PFORMAT_STRING, unsigned char);
|
||||
typedef void (WINAPI *NDR_BUFFERSIZE)(PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
typedef ULONG (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
|
||||
typedef unsigned long (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
|
||||
typedef void (WINAPI *NDR_FREE) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
|
||||
extern const NDR_MARSHALL NdrMarshaller[];
|
||||
extern const NDR_UNMARSHALL NdrUnmarshaller[];
|
||||
extern const NDR_BUFFERSIZE NdrBufferSizer[];
|
||||
extern const NDR_MEMORYSIZE NdrMemorySizer[];
|
||||
extern const NDR_FREE NdrFreer[];
|
||||
extern NDR_MARSHALL NdrMarshaller[];
|
||||
extern NDR_UNMARSHALL NdrUnmarshaller[];
|
||||
extern NDR_BUFFERSIZE NdrBufferSizer[];
|
||||
extern NDR_MEMORYSIZE NdrMemorySizer[];
|
||||
extern NDR_FREE NdrFreer[];
|
||||
|
||||
#endif /* __WINE_NDR_MISC_H */
|
||||
|
|
|
@ -15,10 +15,12 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* TODO:
|
||||
* - fix the wire-protocol to match MS/RPC
|
||||
* - figure out whether we *really* got this right
|
||||
* - check for errors and throw exceptions
|
||||
* - what are the marshalling functions supposed to return?
|
||||
* - finish RpcStream_Vtbl
|
||||
*/
|
||||
|
||||
|
@ -39,9 +41,7 @@
|
|||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
#include "rpcproxy.h"
|
||||
#include "wine/rpcfc.h"
|
||||
#include "cpsf.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -112,7 +112,7 @@ static ULONG WINAPI RpcStream_Release(LPSTREAM iface)
|
|||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (!--(This->RefCount)) {
|
||||
TRACE("size=%d\n", *This->size);
|
||||
TRACE("size=%ld\n", *This->size);
|
||||
This->pMsg->Buffer = (unsigned char*)This->data + *This->size;
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return 0;
|
||||
|
@ -219,7 +219,7 @@ static LPSTREAM RpcStream_Create(PMIDL_STUB_MESSAGE pStubMsg, BOOL init)
|
|||
This->data = (char*)(This->size + 1);
|
||||
This->pos = 0;
|
||||
if (init) *This->size = 0;
|
||||
TRACE("init size=%d\n", *This->size);
|
||||
TRACE("init size=%ld\n", *This->size);
|
||||
return (LPSTREAM)This;
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
|||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
pStubMsg->MaxCount = 0;
|
||||
if (!LoadCOM()) return NULL;
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
stream = RpcStream_Create(pStubMsg, TRUE);
|
||||
if (stream) {
|
||||
if (pMemory)
|
||||
|
@ -288,14 +288,12 @@ unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
|
|||
*(LPVOID*)ppMemory = NULL;
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
stream = RpcStream_Create(pStubMsg, FALSE);
|
||||
if (!stream) RpcRaiseException(E_OUTOFMEMORY);
|
||||
if (*((RpcStreamImpl *)stream)->size != 0)
|
||||
if (stream) {
|
||||
hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory);
|
||||
else
|
||||
hr = S_OK;
|
||||
IStream_Release(stream);
|
||||
if (FAILED(hr))
|
||||
IStream_Release(stream);
|
||||
if (FAILED(hr))
|
||||
RpcRaiseException(hr);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -316,27 +314,18 @@ void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
|
|||
hr = COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory,
|
||||
pStubMsg->dwDestContext, pStubMsg->pvDestContext,
|
||||
MSHLFLAGS_NORMAL);
|
||||
TRACE("size=%d\n", size);
|
||||
TRACE("size=%ld\n", size);
|
||||
pStubMsg->BufferLength += sizeof(DWORD) + size;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerMemorySize [RPCRT4.@]
|
||||
*/
|
||||
ULONG WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
unsigned long WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG size;
|
||||
|
||||
TRACE("(%p,%p)\n", pStubMsg, pFormat);
|
||||
|
||||
size = *(ULONG *)pStubMsg->Buffer;
|
||||
pStubMsg->Buffer += 4;
|
||||
pStubMsg->MemorySize += 4;
|
||||
|
||||
pStubMsg->Buffer += size;
|
||||
|
||||
return pStubMsg->MemorySize;
|
||||
FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -368,27 +357,3 @@ void WINAPI NdrOleFree(void *NodeToFree)
|
|||
if (!LoadCOM()) return;
|
||||
COM_MemFree(NodeToFree);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Helper function to create a stub.
|
||||
* This probably looks very much like NdrpCreateStub.
|
||||
*/
|
||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub)
|
||||
{
|
||||
CLSID clsid;
|
||||
IPSFactoryBuffer *psfac;
|
||||
HRESULT r;
|
||||
|
||||
if(!LoadCOM()) return E_FAIL;
|
||||
|
||||
r = COM_GetPSClsid( iid, &clsid );
|
||||
if(FAILED(r)) return r;
|
||||
|
||||
r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac );
|
||||
if(FAILED(r)) return r;
|
||||
|
||||
r = IPSFactoryBuffer_CreateStub(psfac, iid, pUnk, ppstub);
|
||||
|
||||
IPSFactoryBuffer_Release(psfac);
|
||||
return r;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -15,92 +15,29 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_BINDING_H
|
||||
#define __WINE_RPC_BINDING_H
|
||||
|
||||
#include "wine/rpcss_shared.h"
|
||||
#include "security.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
|
||||
typedef struct _RpcAuthInfo
|
||||
{
|
||||
LONG refs;
|
||||
|
||||
ULONG AuthnLevel;
|
||||
ULONG AuthnSvc;
|
||||
CredHandle cred;
|
||||
TimeStamp exp;
|
||||
ULONG cbMaxToken;
|
||||
} RpcAuthInfo;
|
||||
|
||||
typedef struct _RpcQualityOfService
|
||||
{
|
||||
LONG refs;
|
||||
|
||||
RPC_SECURITY_QOS_V2_W *qos;
|
||||
} RpcQualityOfService;
|
||||
|
||||
typedef struct _RpcAssoc
|
||||
{
|
||||
struct list entry; /* entry in the global list of associations */
|
||||
LONG refs;
|
||||
|
||||
LPSTR Protseq;
|
||||
LPSTR NetworkAddr;
|
||||
LPSTR Endpoint;
|
||||
LPWSTR NetworkOptions;
|
||||
RpcAuthInfo *AuthInfo;
|
||||
|
||||
CRITICAL_SECTION cs;
|
||||
struct list connection_pool;
|
||||
} RpcAssoc;
|
||||
|
||||
struct connection_ops;
|
||||
|
||||
typedef struct _RpcConnection
|
||||
{
|
||||
struct _RpcConnection* Next;
|
||||
struct _RpcBinding* Used;
|
||||
BOOL server;
|
||||
LPSTR Protseq;
|
||||
LPSTR NetworkAddr;
|
||||
LPSTR Endpoint;
|
||||
LPWSTR NetworkOptions;
|
||||
const struct connection_ops *ops;
|
||||
HANDLE conn, thread;
|
||||
OVERLAPPED ovl[2];
|
||||
USHORT MaxTransmissionSize;
|
||||
/* The active interface bound to server. */
|
||||
RPC_SYNTAX_IDENTIFIER ActiveInterface;
|
||||
USHORT NextCallId;
|
||||
|
||||
/* authentication */
|
||||
CtxtHandle ctx;
|
||||
TimeStamp exp;
|
||||
ULONG attr;
|
||||
RpcAuthInfo *AuthInfo;
|
||||
ULONG encryption_auth_len;
|
||||
ULONG signature_auth_len;
|
||||
RpcQualityOfService *QOS;
|
||||
|
||||
/* client-only */
|
||||
struct list conn_pool_entry;
|
||||
} RpcConnection;
|
||||
|
||||
struct connection_ops {
|
||||
const char *name;
|
||||
unsigned char epm_protocols[2]; /* only floors 3 and 4. see http://www.opengroup.org/onlinepubs/9629399/apdxl.htm */
|
||||
RpcConnection *(*alloc)(void);
|
||||
RPC_STATUS (*open_connection_client)(RpcConnection *conn);
|
||||
RPC_STATUS (*handoff)(RpcConnection *old_conn, RpcConnection *new_conn);
|
||||
int (*read)(RpcConnection *conn, void *buffer, unsigned int len);
|
||||
int (*write)(RpcConnection *conn, const void *buffer, unsigned int len);
|
||||
int (*close)(RpcConnection *conn);
|
||||
size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint);
|
||||
RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint);
|
||||
};
|
||||
|
||||
/* don't know what MS's structure looks like */
|
||||
typedef struct _RpcBinding
|
||||
{
|
||||
|
@ -111,44 +48,32 @@ typedef struct _RpcBinding
|
|||
LPSTR Protseq;
|
||||
LPSTR NetworkAddr;
|
||||
LPSTR Endpoint;
|
||||
LPWSTR NetworkOptions;
|
||||
RPC_BLOCKING_FN BlockingFn;
|
||||
ULONG ServerTid;
|
||||
RpcConnection* FromConn;
|
||||
RpcAssoc *Assoc;
|
||||
|
||||
/* authentication */
|
||||
RpcAuthInfo *AuthInfo;
|
||||
RpcQualityOfService *QOS;
|
||||
} RpcBinding;
|
||||
|
||||
LPSTR RPCRT4_strndupA(LPCSTR src, INT len);
|
||||
LPWSTR RPCRT4_strndupW(LPCWSTR src, INT len);
|
||||
LPSTR RPCRT4_strdupWtoA(LPCWSTR src);
|
||||
LPWSTR RPCRT4_strdupAtoW(LPCSTR src);
|
||||
LPWSTR RPCRT4_strndupW(LPWSTR src, INT len);
|
||||
LPSTR RPCRT4_strdupWtoA(LPWSTR src);
|
||||
LPWSTR RPCRT4_strdupAtoW(LPSTR src);
|
||||
void RPCRT4_strfree(LPSTR src);
|
||||
|
||||
#define RPCRT4_strdupA(x) RPCRT4_strndupA((x),-1)
|
||||
#define RPCRT4_strdupW(x) RPCRT4_strndupW((x),-1)
|
||||
|
||||
ULONG RpcAuthInfo_AddRef(RpcAuthInfo *AuthInfo);
|
||||
ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo);
|
||||
ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos);
|
||||
ULONG RpcQualityOfService_Release(RpcQualityOfService *qos);
|
||||
|
||||
RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAssoc **assoc);
|
||||
RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RpcAuthInfo *AuthInfo, const RpcQualityOfService *QOS);
|
||||
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection);
|
||||
ULONG RpcAssoc_Release(RpcAssoc *assoc);
|
||||
|
||||
RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS, RpcBinding* Binding);
|
||||
RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPSTR Protseq, LPSTR NetworkAddr, LPSTR Endpoint, LPSTR NetworkOptions, RpcBinding* Binding);
|
||||
RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_OpenClientConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection);
|
||||
|
||||
RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint);
|
||||
RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid);
|
||||
RPC_STATUS RPCRT4_CreateBindingA(RpcBinding** Binding, BOOL server, LPSTR Protseq);
|
||||
RPC_STATUS RPCRT4_CreateBindingW(RpcBinding** Binding, BOOL server, LPWSTR Protseq);
|
||||
RPC_STATUS RPCRT4_CompleteBindingA(RpcBinding* Binding, LPSTR NetworkAddr, LPSTR Endpoint, LPSTR NetworkOptions);
|
||||
RPC_STATUS RPCRT4_CompleteBindingW(RpcBinding* Binding, LPWSTR NetworkAddr, LPWSTR Endpoint, LPWSTR NetworkOptions);
|
||||
RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPSTR Endpoint);
|
||||
RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, UUID* ObjectUuid);
|
||||
RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding);
|
||||
RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding);
|
||||
|
@ -158,35 +83,4 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC
|
|||
HANDLE RPCRT4_GetMasterMutex(void);
|
||||
HANDLE RPCRT4_RpcssNPConnect(void);
|
||||
|
||||
static inline const char *rpcrt4_conn_get_name(RpcConnection *Connection)
|
||||
{
|
||||
return Connection->ops->name;
|
||||
}
|
||||
|
||||
static inline int rpcrt4_conn_read(RpcConnection *Connection,
|
||||
void *buffer, unsigned int len)
|
||||
{
|
||||
return Connection->ops->read(Connection, buffer, len);
|
||||
}
|
||||
|
||||
static inline int rpcrt4_conn_write(RpcConnection *Connection,
|
||||
const void *buffer, unsigned int len)
|
||||
{
|
||||
return Connection->ops->write(Connection, buffer, len);
|
||||
}
|
||||
|
||||
static inline int rpcrt4_conn_close(RpcConnection *Connection)
|
||||
{
|
||||
return Connection->ops->close(Connection);
|
||||
}
|
||||
|
||||
static inline RPC_STATUS rpcrt4_conn_handoff(RpcConnection *old_conn, RpcConnection *new_conn)
|
||||
{
|
||||
return old_conn->ops->handoff(old_conn, new_conn);
|
||||
}
|
||||
|
||||
/* floors 3 and up */
|
||||
RPC_STATUS RpcTransport_GetTopOfTower(unsigned char *tower_data, size_t *tower_size, const char *protseq, const char *networkaddr, const char *endpoint);
|
||||
RPC_STATUS RpcTransport_ParseTopOfTower(const unsigned char *tower_data, size_t tower_size, char **protseq, char **networkaddr, char **endpoint);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_DEFS_H
|
||||
|
@ -58,10 +58,10 @@ typedef struct
|
|||
RpcPktCommonHdr common;
|
||||
unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */
|
||||
unsigned short context_id; /* Presentation context identifier */
|
||||
unsigned char cancel_count; /* Received cancel count */
|
||||
unsigned char reserved; /* Force alignment! */
|
||||
unsigned char alert_count; /* Pending alert count */
|
||||
unsigned char padding[3]; /* Force alignment! */
|
||||
unsigned long status; /* Runtime fault code (RPC_STATUS) */
|
||||
unsigned long reserved2;
|
||||
unsigned long reserved;
|
||||
} RpcPktFaultHdr;
|
||||
|
||||
typedef struct
|
||||
|
@ -88,8 +88,9 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char padding1[2]; /* Force alignment! */
|
||||
unsigned char num_results; /* Number of results */
|
||||
unsigned char reserved[3]; /* Force alignment! */
|
||||
unsigned char padding2[3]; /* Force alignment! */
|
||||
struct {
|
||||
unsigned short result;
|
||||
unsigned short reason;
|
||||
|
@ -105,7 +106,6 @@ typedef struct
|
|||
/*
|
||||
* Following this header are these fields:
|
||||
* RpcAddressString server_address;
|
||||
* [0 - 3 bytes of padding so that results is 4-byte aligned]
|
||||
* RpcResults results;
|
||||
* RPC_SYNTAX_IDENTIFIER transfer;
|
||||
*/
|
||||
|
@ -134,18 +134,6 @@ typedef union
|
|||
RpcPktBindNAckHdr bind_nack;
|
||||
} RpcPktHdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char auth_type; /* authentication scheme in use */
|
||||
unsigned char auth_level; /* RPC_C_AUTHN_LEVEL* */
|
||||
unsigned char auth_pad_length; /* length of padding to restore n % 4 alignment */
|
||||
unsigned char auth_reserved; /* reserved, must be zero */
|
||||
unsigned long auth_context_id; /* unique value for the authenticated connection */
|
||||
} RpcAuthVerifier;
|
||||
|
||||
#define RPC_AUTH_VERIFIER_LEN(common_hdr) \
|
||||
((common_hdr)->auth_len ? (common_hdr)->auth_len + sizeof(RpcAuthVerifier) : 0)
|
||||
|
||||
#define RPC_VER_MAJOR 5
|
||||
#define RPC_VER_MINOR 0
|
||||
|
||||
|
@ -172,7 +160,6 @@ typedef struct
|
|||
#define PKT_BIND_NACK 13
|
||||
#define PKT_ALTER_CONTEXT 14
|
||||
#define PKT_ALTER_CONTEXT_RESP 15
|
||||
#define PKT_AUTH3 16
|
||||
#define PKT_SHUTDOWN 17
|
||||
#define PKT_CO_CANCEL 18
|
||||
#define PKT_ORPHANED 19
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* TODO:
|
||||
* - actually do things right
|
||||
|
@ -36,7 +36,6 @@
|
|||
#include "wine/debug.h"
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "epm_towers.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
|
@ -68,7 +67,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|||
* RpcEpRegisterA (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
||||
UUID_VECTOR *UuidVector, RPC_CSTR Annotation )
|
||||
UUID_VECTOR *UuidVector, unsigned char *Annotation )
|
||||
{
|
||||
RPCSS_NP_MESSAGE msg;
|
||||
RPCSS_NP_REPLY reply;
|
||||
|
@ -246,140 +245,3 @@ RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE
|
|||
/* otherwise we fully bind the handle & return RPC_S_OK */
|
||||
return RPCRT4_ResolveBinding(Binding, reply.as_string);
|
||||
}
|
||||
|
||||
typedef unsigned int unsigned32;
|
||||
typedef struct twr_t
|
||||
{
|
||||
unsigned32 tower_length;
|
||||
/* [size_is] */ BYTE tower_octet_string[ 1 ];
|
||||
} twr_t;
|
||||
|
||||
/***********************************************************************
|
||||
* TowerExplode (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI TowerExplode(
|
||||
const twr_t *tower, PRPC_SYNTAX_IDENTIFIER object, PRPC_SYNTAX_IDENTIFIER syntax,
|
||||
char **protseq, char **endpoint, char **address)
|
||||
{
|
||||
size_t tower_size;
|
||||
RPC_STATUS status;
|
||||
const unsigned char *p;
|
||||
u_int16 floor_count;
|
||||
const twr_uuid_floor_t *object_floor;
|
||||
const twr_uuid_floor_t *syntax_floor;
|
||||
|
||||
if (protseq)
|
||||
*protseq = NULL;
|
||||
if (endpoint)
|
||||
*endpoint = NULL;
|
||||
if (address)
|
||||
*address = NULL;
|
||||
|
||||
tower_size = tower->tower_length;
|
||||
|
||||
if (tower_size < sizeof(u_int16))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
p = &tower->tower_octet_string[0];
|
||||
|
||||
floor_count = *(const u_int16 *)p;
|
||||
p += sizeof(u_int16);
|
||||
tower_size -= sizeof(u_int16);
|
||||
TRACE("floor_count: %d\n", floor_count);
|
||||
/* FIXME: should we do something with the floor count? at the moment we don't */
|
||||
|
||||
if (tower_size < sizeof(*object_floor) + sizeof(*syntax_floor))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
object_floor = (const twr_uuid_floor_t *)p;
|
||||
p += sizeof(*object_floor);
|
||||
tower_size -= sizeof(*object_floor);
|
||||
syntax_floor = (const twr_uuid_floor_t *)p;
|
||||
p += sizeof(*syntax_floor);
|
||||
tower_size -= sizeof(*syntax_floor);
|
||||
|
||||
if ((object_floor->count_lhs != sizeof(object_floor->protid) +
|
||||
sizeof(object_floor->uuid) + sizeof(object_floor->major_version)) ||
|
||||
(object_floor->protid != EPM_PROTOCOL_UUID) ||
|
||||
(object_floor->count_rhs != sizeof(object_floor->minor_version)))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
if ((syntax_floor->count_lhs != sizeof(syntax_floor->protid) +
|
||||
sizeof(syntax_floor->uuid) + sizeof(syntax_floor->major_version)) ||
|
||||
(syntax_floor->protid != EPM_PROTOCOL_UUID) ||
|
||||
(syntax_floor->count_rhs != sizeof(syntax_floor->minor_version)))
|
||||
return EPT_S_NOT_REGISTERED;
|
||||
|
||||
status = RpcTransport_ParseTopOfTower(p, tower_size, protseq, address, endpoint);
|
||||
if ((status == RPC_S_OK) && syntax && object)
|
||||
{
|
||||
syntax->SyntaxGUID = syntax_floor->uuid;
|
||||
syntax->SyntaxVersion.MajorVersion = syntax_floor->major_version;
|
||||
syntax->SyntaxVersion.MinorVersion = syntax_floor->minor_version;
|
||||
object->SyntaxGUID = object_floor->uuid;
|
||||
object->SyntaxVersion.MajorVersion = object_floor->major_version;
|
||||
object->SyntaxVersion.MinorVersion = object_floor->minor_version;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TowerConstruct (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI TowerConstruct(
|
||||
const RPC_SYNTAX_IDENTIFIER *object, const RPC_SYNTAX_IDENTIFIER *syntax,
|
||||
const char *protseq, const char *endpoint, const char *address,
|
||||
twr_t **tower)
|
||||
{
|
||||
size_t tower_size;
|
||||
RPC_STATUS status;
|
||||
unsigned char *p;
|
||||
twr_uuid_floor_t *object_floor;
|
||||
twr_uuid_floor_t *syntax_floor;
|
||||
|
||||
*tower = NULL;
|
||||
|
||||
status = RpcTransport_GetTopOfTower(NULL, &tower_size, protseq, address, endpoint);
|
||||
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
tower_size += sizeof(u_int16) + sizeof(*object_floor) + sizeof(*syntax_floor);
|
||||
*tower = I_RpcAllocate(FIELD_OFFSET(twr_t, tower_octet_string[tower_size]));
|
||||
if (!*tower)
|
||||
return RPC_S_OUT_OF_RESOURCES;
|
||||
|
||||
(*tower)->tower_length = tower_size;
|
||||
p = &(*tower)->tower_octet_string[0];
|
||||
*(u_int16 *)p = 5; /* number of floors */
|
||||
p += sizeof(u_int16);
|
||||
object_floor = (twr_uuid_floor_t *)p;
|
||||
p += sizeof(*object_floor);
|
||||
syntax_floor = (twr_uuid_floor_t *)p;
|
||||
p += sizeof(*syntax_floor);
|
||||
|
||||
object_floor->count_lhs = sizeof(object_floor->protid) + sizeof(object_floor->uuid) +
|
||||
sizeof(object_floor->major_version);
|
||||
object_floor->protid = EPM_PROTOCOL_UUID;
|
||||
object_floor->count_rhs = sizeof(object_floor->minor_version);
|
||||
object_floor->uuid = object->SyntaxGUID;
|
||||
object_floor->major_version = object->SyntaxVersion.MajorVersion;
|
||||
object_floor->minor_version = object->SyntaxVersion.MinorVersion;
|
||||
|
||||
syntax_floor->count_lhs = sizeof(syntax_floor->protid) + sizeof(syntax_floor->uuid) +
|
||||
sizeof(syntax_floor->major_version);
|
||||
syntax_floor->protid = EPM_PROTOCOL_UUID;
|
||||
syntax_floor->count_rhs = sizeof(syntax_floor->minor_version);
|
||||
syntax_floor->uuid = syntax->SyntaxGUID;
|
||||
syntax_floor->major_version = syntax->SyntaxVersion.MajorVersion;
|
||||
syntax_floor->minor_version = syntax->SyntaxVersion.MinorVersion;
|
||||
|
||||
status = RpcTransport_GetTopOfTower(p, &tower_size, protseq, address, endpoint);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
I_RpcFree(*tower);
|
||||
*tower = NULL;
|
||||
return status;
|
||||
}
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
*
|
||||
* Copyright 2001-2002 Ove Kåven, TransGaming Technologies
|
||||
* Copyright 2004 Filip Navara
|
||||
* Copyright 2006 CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -17,7 +16,11 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* TODO:
|
||||
* - figure out whether we *really* got this right
|
||||
* - check for errors and throw exceptions
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -42,24 +45,7 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
/* note: the DCE/RPC spec says the alignment amount should be 4, but
|
||||
* MS/RPC servers seem to always use 16 */
|
||||
#define AUTH_ALIGNMENT 16
|
||||
|
||||
/* gets the amount needed to round a value up to the specified alignment */
|
||||
#define ROUND_UP_AMOUNT(value, alignment) \
|
||||
(((alignment) - (((value) % (alignment)))) % (alignment))
|
||||
#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
|
||||
|
||||
enum secure_packet_direction
|
||||
{
|
||||
SECURE_PACKET_SEND,
|
||||
SECURE_PACKET_RECEIVE
|
||||
};
|
||||
|
||||
static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg);
|
||||
|
||||
static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
|
||||
static DWORD RPCRT4_GetHeaderSize(RpcPktHdr *Header)
|
||||
{
|
||||
static const DWORD header_sizes[] = {
|
||||
sizeof(Header->request), 0, sizeof(Header->response),
|
||||
|
@ -82,19 +68,6 @@ static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int packet_has_body(const RpcPktHdr *Header)
|
||||
{
|
||||
return (Header->common.ptype == PKT_FAULT) ||
|
||||
(Header->common.ptype == PKT_REQUEST) ||
|
||||
(Header->common.ptype == PKT_RESPONSE);
|
||||
}
|
||||
|
||||
static int packet_has_auth_verifier(const RpcPktHdr *Header)
|
||||
{
|
||||
return !(Header->common.ptype == PKT_BIND_NACK) &&
|
||||
!(Header->common.ptype == PKT_SHUTDOWN);
|
||||
}
|
||||
|
||||
static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType,
|
||||
unsigned long DataRepresentation)
|
||||
{
|
||||
|
@ -200,22 +173,6 @@ RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation,
|
|||
return header;
|
||||
}
|
||||
|
||||
static RpcPktHdr *RPCRT4_BuildAuthHeader(unsigned long DataRepresentation)
|
||||
{
|
||||
RpcPktHdr *header;
|
||||
|
||||
header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(header->common) + 12);
|
||||
if (header == NULL)
|
||||
return NULL;
|
||||
|
||||
RPCRT4_BuildCommonHeader(header, PKT_AUTH3, DataRepresentation);
|
||||
header->common.frag_len = 0x14;
|
||||
header->common.auth_len = 0;
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation,
|
||||
unsigned char RpcVersion,
|
||||
unsigned char RpcVersionMinor)
|
||||
|
@ -250,10 +207,9 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation,
|
|||
RpcResults *results;
|
||||
RPC_SYNTAX_IDENTIFIER *transfer_id;
|
||||
|
||||
header_size = sizeof(header->bind_ack) +
|
||||
ROUND_UP(FIELD_OFFSET(RpcAddressString, string[strlen(ServerAddress) + 1]), 4) +
|
||||
sizeof(RpcResults) +
|
||||
sizeof(RPC_SYNTAX_IDENTIFIER);
|
||||
header_size = sizeof(header->bind_ack) + sizeof(RpcResults) +
|
||||
sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(RpcAddressString) +
|
||||
strlen(ServerAddress);
|
||||
|
||||
header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, header_size);
|
||||
if (header == NULL) {
|
||||
|
@ -267,8 +223,7 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation,
|
|||
server_address = (RpcAddressString*)(&header->bind_ack + 1);
|
||||
server_address->length = strlen(ServerAddress) + 1;
|
||||
strcpy(server_address->string, ServerAddress);
|
||||
/* results is 4-byte aligned */
|
||||
results = (RpcResults*)((ULONG_PTR)server_address + ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4));
|
||||
results = (RpcResults*)((ULONG_PTR)server_address + sizeof(RpcAddressString) + server_address->length - 1);
|
||||
results->num_results = 1;
|
||||
results->results[0].result = Result;
|
||||
results->results[0].reason = Reason;
|
||||
|
@ -283,310 +238,6 @@ VOID RPCRT4_FreeHeader(RpcPktHdr *Header)
|
|||
HeapFree(GetProcessHeap(), 0, Header);
|
||||
}
|
||||
|
||||
static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection,
|
||||
enum secure_packet_direction dir,
|
||||
RpcPktHdr *hdr, unsigned int hdr_size,
|
||||
unsigned char *stub_data, unsigned int stub_data_size,
|
||||
RpcAuthVerifier *auth_hdr,
|
||||
unsigned char *auth_value, unsigned int auth_value_size)
|
||||
{
|
||||
SecBufferDesc message;
|
||||
SecBuffer buffers[4];
|
||||
SECURITY_STATUS sec_status;
|
||||
|
||||
message.ulVersion = SECBUFFER_VERSION;
|
||||
message.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
|
||||
message.pBuffers = buffers;
|
||||
|
||||
buffers[0].cbBuffer = hdr_size;
|
||||
buffers[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
|
||||
buffers[0].pvBuffer = hdr;
|
||||
buffers[1].cbBuffer = stub_data_size;
|
||||
buffers[1].BufferType = SECBUFFER_DATA;
|
||||
buffers[1].pvBuffer = stub_data;
|
||||
buffers[2].cbBuffer = sizeof(*auth_hdr);
|
||||
buffers[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
|
||||
buffers[2].pvBuffer = auth_hdr;
|
||||
buffers[3].cbBuffer = auth_value_size;
|
||||
buffers[3].BufferType = SECBUFFER_TOKEN;
|
||||
buffers[3].pvBuffer = auth_value;
|
||||
|
||||
if (dir == SECURE_PACKET_SEND)
|
||||
{
|
||||
if ((auth_hdr->auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(hdr))
|
||||
{
|
||||
sec_status = EncryptMessage(&Connection->ctx, 0, &message, 0 /* FIXME */);
|
||||
if (sec_status != SEC_E_OK)
|
||||
{
|
||||
ERR("EncryptMessage failed with 0x%08x\n", sec_status);
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
}
|
||||
}
|
||||
else if (auth_hdr->auth_level != RPC_C_AUTHN_LEVEL_NONE)
|
||||
{
|
||||
#ifdef FIX_LATER
|
||||
sec_status = MakeSignature(&Connection->ctx, 0, &message, 0 /* FIXME */);
|
||||
if (sec_status != SEC_E_OK)
|
||||
{
|
||||
ERR("MakeSignature failed with 0x%08x\n", sec_status);
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
}
|
||||
#else
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (dir == SECURE_PACKET_RECEIVE)
|
||||
{
|
||||
if ((auth_hdr->auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(hdr))
|
||||
{
|
||||
sec_status = DecryptMessage(&Connection->ctx, &message, 0 /* FIXME */, 0);
|
||||
if (sec_status != SEC_E_OK)
|
||||
{
|
||||
ERR("EncryptMessage failed with 0x%08x\n", sec_status);
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
}
|
||||
}
|
||||
else if (auth_hdr->auth_level != RPC_C_AUTHN_LEVEL_NONE)
|
||||
{
|
||||
#ifdef FIX_LATER
|
||||
sec_status = VerifySignature(&Connection->ctx, &message, 0 /* FIXME */, NULL);
|
||||
if (sec_status != SEC_E_OK)
|
||||
{
|
||||
ERR("VerifySignature failed with 0x%08x\n", sec_status);
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
}
|
||||
#else
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RPCRT4_SendAuth (internal)
|
||||
*
|
||||
* Transmit a packet with authorization data over connection in acceptable fragments.
|
||||
*/
|
||||
static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
|
||||
void *Buffer, unsigned int BufferLength,
|
||||
void *Auth, unsigned int AuthLength)
|
||||
{
|
||||
PUCHAR buffer_pos;
|
||||
DWORD hdr_size;
|
||||
LONG count;
|
||||
unsigned char *pkt;
|
||||
LONG alen;
|
||||
RPC_STATUS status;
|
||||
|
||||
buffer_pos = Buffer;
|
||||
/* The packet building functions save the packet header size, so we can use it. */
|
||||
hdr_size = Header->common.frag_len;
|
||||
if (AuthLength)
|
||||
Header->common.auth_len = AuthLength;
|
||||
else if (Connection->AuthInfo && packet_has_auth_verifier(Header))
|
||||
{
|
||||
if ((Connection->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(Header))
|
||||
Header->common.auth_len = Connection->encryption_auth_len;
|
||||
else
|
||||
Header->common.auth_len = Connection->signature_auth_len;
|
||||
}
|
||||
else
|
||||
Header->common.auth_len = 0;
|
||||
Header->common.flags |= RPC_FLG_FIRST;
|
||||
Header->common.flags &= ~RPC_FLG_LAST;
|
||||
|
||||
alen = RPC_AUTH_VERIFIER_LEN(&Header->common);
|
||||
|
||||
while (!(Header->common.flags & RPC_FLG_LAST)) {
|
||||
unsigned char auth_pad_len = Header->common.auth_len ? ROUND_UP_AMOUNT(BufferLength, AUTH_ALIGNMENT) : 0;
|
||||
unsigned int pkt_size = BufferLength + hdr_size + alen + auth_pad_len;
|
||||
|
||||
/* decide if we need to split the packet into fragments */
|
||||
if (pkt_size <= Connection->MaxTransmissionSize) {
|
||||
Header->common.flags |= RPC_FLG_LAST;
|
||||
Header->common.frag_len = pkt_size;
|
||||
} else {
|
||||
auth_pad_len = 0;
|
||||
/* make sure packet payload will be a multiple of 16 */
|
||||
Header->common.frag_len =
|
||||
((Connection->MaxTransmissionSize - hdr_size - alen) & ~(AUTH_ALIGNMENT-1)) +
|
||||
hdr_size + alen;
|
||||
}
|
||||
|
||||
pkt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Header->common.frag_len);
|
||||
|
||||
memcpy(pkt, Header, hdr_size);
|
||||
|
||||
/* fragment consisted of header only and is the last one */
|
||||
if (hdr_size == Header->common.frag_len)
|
||||
goto write;
|
||||
|
||||
memcpy(pkt + hdr_size, buffer_pos, Header->common.frag_len - hdr_size - auth_pad_len - alen);
|
||||
|
||||
/* add the authorization info */
|
||||
if (Connection->AuthInfo && packet_has_auth_verifier(Header))
|
||||
{
|
||||
RpcAuthVerifier *auth_hdr = (RpcAuthVerifier *)&pkt[Header->common.frag_len - alen];
|
||||
|
||||
auth_hdr->auth_type = Connection->AuthInfo->AuthnSvc;
|
||||
auth_hdr->auth_level = Connection->AuthInfo->AuthnLevel;
|
||||
auth_hdr->auth_pad_length = auth_pad_len;
|
||||
auth_hdr->auth_reserved = 0;
|
||||
/* a unique number... */
|
||||
auth_hdr->auth_context_id = (unsigned long)Connection;
|
||||
|
||||
if (AuthLength)
|
||||
memcpy(auth_hdr + 1, Auth, AuthLength);
|
||||
else
|
||||
{
|
||||
status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_SEND,
|
||||
(RpcPktHdr *)pkt, hdr_size,
|
||||
pkt + hdr_size, Header->common.frag_len - hdr_size - alen,
|
||||
auth_hdr,
|
||||
(unsigned char *)(auth_hdr + 1), Header->common.auth_len);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, pkt);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write:
|
||||
count = rpcrt4_conn_write(Connection, pkt, Header->common.frag_len);
|
||||
HeapFree(GetProcessHeap(), 0, pkt);
|
||||
if (count<0) {
|
||||
WARN("rpcrt4_conn_write failed (auth)\n");
|
||||
return RPC_S_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
buffer_pos += Header->common.frag_len - hdr_size - alen - auth_pad_len;
|
||||
BufferLength -= Header->common.frag_len - hdr_size - alen - auth_pad_len;
|
||||
Header->common.flags &= ~RPC_FLG_FIRST;
|
||||
}
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RPCRT4_ClientAuthorize (internal)
|
||||
*
|
||||
* Authorize a client connection. A NULL in param signifies a new connection.
|
||||
*/
|
||||
static RPC_STATUS RPCRT4_ClientAuthorize(RpcConnection *conn, SecBuffer *in,
|
||||
SecBuffer *out)
|
||||
{
|
||||
SECURITY_STATUS r;
|
||||
SecBufferDesc out_desc;
|
||||
SecBufferDesc inp_desc;
|
||||
SecPkgContext_Sizes secctx_sizes;
|
||||
BOOL continue_needed;
|
||||
ULONG context_req = ISC_REQ_CONNECTION | ISC_REQ_USE_DCE_STYLE |
|
||||
ISC_REQ_MUTUAL_AUTH | ISC_REQ_DELEGATE;
|
||||
|
||||
if (conn->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY)
|
||||
context_req |= ISC_REQ_INTEGRITY;
|
||||
else if (conn->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
|
||||
context_req |= ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY;
|
||||
|
||||
out->BufferType = SECBUFFER_TOKEN;
|
||||
out->cbBuffer = conn->AuthInfo->cbMaxToken;
|
||||
out->pvBuffer = HeapAlloc(GetProcessHeap(), 0, out->cbBuffer);
|
||||
if (!out->pvBuffer) return ERROR_OUTOFMEMORY;
|
||||
|
||||
out_desc.ulVersion = 0;
|
||||
out_desc.cBuffers = 1;
|
||||
out_desc.pBuffers = out;
|
||||
|
||||
inp_desc.cBuffers = 1;
|
||||
inp_desc.pBuffers = in;
|
||||
inp_desc.ulVersion = 0;
|
||||
|
||||
r = InitializeSecurityContextA(&conn->AuthInfo->cred, in ? &conn->ctx : NULL,
|
||||
NULL, context_req, 0, SECURITY_NETWORK_DREP,
|
||||
in ? &inp_desc : NULL, 0, &conn->ctx, &out_desc, &conn->attr,
|
||||
&conn->exp);
|
||||
if (FAILED(r))
|
||||
{
|
||||
WARN("InitializeSecurityContext failed with error 0x%08x\n", r);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
TRACE("r = 0x%08x, attr = 0x%08x\n", r, conn->attr);
|
||||
continue_needed = ((r == SEC_I_CONTINUE_NEEDED) ||
|
||||
(r == SEC_I_COMPLETE_AND_CONTINUE));
|
||||
|
||||
if ((r == SEC_I_COMPLETE_NEEDED) || (r == SEC_I_COMPLETE_AND_CONTINUE))
|
||||
{
|
||||
TRACE("complete needed\n");
|
||||
r = CompleteAuthToken(&conn->ctx, &out_desc);
|
||||
if (FAILED(r))
|
||||
{
|
||||
WARN("CompleteAuthToken failed with error 0x%08x\n", r);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("cbBuffer = %ld\n", out->cbBuffer);
|
||||
|
||||
if (!continue_needed)
|
||||
{
|
||||
#ifdef FIX_LATER
|
||||
r = QueryContextAttributesA(&conn->ctx, SECPKG_ATTR_SIZES, &secctx_sizes);
|
||||
if (FAILED(r))
|
||||
{
|
||||
WARN("QueryContextAttributes failed with error 0x%08x\n", r);
|
||||
goto failed;
|
||||
}
|
||||
conn->signature_auth_len = secctx_sizes.cbMaxSignature;
|
||||
conn->encryption_auth_len = secctx_sizes.cbSecurityTrailer;
|
||||
#else
|
||||
goto failed;
|
||||
#endif
|
||||
}
|
||||
|
||||
return RPC_S_OK;
|
||||
|
||||
failed:
|
||||
HeapFree(GetProcessHeap(), 0, out->pvBuffer);
|
||||
out->pvBuffer = NULL;
|
||||
return ERROR_ACCESS_DENIED; /* FIXME: is this correct? */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RPCRT4_AuthorizeBinding (internal)
|
||||
*/
|
||||
static RPC_STATUS RPCRT_AuthorizeConnection(RpcConnection* conn,
|
||||
BYTE *challenge, ULONG count)
|
||||
{
|
||||
SecBuffer inp, out;
|
||||
RpcPktHdr *resp_hdr;
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("challenge %s, %d bytes\n", challenge, count);
|
||||
|
||||
inp.BufferType = SECBUFFER_TOKEN;
|
||||
inp.pvBuffer = challenge;
|
||||
inp.cbBuffer = count;
|
||||
|
||||
status = RPCRT4_ClientAuthorize(conn, &inp, &out);
|
||||
if (status) return status;
|
||||
|
||||
resp_hdr = RPCRT4_BuildAuthHeader(NDR_LOCAL_DATA_REPRESENTATION);
|
||||
if (!resp_hdr)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
status = RPCRT4_SendAuth(conn, resp_hdr, NULL, 0, out.pvBuffer, out.cbBuffer);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, out.pvBuffer);
|
||||
RPCRT4_FreeHeader(resp_hdr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RPCRT4_Send (internal)
|
||||
*
|
||||
|
@ -595,20 +246,57 @@ static RPC_STATUS RPCRT_AuthorizeConnection(RpcConnection* conn,
|
|||
RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
|
||||
void *Buffer, unsigned int BufferLength)
|
||||
{
|
||||
RPC_STATUS r;
|
||||
SecBuffer out;
|
||||
PUCHAR buffer_pos;
|
||||
DWORD hdr_size, count;
|
||||
|
||||
if (!Connection->AuthInfo || SecIsValidHandle(&Connection->ctx))
|
||||
{
|
||||
return RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, NULL, 0);
|
||||
buffer_pos = Buffer;
|
||||
/* The packet building functions save the packet header size, so we can use it. */
|
||||
hdr_size = Header->common.frag_len;
|
||||
Header->common.flags |= RPC_FLG_FIRST;
|
||||
Header->common.flags &= ~RPC_FLG_LAST;
|
||||
while (!(Header->common.flags & RPC_FLG_LAST)) {
|
||||
/* decide if we need to split the packet into fragments */
|
||||
if ((BufferLength + hdr_size) <= Connection->MaxTransmissionSize) {
|
||||
Header->common.flags |= RPC_FLG_LAST;
|
||||
Header->common.frag_len = BufferLength + hdr_size;
|
||||
} else {
|
||||
Header->common.frag_len = Connection->MaxTransmissionSize;
|
||||
}
|
||||
|
||||
/* transmit packet header */
|
||||
if (!WriteFile(Connection->conn, Header, hdr_size, &count, &Connection->ovl[1]) &&
|
||||
ERROR_IO_PENDING != GetLastError()) {
|
||||
WARN("WriteFile failed with error %ld\n", GetLastError());
|
||||
return GetLastError();
|
||||
}
|
||||
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[1], &count, TRUE)) {
|
||||
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
/* fragment consisted of header only and is the last one */
|
||||
if (hdr_size == Header->common.frag_len &&
|
||||
Header->common.flags & RPC_FLG_LAST) {
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/* send the fragment data */
|
||||
if (!WriteFile(Connection->conn, buffer_pos, Header->common.frag_len - hdr_size, &count, &Connection->ovl[1]) &&
|
||||
ERROR_IO_PENDING != GetLastError()) {
|
||||
WARN("WriteFile failed with error %ld\n", GetLastError());
|
||||
return GetLastError();
|
||||
}
|
||||
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[1], &count, TRUE)) {
|
||||
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
buffer_pos += Header->common.frag_len - hdr_size;
|
||||
BufferLength -= Header->common.frag_len - hdr_size;
|
||||
Header->common.flags &= ~RPC_FLG_FIRST;
|
||||
}
|
||||
|
||||
/* tack on a negotiate packet */
|
||||
RPCRT4_ClientAuthorize(Connection, NULL, &out);
|
||||
r = RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, out.pvBuffer, out.cbBuffer);
|
||||
HeapFree(GetProcessHeap(), 0, out.pvBuffer);
|
||||
|
||||
return r;
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -620,13 +308,11 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
PRPC_MESSAGE pMsg)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
DWORD hdr_length;
|
||||
LONG dwRead;
|
||||
DWORD dwRead, hdr_length;
|
||||
unsigned short first_flag;
|
||||
unsigned long data_length;
|
||||
unsigned long buffer_length;
|
||||
unsigned long auth_length;
|
||||
unsigned char *auth_data = NULL;
|
||||
unsigned char *buffer_ptr;
|
||||
RpcPktCommonHdr common_hdr;
|
||||
|
||||
*Header = NULL;
|
||||
|
@ -634,9 +320,21 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
TRACE("(%p, %p, %p)\n", Connection, Header, pMsg);
|
||||
|
||||
/* read packet common header */
|
||||
dwRead = rpcrt4_conn_read(Connection, &common_hdr, sizeof(common_hdr));
|
||||
if (!ReadFile(Connection->conn, &common_hdr, sizeof(common_hdr), &dwRead, &Connection->ovl[0]) &&
|
||||
ERROR_IO_PENDING != GetLastError()) {
|
||||
WARN("ReadFile failed with error %ld\n", GetLastError());
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {
|
||||
if (GetLastError() != ERROR_MORE_DATA) {
|
||||
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (dwRead != sizeof(common_hdr)) {
|
||||
WARN("Short read of header, %d bytes\n", dwRead);
|
||||
WARN("Short read of header, %ld/%d bytes\n", dwRead, sizeof(common_hdr));
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -660,12 +358,26 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
memcpy(*Header, &common_hdr, sizeof(common_hdr));
|
||||
|
||||
/* read the rest of packet header */
|
||||
dwRead = rpcrt4_conn_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);
|
||||
if (!ReadFile(Connection->conn, &(*Header)->common + 1,
|
||||
hdr_length - sizeof(common_hdr), &dwRead, &Connection->ovl[0]) &&
|
||||
ERROR_IO_PENDING != GetLastError()) {
|
||||
WARN("ReadFile failed with error %ld\n", GetLastError());
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {
|
||||
if (GetLastError() != ERROR_MORE_DATA) {
|
||||
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (dwRead != hdr_length - sizeof(common_hdr)) {
|
||||
WARN("bad header length, %ld/%ld bytes\n", dwRead, hdr_length - sizeof(common_hdr));
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
/* read packet body */
|
||||
switch (common_hdr.ptype) {
|
||||
|
@ -676,7 +388,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
pMsg->BufferLength = (*Header)->request.alloc_hint;
|
||||
break;
|
||||
default:
|
||||
pMsg->BufferLength = common_hdr.frag_len - hdr_length - RPC_AUTH_VERIFIER_LEN(&common_hdr);
|
||||
pMsg->BufferLength = common_hdr.frag_len - hdr_length;
|
||||
}
|
||||
|
||||
TRACE("buffer length = %u\n", pMsg->BufferLength);
|
||||
|
@ -685,157 +397,89 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
if (status != RPC_S_OK) goto fail;
|
||||
|
||||
first_flag = RPC_FLG_FIRST;
|
||||
auth_length = common_hdr.auth_len;
|
||||
if (auth_length) {
|
||||
auth_data = HeapAlloc(GetProcessHeap(), 0, RPC_AUTH_VERIFIER_LEN(&common_hdr));
|
||||
if (!auth_data) {
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
buffer_length = 0;
|
||||
while (TRUE)
|
||||
buffer_ptr = pMsg->Buffer;
|
||||
while (buffer_length < pMsg->BufferLength)
|
||||
{
|
||||
unsigned int header_auth_len = RPC_AUTH_VERIFIER_LEN(&(*Header)->common);
|
||||
|
||||
/* verify header fields */
|
||||
|
||||
if (((*Header)->common.frag_len < hdr_length) ||
|
||||
((*Header)->common.frag_len - hdr_length < header_auth_len)) {
|
||||
WARN("frag_len %d too small for hdr_length %d and auth_len %d\n",
|
||||
(*Header)->common.frag_len, hdr_length, header_auth_len);
|
||||
data_length = (*Header)->common.frag_len - hdr_length;
|
||||
if (((*Header)->common.flags & RPC_FLG_FIRST) != first_flag ||
|
||||
data_length + buffer_length > pMsg->BufferLength) {
|
||||
TRACE("invalid packet flags or buffer length\n");
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((*Header)->common.auth_len != auth_length) {
|
||||
WARN("auth_len header field changed from %ld to %d\n",
|
||||
auth_length, (*Header)->common.auth_len);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
if (data_length == 0) dwRead = 0; else {
|
||||
if (!ReadFile(Connection->conn, buffer_ptr, data_length, &dwRead, &Connection->ovl[0]) &&
|
||||
ERROR_IO_PENDING != GetLastError()) {
|
||||
WARN("ReadFile failed with error %ld\n", GetLastError());
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {
|
||||
if (GetLastError() != ERROR_MORE_DATA) {
|
||||
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (((*Header)->common.flags & RPC_FLG_FIRST) != first_flag) {
|
||||
TRACE("invalid packet flags\n");
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
data_length = (*Header)->common.frag_len - hdr_length - header_auth_len;
|
||||
if (data_length + buffer_length > pMsg->BufferLength) {
|
||||
TRACE("allocation hint exceeded, new buffer length = %ld\n",
|
||||
data_length + buffer_length);
|
||||
pMsg->BufferLength = data_length + buffer_length;
|
||||
status = I_RpcReAllocateBuffer(pMsg);
|
||||
if (status != RPC_S_OK) goto fail;
|
||||
}
|
||||
|
||||
if (data_length == 0) dwRead = 0; else
|
||||
dwRead = rpcrt4_conn_read(Connection,
|
||||
(unsigned char *)pMsg->Buffer + buffer_length, data_length);
|
||||
if (dwRead != data_length) {
|
||||
WARN("bad data length, %d/%ld\n", dwRead, data_length);
|
||||
WARN("bad data length, %ld/%ld\n", dwRead, data_length);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (header_auth_len) {
|
||||
if (header_auth_len < sizeof(RpcAuthVerifier)) {
|
||||
WARN("bad auth verifier length %d\n", header_auth_len);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* FIXME: we should accumulate authentication data for the bind,
|
||||
* bind_ack, alter_context and alter_context_response if necessary.
|
||||
* however, the details of how this is done is very sketchy in the
|
||||
* DCE/RPC spec. for all other packet types that have authentication
|
||||
* verifier data then it is just duplicated in all the fragments */
|
||||
dwRead = rpcrt4_conn_read(Connection, auth_data, header_auth_len);
|
||||
if (dwRead != header_auth_len) {
|
||||
WARN("bad authentication data length, %d/%d\n", dwRead,
|
||||
header_auth_len);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* these packets are handled specially, not by the generic SecurePacket
|
||||
* function */
|
||||
if ((common_hdr.ptype != PKT_BIND) &&
|
||||
(common_hdr.ptype != PKT_BIND_ACK) &&
|
||||
(common_hdr.ptype != PKT_AUTH3))
|
||||
status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_RECEIVE,
|
||||
*Header, hdr_length,
|
||||
(unsigned char *)pMsg->Buffer + buffer_length, data_length,
|
||||
(RpcAuthVerifier *)auth_data,
|
||||
(unsigned char *)auth_data + sizeof(RpcAuthVerifier),
|
||||
header_auth_len - sizeof(RpcAuthVerifier));
|
||||
/* when there is no more data left, it should be the last packet */
|
||||
if (buffer_length == pMsg->BufferLength &&
|
||||
((*Header)->common.flags & RPC_FLG_LAST) == 0) {
|
||||
WARN("no more data left, but not last packet\n");
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
buffer_length += data_length;
|
||||
if (!((*Header)->common.flags & RPC_FLG_LAST)) {
|
||||
if (buffer_length < pMsg->BufferLength) {
|
||||
TRACE("next header\n");
|
||||
|
||||
/* read the header of next packet */
|
||||
dwRead = rpcrt4_conn_read(Connection, *Header, hdr_length);
|
||||
if (!ReadFile(Connection->conn, *Header, hdr_length, &dwRead, &Connection->ovl[0]) &&
|
||||
ERROR_IO_PENDING != GetLastError()) {
|
||||
WARN("ReadFile failed with error %ld\n", GetLastError());
|
||||
status = GetLastError();
|
||||
goto fail;
|
||||
}
|
||||
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {
|
||||
if (GetLastError() != ERROR_MORE_DATA) {
|
||||
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (dwRead != hdr_length) {
|
||||
WARN("invalid packet header size (%d)\n", dwRead);
|
||||
WARN("invalid packet header size (%ld)\n", dwRead);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
buffer_ptr += data_length;
|
||||
first_flag = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pMsg->BufferLength = buffer_length;
|
||||
|
||||
/* respond to authorization request */
|
||||
if (common_hdr.ptype == PKT_BIND_ACK && auth_length > sizeof(RpcAuthVerifier))
|
||||
{
|
||||
status = RPCRT_AuthorizeConnection(Connection,
|
||||
auth_data + sizeof(RpcAuthVerifier),
|
||||
auth_length);
|
||||
if (status)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* success */
|
||||
status = RPC_S_OK;
|
||||
|
||||
fail:
|
||||
if (status != RPC_S_OK) {
|
||||
if (status != RPC_S_OK && *Header) {
|
||||
RPCRT4_FreeHeader(*Header);
|
||||
*Header = NULL;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, auth_data);
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* I_RpcGetBuffer [RPCRT4.@]
|
||||
*
|
||||
* Allocates a buffer for use by I_RpcSend or I_RpcSendReceive and binds to the
|
||||
* server interface.
|
||||
*
|
||||
* PARAMS
|
||||
* pMsg [I/O] RPC message information.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: RPC_S_OK.
|
||||
* Failure: RPC_S_INVALID_BINDING if pMsg->Handle is invalid.
|
||||
* RPC_S_SERVER_UNAVAILABLE if unable to connect to server.
|
||||
* ERROR_OUTOFMEMORY if buffer allocation failed.
|
||||
*
|
||||
* NOTES
|
||||
* The pMsg->BufferLength field determines the size of the buffer to allocate,
|
||||
* in bytes.
|
||||
*
|
||||
* Use I_RpcFreeBuffer() to unbind from the server and free the message buffer.
|
||||
*
|
||||
* SEE ALSO
|
||||
* I_RpcFreeBuffer(), I_RpcSend(), I_RpcReceive(), I_RpcSendReceive().
|
||||
*/
|
||||
RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
|
||||
{
|
||||
|
@ -848,32 +492,8 @@ RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
|
|||
return pMsg->Buffer ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* I_RpcReAllocateBuffer (internal)
|
||||
*/
|
||||
static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg)
|
||||
{
|
||||
TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
|
||||
pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->BufferLength);
|
||||
|
||||
TRACE("Buffer=%p\n", pMsg->Buffer);
|
||||
return pMsg->Buffer ? RPC_S_OK : RPC_S_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* I_RpcFreeBuffer [RPCRT4.@]
|
||||
*
|
||||
* Frees a buffer allocated by I_RpcGetBuffer or I_RpcReceive and unbinds from
|
||||
* the server interface.
|
||||
*
|
||||
* PARAMS
|
||||
* pMsg [I/O] RPC message information.
|
||||
*
|
||||
* RETURNS
|
||||
* RPC_S_OK.
|
||||
*
|
||||
* SEE ALSO
|
||||
* I_RpcGetBuffer(), I_RpcReceive().
|
||||
*/
|
||||
RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
|
||||
{
|
||||
|
@ -886,20 +506,6 @@ RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
|
|||
|
||||
/***********************************************************************
|
||||
* I_RpcSend [RPCRT4.@]
|
||||
*
|
||||
* Sends a message to the server.
|
||||
*
|
||||
* PARAMS
|
||||
* pMsg [I/O] RPC message information.
|
||||
*
|
||||
* RETURNS
|
||||
* Unknown.
|
||||
*
|
||||
* NOTES
|
||||
* The buffer must have been allocated with I_RpcGetBuffer().
|
||||
*
|
||||
* SEE ALSO
|
||||
* I_RpcGetBuffer(), I_RpcReceive(), I_RpcSendReceive().
|
||||
*/
|
||||
RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
|
||||
{
|
||||
|
@ -921,14 +527,6 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
|
|||
} else {
|
||||
cif = pMsg->RpcInterfaceInformation;
|
||||
if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */
|
||||
|
||||
if (!bind->Endpoint || !bind->Endpoint[0])
|
||||
{
|
||||
TRACE("automatically resolving partially bound binding\n");
|
||||
status = RpcEpResolveBinding(bind, cif);
|
||||
if (status != RPC_S_OK) return status;
|
||||
}
|
||||
|
||||
status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax,
|
||||
&cif->InterfaceId);
|
||||
}
|
||||
|
@ -947,7 +545,6 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
|
|||
hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation,
|
||||
pMsg->BufferLength, pMsg->ProcNum,
|
||||
&bind->ObjectUuid);
|
||||
hdr->common.call_id = conn->NextCallId++;
|
||||
}
|
||||
|
||||
status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength);
|
||||
|
@ -958,9 +555,10 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
|
|||
if (!bind->server) {
|
||||
/* save the connection, so the response can be read from it */
|
||||
pMsg->ReservedForRuntime = conn;
|
||||
return status;
|
||||
return RPC_S_OK;
|
||||
}
|
||||
RPCRT4_CloseBinding(bind, conn);
|
||||
status = RPC_S_OK;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -992,14 +590,6 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
|
|||
} else {
|
||||
cif = pMsg->RpcInterfaceInformation;
|
||||
if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */
|
||||
|
||||
if (!bind->Endpoint || !bind->Endpoint[0])
|
||||
{
|
||||
TRACE("automatically resolving partially bound binding\n");
|
||||
status = RpcEpResolveBinding(bind, cif);
|
||||
if (status != RPC_S_OK) return status;
|
||||
}
|
||||
|
||||
status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax,
|
||||
&cif->InterfaceId);
|
||||
}
|
||||
|
@ -1023,8 +613,8 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
|
|||
break;
|
||||
case PKT_FAULT:
|
||||
pMsg->RpcFlags |= WINE_RPCFLAG_EXCEPTION;
|
||||
ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status);
|
||||
status = hdr->fault.status; /* FIXME: do translation from nca error codes */
|
||||
ERR ("we got fault packet with status %lx\n", hdr->fault.status);
|
||||
status = RPC_S_CALL_FAILED; /* ? */
|
||||
goto fail;
|
||||
default:
|
||||
WARN("bad packet type %d\n", hdr->common.ptype);
|
||||
|
@ -1035,42 +625,23 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
|
|||
status = RPC_S_OK;
|
||||
|
||||
fail:
|
||||
RPCRT4_FreeHeader(hdr);
|
||||
if (hdr) {
|
||||
RPCRT4_FreeHeader(hdr);
|
||||
}
|
||||
RPCRT4_CloseBinding(bind, conn);
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* I_RpcSendReceive [RPCRT4.@]
|
||||
*
|
||||
* Sends a message to the server and receives the response.
|
||||
*
|
||||
* PARAMS
|
||||
* pMsg [I/O] RPC message information.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: RPC_S_OK.
|
||||
* Failure: Any error code.
|
||||
*
|
||||
* NOTES
|
||||
* The buffer must have been allocated with I_RpcGetBuffer().
|
||||
*
|
||||
* SEE ALSO
|
||||
* I_RpcGetBuffer(), I_RpcSend(), I_RpcReceive().
|
||||
*/
|
||||
RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
RPC_MESSAGE original_message;
|
||||
|
||||
TRACE("(%p)\n", pMsg);
|
||||
|
||||
original_message = *pMsg;
|
||||
status = I_RpcSend(pMsg);
|
||||
if (status == RPC_S_OK)
|
||||
status = I_RpcReceive(pMsg);
|
||||
/* free the buffer replaced by a new buffer in I_RpcReceive */
|
||||
if (status == RPC_S_OK)
|
||||
I_RpcFreeBuffer(&original_message);
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_MESSAGE_H
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* TODO:
|
||||
* - a whole lot
|
||||
|
@ -47,10 +47,13 @@
|
|||
#include "rpc_message.h"
|
||||
#include "rpc_defs.h"
|
||||
|
||||
#define MAX_THREADS 128
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
typedef struct _RpcPacket
|
||||
{
|
||||
struct _RpcPacket* next;
|
||||
struct _RpcConnection* conn;
|
||||
RpcPktHdr* hdr;
|
||||
RPC_MESSAGE* msg;
|
||||
|
@ -66,9 +69,8 @@ typedef struct _RpcObjTypeMap
|
|||
|
||||
static RpcObjTypeMap *RpcObjTypeMaps;
|
||||
|
||||
/* list of type RpcServerProtseq */
|
||||
static struct list protseqs = LIST_INIT(protseqs);
|
||||
static struct list server_interfaces = LIST_INIT(server_interfaces);
|
||||
static RpcServerProtseq* protseqs;
|
||||
static RpcServerInterface* ifs;
|
||||
|
||||
static CRITICAL_SECTION server_cs;
|
||||
static CRITICAL_SECTION_DEBUG server_cs_debug =
|
||||
|
@ -94,10 +96,31 @@ static BOOL std_listen;
|
|||
static LONG manual_listen_count;
|
||||
/* total listeners including auto listeners */
|
||||
static LONG listen_count;
|
||||
/* set on change of configuration (e.g. listening on new protseq) */
|
||||
static HANDLE mgr_event;
|
||||
/* mutex for ensuring only one thread can change state at a time */
|
||||
static HANDLE mgr_mutex;
|
||||
/* set when server thread has finished opening connections */
|
||||
static HANDLE server_ready_event;
|
||||
|
||||
static CRITICAL_SECTION spacket_cs;
|
||||
static CRITICAL_SECTION_DEBUG spacket_cs_debug =
|
||||
{
|
||||
0, 0, &spacket_cs,
|
||||
{ &spacket_cs_debug.ProcessLocksList, &spacket_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": spacket_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION spacket_cs = { &spacket_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
static RpcPacket* spacket_head;
|
||||
static RpcPacket* spacket_tail;
|
||||
static HANDLE server_sem;
|
||||
|
||||
static LONG worker_count, worker_free, worker_tls;
|
||||
|
||||
static UUID uuid_nil;
|
||||
|
||||
static inline RpcObjTypeMap *LookupObjTypeMap(UUID *ObjUuid)
|
||||
inline static RpcObjTypeMap *LookupObjTypeMap(UUID *ObjUuid)
|
||||
{
|
||||
RpcObjTypeMap *rslt = RpcObjTypeMaps;
|
||||
RPC_STATUS dummy;
|
||||
|
@ -110,7 +133,7 @@ static inline RpcObjTypeMap *LookupObjTypeMap(UUID *ObjUuid)
|
|||
return rslt;
|
||||
}
|
||||
|
||||
static inline UUID *LookupObjType(UUID *ObjUuid)
|
||||
inline static UUID *LookupObjType(UUID *ObjUuid)
|
||||
{
|
||||
RpcObjTypeMap *map = LookupObjTypeMap(ObjUuid);
|
||||
if (map)
|
||||
|
@ -124,54 +147,93 @@ static RpcServerInterface* RPCRT4_find_interface(UUID* object,
|
|||
BOOL check_object)
|
||||
{
|
||||
UUID* MgrType = NULL;
|
||||
RpcServerInterface* cif;
|
||||
RpcServerInterface* cif = NULL;
|
||||
RPC_STATUS status;
|
||||
|
||||
if (check_object)
|
||||
MgrType = LookupObjType(object);
|
||||
EnterCriticalSection(&server_cs);
|
||||
LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) {
|
||||
cif = ifs;
|
||||
while (cif) {
|
||||
if (!memcmp(if_id, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)) &&
|
||||
(check_object == FALSE || UuidEqual(MgrType, &cif->MgrTypeUuid, &status)) &&
|
||||
std_listen) {
|
||||
InterlockedIncrement(&cif->CurrentCalls);
|
||||
break;
|
||||
}
|
||||
std_listen) break;
|
||||
cif = cif->Next;
|
||||
}
|
||||
LeaveCriticalSection(&server_cs);
|
||||
if (&cif->entry == &server_interfaces) cif = NULL;
|
||||
TRACE("returning %p for %s\n", cif, debugstr_guid(object));
|
||||
return cif;
|
||||
}
|
||||
|
||||
static void RPCRT4_release_server_interface(RpcServerInterface *sif)
|
||||
static void RPCRT4_push_packet(RpcPacket* packet)
|
||||
{
|
||||
if (!InterlockedDecrement(&sif->CurrentCalls) &&
|
||||
sif->CallsCompletedEvent) {
|
||||
/* sif must have been removed from server_interfaces before
|
||||
* CallsCompletedEvent is set */
|
||||
SetEvent(sif->CallsCompletedEvent);
|
||||
HeapFree(GetProcessHeap(), 0, sif);
|
||||
packet->next = NULL;
|
||||
EnterCriticalSection(&spacket_cs);
|
||||
if (spacket_tail) {
|
||||
spacket_tail->next = packet;
|
||||
spacket_tail = packet;
|
||||
} else {
|
||||
spacket_head = packet;
|
||||
spacket_tail = packet;
|
||||
}
|
||||
LeaveCriticalSection(&spacket_cs);
|
||||
}
|
||||
|
||||
static RpcPacket* RPCRT4_pop_packet(void)
|
||||
{
|
||||
RpcPacket* packet;
|
||||
EnterCriticalSection(&spacket_cs);
|
||||
packet = spacket_head;
|
||||
if (packet) {
|
||||
spacket_head = packet->next;
|
||||
if (!spacket_head) spacket_tail = NULL;
|
||||
}
|
||||
LeaveCriticalSection(&spacket_cs);
|
||||
if (packet) packet->next = NULL;
|
||||
return packet;
|
||||
}
|
||||
|
||||
#ifndef __REACTOS__
|
||||
typedef struct {
|
||||
PRPC_MESSAGE msg;
|
||||
void* buf;
|
||||
} packet_state;
|
||||
|
||||
static WINE_EXCEPTION_FILTER(rpc_filter)
|
||||
{
|
||||
WARN("exception caught with code 0x%08x = %d\n", GetExceptionCode(), GetExceptionCode());
|
||||
packet_state* state;
|
||||
PRPC_MESSAGE msg;
|
||||
state = TlsGetValue(worker_tls);
|
||||
msg = state->msg;
|
||||
if (msg->Buffer != state->buf) I_RpcFreeBuffer(msg);
|
||||
msg->RpcFlags |= WINE_RPCFLAG_EXCEPTION;
|
||||
msg->BufferLength = sizeof(DWORD);
|
||||
I_RpcGetBuffer(msg);
|
||||
*(DWORD*)msg->Buffer = GetExceptionCode();
|
||||
WARN("exception caught with code 0x%08lx = %ld\n", *(DWORD*)msg->Buffer, *(DWORD*)msg->Buffer);
|
||||
TRACE("returning failure packet\n");
|
||||
/* catch every exception */
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSAGE* msg)
|
||||
{
|
||||
RpcServerInterface* sif;
|
||||
RPC_DISPATCH_FUNCTION func;
|
||||
#ifndef __REACTOS__
|
||||
packet_state state;
|
||||
#endif
|
||||
UUID *object_uuid;
|
||||
RpcPktHdr *response;
|
||||
void *buf = msg->Buffer;
|
||||
RPC_STATUS status;
|
||||
|
||||
#ifndef __REACTOS__
|
||||
state.msg = msg;
|
||||
state.buf = buf;
|
||||
TlsSetValue(worker_tls, &state);
|
||||
#endif
|
||||
|
||||
switch (hdr->common.ptype) {
|
||||
case PKT_BIND:
|
||||
TRACE("got bind packet\n");
|
||||
|
@ -190,8 +252,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
|||
response = RPCRT4_BuildBindNackHeader(NDR_LOCAL_DATA_REPRESENTATION,
|
||||
RPC_VER_MAJOR, RPC_VER_MINOR);
|
||||
} else {
|
||||
TRACE("accepting bind request on connection %p for %s\n", conn,
|
||||
debugstr_guid(&hdr->bind.abstract.SyntaxGUID));
|
||||
TRACE("accepting bind request on connection %p\n", conn);
|
||||
|
||||
/* accept. */
|
||||
response = RPCRT4_BuildBindAckHeader(NDR_LOCAL_DATA_REPRESENTATION,
|
||||
|
@ -204,13 +265,9 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
|||
/* save the interface for later use */
|
||||
conn->ActiveInterface = hdr->bind.abstract;
|
||||
conn->MaxTransmissionSize = hdr->bind.max_tsize;
|
||||
|
||||
RPCRT4_release_server_interface(sif);
|
||||
}
|
||||
|
||||
status = RPCRT4_Send(conn, response, NULL, 0);
|
||||
RPCRT4_FreeHeader(response);
|
||||
if (status != RPC_S_OK)
|
||||
if (RPCRT4_Send(conn, response, NULL, 0) != RPC_S_OK)
|
||||
goto fail;
|
||||
|
||||
break;
|
||||
|
@ -224,7 +281,6 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
|||
status);
|
||||
|
||||
RPCRT4_Send(conn, response, NULL, 0);
|
||||
RPCRT4_FreeHeader(response);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -235,10 +291,6 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
|||
}
|
||||
|
||||
sif = RPCRT4_find_interface(object_uuid, &conn->ActiveInterface, TRUE);
|
||||
if (!sif) {
|
||||
/* FIXME: send fault packet? */
|
||||
break;
|
||||
}
|
||||
msg->RpcInterfaceInformation = sif->If;
|
||||
/* copy the endpoint vector from sif to msg so that midl-generated code will use it */
|
||||
msg->ManagerEpv = sif->MgrEpv;
|
||||
|
@ -267,27 +319,25 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
|||
MAKEWORD(hdr->common.drep[2], hdr->common.drep[3]));
|
||||
|
||||
/* dispatch */
|
||||
#ifndef __REACTOS__
|
||||
__TRY {
|
||||
if (func) func(msg);
|
||||
} __EXCEPT(rpc_filter) {
|
||||
if (msg->Buffer != buf) I_RpcFreeBuffer(msg);
|
||||
/* this will cause a failure packet to be sent in I_RpcSend */
|
||||
msg->RpcFlags |= WINE_RPCFLAG_EXCEPTION;
|
||||
msg->BufferLength = sizeof(DWORD);
|
||||
I_RpcGetBuffer(msg);
|
||||
*(DWORD*)msg->Buffer = GetExceptionCode();
|
||||
/* failure packet was created in rpc_filter */
|
||||
} __ENDTRY
|
||||
#else
|
||||
if (func) func(msg);
|
||||
#endif
|
||||
|
||||
/* send response packet */
|
||||
I_RpcSend(msg);
|
||||
|
||||
msg->RpcInterfaceInformation = NULL;
|
||||
RPCRT4_release_server_interface(sif);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("unhandled packet type %u\n", hdr->common.ptype);
|
||||
FIXME("unhandled packet type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -301,17 +351,59 @@ fail:
|
|||
I_RpcFreeBuffer(msg);
|
||||
msg->Buffer = NULL;
|
||||
RPCRT4_FreeHeader(hdr);
|
||||
HeapFree(GetProcessHeap(), 0, msg);
|
||||
#ifndef __REACTOS__
|
||||
TlsSetValue(worker_tls, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg)
|
||||
{
|
||||
RpcPacket *pkt = the_arg;
|
||||
RPCRT4_process_packet(pkt->conn, pkt->hdr, pkt->msg);
|
||||
HeapFree(GetProcessHeap(), 0, pkt);
|
||||
DWORD obj;
|
||||
RpcPacket* pkt;
|
||||
|
||||
for (;;) {
|
||||
/* idle timeout after 5s */
|
||||
obj = WaitForSingleObject(server_sem, 5000);
|
||||
if (obj == WAIT_TIMEOUT) {
|
||||
/* if another idle thread exist, self-destruct */
|
||||
if (worker_free > 1) break;
|
||||
continue;
|
||||
}
|
||||
pkt = RPCRT4_pop_packet();
|
||||
if (!pkt) continue;
|
||||
InterlockedDecrement(&worker_free);
|
||||
for (;;) {
|
||||
RPCRT4_process_packet(pkt->conn, pkt->hdr, pkt->msg);
|
||||
HeapFree(GetProcessHeap(), 0, pkt);
|
||||
/* try to grab another packet here without waiting
|
||||
* on the semaphore, in case it hits max */
|
||||
pkt = RPCRT4_pop_packet();
|
||||
if (!pkt) break;
|
||||
/* decrement semaphore */
|
||||
WaitForSingleObject(server_sem, 0);
|
||||
}
|
||||
InterlockedIncrement(&worker_free);
|
||||
}
|
||||
InterlockedDecrement(&worker_free);
|
||||
InterlockedDecrement(&worker_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void RPCRT4_create_worker_if_needed(void)
|
||||
{
|
||||
if (!worker_free && worker_count < MAX_THREADS) {
|
||||
HANDLE thread;
|
||||
InterlockedIncrement(&worker_count);
|
||||
InterlockedIncrement(&worker_free);
|
||||
thread = CreateThread(NULL, 0, RPCRT4_worker_thread, NULL, 0, NULL);
|
||||
if (thread) CloseHandle(thread);
|
||||
else {
|
||||
InterlockedDecrement(&worker_free);
|
||||
InterlockedDecrement(&worker_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
|
||||
{
|
||||
RpcConnection* conn = (RpcConnection*)the_arg;
|
||||
|
@ -334,7 +426,6 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
|
|||
status = RPCRT4_Receive(conn, &hdr, msg);
|
||||
if (status != RPC_S_OK) {
|
||||
WARN("receive failed with error %lx\n", status);
|
||||
HeapFree(GetProcessHeap(), 0, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -345,20 +436,23 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
|
|||
packet->conn = conn;
|
||||
packet->hdr = hdr;
|
||||
packet->msg = msg;
|
||||
QueueUserWorkItem(RPCRT4_worker_thread, packet, WT_EXECUTELONGFUNCTION);
|
||||
RPCRT4_create_worker_if_needed();
|
||||
RPCRT4_push_packet(packet);
|
||||
ReleaseSemaphore(server_sem, 1, NULL);
|
||||
#endif
|
||||
msg = NULL;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, msg);
|
||||
RPCRT4_DestroyConnection(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RPCRT4_new_client(RpcConnection* conn)
|
||||
static void RPCRT4_new_client(RpcConnection* conn)
|
||||
{
|
||||
HANDLE thread = CreateThread(NULL, 0, RPCRT4_io_thread, conn, 0, NULL);
|
||||
if (!thread) {
|
||||
DWORD err = GetLastError();
|
||||
ERR("failed to create thread, error=%08x\n", err);
|
||||
ERR("failed to create thread, error=%08lx\n", err);
|
||||
RPCRT4_DestroyConnection(conn);
|
||||
}
|
||||
/* we could set conn->thread, but then we'd have to make the io_thread wait
|
||||
|
@ -371,96 +465,128 @@ void RPCRT4_new_client(RpcConnection* conn)
|
|||
|
||||
static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
|
||||
{
|
||||
int res;
|
||||
unsigned int count;
|
||||
void *objs = NULL;
|
||||
RpcServerProtseq* cps = the_arg;
|
||||
HANDLE m_event = mgr_event, b_handle;
|
||||
HANDLE *objs = NULL;
|
||||
DWORD count, res;
|
||||
RpcServerProtseq* cps;
|
||||
RpcConnection* conn;
|
||||
RpcConnection* cconn;
|
||||
BOOL set_ready_event = FALSE;
|
||||
|
||||
TRACE("(the_arg == ^%p)\n", the_arg);
|
||||
|
||||
for (;;) {
|
||||
objs = cps->ops->get_wait_array(cps, objs, &count);
|
||||
EnterCriticalSection(&server_cs);
|
||||
/* open and count connections */
|
||||
count = 1;
|
||||
cps = protseqs;
|
||||
while (cps) {
|
||||
conn = cps->conn;
|
||||
while (conn) {
|
||||
RPCRT4_OpenConnection(conn);
|
||||
if (conn->ovl[0].hEvent) count++;
|
||||
conn = conn->Next;
|
||||
}
|
||||
cps = cps->Next;
|
||||
}
|
||||
/* make array of connections */
|
||||
if (objs)
|
||||
objs = HeapReAlloc(GetProcessHeap(), 0, objs, count*sizeof(HANDLE));
|
||||
else
|
||||
objs = HeapAlloc(GetProcessHeap(), 0, count*sizeof(HANDLE));
|
||||
|
||||
objs[0] = m_event;
|
||||
count = 1;
|
||||
cps = protseqs;
|
||||
while (cps) {
|
||||
conn = cps->conn;
|
||||
while (conn) {
|
||||
if (conn->ovl[0].hEvent) objs[count++] = conn->ovl[0].hEvent;
|
||||
conn = conn->Next;
|
||||
}
|
||||
cps = cps->Next;
|
||||
}
|
||||
LeaveCriticalSection(&server_cs);
|
||||
|
||||
if (set_ready_event)
|
||||
{
|
||||
/* signal to function that changed state that we are now sync'ed */
|
||||
SetEvent(cps->server_ready_event);
|
||||
SetEvent(server_ready_event);
|
||||
set_ready_event = FALSE;
|
||||
}
|
||||
|
||||
/* start waiting */
|
||||
res = cps->ops->wait_for_new_connection(cps, count, objs);
|
||||
if (res == -1)
|
||||
break;
|
||||
else if (res == 0)
|
||||
{
|
||||
res = WaitForMultipleObjects(count, objs, FALSE, INFINITE);
|
||||
if (res == WAIT_OBJECT_0) {
|
||||
if (!std_listen)
|
||||
{
|
||||
SetEvent(cps->server_ready_event);
|
||||
SetEvent(server_ready_event);
|
||||
break;
|
||||
}
|
||||
set_ready_event = TRUE;
|
||||
}
|
||||
else if (res == WAIT_FAILED) {
|
||||
ERR("wait failed\n");
|
||||
}
|
||||
else {
|
||||
b_handle = objs[res - WAIT_OBJECT_0];
|
||||
/* find which connection got a RPC */
|
||||
EnterCriticalSection(&server_cs);
|
||||
conn = NULL;
|
||||
cps = protseqs;
|
||||
while (cps) {
|
||||
conn = cps->conn;
|
||||
while (conn) {
|
||||
if (conn->ovl[0].hEvent == b_handle) break;
|
||||
conn = conn->Next;
|
||||
}
|
||||
if (conn) break;
|
||||
cps = cps->Next;
|
||||
}
|
||||
cconn = NULL;
|
||||
if (conn) RPCRT4_SpawnConnection(&cconn, conn);
|
||||
LeaveCriticalSection(&server_cs);
|
||||
if (!conn) {
|
||||
ERR("failed to locate connection for handle %p\n", b_handle);
|
||||
}
|
||||
if (cconn) RPCRT4_new_client(cconn);
|
||||
}
|
||||
}
|
||||
cps->ops->free_wait_array(cps, objs);
|
||||
EnterCriticalSection(&cps->cs);
|
||||
HeapFree(GetProcessHeap(), 0, objs);
|
||||
EnterCriticalSection(&server_cs);
|
||||
/* close connections */
|
||||
conn = cps->conn;
|
||||
while (conn) {
|
||||
RPCRT4_CloseConnection(conn);
|
||||
conn = conn->Next;
|
||||
cps = protseqs;
|
||||
while (cps) {
|
||||
conn = cps->conn;
|
||||
while (conn) {
|
||||
RPCRT4_CloseConnection(conn);
|
||||
conn = conn->Next;
|
||||
}
|
||||
cps = cps->Next;
|
||||
}
|
||||
LeaveCriticalSection(&cps->cs);
|
||||
LeaveCriticalSection(&server_cs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* tells the server thread that the state has changed and waits for it to
|
||||
* make the changes */
|
||||
static void RPCRT4_sync_with_server_thread(RpcServerProtseq *ps)
|
||||
static void RPCRT4_sync_with_server_thread(void)
|
||||
{
|
||||
/* make sure we are the only thread sync'ing the server state, otherwise
|
||||
* there is a race with the server thread setting an older state and setting
|
||||
* the server_ready_event when the new state hasn't yet been applied */
|
||||
WaitForSingleObject(ps->mgr_mutex, INFINITE);
|
||||
|
||||
ps->ops->signal_state_changed(ps);
|
||||
WaitForSingleObject(mgr_mutex, INFINITE);
|
||||
|
||||
SetEvent(mgr_event);
|
||||
/* wait for server thread to make the requested changes before returning */
|
||||
WaitForSingleObject(ps->server_ready_event, INFINITE);
|
||||
WaitForSingleObject(server_ready_event, INFINITE);
|
||||
|
||||
ReleaseMutex(ps->mgr_mutex);
|
||||
}
|
||||
|
||||
static RPC_STATUS RPCRT4_start_listen_protseq(RpcServerProtseq *ps, BOOL auto_listen)
|
||||
{
|
||||
RPC_STATUS status = RPC_S_OK;
|
||||
HANDLE server_thread;
|
||||
|
||||
EnterCriticalSection(&listen_cs);
|
||||
if (ps->is_listening) goto done;
|
||||
|
||||
if (!ps->mgr_mutex) ps->mgr_mutex = CreateMutexW(NULL, FALSE, NULL);
|
||||
if (!ps->server_ready_event) ps->server_ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, ps, 0, NULL);
|
||||
if (!server_thread)
|
||||
{
|
||||
status = RPC_S_OUT_OF_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
ps->is_listening = TRUE;
|
||||
CloseHandle(server_thread);
|
||||
|
||||
done:
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
return status;
|
||||
ReleaseMutex(mgr_mutex);
|
||||
}
|
||||
|
||||
static RPC_STATUS RPCRT4_start_listen(BOOL auto_listen)
|
||||
{
|
||||
RPC_STATUS status = RPC_S_ALREADY_LISTENING;
|
||||
RpcServerProtseq *cps;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
|
@ -468,27 +594,21 @@ static RPC_STATUS RPCRT4_start_listen(BOOL auto_listen)
|
|||
if (auto_listen || (manual_listen_count++ == 0))
|
||||
{
|
||||
status = RPC_S_OK;
|
||||
if (++listen_count == 1)
|
||||
if (++listen_count == 1) {
|
||||
HANDLE server_thread;
|
||||
/* first listener creates server thread */
|
||||
if (!mgr_mutex) mgr_mutex = CreateMutexW(NULL, FALSE, NULL);
|
||||
if (!mgr_event) mgr_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!server_ready_event) server_ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!server_sem) server_sem = CreateSemaphoreW(NULL, 0, MAX_THREADS, NULL);
|
||||
if (!worker_tls) worker_tls = TlsAlloc();
|
||||
std_listen = TRUE;
|
||||
server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, NULL, 0, NULL);
|
||||
CloseHandle(server_thread);
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
|
||||
if (std_listen)
|
||||
{
|
||||
EnterCriticalSection(&server_cs);
|
||||
LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
|
||||
{
|
||||
status = RPCRT4_start_listen_protseq(cps, TRUE);
|
||||
if (status != RPC_S_OK)
|
||||
break;
|
||||
|
||||
/* make sure server is actually listening on the interface before
|
||||
* returning */
|
||||
RPCRT4_sync_with_server_thread(cps);
|
||||
}
|
||||
LeaveCriticalSection(&server_cs);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -498,14 +618,9 @@ static void RPCRT4_stop_listen(BOOL auto_listen)
|
|||
if (auto_listen || (--manual_listen_count == 0))
|
||||
{
|
||||
if (listen_count != 0 && --listen_count == 0) {
|
||||
RpcServerProtseq *cps;
|
||||
|
||||
std_listen = FALSE;
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
|
||||
RPCRT4_sync_with_server_thread(cps);
|
||||
|
||||
RPCRT4_sync_with_server_thread();
|
||||
return;
|
||||
}
|
||||
assert(listen_count >= 0);
|
||||
|
@ -513,22 +628,18 @@ static void RPCRT4_stop_listen(BOOL auto_listen)
|
|||
LeaveCriticalSection(&listen_cs);
|
||||
}
|
||||
|
||||
static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, LPSTR endpoint)
|
||||
static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
RPCRT4_CreateConnection(&ps->conn, TRUE, ps->Protseq, NULL, ps->Endpoint, NULL, NULL);
|
||||
|
||||
status = ps->ops->open_endpoint(ps, endpoint);
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
EnterCriticalSection(&server_cs);
|
||||
ps->Next = protseqs;
|
||||
protseqs = ps;
|
||||
LeaveCriticalSection(&server_cs);
|
||||
|
||||
if (std_listen)
|
||||
{
|
||||
status = RPCRT4_start_listen_protseq(ps, FALSE);
|
||||
if (status == RPC_S_OK)
|
||||
RPCRT4_sync_with_server_thread(ps);
|
||||
}
|
||||
if (std_listen) RPCRT4_sync_with_server_thread();
|
||||
|
||||
return status;
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -549,14 +660,14 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
|
|||
EnterCriticalSection(&server_cs);
|
||||
/* count connections */
|
||||
count = 0;
|
||||
LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
|
||||
EnterCriticalSection(&ps->cs);
|
||||
ps = protseqs;
|
||||
while (ps) {
|
||||
conn = ps->conn;
|
||||
while (conn) {
|
||||
count++;
|
||||
conn = conn->Next;
|
||||
}
|
||||
LeaveCriticalSection(&ps->cs);
|
||||
ps = ps->Next;
|
||||
}
|
||||
if (count) {
|
||||
/* export bindings */
|
||||
|
@ -565,8 +676,8 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
|
|||
sizeof(RPC_BINDING_HANDLE)*(count-1));
|
||||
(*BindingVector)->Count = count;
|
||||
count = 0;
|
||||
LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
|
||||
EnterCriticalSection(&ps->cs);
|
||||
ps = protseqs;
|
||||
while (ps) {
|
||||
conn = ps->conn;
|
||||
while (conn) {
|
||||
RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count],
|
||||
|
@ -574,7 +685,7 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
|
|||
count++;
|
||||
conn = conn->Next;
|
||||
}
|
||||
LeaveCriticalSection(&ps->cs);
|
||||
ps = ps->Next;
|
||||
}
|
||||
status = RPC_S_OK;
|
||||
} else {
|
||||
|
@ -588,7 +699,7 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
|
|||
/***********************************************************************
|
||||
* RpcServerUseProtseqEpA (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqEpA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor )
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqEpA( unsigned char *Protseq, UINT MaxCalls, unsigned char *Endpoint, LPVOID SecurityDescriptor )
|
||||
{
|
||||
RPC_POLICY policy;
|
||||
|
||||
|
@ -605,7 +716,7 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpA( RPC_CSTR Protseq, UINT MaxCalls, RPC_C
|
|||
/***********************************************************************
|
||||
* RpcServerUseProtseqEpW (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor )
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqEpW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor )
|
||||
{
|
||||
RPC_POLICY policy;
|
||||
|
||||
|
@ -619,114 +730,50 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_W
|
|||
return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* alloc_serverprotoseq (internal)
|
||||
*
|
||||
* Must be called with server_cs held.
|
||||
*/
|
||||
static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps)
|
||||
{
|
||||
const struct protseq_ops *ops = rpcrt4_get_protseq_ops(Protseq);
|
||||
|
||||
if (!ops)
|
||||
{
|
||||
FIXME("protseq %s not supported\n", debugstr_a(Protseq));
|
||||
return RPC_S_PROTSEQ_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
*ps = ops->alloc();
|
||||
if (!*ps)
|
||||
return RPC_S_OUT_OF_RESOURCES;
|
||||
(*ps)->MaxCalls = MaxCalls;
|
||||
(*ps)->Protseq = Protseq;
|
||||
(*ps)->ops = ops;
|
||||
(*ps)->MaxCalls = 0;
|
||||
(*ps)->conn = NULL;
|
||||
InitializeCriticalSection(&(*ps)->cs);
|
||||
(*ps)->is_listening = FALSE;
|
||||
(*ps)->mgr_mutex = NULL;
|
||||
(*ps)->server_ready_event = NULL;
|
||||
|
||||
list_add_head(&protseqs, &(*ps)->entry);
|
||||
|
||||
TRACE("new protseq %p created for %s\n", *ps, Protseq);
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/* Finds a given protseq or creates a new one if one doesn't already exist */
|
||||
static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
RpcServerProtseq *cps;
|
||||
|
||||
EnterCriticalSection(&server_cs);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
|
||||
if (!strcmp(cps->Protseq, Protseq))
|
||||
{
|
||||
TRACE("found existing protseq object for %s\n", Protseq);
|
||||
*ps = cps;
|
||||
LeaveCriticalSection(&server_cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
status = alloc_serverprotoseq(MaxCalls, Protseq, ps);
|
||||
|
||||
LeaveCriticalSection(&server_cs);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcServerUseProtseqEpExA (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqEpExA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor,
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqEpExA( unsigned char *Protseq, UINT MaxCalls, unsigned char *Endpoint, LPVOID SecurityDescriptor,
|
||||
PRPC_POLICY lpPolicy )
|
||||
{
|
||||
char *szps = (char*)Protseq, *szep = (char*)Endpoint;
|
||||
RpcServerProtseq* ps;
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_a(szps), MaxCalls,
|
||||
debugstr_a(szep), SecurityDescriptor,
|
||||
TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_a( (char*)Protseq ), MaxCalls,
|
||||
debugstr_a( (char*)Endpoint ), SecurityDescriptor,
|
||||
lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
|
||||
|
||||
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupA(szps), &ps);
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerProtseq));
|
||||
ps->MaxCalls = MaxCalls;
|
||||
ps->Protseq = RPCRT4_strdupA((char*)Protseq);
|
||||
ps->Endpoint = RPCRT4_strdupA((char*)Endpoint);
|
||||
|
||||
return RPCRT4_use_protseq(ps, szep);
|
||||
return RPCRT4_use_protseq(ps);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcServerUseProtseqEpExW (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor,
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqEpExW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor,
|
||||
PRPC_POLICY lpPolicy )
|
||||
{
|
||||
RpcServerProtseq* ps;
|
||||
RPC_STATUS status;
|
||||
LPSTR EndpointA;
|
||||
|
||||
TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_w( Protseq ), MaxCalls,
|
||||
debugstr_w( Endpoint ), SecurityDescriptor,
|
||||
lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
|
||||
|
||||
status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps);
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerProtseq));
|
||||
ps->MaxCalls = MaxCalls;
|
||||
ps->Protseq = RPCRT4_strdupWtoA(Protseq);
|
||||
ps->Endpoint = RPCRT4_strdupWtoA(Endpoint);
|
||||
|
||||
EndpointA = RPCRT4_strdupWtoA(Endpoint);
|
||||
status = RPCRT4_use_protseq(ps, EndpointA);
|
||||
RPCRT4_strfree(EndpointA);
|
||||
return status;
|
||||
return RPCRT4_use_protseq(ps);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcServerUseProtseqA (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqA(unsigned char *Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
|
||||
{
|
||||
TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_a((char*)Protseq), MaxCalls, SecurityDescriptor);
|
||||
return RpcServerUseProtseqEpA(Protseq, MaxCalls, NULL, SecurityDescriptor);
|
||||
|
@ -735,7 +782,7 @@ RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls,
|
|||
/***********************************************************************
|
||||
* RpcServerUseProtseqW (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
|
||||
RPC_STATUS WINAPI RpcServerUseProtseqW(LPWSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
|
||||
{
|
||||
TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_w(Protseq), MaxCalls, SecurityDescriptor);
|
||||
return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor);
|
||||
|
@ -805,11 +852,17 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid,
|
|||
sif->IfCallbackFn = IfCallbackFn;
|
||||
|
||||
EnterCriticalSection(&server_cs);
|
||||
list_add_head(&server_interfaces, &sif->entry);
|
||||
sif->Next = ifs;
|
||||
ifs = sif;
|
||||
LeaveCriticalSection(&server_cs);
|
||||
|
||||
if (sif->Flags & RPC_IF_AUTOLISTEN)
|
||||
RPCRT4_start_listen(TRUE);
|
||||
if (sif->Flags & RPC_IF_AUTOLISTEN) {
|
||||
RPCRT4_start_listen(TRUE);
|
||||
|
||||
/* make sure server is actually listening on the interface before
|
||||
* returning */
|
||||
RPCRT4_sync_with_server_thread();
|
||||
}
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
@ -819,45 +872,8 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid,
|
|||
*/
|
||||
RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete )
|
||||
{
|
||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||
HANDLE event = NULL;
|
||||
BOOL found = FALSE;
|
||||
BOOL completed = TRUE;
|
||||
RpcServerInterface *cif;
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(IfSpec == (RPC_IF_HANDLE)^%p (%s), MgrTypeUuid == %s, WaitForCallsToComplete == %u)\n",
|
||||
IfSpec, debugstr_guid(&If->InterfaceId.SyntaxGUID), debugstr_guid(MgrTypeUuid), WaitForCallsToComplete);
|
||||
|
||||
EnterCriticalSection(&server_cs);
|
||||
LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) {
|
||||
if ((!IfSpec || !memcmp(&If->InterfaceId, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER))) &&
|
||||
UuidEqual(MgrTypeUuid, &cif->MgrTypeUuid, &status)) {
|
||||
list_remove(&cif->entry);
|
||||
if (cif->CurrentCalls) {
|
||||
completed = FALSE;
|
||||
if (WaitForCallsToComplete)
|
||||
cif->CallsCompletedEvent = event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
}
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&server_cs);
|
||||
|
||||
if (!found) {
|
||||
ERR("not found for object %s\n", debugstr_guid(MgrTypeUuid));
|
||||
return RPC_S_UNKNOWN_IF;
|
||||
}
|
||||
|
||||
if (completed)
|
||||
HeapFree(GetProcessHeap(), 0, cif);
|
||||
else if (event) {
|
||||
/* sif will be freed when the last call is completed, so be careful not to
|
||||
* touch that memory here as that could happen before we get here */
|
||||
WaitForSingleObject(event, INFINITE);
|
||||
CloseHandle(event);
|
||||
}
|
||||
FIXME("(IfSpec == (RPC_IF_HANDLE)^%p, MgrTypeUuid == %s, WaitForCallsToComplete == %u): stub\n",
|
||||
IfSpec, debugstr_guid(MgrTypeUuid), WaitForCallsToComplete);
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
@ -940,10 +956,10 @@ RPC_STATUS WINAPI RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid )
|
|||
/***********************************************************************
|
||||
* RpcServerRegisterAuthInfoA (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( RPC_CSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
|
||||
RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( unsigned char *ServerPrincName, unsigned long AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
|
||||
LPVOID Arg )
|
||||
{
|
||||
FIXME( "(%s,%u,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg );
|
||||
FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg );
|
||||
|
||||
return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
|
||||
}
|
||||
|
@ -951,10 +967,10 @@ RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( RPC_CSTR ServerPrincName, ULONG Au
|
|||
/***********************************************************************
|
||||
* RpcServerRegisterAuthInfoW (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( RPC_WSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
|
||||
RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName, unsigned long AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
|
||||
LPVOID Arg )
|
||||
{
|
||||
FIXME( "(%s,%u,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg );
|
||||
FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg );
|
||||
|
||||
return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
|
||||
}
|
||||
|
@ -964,15 +980,18 @@ RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( RPC_WSTR ServerPrincName, ULONG Au
|
|||
*/
|
||||
RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait )
|
||||
{
|
||||
RPC_STATUS status = RPC_S_OK;
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(%u,%u,%u)\n", MinimumCallThreads, MaxCalls, DontWait);
|
||||
|
||||
if (list_empty(&protseqs))
|
||||
if (!protseqs)
|
||||
return RPC_S_NO_PROTSEQS_REGISTERED;
|
||||
|
||||
status = RPCRT4_start_listen(FALSE);
|
||||
|
||||
if (status == RPC_S_OK)
|
||||
RPCRT4_sync_with_server_thread();
|
||||
|
||||
if (DontWait || (status != RPC_S_OK)) return status;
|
||||
|
||||
return RpcMgmtWaitServerListen();
|
||||
|
@ -994,8 +1013,6 @@ RPC_STATUS WINAPI RpcMgmtWaitServerListen( void )
|
|||
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
|
||||
FIXME("not waiting for server calls to finish\n");
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
|
@ -1016,15 +1033,6 @@ RPC_STATUS WINAPI RpcMgmtStopServerListening ( RPC_BINDING_HANDLE Binding )
|
|||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcMgmtEnableIdleCleanup (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcMgmtEnableIdleCleanup(void)
|
||||
{
|
||||
FIXME("(): stub\n");
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* I_RpcServerStartListening (RPCRT4.@)
|
||||
*/
|
||||
|
@ -1050,45 +1058,7 @@ RPC_STATUS WINAPI I_RpcServerStopListening( void )
|
|||
*/
|
||||
UINT WINAPI I_RpcWindowProc( void *hWnd, UINT Message, UINT wParam, ULONG lParam )
|
||||
{
|
||||
FIXME( "(%p,%08x,%08x,%08x): stub\n", hWnd, Message, wParam, lParam );
|
||||
FIXME( "(%p,%08x,%08x,%08lx): stub\n", hWnd, Message, wParam, lParam );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcMgmtInqIfIds (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcMgmtInqIfIds(RPC_BINDING_HANDLE Binding, RPC_IF_ID_VECTOR **IfIdVector)
|
||||
{
|
||||
FIXME("(%p,%p): stub\n", Binding, IfIdVector);
|
||||
return RPC_S_INVALID_BINDING;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcMgmtEpEltInqBegin (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcMgmtEpEltInqBegin(RPC_BINDING_HANDLE Binding, ULONG InquiryType,
|
||||
RPC_IF_ID *IfId, ULONG VersOption, UUID *ObjectUuid, RPC_EP_INQ_HANDLE* InquiryContext)
|
||||
{
|
||||
FIXME("(%p,%u,%p,%u,%p,%p): stub\n",
|
||||
Binding, InquiryType, IfId, VersOption, ObjectUuid, InquiryContext);
|
||||
return RPC_S_INVALID_BINDING;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcMgmtIsServerListening (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcMgmtIsServerListening(RPC_BINDING_HANDLE Binding)
|
||||
{
|
||||
FIXME("(%p): stub\n", Binding);
|
||||
return RPC_S_INVALID_BINDING;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcMgmtSetServerStackSize (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcMgmtSetServerStackSize(ULONG ThreadStackSize)
|
||||
{
|
||||
FIXME("(0x%x): stub\n", ThreadStackSize);
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
|
|
@ -15,53 +15,26 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPC_SERVER_H
|
||||
#define __WINE_RPC_SERVER_H
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
struct protseq_ops;
|
||||
|
||||
typedef struct _RpcServerProtseq
|
||||
{
|
||||
const struct protseq_ops *ops; /* RO */
|
||||
struct list entry; /* CS ::server_cs */
|
||||
LPSTR Protseq; /* RO */
|
||||
UINT MaxCalls; /* RO */
|
||||
/* list of listening connections */
|
||||
RpcConnection* conn; /* CS cs */
|
||||
CRITICAL_SECTION cs;
|
||||
|
||||
/* is the server currently listening? */
|
||||
BOOL is_listening; /* CS ::listen_cs */
|
||||
/* mutex for ensuring only one thread can change state at a time */
|
||||
HANDLE mgr_mutex;
|
||||
/* set when server thread has finished opening connections */
|
||||
HANDLE server_ready_event;
|
||||
struct _RpcServerProtseq* Next;
|
||||
LPSTR Protseq;
|
||||
LPSTR Endpoint;
|
||||
UINT MaxCalls;
|
||||
RpcConnection* conn;
|
||||
} RpcServerProtseq;
|
||||
|
||||
struct protseq_ops
|
||||
{
|
||||
const char *name;
|
||||
RpcServerProtseq *(*alloc)(void);
|
||||
void (*signal_state_changed)(RpcServerProtseq *protseq);
|
||||
/* previous array is passed in to allow reuse of memory */
|
||||
void *(*get_wait_array)(RpcServerProtseq *protseq, void *prev_array, unsigned int *count);
|
||||
void (*free_wait_array)(RpcServerProtseq *protseq, void *array);
|
||||
/* returns -1 for failure, 0 for server state changed and 1 to indicate a
|
||||
* new connection was established */
|
||||
int (*wait_for_new_connection)(RpcServerProtseq *protseq, unsigned int count, void *wait_array);
|
||||
/* opens the endpoint and optionally begins listening */
|
||||
RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, LPSTR endpoint);
|
||||
};
|
||||
|
||||
typedef struct _RpcServerInterface
|
||||
{
|
||||
struct list entry;
|
||||
struct _RpcServerInterface* Next;
|
||||
RPC_SERVER_INTERFACE* If;
|
||||
UUID MgrTypeUuid;
|
||||
RPC_MGR_EPV* MgrEpv;
|
||||
|
@ -69,13 +42,6 @@ typedef struct _RpcServerInterface
|
|||
UINT MaxCalls;
|
||||
UINT MaxRpcSize;
|
||||
RPC_IF_CALLBACK_FN* IfCallbackFn;
|
||||
LONG CurrentCalls; /* number of calls currently executing */
|
||||
/* set when unregistering interface to let the caller of
|
||||
* RpcServerUnregisterIf* know that all calls have finished */
|
||||
HANDLE CallsCompletedEvent;
|
||||
} RpcServerInterface;
|
||||
|
||||
void RPCRT4_new_client(RpcConnection* conn);
|
||||
const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq);
|
||||
|
||||
#endif /* __WINE_RPC_SERVER_H */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,22 +17,19 @@
|
|||
<library>ntdll</library>
|
||||
<library>kernel32</library>
|
||||
<library>advapi32</library>
|
||||
<library>secur32</library>
|
||||
<library>iphlpapi</library>
|
||||
<library>ws2_32</library>
|
||||
<file>cproxy.c</file>
|
||||
<file>cpsf.c</file>
|
||||
<file>cstub.c</file>
|
||||
<file>ndr_clientserver.c</file>
|
||||
<file>ndr_fullpointer.c</file>
|
||||
<file>ndr_marshall.c</file>
|
||||
<file>ndr_midl.c</file>
|
||||
<file>ndr_ole.c</file>
|
||||
<file>ndr_stubless.c</file>
|
||||
<file>rpc_binding.c</file>
|
||||
<file>rpc_epmap.c</file>
|
||||
<file>rpc_message.c</file>
|
||||
<file>rpc_server.c</file>
|
||||
<file>rpc_transport.c</file>
|
||||
<file>ndr_contexth.c</file>
|
||||
<file>rpcrt4_main.c</file>
|
||||
<file>rpcss_np_client.c</file>
|
||||
<file>rpcrt4.rc</file>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
@ stdcall IUnknown_QueryInterface_Proxy(ptr ptr ptr)
|
||||
@ stdcall IUnknown_Release_Proxy(ptr)
|
||||
@ stub I_RpcAbortAsyncCall
|
||||
@ stdcall I_RpcAllocate(long)
|
||||
@ stub I_RpcAllocate
|
||||
@ stub I_RpcAsyncAbortCall
|
||||
@ stub I_RpcAsyncSendReceive # NT4
|
||||
@ stub I_RpcAsyncSetHandle
|
||||
|
@ -45,7 +45,7 @@
|
|||
@ stub I_RpcDeleteMutex
|
||||
@ stub I_RpcEnableWmiTrace # wxp
|
||||
@ stub I_RpcExceptionFilter # wxp
|
||||
@ stdcall I_RpcFree(ptr)
|
||||
@ stub I_RpcFree
|
||||
@ stdcall I_RpcFreeBuffer(ptr)
|
||||
@ stub I_RpcFreePipeBuffer
|
||||
@ stub I_RpcGetAssociationContext
|
||||
|
@ -59,7 +59,7 @@
|
|||
@ stub I_RpcIfInqTransferSyntaxes
|
||||
@ stub I_RpcLaunchDatagramReceiveThread # win9x
|
||||
@ stub I_RpcLogEvent
|
||||
@ stdcall I_RpcMapWin32Status(long)
|
||||
@ stub I_RpcMapWin32Status
|
||||
@ stub I_RpcMonitorAssociation
|
||||
@ stub I_RpcNegotiateTransferSyntax # wxp
|
||||
@ stub I_RpcNsBindingSetEntryName
|
||||
|
@ -140,12 +140,12 @@
|
|||
@ stdcall NDRCContextBinding(ptr)
|
||||
@ stdcall NDRCContextMarshall(ptr ptr)
|
||||
@ stdcall NDRCContextUnmarshall(ptr ptr ptr long)
|
||||
@ stdcall NDRSContextMarshall2(ptr ptr ptr ptr ptr long)
|
||||
@ stub NDRSContextMarshall2
|
||||
@ stdcall NDRSContextMarshall(ptr ptr ptr)
|
||||
@ stdcall NDRSContextMarshallEx(ptr ptr ptr ptr)
|
||||
@ stdcall NDRSContextUnmarshall2(ptr ptr ptr ptr long)
|
||||
@ stdcall NDRSContextUnmarshall(ptr ptr)
|
||||
@ stdcall NDRSContextUnmarshallEx(ptr ptr ptr)
|
||||
@ stub NDRSContextUnmarshall2
|
||||
@ stdcall NDRSContextUnmarshall(ptr long)
|
||||
@ stdcall NDRSContextUnmarshallEx(ptr ptr long)
|
||||
@ stub NDRcopy
|
||||
@ stdcall NdrAllocate(ptr long)
|
||||
@ stub NdrAsyncClientCall
|
||||
|
@ -158,7 +158,7 @@
|
|||
@ stdcall NdrCStdStubBuffer_Release(ptr ptr)
|
||||
@ stdcall NdrClearOutParameters(ptr ptr ptr)
|
||||
@ varargs NdrClientCall2(ptr ptr)
|
||||
@ varargs NdrClientCall(ptr ptr) NdrClientCall2
|
||||
@ stub NdrClientCall
|
||||
@ stdcall NdrClientContextMarshall(ptr ptr long)
|
||||
@ stdcall NdrClientContextUnmarshall(ptr ptr ptr)
|
||||
@ stub NdrClientInitialize
|
||||
|
@ -221,12 +221,12 @@
|
|||
@ stdcall NdrFixedArrayMemorySize(ptr ptr)
|
||||
@ stdcall NdrFixedArrayUnmarshall(ptr ptr ptr long)
|
||||
@ stdcall NdrFreeBuffer(ptr)
|
||||
@ stdcall NdrFullPointerFree(ptr ptr)
|
||||
@ stdcall NdrFullPointerInsertRefId(ptr long ptr)
|
||||
@ stdcall NdrFullPointerQueryPointer(ptr ptr long ptr)
|
||||
@ stdcall NdrFullPointerQueryRefId(ptr long long ptr)
|
||||
@ stdcall NdrFullPointerXlatFree(ptr)
|
||||
@ stdcall NdrFullPointerXlatInit(long long)
|
||||
@ stub NdrFullPointerFree
|
||||
@ stub NdrFullPointerInsertRefId
|
||||
@ stub NdrFullPointerQueryPointer
|
||||
@ stub NdrFullPointerQueryRefId
|
||||
@ stub NdrFullPointerXlatFree
|
||||
@ stub NdrFullPointerXlatInit
|
||||
@ stdcall NdrGetBuffer(ptr long ptr)
|
||||
@ stub NdrGetDcomProtocolVersion
|
||||
@ stub NdrGetPartialBuffer
|
||||
|
@ -377,20 +377,20 @@
|
|||
@ stub RpcBindingInqAuthClientExA
|
||||
@ stub RpcBindingInqAuthClientExW
|
||||
@ stub RpcBindingInqAuthClientW
|
||||
@ stdcall RpcBindingInqAuthInfoA(ptr ptr ptr ptr ptr ptr)
|
||||
@ stdcall RpcBindingInqAuthInfoExA(ptr ptr ptr ptr ptr ptr long ptr)
|
||||
@ stdcall RpcBindingInqAuthInfoExW(ptr ptr ptr ptr ptr ptr long ptr)
|
||||
@ stdcall RpcBindingInqAuthInfoW(ptr ptr ptr ptr ptr ptr)
|
||||
@ stub RpcBindingInqAuthInfoA
|
||||
@ stub RpcBindingInqAuthInfoExA
|
||||
@ stub RpcBindingInqAuthInfoExW
|
||||
@ stub RpcBindingInqAuthInfoW
|
||||
@ stdcall RpcBindingInqObject(ptr ptr)
|
||||
@ stub RpcBindingInqOption
|
||||
@ stub RpcBindingReset
|
||||
@ stub RpcBindingServerFromClient
|
||||
@ stdcall RpcBindingSetAuthInfoA(ptr str long long ptr long)
|
||||
@ stdcall RpcBindingSetAuthInfoExA(ptr str long long ptr long ptr)
|
||||
@ stdcall RpcBindingSetAuthInfoExW(ptr wstr long long ptr long ptr)
|
||||
@ stdcall RpcBindingSetAuthInfoW(ptr wstr long long ptr long)
|
||||
@ stub RpcBindingSetAuthInfoA
|
||||
@ stub RpcBindingSetAuthInfoExA
|
||||
@ stub RpcBindingSetAuthInfoExW
|
||||
@ stub RpcBindingSetAuthInfoW
|
||||
@ stdcall RpcBindingSetObject(ptr ptr)
|
||||
@ stdcall RpcBindingSetOption(ptr long long)
|
||||
@ stub RpcBindingSetOption
|
||||
@ stdcall RpcBindingToStringBindingA(ptr ptr)
|
||||
@ stdcall RpcBindingToStringBindingW(ptr ptr)
|
||||
@ stdcall RpcBindingVectorFree(ptr)
|
||||
|
@ -423,25 +423,25 @@
|
|||
@ stub RpcInitializeAsyncHandle
|
||||
@ stub RpcMgmtBindingInqParameter # win9x
|
||||
@ stub RpcMgmtBindingSetParameter # win9x
|
||||
@ stdcall RpcMgmtEnableIdleCleanup()
|
||||
@ stdcall RpcMgmtEpEltInqBegin(ptr long ptr long ptr ptr)
|
||||
@ stub RpcMgmtEnableIdleCleanup
|
||||
@ stub RpcMgmtEpEltInqBegin
|
||||
@ stub RpcMgmtEpEltInqDone
|
||||
@ stub RpcMgmtEpEltInqNextA
|
||||
@ stub RpcMgmtEpEltInqNextW
|
||||
@ stub RpcMgmtEpUnregister
|
||||
@ stub RpcMgmtInqComTimeout
|
||||
@ stub RpcMgmtInqDefaultProtectLevel
|
||||
@ stdcall RpcMgmtInqIfIds(ptr ptr)
|
||||
@ stub RpcMgmtInqIfIds
|
||||
@ stub RpcMgmtInqParameter # win9x
|
||||
@ stub RpcMgmtInqServerPrincNameA
|
||||
@ stub RpcMgmtInqServerPrincNameW
|
||||
@ stub RpcMgmtInqStats
|
||||
@ stdcall RpcMgmtIsServerListening(ptr)
|
||||
@ stub RpcMgmtIsServerListening
|
||||
@ stub RpcMgmtSetAuthorizationFn
|
||||
@ stub RpcMgmtSetCancelTimeout
|
||||
@ stdcall RpcMgmtSetComTimeout(ptr long)
|
||||
@ stub RpcMgmtSetComTimeout
|
||||
@ stub RpcMgmtSetParameter # win9x
|
||||
@ stdcall RpcMgmtSetServerStackSize(long)
|
||||
@ stub RpcMgmtSetServerStackSize
|
||||
@ stub RpcMgmtStatsVectorFree
|
||||
@ stdcall RpcMgmtStopServerListening(ptr)
|
||||
@ stdcall RpcMgmtWaitServerListen()
|
||||
|
@ -494,7 +494,7 @@
|
|||
@ stub RpcServerYield
|
||||
@ stub RpcSmAllocate
|
||||
@ stub RpcSmClientFree
|
||||
@ stub RpcSmDestroyClientContext
|
||||
@ stdcall RpcSmDestroyClientContext (ptr)
|
||||
@ stub RpcSmDisableAllocate
|
||||
@ stub RpcSmEnableAllocate
|
||||
@ stub RpcSmFree
|
||||
|
@ -505,7 +505,7 @@
|
|||
@ stub RpcSsAllocate
|
||||
@ stub RpcSsContextLockExclusive # wxp
|
||||
@ stub RpcSsContextLockShared # wxp
|
||||
@ stub RpcSsDestroyClientContext
|
||||
@ stdcall RpcSsDestroyClientContext (ptr)
|
||||
@ stub RpcSsDisableAllocate
|
||||
@ stub RpcSsDontSerializeContext
|
||||
@ stub RpcSsEnableAllocate
|
||||
|
@ -527,8 +527,8 @@
|
|||
@ stub SimpleTypeBufferSize # wxp
|
||||
@ stub SimpleTypeMemorySize # wxp
|
||||
@ stub StartServiceIfNecessary # win9x
|
||||
@ stdcall TowerConstruct(ptr ptr ptr ptr ptr ptr)
|
||||
@ stdcall TowerExplode(ptr ptr ptr ptr ptr ptr)
|
||||
@ stub TowerConstruct
|
||||
@ stub TowerExplode
|
||||
@ stdcall UuidCompare(ptr ptr ptr)
|
||||
@ stdcall UuidCreate(ptr)
|
||||
@ stdcall UuidCreateNil(ptr)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* WINE RPC TODO's (and a few TODONT's)
|
||||
*
|
||||
|
@ -152,8 +152,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
master_mutex = CreateMutexA( NULL, FALSE, RPCSS_MASTER_MUTEX_NAME);
|
||||
if (!master_mutex)
|
||||
ERR("Failed to create master mutex\n");
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
|
@ -174,7 +172,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
*
|
||||
* S_OK if successful.
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcStringFreeA(RPC_CSTR* String)
|
||||
RPC_STATUS WINAPI RpcStringFreeA(unsigned char** String)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, *String);
|
||||
|
||||
|
@ -190,7 +188,7 @@ RPC_STATUS WINAPI RpcStringFreeA(RPC_CSTR* String)
|
|||
*
|
||||
* S_OK if successful.
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR* String)
|
||||
RPC_STATUS WINAPI RpcStringFreeW(unsigned short** String)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, *String);
|
||||
|
||||
|
@ -321,6 +319,8 @@ static void RPC_UuidGetSystemTime(ULONGLONG *time)
|
|||
*time += TICKS_15_OCT_1582_TO_1601;
|
||||
}
|
||||
|
||||
typedef DWORD WINAPI (*LPGETADAPTERSINFO)(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);
|
||||
|
||||
/* Assume that a hardware address is at least 6 bytes long */
|
||||
#define ADDRESS_BYTES_NEEDED 6
|
||||
|
||||
|
@ -331,28 +331,46 @@ static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address)
|
|||
|
||||
ULONG buflen = sizeof(IP_ADAPTER_INFO);
|
||||
PIP_ADAPTER_INFO adapter = HeapAlloc(GetProcessHeap(), 0, buflen);
|
||||
HANDLE hIpHlpApi;
|
||||
LPGETADAPTERSINFO pGetAdaptersInfo;
|
||||
|
||||
hIpHlpApi = LoadLibrary("iphlpapi.dll");
|
||||
if (hIpHlpApi)
|
||||
{
|
||||
pGetAdaptersInfo = (LPGETADAPTERSINFO)GetProcAddress(hIpHlpApi, "GetAdaptersInfo");
|
||||
if (pGetAdaptersInfo)
|
||||
{
|
||||
if (pGetAdaptersInfo(adapter, &buflen) == ERROR_BUFFER_OVERFLOW) {
|
||||
HeapFree(GetProcessHeap(), 0, adapter);
|
||||
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];
|
||||
if (pGetAdaptersInfo(adapter, &buflen) == NO_ERROR) {
|
||||
for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) {
|
||||
address[i] = adapter->Address[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto local;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the Library */
|
||||
FreeLibrary(hIpHlpApi);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
local:
|
||||
/* 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;
|
||||
Set the multicast bit to prevent conflicts with real cards. */
|
||||
for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) {
|
||||
address[i] = rand() & 0xff;
|
||||
}
|
||||
|
||||
address[0] |= 0x01;
|
||||
status = RPC_S_UUID_LOCAL_ONLY;
|
||||
|
||||
exit:
|
||||
HeapFree(GetProcessHeap(), 0, adapter);
|
||||
return status;
|
||||
}
|
||||
|
@ -507,9 +525,9 @@ unsigned short WINAPI UuidHash(UUID *uuid, RPC_STATUS *Status)
|
|||
* RETURNS
|
||||
*
|
||||
* S_OK if successful.
|
||||
* S_OUT_OF_MEMORY if unsuccessful.
|
||||
* S_OUT_OF_MEMORY if unsucessful.
|
||||
*/
|
||||
RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, RPC_CSTR* StringUuid)
|
||||
RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, unsigned char** StringUuid)
|
||||
{
|
||||
*StringUuid = HeapAlloc( GetProcessHeap(), 0, sizeof(char) * 37);
|
||||
|
||||
|
@ -518,7 +536,7 @@ RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, RPC_CSTR* StringUuid)
|
|||
|
||||
if (!Uuid) Uuid = &uuid_nil;
|
||||
|
||||
sprintf( (char*)*StringUuid, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
sprintf( (char*)*StringUuid, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
Uuid->Data1, Uuid->Data2, Uuid->Data3,
|
||||
Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2],
|
||||
Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5],
|
||||
|
@ -533,15 +551,15 @@ RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, RPC_CSTR* StringUuid)
|
|||
* Converts a UUID to a string.
|
||||
*
|
||||
* S_OK if successful.
|
||||
* S_OUT_OF_MEMORY if unsuccessful.
|
||||
* S_OUT_OF_MEMORY if unsucessful.
|
||||
*/
|
||||
RPC_STATUS WINAPI UuidToStringW(UUID *Uuid, RPC_WSTR* StringUuid)
|
||||
RPC_STATUS WINAPI UuidToStringW(UUID *Uuid, unsigned short** StringUuid)
|
||||
{
|
||||
char buf[37];
|
||||
|
||||
if (!Uuid) Uuid = &uuid_nil;
|
||||
|
||||
sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
sprintf(buf, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
Uuid->Data1, Uuid->Data2, Uuid->Data3,
|
||||
Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2],
|
||||
Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5],
|
||||
|
@ -569,7 +587,7 @@ static const BYTE hex2bin[] =
|
|||
/***********************************************************************
|
||||
* UuidFromStringA (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI UuidFromStringA(RPC_CSTR s, UUID *uuid)
|
||||
RPC_STATUS WINAPI UuidFromStringA(unsigned char* s, UUID *uuid)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -609,7 +627,7 @@ RPC_STATUS WINAPI UuidFromStringA(RPC_CSTR s, UUID *uuid)
|
|||
/***********************************************************************
|
||||
* UuidFromStringW (RPCRT4.@)
|
||||
*/
|
||||
RPC_STATUS WINAPI UuidFromStringW(RPC_WSTR s, UUID *uuid)
|
||||
RPC_STATUS WINAPI UuidFromStringW(unsigned short* s, UUID *uuid)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -655,8 +673,8 @@ HRESULT WINAPI DllRegisterServer( void )
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static BOOL RPCRT4_StartRPCSS(void)
|
||||
{
|
||||
BOOL RPCRT4_StartRPCSS(void)
|
||||
{
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFOA si;
|
||||
static char cmd[6];
|
||||
|
@ -710,14 +728,13 @@ static BOOL RPCRT4_StartRPCSS(void)
|
|||
BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply)
|
||||
{
|
||||
HANDLE client_handle;
|
||||
BOOL ret;
|
||||
int i, j = 0;
|
||||
|
||||
TRACE("(msg == %p, vardata_payload == %p, reply == %p)\n", msg, vardata_payload, reply);
|
||||
|
||||
client_handle = RPCRT4_RpcssNPConnect();
|
||||
|
||||
while (INVALID_HANDLE_VALUE == client_handle) {
|
||||
while (!client_handle) {
|
||||
/* start the RPCSS process */
|
||||
if (!RPCRT4_StartRPCSS()) {
|
||||
ERR("Unable to start RPCSS process.\n");
|
||||
|
@ -727,13 +744,13 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC
|
|||
for (i = 0; i < 60; i++) {
|
||||
Sleep(200);
|
||||
client_handle = RPCRT4_RpcssNPConnect();
|
||||
if (INVALID_HANDLE_VALUE != client_handle) break;
|
||||
if (client_handle) break;
|
||||
}
|
||||
/* we are only willing to try twice */
|
||||
if (j++ >= 1) break;
|
||||
}
|
||||
|
||||
if (INVALID_HANDLE_VALUE == client_handle) {
|
||||
if (!client_handle) {
|
||||
/* no dice! */
|
||||
ERR("Unable to connect to RPCSS process!\n");
|
||||
SetLastError(RPC_E_SERVER_DIED_DNE);
|
||||
|
@ -741,14 +758,12 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC
|
|||
}
|
||||
|
||||
/* great, we're connected. now send the message */
|
||||
ret = TRUE;
|
||||
if (!RPCRT4_SendReceiveNPMsg(client_handle, msg, vardata_payload, reply)) {
|
||||
ERR("Something is amiss: RPC_SendReceive failed.\n");
|
||||
ret = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
CloseHandle(client_handle);
|
||||
|
||||
return ret;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define MAX_RPC_ERROR_TEXT 256
|
||||
|
@ -765,7 +780,7 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC
|
|||
* 4. The MSDN documentation currently declares that the second argument is
|
||||
* unsigned char *, even for the W version. I don't believe it.
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY DceErrorInqTextW (RPC_STATUS e, RPC_WSTR buffer)
|
||||
RPC_STATUS RPC_ENTRY DceErrorInqTextW (RPC_STATUS e, unsigned short *buffer)
|
||||
{
|
||||
DWORD count;
|
||||
count = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
|
@ -778,7 +793,7 @@ RPC_STATUS RPC_ENTRY DceErrorInqTextW (RPC_STATUS e, RPC_WSTR buffer)
|
|||
NULL, RPC_S_NOT_RPC_ERROR, 0, buffer, MAX_RPC_ERROR_TEXT, NULL);
|
||||
if (!count)
|
||||
{
|
||||
ERR ("Failed to translate error\n");
|
||||
ERR ("Failed to translate error");
|
||||
return RPC_S_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
@ -788,7 +803,7 @@ RPC_STATUS RPC_ENTRY DceErrorInqTextW (RPC_STATUS e, RPC_WSTR buffer)
|
|||
/******************************************************************************
|
||||
* DceErrorInqTextA (rpcrt4.@)
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY DceErrorInqTextA (RPC_STATUS e, RPC_CSTR buffer)
|
||||
RPC_STATUS RPC_ENTRY DceErrorInqTextA (RPC_STATUS e, unsigned char *buffer)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
WCHAR bufferW [MAX_RPC_ERROR_TEXT];
|
||||
|
@ -797,34 +812,9 @@ RPC_STATUS RPC_ENTRY DceErrorInqTextA (RPC_STATUS e, RPC_CSTR buffer)
|
|||
if (!WideCharToMultiByte(CP_ACP, 0, bufferW, -1, (LPSTR)buffer, MAX_RPC_ERROR_TEXT,
|
||||
NULL, NULL))
|
||||
{
|
||||
ERR ("Failed to translate error\n");
|
||||
ERR ("Failed to translate error");
|
||||
status = RPC_S_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* I_RpcAllocate (rpcrt4.@)
|
||||
*/
|
||||
void * WINAPI I_RpcAllocate(unsigned int Size)
|
||||
{
|
||||
return HeapAlloc(GetProcessHeap(), 0, Size);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* I_RpcFree (rpcrt4.@)
|
||||
*/
|
||||
void WINAPI I_RpcFree(void *Object)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, Object);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* I_RpcMapWin32Status (rpcrt4.@)
|
||||
*/
|
||||
DWORD WINAPI I_RpcMapWin32Status(RPC_STATUS status)
|
||||
{
|
||||
FIXME("(%ld): stub\n", status);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -32,7 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|||
|
||||
HANDLE RPCRT4_RpcssNPConnect(void)
|
||||
{
|
||||
HANDLE the_pipe;
|
||||
HANDLE the_pipe = NULL;
|
||||
DWORD dwmode, wait_result;
|
||||
HANDLE master_mutex = RPCRT4_GetMasterMutex();
|
||||
|
||||
|
@ -69,6 +69,7 @@ HANDLE RPCRT4_RpcssNPConnect(void)
|
|||
if (GetLastError() != ERROR_PIPE_BUSY) {
|
||||
WARN("Unable to open named pipe %s (assuming unavailable).\n",
|
||||
debugstr_a(NAME_RPCSS_NAMED_PIPE));
|
||||
the_pipe = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -77,17 +78,18 @@ HANDLE RPCRT4_RpcssNPConnect(void)
|
|||
if (!ReleaseMutex(master_mutex))
|
||||
ERR("Failed to release master mutex. Expect deadlock.\n");
|
||||
|
||||
/* wait for the named pipe. We are only willing to wait for 5 seconds.
|
||||
It should be available /very/ soon. */
|
||||
/* wait for the named pipe. We are only
|
||||
willing to wait only 5 seconds. It should be available /very/ soon. */
|
||||
if (! WaitNamedPipeA(NAME_RPCSS_NAMED_PIPE, MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT))
|
||||
{
|
||||
ERR("Named pipe unavailable after waiting. Something is probably wrong.\n");
|
||||
the_pipe = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (the_pipe != INVALID_HANDLE_VALUE) {
|
||||
if (the_pipe) {
|
||||
dwmode = PIPE_READMODE_MESSAGE;
|
||||
/* SetNamedPipeHandleState not implemented ATM, but still seems to work somehow. */
|
||||
if (! SetNamedPipeHandleState(the_pipe, &dwmode, NULL, NULL))
|
||||
|
@ -143,7 +145,7 @@ BOOL RPCRT4_SendReceiveNPMsg(HANDLE np, PRPCSS_NP_MESSAGE msg, char *vardata, PR
|
|||
}
|
||||
|
||||
if (count != sizeof(RPCSS_NP_REPLY)) {
|
||||
ERR("read count mismatch. got %d.\n", count);
|
||||
ERR("read count mismatch. got %ld, expected %u.\n", count, sizeof(RPCSS_NP_REPLY));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_RPCSS_NP_CLIENT_H
|
||||
|
|
|
@ -72,7 +72,7 @@ reactos/dll/win32/olepro32 # Autosync
|
|||
reactos/dll/win32/powrprof # Synced to Wine-0_9_14
|
||||
reactos/dll/win32/riched20 # Synced to Wine-0_9_5
|
||||
reactos/dll/win32/riched32 # Autosync
|
||||
reactos/dll/win32/rpcrt4 # Synced to Wine-20070507
|
||||
reactos/dll/win32/rpcrt4 # Synced to Wine-0_9_10
|
||||
reactos/dll/win32/sensapi # Autosync
|
||||
reactos/dll/win32/setupapi # Forked at Wine-20050524
|
||||
reactos/dll/win32/shell32 # Synced to Wine-0_9_5
|
||||
|
|
Loading…
Reference in a new issue