mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 04:35:53 +00:00
- Sync rpcrt4.dll to Wine-20081106. ros.diff and regtests aren't updated yet.
svn path=/trunk/; revision=37225
This commit is contained in:
parent
ab7c1ded60
commit
f08921caf1
31 changed files with 650 additions and 577 deletions
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* COM proxy implementation
|
* COM proxy implementation
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -58,10 +58,6 @@ static const IRpcProxyBufferVtbl StdProxy_Vtbl;
|
||||||
|
|
||||||
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
|
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
|
||||||
|
|
||||||
/* How the Windows stubless proxy thunks work is explained at
|
|
||||||
* http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp,
|
|
||||||
* but I'll use a slightly different method, to make life easier */
|
|
||||||
|
|
||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
|
|
||||||
#include "pshpack1.h"
|
#include "pshpack1.h"
|
||||||
|
@ -389,6 +385,8 @@ void WINAPI NdrProxySendReceive(void *This,
|
||||||
}
|
}
|
||||||
|
|
||||||
pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
|
pStubMsg->dwStubPhase = PROXY_SENDRECEIVE;
|
||||||
|
/* avoid sending uninitialised parts of the buffer on the wire */
|
||||||
|
pStubMsg->RpcMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
|
||||||
hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer,
|
hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer,
|
||||||
(RPCOLEMESSAGE*)pStubMsg->RpcMsg,
|
(RPCOLEMESSAGE*)pStubMsg->RpcMsg,
|
||||||
&Status);
|
&Status);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* COM proxy/stub factory (CStdPSFactory) implementation
|
* COM proxy/stub factory (CStdPSFactory) implementation
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -174,7 +174,7 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
|
||||||
if(max_delegating_vtbl_size > 0)
|
if(max_delegating_vtbl_size > 0)
|
||||||
create_delegating_vtbl(max_delegating_vtbl_size);
|
create_delegating_vtbl(max_delegating_vtbl_size);
|
||||||
}
|
}
|
||||||
if (IsEqualGUID(rclsid, pclsid))
|
if (pclsid && IsEqualGUID(rclsid, pclsid))
|
||||||
return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
|
return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
|
||||||
else {
|
else {
|
||||||
const ProxyFileInfo *info;
|
const ProxyFileInfo *info;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* COM proxy definitions
|
* COM proxy definitions
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* COM stub (CStdStubBuffer) implementation
|
* COM stub (CStdStubBuffer) implementation
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -18,6 +18,9 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "wine/port.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
|
@ -39,9 +42,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
|
|
||||||
#define STUB_HEADER(This) (((const CInterfaceStubHeader*)((This)->lpVtbl))[-1])
|
#define STUB_HEADER(This) (((const CInterfaceStubHeader*)((This)->lpVtbl))[-1])
|
||||||
|
|
||||||
static WINE_EXCEPTION_FILTER(stub_filter)
|
static LONG WINAPI stub_filter(EXCEPTION_POINTERS *eptr)
|
||||||
{
|
{
|
||||||
if (GetExceptionInformation()->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
if (eptr->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
return EXCEPTION_EXECUTE_HANDLER;
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
}
|
}
|
||||||
|
@ -194,7 +197,7 @@ static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num)
|
||||||
#else /* __i386__ */
|
#else /* __i386__ */
|
||||||
|
|
||||||
typedef struct {int dummy;} vtbl_method_t;
|
typedef struct {int dummy;} vtbl_method_t;
|
||||||
static void fill_table(IUnknownVtbl *vtbl, DWORD num)
|
static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num)
|
||||||
{
|
{
|
||||||
ERR("delegated stubs are not supported on this architecture\n");
|
ERR("delegated stubs are not supported on this architecture\n");
|
||||||
}
|
}
|
||||||
|
@ -218,9 +221,7 @@ void create_delegating_vtbl(DWORD num_methods)
|
||||||
if(current_vtbl.table && current_vtbl.table->ref == 0)
|
if(current_vtbl.table && current_vtbl.table->ref == 0)
|
||||||
{
|
{
|
||||||
TRACE("freeing old table\n");
|
TRACE("freeing old table\n");
|
||||||
VirtualFree(current_vtbl.table->methods,
|
VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE);
|
||||||
(current_vtbl.table->size - 3) * sizeof(vtbl_method_t),
|
|
||||||
MEM_RELEASE);
|
|
||||||
HeapFree(GetProcessHeap(), 0, current_vtbl.table);
|
HeapFree(GetProcessHeap(), 0, current_vtbl.table);
|
||||||
}
|
}
|
||||||
size = (num_methods - 3) * sizeof(vtbl_method_t);
|
size = (num_methods - 3) * sizeof(vtbl_method_t);
|
||||||
|
@ -255,9 +256,7 @@ static void release_delegating_vtbl(IUnknownVtbl *vtbl)
|
||||||
if(table->ref == 0 && table != current_vtbl.table)
|
if(table->ref == 0 && table != current_vtbl.table)
|
||||||
{
|
{
|
||||||
TRACE("... and we're not current so free'ing\n");
|
TRACE("... and we're not current so free'ing\n");
|
||||||
VirtualFree(current_vtbl.table->methods,
|
VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE);
|
||||||
(current_vtbl.table->size - 3) * sizeof(vtbl_method_t),
|
|
||||||
MEM_RELEASE);
|
|
||||||
HeapFree(GetProcessHeap(), 0, table);
|
HeapFree(GetProcessHeap(), 0, table);
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&delegating_vtbl_section);
|
LeaveCriticalSection(&delegating_vtbl_section);
|
||||||
|
|
|
@ -1,26 +1,19 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Greg Turner
|
* Copyright 2008 Robert Shearman
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
* License as published by the Free Software Foundation; either
|
* License as published by the Free Software Foundation; either
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
* 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,
|
* This library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __WINE_RPCSS_NP_CLIENT_H
|
#include "wine/epm.idl"
|
||||||
#define __WINE_RPCSS_NP_CLIENT_H
|
|
||||||
|
|
||||||
/* rpcss_np_client.c */
|
|
||||||
HANDLE RPC_RpcssNPConnect(void);
|
|
||||||
BOOL RPCRT4_SendReceiveNPMsg(HANDLE, PRPCSS_NP_MESSAGE, char *, PRPCSS_NP_REPLY);
|
|
||||||
|
|
||||||
#endif /* __RPCSS_NP_CLINET_H */
|
|
|
@ -19,6 +19,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "epm_c.h"
|
||||||
|
|
||||||
#define EPM_PROTOCOL_DNET_NSP 0x04
|
#define EPM_PROTOCOL_DNET_NSP 0x04
|
||||||
#define EPM_PROTOCOL_OSI_TP4 0x05
|
#define EPM_PROTOCOL_OSI_TP4 0x05
|
||||||
#define EPM_PROTOCOL_OSI_CLNS 0x06
|
#define EPM_PROTOCOL_OSI_CLNS 0x06
|
||||||
|
@ -48,10 +50,6 @@
|
||||||
|
|
||||||
#include <pshpack1.h>
|
#include <pshpack1.h>
|
||||||
|
|
||||||
typedef unsigned char u_int8;
|
|
||||||
typedef unsigned short u_int16;
|
|
||||||
typedef unsigned int u_int32;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
u_int16 count_lhs;
|
u_int16 count_lhs;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* MIDL proxy/stub stuff
|
* MIDL proxy/stub stuff
|
||||||
*
|
*
|
||||||
* Copyright 2002 Ove Kåven, TransGaming Technologies
|
* Copyright 2002 Ove Kåven, TransGaming Technologies
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
|
@ -156,7 +156,18 @@ RPC_STATUS RPC_ENTRY MesEncodeFixedBufferHandleCreate(
|
||||||
|
|
||||||
*pHandle = (handle_t)pEsMsg;
|
*pHandle = (handle_t)pEsMsg;
|
||||||
|
|
||||||
return RPC_S_OK;}
|
return RPC_S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MesEncodeDynBufferHandleCreate [RPCRT4.@]
|
||||||
|
*/
|
||||||
|
RPC_STATUS RPC_ENTRY MesEncodeDynBufferHandleCreate(char **ppBuffer,
|
||||||
|
ULONG *pEncodedSize, handle_t *pHandle)
|
||||||
|
{
|
||||||
|
FIXME("%p %p %p stub\n", ppBuffer, pEncodedSize, pHandle);
|
||||||
|
return RPC_S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* MesDecodeBufferHandleCreate [RPCRT4.@]
|
* MesDecodeBufferHandleCreate [RPCRT4.@]
|
||||||
|
|
|
@ -361,10 +361,10 @@ typedef struct _NDR_MEMORY_LIST
|
||||||
* If the function is unable to allocate memory an ERROR_OUTOFMEMORY
|
* If the function is unable to allocate memory an ERROR_OUTOFMEMORY
|
||||||
* exception is raised.
|
* exception is raised.
|
||||||
*/
|
*/
|
||||||
void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
|
void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
|
||||||
{
|
{
|
||||||
size_t aligned_len;
|
SIZE_T aligned_len;
|
||||||
size_t adjusted_len;
|
SIZE_T adjusted_len;
|
||||||
void *p;
|
void *p;
|
||||||
NDR_MEMORY_LIST *mem_list;
|
NDR_MEMORY_LIST *mem_list;
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
|
||||||
/* check for overflow */
|
/* check for overflow */
|
||||||
if (adjusted_len < len)
|
if (adjusted_len < len)
|
||||||
{
|
{
|
||||||
ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
|
ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
|
||||||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,7 +861,10 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||||
if (pointer_id)
|
if (pointer_id)
|
||||||
pointer_needs_unmarshaling = 1;
|
pointer_needs_unmarshaling = 1;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
*pPointer = NULL;
|
||||||
pointer_needs_unmarshaling = 0;
|
pointer_needs_unmarshaling = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case RPC_FC_FP:
|
case RPC_FC_FP:
|
||||||
pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
|
pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* NDR definitions
|
* NDR definitions
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* OLE32 callouts, COM interface marshalling
|
* OLE32 callouts, COM interface marshalling
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* NDR -Oi,-Oif,-Oicf Interpreter
|
* NDR -Oi,-Oif,-Oicf Interpreter
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
* Copyright 2003-5 Robert Shearman (for CodeWeavers)
|
* Copyright 2003-5 Robert Shearman (for CodeWeavers)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
|
@ -64,7 +64,7 @@ RPC_STATUS WINAPI RpcAsyncInitializeHandle(PRPC_ASYNC_STATE pAsync, unsigned int
|
||||||
pAsync->Flags = 0;
|
pAsync->Flags = 0;
|
||||||
pAsync->StubInfo = NULL;
|
pAsync->StubInfo = NULL;
|
||||||
pAsync->RuntimeInfo = NULL;
|
pAsync->RuntimeInfo = NULL;
|
||||||
memset(&pAsync->Reserved, 0, sizeof(*pAsync) - FIELD_OFFSET(RPC_ASYNC_STATE, Reserved));
|
memset(pAsync->Reserved, 0, sizeof(*pAsync) - FIELD_OFFSET(RPC_ASYNC_STATE, Reserved));
|
||||||
|
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* RPC binding API
|
* RPC binding API
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
* Copyright 2003 Mike Hearn
|
* Copyright 2003 Mike Hearn
|
||||||
* Copyright 2004 Filip Navara
|
* Copyright 2004 Filip Navara
|
||||||
* Copyright 2006 CodeWeavers
|
* Copyright 2006 CodeWeavers
|
||||||
|
@ -435,7 +435,7 @@ static RPC_WSTR unescape_string_binding_componentW(
|
||||||
{
|
{
|
||||||
RPC_WSTR component, p;
|
RPC_WSTR component, p;
|
||||||
|
|
||||||
if (len == -1) len = strlen((const char *)string_binding);
|
if (len == -1) len = strlenW(string_binding);
|
||||||
|
|
||||||
component = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(*component));
|
component = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(*component));
|
||||||
if (!component) return NULL;
|
if (!component) return NULL;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* RPC binding API
|
* RPC binding API
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -21,7 +21,6 @@
|
||||||
#ifndef __WINE_RPC_BINDING_H
|
#ifndef __WINE_RPC_BINDING_H
|
||||||
#define __WINE_RPC_BINDING_H
|
#define __WINE_RPC_BINDING_H
|
||||||
|
|
||||||
#include "wine/rpcss_shared.h"
|
|
||||||
#include "rpcndr.h"
|
#include "rpcndr.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
|
@ -150,9 +149,6 @@ RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding);
|
||||||
RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
|
RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
|
||||||
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId);
|
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId);
|
||||||
RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection);
|
RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection);
|
||||||
BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply);
|
|
||||||
HANDLE RPCRT4_GetMasterMutex(void);
|
|
||||||
HANDLE RPCRT4_RpcssNPConnect(void);
|
|
||||||
|
|
||||||
static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection)
|
static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* RPC definitions
|
* RPC definitions
|
||||||
*
|
*
|
||||||
* Copyright 2001-2002 Ove Kåven, TransGaming Technologies
|
* Copyright 2001-2002 Ove Kåven, TransGaming Technologies
|
||||||
* Copyright 2004 Filip Navara
|
* Copyright 2004 Filip Navara
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
* RPC endpoint mapper
|
* RPC endpoint mapper
|
||||||
*
|
*
|
||||||
* Copyright 2002 Greg Turner
|
* Copyright 2002 Greg Turner
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
|
* Copyright 2008 Robert Shearman (for CodeWeavers)
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -17,14 +18,9 @@
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* - actually do things right
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
@ -33,8 +29,10 @@
|
||||||
#include "rpc.h"
|
#include "rpc.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
#include "wine/exception.h"
|
||||||
|
|
||||||
#include "rpc_binding.h"
|
#include "rpc_binding.h"
|
||||||
|
#include "epm_c.h"
|
||||||
#include "epm_towers.h"
|
#include "epm_towers.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
|
@ -43,8 +41,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
*
|
*
|
||||||
* ncadg_ip_udp: 135
|
* ncadg_ip_udp: 135
|
||||||
* ncacn_ip_tcp: 135
|
* ncacn_ip_tcp: 135
|
||||||
* ncacn_np: \\pipe\epmapper (?)
|
* ncacn_np: \\pipe\epmapper
|
||||||
* ncalrpc: epmapper
|
* ncalrpc: epmapper
|
||||||
|
* ncacn_http: 593
|
||||||
*
|
*
|
||||||
* If the user's machine ran a DCE RPC daemon, it would
|
* If the user's machine ran a DCE RPC daemon, it would
|
||||||
* probably be possible to connect to it, but there are many
|
* probably be possible to connect to it, but there are many
|
||||||
|
@ -63,77 +62,222 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
* of running a fully functional DCOM server using Wine...
|
* of running a fully functional DCOM server using Wine...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const struct epm_endpoints
|
||||||
|
{
|
||||||
|
const char *protseq;
|
||||||
|
const char *endpoint;
|
||||||
|
} epm_endpoints[] =
|
||||||
|
{
|
||||||
|
{ "ncacn_np", "\\pipe\\epmapper" },
|
||||||
|
{ "ncacn_ip_tcp", "135" },
|
||||||
|
{ "ncacn_ip_udp", "135" },
|
||||||
|
{ "ncalrpc", "epmapper" },
|
||||||
|
{ "ncacn_http", "593" },
|
||||||
|
};
|
||||||
|
|
||||||
|
static BOOL start_rpcss(void)
|
||||||
|
{
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
STARTUPINFOW si;
|
||||||
|
static WCHAR cmd[6];
|
||||||
|
static const WCHAR rpcss[] = {'r','p','c','s','s',0};
|
||||||
|
BOOL rslt;
|
||||||
|
|
||||||
|
TRACE("\n");
|
||||||
|
|
||||||
|
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
|
||||||
|
ZeroMemory(&si, sizeof(STARTUPINFOA));
|
||||||
|
si.cb = sizeof(STARTUPINFOA);
|
||||||
|
|
||||||
|
memcpy(cmd, rpcss, sizeof(rpcss));
|
||||||
|
|
||||||
|
rslt = CreateProcessW(
|
||||||
|
NULL, /* executable */
|
||||||
|
cmd, /* command line */
|
||||||
|
NULL, /* process security attributes */
|
||||||
|
NULL, /* primary thread security attributes */
|
||||||
|
FALSE, /* inherit handles */
|
||||||
|
0, /* creation flags */
|
||||||
|
NULL, /* use parent's environment */
|
||||||
|
NULL, /* use parent's current directory */
|
||||||
|
&si, /* STARTUPINFO pointer */
|
||||||
|
&pi /* PROCESS_INFORMATION */
|
||||||
|
);
|
||||||
|
|
||||||
|
if (rslt)
|
||||||
|
{
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
Sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rslt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle)
|
||||||
|
{
|
||||||
|
RpcBinding *bind = (RpcBinding *)handle;
|
||||||
|
const char *protseq = bind->Protseq;
|
||||||
|
const char *network_addr = bind->NetworkAddr;
|
||||||
|
|
||||||
|
return ((!strcmp(protseq, "ncalrpc") && !network_addr) ||
|
||||||
|
(!strcmp(protseq, "ncacn_np") &&
|
||||||
|
(!network_addr || !strcmp(network_addr, "."))));
|
||||||
|
}
|
||||||
|
|
||||||
|
static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_HANDLE *epm_handle)
|
||||||
|
{
|
||||||
|
RpcBinding *bind = (RpcBinding *)handle;
|
||||||
|
const char * pszEndpoint = NULL;
|
||||||
|
RPC_STATUS status;
|
||||||
|
RpcBinding* epm_bind;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (bind->server)
|
||||||
|
return RPC_S_INVALID_BINDING;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(epm_endpoints)/sizeof(epm_endpoints[0]); i++)
|
||||||
|
if (!strcmp(bind->Protseq, epm_endpoints[i].protseq))
|
||||||
|
pszEndpoint = epm_endpoints[i].endpoint;
|
||||||
|
|
||||||
|
if (!pszEndpoint)
|
||||||
|
{
|
||||||
|
FIXME("no endpoint for the endpoint-mapper found for protseq %s\n", debugstr_a(bind->Protseq));
|
||||||
|
return RPC_S_PROTSEQ_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = RpcBindingCopy(handle, epm_handle);
|
||||||
|
if (status != RPC_S_OK) return status;
|
||||||
|
|
||||||
|
epm_bind = (RpcBinding*)*epm_handle;
|
||||||
|
if (epm_bind->AuthInfo)
|
||||||
|
{
|
||||||
|
/* don't bother with authenticating against the EPM by default
|
||||||
|
* (see EnableAuthEpResolution registry value) */
|
||||||
|
RpcAuthInfo_Release(epm_bind->AuthInfo);
|
||||||
|
epm_bind->AuthInfo = NULL;
|
||||||
|
}
|
||||||
|
RPCRT4_ResolveBinding(epm_bind, pszEndpoint);
|
||||||
|
TRACE("RPC_S_OK\n");
|
||||||
|
return RPC_S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RPC_STATUS get_epm_handle_server(RPC_BINDING_HANDLE *epm_handle)
|
||||||
|
{
|
||||||
|
unsigned char string_binding[] = "ncacn_np:.[\\\\pipe\\\\epmapper]";
|
||||||
|
|
||||||
|
return RpcBindingFromStringBindingA(string_binding, epm_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *__eptr)
|
||||||
|
{
|
||||||
|
switch (GetExceptionCode())
|
||||||
|
{
|
||||||
|
case EXCEPTION_ACCESS_VIOLATION:
|
||||||
|
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
default:
|
||||||
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* RpcEpRegisterA (RPCRT4.@)
|
* RpcEpRegisterA (RPCRT4.@)
|
||||||
*/
|
*/
|
||||||
RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
||||||
UUID_VECTOR *UuidVector, RPC_CSTR Annotation )
|
UUID_VECTOR *UuidVector, RPC_CSTR Annotation )
|
||||||
{
|
{
|
||||||
RPCSS_NP_MESSAGE msg;
|
|
||||||
RPCSS_NP_REPLY reply;
|
|
||||||
char *vardata_payload, *vp;
|
|
||||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||||
unsigned long c;
|
unsigned long i;
|
||||||
RPC_STATUS rslt = RPC_S_OK;
|
RPC_STATUS status = RPC_S_OK;
|
||||||
|
error_status_t status2;
|
||||||
|
ept_entry_t *entries;
|
||||||
|
handle_t handle;
|
||||||
|
|
||||||
TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation));
|
TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation));
|
||||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||||
for (c=0; c<BindingVector->Count; c++) {
|
for (i=0; i<BindingVector->Count; i++) {
|
||||||
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
|
||||||
TRACE(" protseq[%ld]=%s\n", c, debugstr_a(bind->Protseq));
|
TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq));
|
||||||
TRACE(" endpoint[%ld]=%s\n", c, debugstr_a(bind->Endpoint));
|
TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint));
|
||||||
}
|
}
|
||||||
if (UuidVector) {
|
if (UuidVector) {
|
||||||
for (c=0; c<UuidVector->Count; c++)
|
for (i=0; i<UuidVector->Count; i++)
|
||||||
TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c]));
|
TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Do something with annotation. */
|
if (!BindingVector->Count) return RPC_S_OK;
|
||||||
|
|
||||||
/* construct the message to rpcss */
|
entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*entries) * BindingVector->Count * (UuidVector ? UuidVector->Count : 1));
|
||||||
msg.message_type = RPCSS_NP_MESSAGE_TYPEID_REGISTEREPMSG;
|
if (!entries)
|
||||||
msg.message.registerepmsg.iface = If->InterfaceId;
|
return RPC_S_OUT_OF_MEMORY;
|
||||||
msg.message.registerepmsg.no_replace = 0;
|
|
||||||
|
|
||||||
msg.message.registerepmsg.object_count = (UuidVector) ? UuidVector->Count : 0;
|
status = get_epm_handle_server(&handle);
|
||||||
msg.message.registerepmsg.binding_count = BindingVector->Count;
|
if (status != RPC_S_OK)
|
||||||
|
{
|
||||||
/* calculate vardata payload size */
|
HeapFree(GetProcessHeap(), 0, entries);
|
||||||
msg.vardata_payload_size = msg.message.registerepmsg.object_count * sizeof(UUID);
|
return status;
|
||||||
for (c=0; c < msg.message.registerepmsg.binding_count; c++) {
|
|
||||||
RpcBinding *bind = (RpcBinding *)(BindingVector->BindingH[c]);
|
|
||||||
msg.vardata_payload_size += strlen(bind->Protseq) + 1;
|
|
||||||
msg.vardata_payload_size += strlen(bind->Endpoint) + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate the payload buffer */
|
for (i = 0; i < BindingVector->Count; i++)
|
||||||
vp = vardata_payload = LocalAlloc(LPTR, msg.vardata_payload_size);
|
{
|
||||||
if (!vardata_payload)
|
unsigned j;
|
||||||
return RPC_S_OUT_OF_MEMORY;
|
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
|
||||||
|
for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++)
|
||||||
|
{
|
||||||
|
int len = strlen((char *)Annotation);
|
||||||
|
status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax,
|
||||||
|
bind->Protseq, bind->Endpoint,
|
||||||
|
bind->NetworkAddr,
|
||||||
|
&entries[i*(UuidVector ? UuidVector->Count : 1) + j].tower);
|
||||||
|
if (status != RPC_S_OK) break;
|
||||||
|
|
||||||
/* populate the payload data */
|
if (UuidVector)
|
||||||
for (c=0; c < msg.message.registerepmsg.object_count; c++) {
|
memcpy(&entries[i * UuidVector->Count].object, &UuidVector->Uuid[j], sizeof(GUID));
|
||||||
CopyMemory(vp, UuidVector->Uuid[c], sizeof(UUID));
|
else
|
||||||
vp += sizeof(UUID);
|
memset(&entries[i].object, 0, sizeof(entries[i].object));
|
||||||
|
memcpy(entries[i].annotation, Annotation, min(len + 1, ept_max_annotation_size));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c=0; c < msg.message.registerepmsg.binding_count; c++) {
|
if (status == RPC_S_OK)
|
||||||
RpcBinding *bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
{
|
||||||
unsigned long pslen = strlen(bind->Protseq) + 1, eplen = strlen(bind->Endpoint) + 1;
|
while (TRUE)
|
||||||
CopyMemory(vp, bind->Protseq, pslen);
|
{
|
||||||
vp += pslen;
|
__TRY
|
||||||
CopyMemory(vp, bind->Endpoint, eplen);
|
{
|
||||||
vp += eplen;
|
ept_insert(handle, BindingVector->Count * (UuidVector ? UuidVector->Count : 1),
|
||||||
|
entries, TRUE, &status2);
|
||||||
|
}
|
||||||
|
__EXCEPT(rpc_filter)
|
||||||
|
{
|
||||||
|
status2 = GetExceptionCode();
|
||||||
|
}
|
||||||
|
__ENDTRY
|
||||||
|
if (status2 == RPC_S_SERVER_UNAVAILABLE &&
|
||||||
|
is_epm_destination_local(handle))
|
||||||
|
{
|
||||||
|
if (start_rpcss())
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (status2 != RPC_S_OK)
|
||||||
|
ERR("ept_insert failed with error %d\n", status2);
|
||||||
|
status = status2; /* FIXME: convert status? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RpcBindingFree(&handle);
|
||||||
|
|
||||||
|
for (i = 0; i < BindingVector->Count; i++)
|
||||||
|
{
|
||||||
|
unsigned j;
|
||||||
|
for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++)
|
||||||
|
I_RpcFree(entries[i*(UuidVector ? UuidVector->Count : 1) + j].tower);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send our request */
|
HeapFree(GetProcessHeap(), 0, entries);
|
||||||
if (!RPCRT4_RPCSSOnDemandCall(&msg, vardata_payload, &reply))
|
|
||||||
rslt = RPC_S_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
/* free the payload buffer */
|
return status;
|
||||||
LocalFree(vardata_payload);
|
|
||||||
|
|
||||||
return rslt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -142,68 +286,85 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind
|
||||||
RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector,
|
||||||
UUID_VECTOR *UuidVector )
|
UUID_VECTOR *UuidVector )
|
||||||
{
|
{
|
||||||
RPCSS_NP_MESSAGE msg;
|
|
||||||
RPCSS_NP_REPLY reply;
|
|
||||||
char *vardata_payload, *vp;
|
|
||||||
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
|
||||||
unsigned long c;
|
unsigned long i;
|
||||||
RPC_STATUS rslt = RPC_S_OK;
|
RPC_STATUS status = RPC_S_OK;
|
||||||
|
error_status_t status2;
|
||||||
|
ept_entry_t *entries;
|
||||||
|
handle_t handle;
|
||||||
|
|
||||||
TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector);
|
TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector);
|
||||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||||
for (c=0; c<BindingVector->Count; c++) {
|
for (i=0; i<BindingVector->Count; i++) {
|
||||||
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
|
||||||
TRACE(" protseq[%ld]=%s\n", c, debugstr_a(bind->Protseq));
|
TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq));
|
||||||
TRACE(" endpoint[%ld]=%s\n", c, debugstr_a(bind->Endpoint));
|
TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint));
|
||||||
}
|
}
|
||||||
if (UuidVector) {
|
if (UuidVector) {
|
||||||
for (c=0; c<UuidVector->Count; c++)
|
for (i=0; i<UuidVector->Count; i++)
|
||||||
TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c]));
|
TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* construct the message to rpcss */
|
entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*entries) * BindingVector->Count * (UuidVector ? UuidVector->Count : 1));
|
||||||
msg.message_type = RPCSS_NP_MESSAGE_TYPEID_UNREGISTEREPMSG;
|
if (!entries)
|
||||||
msg.message.unregisterepmsg.iface = If->InterfaceId;
|
return RPC_S_OUT_OF_MEMORY;
|
||||||
|
|
||||||
msg.message.unregisterepmsg.object_count = (UuidVector) ? UuidVector->Count : 0;
|
status = get_epm_handle_server(&handle);
|
||||||
msg.message.unregisterepmsg.binding_count = BindingVector->Count;
|
if (status != RPC_S_OK)
|
||||||
|
{
|
||||||
/* calculate vardata payload size */
|
HeapFree(GetProcessHeap(), 0, entries);
|
||||||
msg.vardata_payload_size = msg.message.unregisterepmsg.object_count * sizeof(UUID);
|
return status;
|
||||||
for (c=0; c < msg.message.unregisterepmsg.binding_count; c++) {
|
|
||||||
RpcBinding *bind = (RpcBinding *)(BindingVector->BindingH[c]);
|
|
||||||
msg.vardata_payload_size += strlen(bind->Protseq) + 1;
|
|
||||||
msg.vardata_payload_size += strlen(bind->Endpoint) + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate the payload buffer */
|
for (i = 0; i < BindingVector->Count; i++)
|
||||||
vp = vardata_payload = LocalAlloc(LPTR, msg.vardata_payload_size);
|
{
|
||||||
if (!vardata_payload)
|
unsigned j;
|
||||||
return RPC_S_OUT_OF_MEMORY;
|
RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]);
|
||||||
|
for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++)
|
||||||
|
{
|
||||||
|
status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax,
|
||||||
|
bind->Protseq, bind->Endpoint,
|
||||||
|
bind->NetworkAddr,
|
||||||
|
&entries[i*(UuidVector ? UuidVector->Count : 1) + j].tower);
|
||||||
|
if (status != RPC_S_OK) break;
|
||||||
|
|
||||||
/* populate the payload data */
|
if (UuidVector)
|
||||||
for (c=0; c < msg.message.unregisterepmsg.object_count; c++) {
|
memcpy(&entries[i * UuidVector->Count + j].object, &UuidVector->Uuid[j], sizeof(GUID));
|
||||||
CopyMemory(vp, UuidVector->Uuid[c], sizeof(UUID));
|
else
|
||||||
vp += sizeof(UUID);
|
memset(&entries[i].object, 0, sizeof(entries[i].object));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c=0; c < msg.message.unregisterepmsg.binding_count; c++) {
|
if (status == RPC_S_OK)
|
||||||
RpcBinding *bind = (RpcBinding*)(BindingVector->BindingH[c]);
|
{
|
||||||
unsigned long pslen = strlen(bind->Protseq) + 1, eplen = strlen(bind->Endpoint) + 1;
|
__TRY
|
||||||
CopyMemory(vp, bind->Protseq, pslen);
|
{
|
||||||
vp += pslen;
|
ept_insert(handle, BindingVector->Count * (UuidVector ? UuidVector->Count : 1),
|
||||||
CopyMemory(vp, bind->Endpoint, eplen);
|
entries, TRUE, &status2);
|
||||||
vp += eplen;
|
}
|
||||||
|
__EXCEPT(rpc_filter)
|
||||||
|
{
|
||||||
|
status2 = GetExceptionCode();
|
||||||
|
}
|
||||||
|
__ENDTRY
|
||||||
|
if (status2 == RPC_S_SERVER_UNAVAILABLE)
|
||||||
|
status2 = EPT_S_NOT_REGISTERED;
|
||||||
|
if (status2 != RPC_S_OK)
|
||||||
|
ERR("ept_insert failed with error %d\n", status2);
|
||||||
|
status = status2; /* FIXME: convert status? */
|
||||||
|
}
|
||||||
|
RpcBindingFree(&handle);
|
||||||
|
|
||||||
|
for (i = 0; i < BindingVector->Count; i++)
|
||||||
|
{
|
||||||
|
unsigned j;
|
||||||
|
for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++)
|
||||||
|
I_RpcFree(entries[i*(UuidVector ? UuidVector->Count : 1) + j].tower);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send our request */
|
HeapFree(GetProcessHeap(), 0, entries);
|
||||||
if (!RPCRT4_RPCSSOnDemandCall(&msg, vardata_payload, &reply))
|
|
||||||
rslt = RPC_S_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
/* free the payload buffer */
|
return status;
|
||||||
LocalFree(vardata_payload);
|
|
||||||
|
|
||||||
return rslt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -211,50 +372,96 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin
|
||||||
*/
|
*/
|
||||||
RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec )
|
RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec )
|
||||||
{
|
{
|
||||||
RPCSS_NP_MESSAGE msg;
|
|
||||||
RPCSS_NP_REPLY reply;
|
|
||||||
PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec;
|
PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec;
|
||||||
RpcBinding* bind = (RpcBinding*)Binding;
|
RpcBinding* bind = (RpcBinding*)Binding;
|
||||||
|
RPC_STATUS status;
|
||||||
|
error_status_t status2;
|
||||||
|
handle_t handle;
|
||||||
|
ept_lookup_handle_t entry_handle = NULL;
|
||||||
|
twr_t *tower;
|
||||||
|
twr_t *towers[4] = { NULL };
|
||||||
|
unsigned32 num_towers, i;
|
||||||
|
GUID uuid = GUID_NULL;
|
||||||
|
char *resolved_endpoint = NULL;
|
||||||
|
|
||||||
TRACE("(%p,%p)\n", Binding, IfSpec);
|
TRACE("(%p,%p)\n", Binding, IfSpec);
|
||||||
TRACE(" protseq=%s\n", debugstr_a(bind->Protseq));
|
TRACE(" protseq=%s\n", debugstr_a(bind->Protseq));
|
||||||
TRACE(" obj=%s\n", debugstr_guid(&bind->ObjectUuid));
|
TRACE(" obj=%s\n", debugstr_guid(&bind->ObjectUuid));
|
||||||
|
TRACE(" networkaddr=%s\n", debugstr_a(bind->NetworkAddr));
|
||||||
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID));
|
||||||
|
|
||||||
/* FIXME: totally untested */
|
|
||||||
|
|
||||||
/* just return for fully bound handles */
|
/* just return for fully bound handles */
|
||||||
if (bind->Endpoint && (bind->Endpoint[0] != '\0'))
|
if (bind->Endpoint && (bind->Endpoint[0] != '\0'))
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
|
|
||||||
/* construct the message to rpcss */
|
status = get_epm_handle_client(Binding, &handle);
|
||||||
msg.message_type = RPCSS_NP_MESSAGE_TYPEID_RESOLVEEPMSG;
|
if (status != RPC_S_OK) return status;
|
||||||
msg.message.resolveepmsg.iface = If->InterfaceId;
|
|
||||||
msg.message.resolveepmsg.object = bind->ObjectUuid;
|
|
||||||
|
|
||||||
msg.vardata_payload_size = strlen(bind->Protseq) + 1;
|
|
||||||
|
|
||||||
/* send the message */
|
|
||||||
if (!RPCRT4_RPCSSOnDemandCall(&msg, bind->Protseq, &reply))
|
|
||||||
return RPC_S_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
/* empty-string result means not registered */
|
|
||||||
if (reply.as_string[0] == '\0')
|
|
||||||
return EPT_S_NOT_REGISTERED;
|
|
||||||
|
|
||||||
/* otherwise we fully bind the handle & return RPC_S_OK */
|
status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax, bind->Protseq,
|
||||||
return RPCRT4_ResolveBinding(Binding, reply.as_string);
|
((RpcBinding *)handle)->Endpoint,
|
||||||
|
bind->NetworkAddr, &tower);
|
||||||
|
if (status != RPC_S_OK)
|
||||||
|
{
|
||||||
|
WARN("couldn't get tower\n");
|
||||||
|
RpcBindingFree(&handle);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
__TRY
|
||||||
|
{
|
||||||
|
ept_map(handle, &uuid, tower, &entry_handle, sizeof(towers)/sizeof(towers[0]), &num_towers, towers, &status2);
|
||||||
|
/* FIXME: translate status2? */
|
||||||
|
}
|
||||||
|
__EXCEPT(rpc_filter)
|
||||||
|
{
|
||||||
|
status2 = GetExceptionCode();
|
||||||
|
}
|
||||||
|
__ENDTRY
|
||||||
|
if (status2 == RPC_S_SERVER_UNAVAILABLE &&
|
||||||
|
is_epm_destination_local(handle))
|
||||||
|
{
|
||||||
|
if (start_rpcss())
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
RpcBindingFree(&handle);
|
||||||
|
I_RpcFree(tower);
|
||||||
|
|
||||||
|
if (status2 != RPC_S_OK)
|
||||||
|
{
|
||||||
|
ERR("ept_map failed for ifid %s, protseq %s, networkaddr %s\n", debugstr_guid(&If->TransferSyntax.SyntaxGUID), bind->Protseq, bind->NetworkAddr);
|
||||||
|
return status2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_towers; i++)
|
||||||
|
{
|
||||||
|
/* only parse the tower if we haven't already found a suitable
|
||||||
|
* endpoint, otherwise just free the tower */
|
||||||
|
if (!resolved_endpoint)
|
||||||
|
{
|
||||||
|
status = TowerExplode(towers[i], NULL, NULL, NULL, &resolved_endpoint, NULL);
|
||||||
|
TRACE("status = %ld\n", status);
|
||||||
|
}
|
||||||
|
I_RpcFree(towers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolved_endpoint)
|
||||||
|
{
|
||||||
|
RPCRT4_ResolveBinding(Binding, resolved_endpoint);
|
||||||
|
I_RpcFree(resolved_endpoint);
|
||||||
|
return RPC_S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN("couldn't find an endpoint\n");
|
||||||
|
return EPT_S_NOT_REGISTERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef unsigned int unsigned32;
|
/*****************************************************************************
|
||||||
typedef struct twr_t
|
* TowerExplode (RPCRT4.@)
|
||||||
{
|
|
||||||
unsigned32 tower_length;
|
|
||||||
/* [size_is] */ BYTE tower_octet_string[ 1 ];
|
|
||||||
} twr_t;
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* TowerExplode (RPCRT4.@)
|
|
||||||
*/
|
*/
|
||||||
RPC_STATUS WINAPI TowerExplode(
|
RPC_STATUS WINAPI TowerExplode(
|
||||||
const twr_t *tower, PRPC_SYNTAX_IDENTIFIER object, PRPC_SYNTAX_IDENTIFIER syntax,
|
const twr_t *tower, PRPC_SYNTAX_IDENTIFIER object, PRPC_SYNTAX_IDENTIFIER syntax,
|
||||||
|
@ -388,3 +595,13 @@ RPC_STATUS WINAPI TowerConstruct(
|
||||||
}
|
}
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t len)
|
||||||
|
{
|
||||||
|
return HeapAlloc(GetProcessHeap(), 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __RPC_USER MIDL_user_free(void __RPC_FAR * ptr)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, ptr);
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* RPC messages
|
* RPC messages
|
||||||
*
|
*
|
||||||
* Copyright 2001-2002 Ove Kåven, TransGaming Technologies
|
* Copyright 2001-2002 Ove Kåven, TransGaming Technologies
|
||||||
* Copyright 2004 Filip Navara
|
* Copyright 2004 Filip Navara
|
||||||
* Copyright 2006 CodeWeavers
|
* Copyright 2006 CodeWeavers
|
||||||
*
|
*
|
||||||
|
@ -1005,7 +1005,10 @@ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg)
|
||||||
TRACE("(%p)\n", pMsg);
|
TRACE("(%p)\n", pMsg);
|
||||||
|
|
||||||
if (!bind || bind->server)
|
if (!bind || bind->server)
|
||||||
|
{
|
||||||
|
ERR("no binding\n");
|
||||||
return RPC_S_INVALID_BINDING;
|
return RPC_S_INVALID_BINDING;
|
||||||
|
}
|
||||||
|
|
||||||
/* if we already have a connection, we don't need to negotiate again */
|
/* if we already have a connection, we don't need to negotiate again */
|
||||||
if (!pMsg->ReservedForRuntime)
|
if (!pMsg->ReservedForRuntime)
|
||||||
|
@ -1065,7 +1068,10 @@ RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
|
||||||
TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
|
TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
|
||||||
|
|
||||||
if (!bind)
|
if (!bind)
|
||||||
|
{
|
||||||
|
ERR("no binding\n");
|
||||||
return RPC_S_INVALID_BINDING;
|
return RPC_S_INVALID_BINDING;
|
||||||
|
}
|
||||||
|
|
||||||
pMsg->Buffer = I_RpcAllocate(pMsg->BufferLength);
|
pMsg->Buffer = I_RpcAllocate(pMsg->BufferLength);
|
||||||
TRACE("Buffer=%p\n", pMsg->Buffer);
|
TRACE("Buffer=%p\n", pMsg->Buffer);
|
||||||
|
@ -1118,7 +1124,11 @@ RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
|
||||||
|
|
||||||
TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer);
|
TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer);
|
||||||
|
|
||||||
if (!bind) return RPC_S_INVALID_BINDING;
|
if (!bind)
|
||||||
|
{
|
||||||
|
ERR("no binding\n");
|
||||||
|
return RPC_S_INVALID_BINDING;
|
||||||
|
}
|
||||||
|
|
||||||
if (pMsg->ReservedForRuntime)
|
if (pMsg->ReservedForRuntime)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#ifndef __WINE_RPC_MESSAGE_H
|
#ifndef __WINE_RPC_MESSAGE_H
|
||||||
#define __WINE_RPC_MESSAGE_H
|
#define __WINE_RPC_MESSAGE_H
|
||||||
|
|
||||||
#include "wine/rpcss_shared.h"
|
|
||||||
#include "rpc_defs.h"
|
#include "rpc_defs.h"
|
||||||
|
|
||||||
typedef unsigned int NCA_STATUS;
|
typedef unsigned int NCA_STATUS;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* RPC server API
|
* RPC server API
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
* Copyright 2004 Filip Navara
|
* Copyright 2004 Filip Navara
|
||||||
* Copyright 2006-2008 Robert Shearman (for CodeWeavers)
|
* Copyright 2006-2008 Robert Shearman (for CodeWeavers)
|
||||||
*
|
*
|
||||||
|
@ -138,29 +138,24 @@ static RpcServerInterface* RPCRT4_find_interface(UUID* object,
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&server_cs);
|
LeaveCriticalSection(&server_cs);
|
||||||
if (&cif->entry == &server_interfaces) cif = NULL;
|
if (&cif->entry == &server_interfaces) cif = NULL;
|
||||||
TRACE("returning %p for %s\n", cif, debugstr_guid(object));
|
TRACE("returning %p for object %s, if_id { %d.%d %s }\n", cif,
|
||||||
|
debugstr_guid(object), if_id->SyntaxVersion.MajorVersion,
|
||||||
|
if_id->SyntaxVersion.MinorVersion, debugstr_guid(&if_id->SyntaxGUID));
|
||||||
return cif;
|
return cif;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RPCRT4_release_server_interface(RpcServerInterface *sif)
|
static void RPCRT4_release_server_interface(RpcServerInterface *sif)
|
||||||
{
|
{
|
||||||
if (!InterlockedDecrement(&sif->CurrentCalls) &&
|
if (!InterlockedDecrement(&sif->CurrentCalls) &&
|
||||||
sif->CallsCompletedEvent) {
|
sif->Delete) {
|
||||||
/* sif must have been removed from server_interfaces before
|
/* sif must have been removed from server_interfaces before
|
||||||
* CallsCompletedEvent is set */
|
* CallsCompletedEvent is set */
|
||||||
SetEvent(sif->CallsCompletedEvent);
|
if (sif->CallsCompletedEvent)
|
||||||
|
SetEvent(sif->CallsCompletedEvent);
|
||||||
HeapFree(GetProcessHeap(), 0, sif);
|
HeapFree(GetProcessHeap(), 0, sif);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static WINE_EXCEPTION_FILTER(rpc_filter)
|
|
||||||
{
|
|
||||||
WARN("exception caught with code 0x%08x = %d\n", GetExceptionCode(), GetExceptionCode());
|
|
||||||
TRACE("returning failure packet\n");
|
|
||||||
/* catch every exception */
|
|
||||||
return EXCEPTION_EXECUTE_HANDLER;
|
|
||||||
}
|
|
||||||
|
|
||||||
static RPC_STATUS process_bind_packet(RpcConnection *conn, RpcPktBindHdr *hdr, RPC_MESSAGE *msg)
|
static RPC_STATUS process_bind_packet(RpcConnection *conn, RpcPktBindHdr *hdr, RPC_MESSAGE *msg)
|
||||||
{
|
{
|
||||||
RPC_STATUS status;
|
RPC_STATUS status;
|
||||||
|
@ -294,7 +289,8 @@ static RPC_STATUS process_request_packet(RpcConnection *conn, RpcPktRequestHdr *
|
||||||
RPCRT4_SetThreadCurrentCallHandle(msg->Handle);
|
RPCRT4_SetThreadCurrentCallHandle(msg->Handle);
|
||||||
__TRY {
|
__TRY {
|
||||||
if (func) func(msg);
|
if (func) func(msg);
|
||||||
} __EXCEPT(rpc_filter) {
|
} __EXCEPT_ALL {
|
||||||
|
WARN("exception caught with code 0x%08x = %d\n", GetExceptionCode(), GetExceptionCode());
|
||||||
exception = TRUE;
|
exception = TRUE;
|
||||||
if (GetExceptionCode() == STATUS_ACCESS_VIOLATION)
|
if (GetExceptionCode() == STATUS_ACCESS_VIOLATION)
|
||||||
status = ERROR_NOACCESS;
|
status = ERROR_NOACCESS;
|
||||||
|
@ -356,7 +352,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
I_RpcFreeBuffer(msg);
|
I_RpcFree(msg->Buffer);
|
||||||
RPCRT4_FreeHeader(hdr);
|
RPCRT4_FreeHeader(hdr);
|
||||||
HeapFree(GetProcessHeap(), 0, msg);
|
HeapFree(GetProcessHeap(), 0, msg);
|
||||||
}
|
}
|
||||||
|
@ -392,6 +388,7 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
|
||||||
packet = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcPacket));
|
packet = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcPacket));
|
||||||
if (!packet) {
|
if (!packet) {
|
||||||
I_RpcFree(msg->Buffer);
|
I_RpcFree(msg->Buffer);
|
||||||
|
RPCRT4_FreeHeader(hdr);
|
||||||
HeapFree(GetProcessHeap(), 0, msg);
|
HeapFree(GetProcessHeap(), 0, msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -401,6 +398,7 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
|
||||||
if (!QueueUserWorkItem(RPCRT4_worker_thread, packet, WT_EXECUTELONGFUNCTION)) {
|
if (!QueueUserWorkItem(RPCRT4_worker_thread, packet, WT_EXECUTELONGFUNCTION)) {
|
||||||
ERR("couldn't queue work item for worker thread, error was %d\n", GetLastError());
|
ERR("couldn't queue work item for worker thread, error was %d\n", GetLastError());
|
||||||
I_RpcFree(msg->Buffer);
|
I_RpcFree(msg->Buffer);
|
||||||
|
RPCRT4_FreeHeader(hdr);
|
||||||
HeapFree(GetProcessHeap(), 0, msg);
|
HeapFree(GetProcessHeap(), 0, msg);
|
||||||
HeapFree(GetProcessHeap(), 0, packet);
|
HeapFree(GetProcessHeap(), 0, packet);
|
||||||
break;
|
break;
|
||||||
|
@ -852,7 +850,7 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid,
|
||||||
sif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerInterface));
|
sif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerInterface));
|
||||||
sif->If = If;
|
sif->If = If;
|
||||||
if (MgrTypeUuid) {
|
if (MgrTypeUuid) {
|
||||||
memcpy(&sif->MgrTypeUuid, MgrTypeUuid, sizeof(UUID));
|
sif->MgrTypeUuid = *MgrTypeUuid;
|
||||||
sif->MgrEpv = MgrEpv;
|
sif->MgrEpv = MgrEpv;
|
||||||
} else {
|
} else {
|
||||||
memset(&sif->MgrTypeUuid, 0, sizeof(UUID));
|
memset(&sif->MgrTypeUuid, 0, sizeof(UUID));
|
||||||
|
@ -893,8 +891,10 @@ RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid
|
||||||
if ((!IfSpec || !memcmp(&If->InterfaceId, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER))) &&
|
if ((!IfSpec || !memcmp(&If->InterfaceId, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER))) &&
|
||||||
UuidEqual(MgrTypeUuid, &cif->MgrTypeUuid, &status)) {
|
UuidEqual(MgrTypeUuid, &cif->MgrTypeUuid, &status)) {
|
||||||
list_remove(&cif->entry);
|
list_remove(&cif->entry);
|
||||||
|
TRACE("unregistering cif %p\n", cif);
|
||||||
if (cif->CurrentCalls) {
|
if (cif->CurrentCalls) {
|
||||||
completed = FALSE;
|
completed = FALSE;
|
||||||
|
cif->Delete = TRUE;
|
||||||
if (WaitForCallsToComplete)
|
if (WaitForCallsToComplete)
|
||||||
cif->CallsCompletedEvent = event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
cif->CallsCompletedEvent = event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
}
|
}
|
||||||
|
@ -984,8 +984,8 @@ RPC_STATUS WINAPI RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid )
|
||||||
return RPC_S_ALREADY_REGISTERED;
|
return RPC_S_ALREADY_REGISTERED;
|
||||||
/* ... otherwise create a new one and add it in. */
|
/* ... otherwise create a new one and add it in. */
|
||||||
map = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcObjTypeMap));
|
map = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcObjTypeMap));
|
||||||
memcpy(&map->Object, ObjUuid, sizeof(UUID));
|
map->Object = *ObjUuid;
|
||||||
memcpy(&map->Type, TypeUuid, sizeof(UUID));
|
map->Type = *TypeUuid;
|
||||||
map->next = NULL;
|
map->next = NULL;
|
||||||
if (prev)
|
if (prev)
|
||||||
prev->next = map; /* prev is the last map in the linklist */
|
prev->next = map; /* prev is the last map in the linklist */
|
||||||
|
@ -1050,13 +1050,11 @@ RPC_STATUS WINAPI RpcMgmtWaitServerListen( void )
|
||||||
LeaveCriticalSection(&listen_cs);
|
LeaveCriticalSection(&listen_cs);
|
||||||
return RPC_S_NOT_LISTENING;
|
return RPC_S_NOT_LISTENING;
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
LeaveCriticalSection(&listen_cs);
|
|
||||||
|
|
||||||
|
do {
|
||||||
|
LeaveCriticalSection(&listen_cs);
|
||||||
LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
|
LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
|
||||||
WaitForSingleObject(cps->server_ready_event, INFINITE);
|
WaitForSingleObject(cps->server_ready_event, INFINITE);
|
||||||
|
|
||||||
EnterCriticalSection(&listen_cs);
|
EnterCriticalSection(&listen_cs);
|
||||||
} while (!std_listen);
|
} while (!std_listen);
|
||||||
|
@ -1131,6 +1129,40 @@ RPC_STATUS WINAPI RpcMgmtInqIfIds(RPC_BINDING_HANDLE Binding, RPC_IF_ID_VECTOR *
|
||||||
return RPC_S_INVALID_BINDING;
|
return RPC_S_INVALID_BINDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RpcMgmtInqStats (RPCRT4.@)
|
||||||
|
*/
|
||||||
|
RPC_STATUS WINAPI RpcMgmtInqStats(RPC_BINDING_HANDLE Binding, RPC_STATS_VECTOR **Statistics)
|
||||||
|
{
|
||||||
|
RPC_STATS_VECTOR *stats;
|
||||||
|
|
||||||
|
FIXME("(%p,%p)\n", Binding, Statistics);
|
||||||
|
|
||||||
|
if ((stats = HeapAlloc(GetProcessHeap(), 0, sizeof(RPC_STATS_VECTOR))))
|
||||||
|
{
|
||||||
|
stats->Count = 1;
|
||||||
|
stats->Stats[0] = 0;
|
||||||
|
*Statistics = stats;
|
||||||
|
return RPC_S_OK;
|
||||||
|
}
|
||||||
|
return RPC_S_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RpcMgmtStatsVectorFree (RPCRT4.@)
|
||||||
|
*/
|
||||||
|
RPC_STATUS WINAPI RpcMgmtStatsVectorFree(RPC_STATS_VECTOR **StatsVector)
|
||||||
|
{
|
||||||
|
FIXME("(%p)\n", StatsVector);
|
||||||
|
|
||||||
|
if (StatsVector)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, *StatsVector);
|
||||||
|
*StatsVector = NULL;
|
||||||
|
}
|
||||||
|
return RPC_S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* RpcMgmtEpEltInqBegin (RPCRT4.@)
|
* RpcMgmtEpEltInqBegin (RPCRT4.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* RPC server API
|
* RPC server API
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -73,6 +73,7 @@ typedef struct _RpcServerInterface
|
||||||
/* set when unregistering interface to let the caller of
|
/* set when unregistering interface to let the caller of
|
||||||
* RpcServerUnregisterIf* know that all calls have finished */
|
* RpcServerUnregisterIf* know that all calls have finished */
|
||||||
HANDLE CallsCompletedEvent;
|
HANDLE CallsCompletedEvent;
|
||||||
|
BOOL Delete; /* delete when the last call finishes */
|
||||||
} RpcServerInterface;
|
} RpcServerInterface;
|
||||||
|
|
||||||
void RPCRT4_new_client(RpcConnection* conn);
|
void RPCRT4_new_client(RpcConnection* conn);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* RPC transport layer
|
* RPC transport layer
|
||||||
*
|
*
|
||||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||||
* Copyright 2003 Mike Hearn
|
* Copyright 2003 Mike Hearn
|
||||||
* Copyright 2004 Filip Navara
|
* Copyright 2004 Filip Navara
|
||||||
* Copyright 2006 Mike McCormack
|
* Copyright 2006 Mike McCormack
|
||||||
|
@ -29,32 +29,43 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
# include <sys/socket.h>
|
#if defined(__MINGW32__) || defined (_MSC_VER)
|
||||||
#endif
|
# include <ws2tcpip.h>
|
||||||
#ifdef HAVE_NETINET_IN_H
|
# ifndef EADDRINUSE
|
||||||
# include <netinet/in.h>
|
# define EADDRINUSE WSAEADDRINUSE
|
||||||
#endif
|
# endif
|
||||||
#ifdef HAVE_NETINET_TCP_H
|
# ifndef EAGAIN
|
||||||
# include <netinet/tcp.h>
|
# define EAGAIN WSAEWOULDBLOCK
|
||||||
#endif
|
# endif
|
||||||
#ifdef HAVE_ARPA_INET_H
|
#else
|
||||||
# include <arpa/inet.h>
|
# include <errno.h>
|
||||||
#endif
|
# ifdef HAVE_UNISTD_H
|
||||||
#ifdef HAVE_NETDB_H
|
# include <unistd.h>
|
||||||
#include <netdb.h>
|
# endif
|
||||||
#endif
|
# include <fcntl.h>
|
||||||
#ifdef HAVE_SYS_POLL_H
|
# ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/poll.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
# endif
|
||||||
|
# ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_NETINET_TCP_H
|
||||||
|
# include <netinet/tcp.h>
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_ARPA_INET_H
|
||||||
|
# include <arpa/inet.h>
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_NETDB_H
|
||||||
|
# include <netdb.h>
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_SYS_POLL_H
|
||||||
|
# include <sys/poll.h>
|
||||||
|
# endif
|
||||||
|
# define closesocket close
|
||||||
|
#endif /* defined(__MINGW32__) || defined (_MSC_VER) */
|
||||||
|
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
@ -112,20 +123,29 @@ static RPC_STATUS rpcrt4_conn_listen_pipe(RpcConnection_np *npc)
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
|
|
||||||
npc->listening = TRUE;
|
npc->listening = TRUE;
|
||||||
if (ConnectNamedPipe(npc->pipe, &npc->ovl[0]))
|
for (;;)
|
||||||
return RPC_S_OK;
|
{
|
||||||
|
if (ConnectNamedPipe(npc->pipe, &npc->ovl[0]))
|
||||||
|
return RPC_S_OK;
|
||||||
|
|
||||||
if (GetLastError() == ERROR_PIPE_CONNECTED) {
|
switch(GetLastError())
|
||||||
SetEvent(npc->ovl[0].hEvent);
|
{
|
||||||
return RPC_S_OK;
|
case ERROR_PIPE_CONNECTED:
|
||||||
|
SetEvent(npc->ovl[0].hEvent);
|
||||||
|
return RPC_S_OK;
|
||||||
|
case ERROR_IO_PENDING:
|
||||||
|
/* will be completed in rpcrt4_protseq_np_wait_for_new_connection */
|
||||||
|
return RPC_S_OK;
|
||||||
|
case ERROR_NO_DATA_DETECTED:
|
||||||
|
/* client has disconnected, retry */
|
||||||
|
DisconnectNamedPipe( npc->pipe );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
npc->listening = FALSE;
|
||||||
|
WARN("Couldn't ConnectNamedPipe (error was %d)\n", GetLastError());
|
||||||
|
return RPC_S_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (GetLastError() == ERROR_IO_PENDING) {
|
|
||||||
/* will be completed in rpcrt4_protseq_np_wait_for_new_connection */
|
|
||||||
return RPC_S_OK;
|
|
||||||
}
|
|
||||||
npc->listening = FALSE;
|
|
||||||
WARN("Couldn't ConnectNamedPipe (error was %d)\n", GetLastError());
|
|
||||||
return RPC_S_OUT_OF_RESOURCES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static RPC_STATUS rpcrt4_conn_create_pipe(RpcConnection *Connection, LPCSTR pname)
|
static RPC_STATUS rpcrt4_conn_create_pipe(RpcConnection *Connection, LPCSTR pname)
|
||||||
|
@ -196,9 +216,7 @@ static RPC_STATUS rpcrt4_conn_open_pipe(RpcConnection *Connection, LPCSTR pname,
|
||||||
TRACE("connection failed, error=%x\n", err);
|
TRACE("connection failed, error=%x\n", err);
|
||||||
return RPC_S_SERVER_TOO_BUSY;
|
return RPC_S_SERVER_TOO_BUSY;
|
||||||
}
|
}
|
||||||
if (!wait)
|
if (!wait || !WaitNamedPipeA(pname, NMPWAIT_WAIT_FOREVER)) {
|
||||||
return RPC_S_SERVER_UNAVAILABLE;
|
|
||||||
if (!WaitNamedPipeA(pname, NMPWAIT_WAIT_FOREVER)) {
|
|
||||||
err = GetLastError();
|
err = GetLastError();
|
||||||
WARN("connection failed, error=%x\n", err);
|
WARN("connection failed, error=%x\n", err);
|
||||||
return RPC_S_SERVER_UNAVAILABLE;
|
return RPC_S_SERVER_UNAVAILABLE;
|
||||||
|
@ -212,7 +230,6 @@ static RPC_STATUS rpcrt4_conn_open_pipe(RpcConnection *Connection, LPCSTR pname,
|
||||||
SetNamedPipeHandleState(pipe, &dwMode, NULL, NULL);
|
SetNamedPipeHandleState(pipe, &dwMode, NULL, NULL);
|
||||||
npc->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
npc->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
npc->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
npc->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
|
|
||||||
npc->pipe = pipe;
|
npc->pipe = pipe;
|
||||||
|
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
|
@ -375,7 +392,7 @@ static int rpcrt4_conn_np_read(RpcConnection *Connection,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ret = GetOverlappedResult(npc->pipe, &npc->ovl[0], &bytes_read, TRUE);
|
ret = GetOverlappedResult(npc->pipe, &npc->ovl[0], &bytes_read, TRUE);
|
||||||
if (!ret && GetLastError() != ERROR_MORE_DATA)
|
if (!ret && (GetLastError() != ERROR_MORE_DATA))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
bytes_left -= bytes_read;
|
bytes_left -= bytes_read;
|
||||||
|
@ -395,12 +412,12 @@ static int rpcrt4_conn_np_write(RpcConnection *Connection,
|
||||||
while (bytes_left)
|
while (bytes_left)
|
||||||
{
|
{
|
||||||
DWORD bytes_written;
|
DWORD bytes_written;
|
||||||
ret = WriteFile(npc->pipe, buf, count, &bytes_written, &npc->ovl[1]);
|
ret = WriteFile(npc->pipe, buf, bytes_left, &bytes_written, &npc->ovl[1]);
|
||||||
if ((!ret || !bytes_written) && (GetLastError() != ERROR_IO_PENDING))
|
if ((!ret || !bytes_written) && (GetLastError() != ERROR_IO_PENDING))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ret = GetOverlappedResult(npc->pipe, &npc->ovl[1], &bytes_written, TRUE);
|
ret = GetOverlappedResult(npc->pipe, &npc->ovl[1], &bytes_written, TRUE);
|
||||||
if (!ret && GetLastError() != ERROR_MORE_DATA)
|
if (!ret && (GetLastError() != ERROR_MORE_DATA))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
bytes_left -= bytes_written;
|
bytes_left -= bytes_written;
|
||||||
|
@ -425,7 +442,6 @@ static int rpcrt4_conn_np_close(RpcConnection *Connection)
|
||||||
CloseHandle(npc->ovl[1].hEvent);
|
CloseHandle(npc->ovl[1].hEvent);
|
||||||
npc->ovl[1].hEvent = 0;
|
npc->ovl[1].hEvent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +524,8 @@ static RPC_STATUS rpcrt4_ncacn_np_parse_top_of_tower(const unsigned char *tower_
|
||||||
|
|
||||||
if ((smb_floor->count_lhs != sizeof(smb_floor->protid)) ||
|
if ((smb_floor->count_lhs != sizeof(smb_floor->protid)) ||
|
||||||
(smb_floor->protid != EPM_PROTOCOL_SMB) ||
|
(smb_floor->protid != EPM_PROTOCOL_SMB) ||
|
||||||
(smb_floor->count_rhs > tower_size))
|
(smb_floor->count_rhs > tower_size) ||
|
||||||
|
(tower_data[smb_floor->count_rhs - 1] != '\0'))
|
||||||
return EPT_S_NOT_REGISTERED;
|
return EPT_S_NOT_REGISTERED;
|
||||||
|
|
||||||
if (endpoint)
|
if (endpoint)
|
||||||
|
@ -531,7 +548,8 @@ static RPC_STATUS rpcrt4_ncacn_np_parse_top_of_tower(const unsigned char *tower_
|
||||||
|
|
||||||
if ((nb_floor->count_lhs != sizeof(nb_floor->protid)) ||
|
if ((nb_floor->count_lhs != sizeof(nb_floor->protid)) ||
|
||||||
(nb_floor->protid != EPM_PROTOCOL_NETBIOS) ||
|
(nb_floor->protid != EPM_PROTOCOL_NETBIOS) ||
|
||||||
(nb_floor->count_rhs > tower_size))
|
(nb_floor->count_rhs > tower_size) ||
|
||||||
|
(tower_data[nb_floor->count_rhs - 1] != '\0'))
|
||||||
return EPT_S_NOT_REGISTERED;
|
return EPT_S_NOT_REGISTERED;
|
||||||
|
|
||||||
if (networkaddr)
|
if (networkaddr)
|
||||||
|
@ -681,7 +699,7 @@ static size_t rpcrt4_ncalrpc_get_top_of_tower(unsigned char *tower_data,
|
||||||
|
|
||||||
TRACE("(%p, %s, %s)\n", tower_data, networkaddr, endpoint);
|
TRACE("(%p, %s, %s)\n", tower_data, networkaddr, endpoint);
|
||||||
|
|
||||||
endpoint_size = strlen(networkaddr) + 1;
|
endpoint_size = strlen(endpoint) + 1;
|
||||||
size = sizeof(*pipe_floor) + endpoint_size;
|
size = sizeof(*pipe_floor) + endpoint_size;
|
||||||
|
|
||||||
if (!tower_data)
|
if (!tower_data)
|
||||||
|
@ -692,7 +710,7 @@ static size_t rpcrt4_ncalrpc_get_top_of_tower(unsigned char *tower_data,
|
||||||
tower_data += sizeof(*pipe_floor);
|
tower_data += sizeof(*pipe_floor);
|
||||||
|
|
||||||
pipe_floor->count_lhs = sizeof(pipe_floor->protid);
|
pipe_floor->count_lhs = sizeof(pipe_floor->protid);
|
||||||
pipe_floor->protid = EPM_PROTOCOL_SMB;
|
pipe_floor->protid = EPM_PROTOCOL_PIPE;
|
||||||
pipe_floor->count_rhs = endpoint_size;
|
pipe_floor->count_rhs = endpoint_size;
|
||||||
|
|
||||||
memcpy(tower_data, endpoint, endpoint_size);
|
memcpy(tower_data, endpoint, endpoint_size);
|
||||||
|
@ -710,9 +728,6 @@ static RPC_STATUS rpcrt4_ncalrpc_parse_top_of_tower(const unsigned char *tower_d
|
||||||
|
|
||||||
TRACE("(%p, %d, %p, %p)\n", tower_data, (int)tower_size, networkaddr, endpoint);
|
TRACE("(%p, %d, %p, %p)\n", tower_data, (int)tower_size, networkaddr, endpoint);
|
||||||
|
|
||||||
*networkaddr = NULL;
|
|
||||||
*endpoint = NULL;
|
|
||||||
|
|
||||||
if (tower_size < sizeof(*pipe_floor))
|
if (tower_size < sizeof(*pipe_floor))
|
||||||
return EPT_S_NOT_REGISTERED;
|
return EPT_S_NOT_REGISTERED;
|
||||||
|
|
||||||
|
@ -720,10 +735,14 @@ static RPC_STATUS rpcrt4_ncalrpc_parse_top_of_tower(const unsigned char *tower_d
|
||||||
tower_size -= sizeof(*pipe_floor);
|
tower_size -= sizeof(*pipe_floor);
|
||||||
|
|
||||||
if ((pipe_floor->count_lhs != sizeof(pipe_floor->protid)) ||
|
if ((pipe_floor->count_lhs != sizeof(pipe_floor->protid)) ||
|
||||||
(pipe_floor->protid != EPM_PROTOCOL_SMB) ||
|
(pipe_floor->protid != EPM_PROTOCOL_PIPE) ||
|
||||||
(pipe_floor->count_rhs > tower_size))
|
(pipe_floor->count_rhs > tower_size) ||
|
||||||
|
(tower_data[pipe_floor->count_rhs - 1] != '\0'))
|
||||||
return EPT_S_NOT_REGISTERED;
|
return EPT_S_NOT_REGISTERED;
|
||||||
|
|
||||||
|
if (networkaddr)
|
||||||
|
*networkaddr = NULL;
|
||||||
|
|
||||||
if (endpoint)
|
if (endpoint)
|
||||||
{
|
{
|
||||||
*endpoint = I_RpcAllocate(pipe_floor->count_rhs);
|
*endpoint = I_RpcAllocate(pipe_floor->count_rhs);
|
||||||
|
@ -751,14 +770,12 @@ static RpcConnection *rpcrt4_conn_tcp_alloc(void)
|
||||||
if (tcpc == NULL)
|
if (tcpc == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
tcpc->sock = -1;
|
tcpc->sock = -1;
|
||||||
#ifndef __REACTOS__
|
|
||||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0)
|
if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0)
|
||||||
{
|
{
|
||||||
ERR("socketpair() failed: %s\n", strerror(errno));
|
ERR("socketpair() failed: %s\n", strerror(errno));
|
||||||
HeapFree(GetProcessHeap(), 0, tcpc);
|
HeapFree(GetProcessHeap(), 0, tcpc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return &tcpc->common;
|
return &tcpc->common;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,13 +834,14 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection)
|
||||||
if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen))
|
if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen))
|
||||||
{
|
{
|
||||||
WARN("connect() failed: %s\n", strerror(errno));
|
WARN("connect() failed: %s\n", strerror(errno));
|
||||||
close(sock);
|
closesocket(sock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RPC depends on having minimal latency so disable the Nagle algorithm */
|
/* RPC depends on having minimal latency so disable the Nagle algorithm */
|
||||||
val = 1;
|
val = 1;
|
||||||
setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
setsockopt(sock, SOL_TCP, TCP_NODELAY, &val, sizeof(val));
|
||||||
|
fcntl(sock, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
|
||||||
|
|
||||||
tcpc->sock = sock;
|
tcpc->sock = sock;
|
||||||
|
|
||||||
|
@ -845,7 +863,6 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
|
||||||
struct addrinfo *ai;
|
struct addrinfo *ai;
|
||||||
struct addrinfo *ai_cur;
|
struct addrinfo *ai_cur;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
u_long blocking;
|
|
||||||
RpcConnection *first_connection = NULL;
|
RpcConnection *first_connection = NULL;
|
||||||
|
|
||||||
TRACE("(%p, %s)\n", protseq, endpoint);
|
TRACE("(%p, %s)\n", protseq, endpoint);
|
||||||
|
@ -896,8 +913,8 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
WARN("bind failed: %s\n", strerror(errno));
|
WARN("bind failed: %s\n", strerror(errno));
|
||||||
close(sock);
|
closesocket(sock);
|
||||||
if (errno == WSAEADDRINUSE)
|
if (errno == EADDRINUSE)
|
||||||
status = RPC_S_DUPLICATE_ENDPOINT;
|
status = RPC_S_DUPLICATE_ENDPOINT;
|
||||||
else
|
else
|
||||||
status = RPC_S_CANT_CREATE_ENDPOINT;
|
status = RPC_S_CANT_CREATE_ENDPOINT;
|
||||||
|
@ -908,7 +925,7 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
|
||||||
endpoint, NULL, NULL, NULL);
|
endpoint, NULL, NULL, NULL);
|
||||||
if (create_status != RPC_S_OK)
|
if (create_status != RPC_S_OK)
|
||||||
{
|
{
|
||||||
close(sock);
|
closesocket(sock);
|
||||||
status = create_status;
|
status = create_status;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -926,8 +943,7 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
|
||||||
* race-condition (poll() says it is readable, connection drops,
|
* race-condition (poll() says it is readable, connection drops,
|
||||||
* and accept() blocks until the next connection comes...)
|
* and accept() blocks until the next connection comes...)
|
||||||
*/
|
*/
|
||||||
blocking = 1;
|
ret = fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||||
ret = ioctlsocket(sock, FIONBIO, &blocking);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
WARN("couldn't make socket non-blocking, error %d\n", ret);
|
WARN("couldn't make socket non-blocking, error %d\n", ret);
|
||||||
|
@ -970,7 +986,6 @@ static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection
|
||||||
int ret;
|
int ret;
|
||||||
struct sockaddr_in address;
|
struct sockaddr_in address;
|
||||||
socklen_t addrsize;
|
socklen_t addrsize;
|
||||||
u_long blocking;
|
|
||||||
RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn;
|
RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn;
|
||||||
RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn;
|
RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn;
|
||||||
|
|
||||||
|
@ -982,8 +997,7 @@ static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection
|
||||||
return RPC_S_OUT_OF_RESOURCES;
|
return RPC_S_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
/* reset to blocking behaviour */
|
/* reset to blocking behaviour */
|
||||||
blocking = 0;
|
fcntl(ret, F_SETFL, 0);
|
||||||
ret = ioctlsocket(ret, FIONBIO, &blocking);
|
|
||||||
client->sock = ret;
|
client->sock = ret;
|
||||||
TRACE("Accepted a new TCP connection\n");
|
TRACE("Accepted a new TCP connection\n");
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
|
@ -1065,7 +1079,7 @@ static int rpcrt4_conn_tcp_close(RpcConnection *Connection)
|
||||||
TRACE("%d\n", tcpc->sock);
|
TRACE("%d\n", tcpc->sock);
|
||||||
|
|
||||||
if (tcpc->sock != -1)
|
if (tcpc->sock != -1)
|
||||||
close(tcpc->sock);
|
closesocket(tcpc->sock);
|
||||||
tcpc->sock = -1;
|
tcpc->sock = -1;
|
||||||
close(tcpc->cancel_fds[0]);
|
close(tcpc->cancel_fds[0]);
|
||||||
close(tcpc->cancel_fds[1]);
|
close(tcpc->cancel_fds[1]);
|
||||||
|
@ -1256,12 +1270,10 @@ static RpcServerProtseq *rpcrt4_protseq_sock_alloc(void)
|
||||||
if (ps)
|
if (ps)
|
||||||
{
|
{
|
||||||
int fds[2];
|
int fds[2];
|
||||||
u_long blocking;
|
|
||||||
if (!socketpair(PF_UNIX, SOCK_DGRAM, 0, fds))
|
if (!socketpair(PF_UNIX, SOCK_DGRAM, 0, fds))
|
||||||
{
|
{
|
||||||
blocking = 1;
|
fcntl(fds[0], F_SETFL, O_NONBLOCK);
|
||||||
ioctlsocket(fds[0], FIONBIO, &blocking);
|
fcntl(fds[1], F_SETFL, O_NONBLOCK);
|
||||||
ioctlsocket(fds[1], FIONBIO, &blocking);
|
|
||||||
ps->mgr_event_rcv = fds[0];
|
ps->mgr_event_rcv = fds[0];
|
||||||
ps->mgr_event_snd = fds[1];
|
ps->mgr_event_snd = fds[1];
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<define name="MSWMSG" />
|
<define name="MSWMSG" />
|
||||||
<library>wine</library>
|
<library>wine</library>
|
||||||
<library>uuid</library>
|
<library>uuid</library>
|
||||||
|
<library>rpcrt4_epm_client</library>
|
||||||
<library>kernel32</library>
|
<library>kernel32</library>
|
||||||
<library>user32</library>
|
<library>user32</library>
|
||||||
<library>advapi32</library>
|
<library>advapi32</library>
|
||||||
|
@ -33,9 +34,16 @@
|
||||||
<file>rpc_server.c</file>
|
<file>rpc_server.c</file>
|
||||||
<file>rpc_transport.c</file>
|
<file>rpc_transport.c</file>
|
||||||
<file>rpcrt4_main.c</file>
|
<file>rpcrt4_main.c</file>
|
||||||
<file>rpcss_np_client.c</file>
|
|
||||||
<file>unix_func.c</file>
|
<file>unix_func.c</file>
|
||||||
<file>ndr_es.c</file>
|
<file>ndr_es.c</file>
|
||||||
<file>rpcrt4.rc</file>
|
<file>rpcrt4.rc</file>
|
||||||
|
<file>epm.idl</file>
|
||||||
|
<include base="rpcrt4" root="intermediate">.</include>
|
||||||
<file>rpcrt4.spec</file>
|
<file>rpcrt4.spec</file>
|
||||||
</module>
|
</module>
|
||||||
|
<module name="rpcrt4_epm_server" type="rpcserver">
|
||||||
|
<file>epm.idl</file>
|
||||||
|
</module>
|
||||||
|
<module name="rpcrt4_epm_client" type="rpcclient">
|
||||||
|
<file>epm.idl</file>
|
||||||
|
</module>
|
||||||
|
|
|
@ -99,7 +99,7 @@
|
||||||
@ stub MesBufferHandleReset
|
@ stub MesBufferHandleReset
|
||||||
@ stdcall MesDecodeBufferHandleCreate(ptr long ptr)
|
@ stdcall MesDecodeBufferHandleCreate(ptr long ptr)
|
||||||
@ stdcall MesDecodeIncrementalHandleCreate(ptr ptr ptr)
|
@ stdcall MesDecodeIncrementalHandleCreate(ptr ptr ptr)
|
||||||
@ stub MesEncodeDynBufferHandleCreate
|
@ stdcall MesEncodeDynBufferHandleCreate(ptr ptr ptr)
|
||||||
@ stdcall MesEncodeFixedBufferHandleCreate(ptr long ptr ptr)
|
@ stdcall MesEncodeFixedBufferHandleCreate(ptr long ptr ptr)
|
||||||
@ stdcall MesEncodeIncrementalHandleCreate(ptr ptr ptr ptr)
|
@ stdcall MesEncodeIncrementalHandleCreate(ptr ptr ptr ptr)
|
||||||
@ stdcall MesHandleFree(ptr)
|
@ stdcall MesHandleFree(ptr)
|
||||||
|
@ -363,7 +363,7 @@
|
||||||
@ stdcall RpcBindingVectorFree(ptr)
|
@ stdcall RpcBindingVectorFree(ptr)
|
||||||
@ stdcall RpcCancelAsyncCall(ptr long) RpcAsyncCancelCall
|
@ stdcall RpcCancelAsyncCall(ptr long) RpcAsyncCancelCall
|
||||||
@ stdcall RpcCancelThread(ptr)
|
@ stdcall RpcCancelThread(ptr)
|
||||||
@ stub RpcCancelThreadEx
|
@ stdcall RpcCancelThreadEx(ptr long)
|
||||||
@ stub RpcCertGeneratePrincipalNameA
|
@ stub RpcCertGeneratePrincipalNameA
|
||||||
@ stub RpcCertGeneratePrincipalNameW
|
@ stub RpcCertGeneratePrincipalNameW
|
||||||
@ stdcall RpcCompleteAsyncCall(ptr ptr) RpcAsyncCompleteCall
|
@ stdcall RpcCompleteAsyncCall(ptr ptr) RpcAsyncCompleteCall
|
||||||
|
@ -399,13 +399,13 @@
|
||||||
@ stdcall RpcMgmtInqIfIds(ptr ptr)
|
@ stdcall RpcMgmtInqIfIds(ptr ptr)
|
||||||
@ stub RpcMgmtInqServerPrincNameA
|
@ stub RpcMgmtInqServerPrincNameA
|
||||||
@ stub RpcMgmtInqServerPrincNameW
|
@ stub RpcMgmtInqServerPrincNameW
|
||||||
@ stub RpcMgmtInqStats
|
@ stdcall RpcMgmtInqStats(ptr ptr)
|
||||||
@ stdcall RpcMgmtIsServerListening(ptr)
|
@ stdcall RpcMgmtIsServerListening(ptr)
|
||||||
@ stub RpcMgmtSetAuthorizationFn
|
@ stub RpcMgmtSetAuthorizationFn
|
||||||
@ stdcall RpcMgmtSetCancelTimeout(long)
|
@ stdcall RpcMgmtSetCancelTimeout(long)
|
||||||
@ stdcall RpcMgmtSetComTimeout(ptr long)
|
@ stdcall RpcMgmtSetComTimeout(ptr long)
|
||||||
@ stdcall RpcMgmtSetServerStackSize(long)
|
@ stdcall RpcMgmtSetServerStackSize(long)
|
||||||
@ stub RpcMgmtStatsVectorFree
|
@ stdcall RpcMgmtStatsVectorFree(ptr)
|
||||||
@ stdcall RpcMgmtStopServerListening(ptr)
|
@ stdcall RpcMgmtStopServerListening(ptr)
|
||||||
@ stdcall RpcMgmtWaitServerListen()
|
@ stdcall RpcMgmtWaitServerListen()
|
||||||
@ stub RpcNetworkInqProtseqsA
|
@ stub RpcNetworkInqProtseqsA
|
||||||
|
|
|
@ -53,19 +53,12 @@
|
||||||
#include "rpcproxy.h"
|
#include "rpcproxy.h"
|
||||||
|
|
||||||
#include "rpc_binding.h"
|
#include "rpc_binding.h"
|
||||||
#include "rpcss_np_client.h"
|
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||||
|
|
||||||
static UUID uuid_nil;
|
static UUID uuid_nil;
|
||||||
static HANDLE master_mutex;
|
|
||||||
|
|
||||||
HANDLE RPCRT4_GetMasterMutex(void)
|
|
||||||
{
|
|
||||||
return master_mutex;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CRITICAL_SECTION uuid_cs;
|
static CRITICAL_SECTION uuid_cs;
|
||||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||||
|
@ -122,9 +115,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
|
|
||||||
switch (fdwReason) {
|
switch (fdwReason) {
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
master_mutex = CreateMutexA( NULL, FALSE, RPCSS_MASTER_MUTEX_NAME);
|
|
||||||
if (!master_mutex)
|
|
||||||
ERR("Failed to create master mutex\n");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
|
@ -145,8 +135,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
CloseHandle(master_mutex);
|
|
||||||
master_mutex = NULL;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +253,7 @@ int WINAPI UuidEqual(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status)
|
||||||
*
|
*
|
||||||
* PARAMS
|
* PARAMS
|
||||||
* UUID *Uuid [I] Uuid to compare
|
* UUID *Uuid [I] Uuid to compare
|
||||||
* RPC_STATUS *Status [O] retuns RPC_S_OK
|
* RPC_STATUS *Status [O] returns RPC_S_OK
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* TRUE/FALSE
|
* TRUE/FALSE
|
||||||
|
@ -645,102 +633,6 @@ HRESULT WINAPI DllRegisterServer( void )
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL RPCRT4_StartRPCSS(void)
|
|
||||||
{
|
|
||||||
PROCESS_INFORMATION pi;
|
|
||||||
STARTUPINFOA si;
|
|
||||||
static char cmd[6];
|
|
||||||
BOOL rslt;
|
|
||||||
|
|
||||||
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
|
|
||||||
ZeroMemory(&si, sizeof(STARTUPINFOA));
|
|
||||||
si.cb = sizeof(STARTUPINFOA);
|
|
||||||
|
|
||||||
/* apparently it's not OK to use a constant string below */
|
|
||||||
CopyMemory(cmd, "rpcss", 6);
|
|
||||||
|
|
||||||
/* FIXME: will this do the right thing when run as a test? */
|
|
||||||
rslt = CreateProcessA(
|
|
||||||
NULL, /* executable */
|
|
||||||
cmd, /* command line */
|
|
||||||
NULL, /* process security attributes */
|
|
||||||
NULL, /* primary thread security attributes */
|
|
||||||
FALSE, /* inherit handles */
|
|
||||||
0, /* creation flags */
|
|
||||||
NULL, /* use parent's environment */
|
|
||||||
NULL, /* use parent's current directory */
|
|
||||||
&si, /* STARTUPINFO pointer */
|
|
||||||
&pi /* PROCESS_INFORMATION */
|
|
||||||
);
|
|
||||||
|
|
||||||
if (rslt) {
|
|
||||||
CloseHandle(pi.hProcess);
|
|
||||||
CloseHandle(pi.hThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rslt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* RPCRT4_RPCSSOnDemandCall (internal)
|
|
||||||
*
|
|
||||||
* Attempts to send a message to the RPCSS process
|
|
||||||
* on the local machine, invoking it if necessary.
|
|
||||||
* For remote RPCSS calls, use.... your imagination.
|
|
||||||
*
|
|
||||||
* PARAMS
|
|
||||||
* msg [I] pointer to the RPCSS message
|
|
||||||
* vardata_payload [I] pointer vardata portion of the RPCSS message
|
|
||||||
* reply [O] pointer to reply structure
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
* TRUE if successful
|
|
||||||
* FALSE otherwise
|
|
||||||
*/
|
|
||||||
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) {
|
|
||||||
/* start the RPCSS process */
|
|
||||||
if (!RPCRT4_StartRPCSS()) {
|
|
||||||
ERR("Unable to start RPCSS process.\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* wait for a connection (w/ periodic polling) */
|
|
||||||
for (i = 0; i < 60; i++) {
|
|
||||||
Sleep(200);
|
|
||||||
client_handle = RPCRT4_RpcssNPConnect();
|
|
||||||
if (INVALID_HANDLE_VALUE != client_handle) break;
|
|
||||||
}
|
|
||||||
/* we are only willing to try twice */
|
|
||||||
if (j++ >= 1) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (INVALID_HANDLE_VALUE == client_handle) {
|
|
||||||
/* no dice! */
|
|
||||||
ERR("Unable to connect to RPCSS process!\n");
|
|
||||||
SetLastError(RPC_E_SERVER_DIED_DNE);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
CloseHandle(client_handle);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_RPC_ERROR_TEXT 256
|
#define MAX_RPC_ERROR_TEXT 256
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -1076,20 +968,10 @@ NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void)
|
||||||
return context_handle;
|
return context_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
static RPC_STATUS rpc_cancel_thread(DWORD target_tid)
|
||||||
* RpcCancelThread (rpcrt4.@)
|
|
||||||
*/
|
|
||||||
RPC_STATUS RPC_ENTRY RpcCancelThread(void* ThreadHandle)
|
|
||||||
{
|
{
|
||||||
DWORD target_tid;
|
|
||||||
struct threaddata *tdata;
|
struct threaddata *tdata;
|
||||||
|
|
||||||
TRACE("(%p)\n", ThreadHandle);
|
|
||||||
|
|
||||||
target_tid = GetThreadId(ThreadHandle);
|
|
||||||
if (!target_tid)
|
|
||||||
return RPC_S_INVALID_ARG;
|
|
||||||
|
|
||||||
EnterCriticalSection(&threaddata_cs);
|
EnterCriticalSection(&threaddata_cs);
|
||||||
LIST_FOR_EACH_ENTRY(tdata, &threaddata_list, struct threaddata, entry)
|
LIST_FOR_EACH_ENTRY(tdata, &threaddata_list, struct threaddata, entry)
|
||||||
if (tdata->thread_id == target_tid)
|
if (tdata->thread_id == target_tid)
|
||||||
|
@ -1103,3 +985,34 @@ RPC_STATUS RPC_ENTRY RpcCancelThread(void* ThreadHandle)
|
||||||
|
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* RpcCancelThread (rpcrt4.@)
|
||||||
|
*/
|
||||||
|
RPC_STATUS RPC_ENTRY RpcCancelThread(void* ThreadHandle)
|
||||||
|
{
|
||||||
|
TRACE("(%p)\n", ThreadHandle);
|
||||||
|
return RpcCancelThreadEx(ThreadHandle, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* RpcCancelThreadEx (rpcrt4.@)
|
||||||
|
*/
|
||||||
|
RPC_STATUS RPC_ENTRY RpcCancelThreadEx(void* ThreadHandle, LONG Timeout)
|
||||||
|
{
|
||||||
|
DWORD target_tid;
|
||||||
|
|
||||||
|
FIXME("(%p, %d)\n", ThreadHandle, Timeout);
|
||||||
|
|
||||||
|
target_tid = GetThreadId(ThreadHandle);
|
||||||
|
if (!target_tid)
|
||||||
|
return RPC_S_INVALID_ARG;
|
||||||
|
|
||||||
|
if (Timeout)
|
||||||
|
{
|
||||||
|
FIXME("(%p, %d)\n", ThreadHandle, Timeout);
|
||||||
|
return RPC_S_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return rpc_cancel_thread(target_tid);
|
||||||
|
}
|
||||||
|
|
|
@ -1,152 +0,0 @@
|
||||||
/*
|
|
||||||
* RPCSS named pipe client implementation
|
|
||||||
*
|
|
||||||
* Copyright (C) 2002 Greg Turner
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#include "windef.h"
|
|
||||||
#include "winbase.h"
|
|
||||||
#include "wine/rpcss_shared.h"
|
|
||||||
#include "wine/debug.h"
|
|
||||||
|
|
||||||
#include "rpc_binding.h"
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|
||||||
|
|
||||||
HANDLE RPCRT4_RpcssNPConnect(void)
|
|
||||||
{
|
|
||||||
HANDLE the_pipe;
|
|
||||||
DWORD dwmode, wait_result;
|
|
||||||
HANDLE master_mutex = RPCRT4_GetMasterMutex();
|
|
||||||
|
|
||||||
TRACE("\n");
|
|
||||||
|
|
||||||
while (TRUE) {
|
|
||||||
|
|
||||||
wait_result = WaitForSingleObject(master_mutex, MASTER_MUTEX_TIMEOUT);
|
|
||||||
switch (wait_result) {
|
|
||||||
case WAIT_ABANDONED:
|
|
||||||
case WAIT_OBJECT_0:
|
|
||||||
break;
|
|
||||||
case WAIT_FAILED:
|
|
||||||
case WAIT_TIMEOUT:
|
|
||||||
default:
|
|
||||||
ERR("This should never happen: couldn't enter mutex.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* try to open the client side of the named pipe. */
|
|
||||||
the_pipe = CreateFileA(
|
|
||||||
NAME_RPCSS_NAMED_PIPE, /* pipe name */
|
|
||||||
GENERIC_READ | GENERIC_WRITE, /* r/w access */
|
|
||||||
0, /* no sharing */
|
|
||||||
NULL, /* no security attributes */
|
|
||||||
OPEN_EXISTING, /* open an existing pipe */
|
|
||||||
0, /* default attributes */
|
|
||||||
NULL /* no template file */
|
|
||||||
);
|
|
||||||
|
|
||||||
if (the_pipe != INVALID_HANDLE_VALUE)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (GetLastError() != ERROR_PIPE_BUSY) {
|
|
||||||
WARN("Unable to open named pipe %s (assuming unavailable).\n",
|
|
||||||
debugstr_a(NAME_RPCSS_NAMED_PIPE));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN("Named pipe busy (will wait)\n");
|
|
||||||
|
|
||||||
if (!ReleaseMutex(master_mutex))
|
|
||||||
ERR("Failed to release master mutex. Expect deadlock.\n");
|
|
||||||
|
|
||||||
/* wait for the named pipe. We are only willing to wait for 5 seconds.
|
|
||||||
It should be available /very/ soon. */
|
|
||||||
if (! WaitNamedPipeA(NAME_RPCSS_NAMED_PIPE, MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT))
|
|
||||||
{
|
|
||||||
ERR("Named pipe unavailable after waiting. Something is probably wrong.\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (the_pipe != INVALID_HANDLE_VALUE) {
|
|
||||||
dwmode = PIPE_READMODE_MESSAGE;
|
|
||||||
/* SetNamedPipeHandleState not implemented ATM, but still seems to work somehow. */
|
|
||||||
if (! SetNamedPipeHandleState(the_pipe, &dwmode, NULL, NULL))
|
|
||||||
WARN("Failed to set pipe handle state\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ReleaseMutex(master_mutex))
|
|
||||||
ERR("Uh oh, failed to leave the RPC Master Mutex!\n");
|
|
||||||
|
|
||||||
return the_pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL RPCRT4_SendReceiveNPMsg(HANDLE np, PRPCSS_NP_MESSAGE msg, char *vardata, PRPCSS_NP_REPLY reply)
|
|
||||||
{
|
|
||||||
DWORD count;
|
|
||||||
UINT32 payload_offset;
|
|
||||||
RPCSS_NP_MESSAGE vardata_payload_msg;
|
|
||||||
|
|
||||||
TRACE("(np == %p, msg == %p, vardata == %p, reply == %p)\n",
|
|
||||||
np, msg, vardata, reply);
|
|
||||||
|
|
||||||
if (! WriteFile(np, msg, sizeof(RPCSS_NP_MESSAGE), &count, NULL)) {
|
|
||||||
ERR("write failed.\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count != sizeof(RPCSS_NP_MESSAGE)) {
|
|
||||||
ERR("write count mismatch.\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* process the vardata payload if necessary */
|
|
||||||
vardata_payload_msg.message_type = RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG;
|
|
||||||
vardata_payload_msg.vardata_payload_size = 0; /* meaningless */
|
|
||||||
for ( payload_offset = 0; payload_offset < msg->vardata_payload_size;
|
|
||||||
payload_offset += VARDATA_PAYLOAD_BYTES ) {
|
|
||||||
TRACE("sending vardata payload. vd=%p, po=%d, ps=%d\n", vardata,
|
|
||||||
payload_offset, msg->vardata_payload_size);
|
|
||||||
ZeroMemory(vardata_payload_msg.message.vardatapayloadmsg.payload, VARDATA_PAYLOAD_BYTES);
|
|
||||||
CopyMemory(vardata_payload_msg.message.vardatapayloadmsg.payload,
|
|
||||||
vardata,
|
|
||||||
min( VARDATA_PAYLOAD_BYTES, msg->vardata_payload_size - payload_offset ));
|
|
||||||
vardata += VARDATA_PAYLOAD_BYTES;
|
|
||||||
if (! WriteFile(np, &vardata_payload_msg, sizeof(RPCSS_NP_MESSAGE), &count, NULL)) {
|
|
||||||
ERR("vardata write failed at %u bytes.\n", payload_offset);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! ReadFile(np, reply, sizeof(RPCSS_NP_REPLY), &count, NULL)) {
|
|
||||||
ERR("read failed.\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count != sizeof(RPCSS_NP_REPLY)) {
|
|
||||||
ERR("read count mismatch. got %d.\n", count);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* message execution was successful */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
|
@ -167,3 +167,11 @@ inet_ntop (int af,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fcntl(int fd,
|
||||||
|
int cmd,
|
||||||
|
long arg)
|
||||||
|
{
|
||||||
|
// Stub
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,15 @@ struct pollfd
|
||||||
short revents; /* returned events */
|
short revents; /* returned events */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define F_SETFL 4 /* set file->f_flags */
|
||||||
|
|
||||||
|
#ifndef O_NONBLOCK
|
||||||
|
#define O_NONBLOCK 00004000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EINTR 4 /* Interrupted system call */
|
||||||
|
|
||||||
int poll(struct pollfd *fds, unsigned long nfds, int timo);
|
int poll(struct pollfd *fds, unsigned long nfds, int timo);
|
||||||
int socketpair (int af, int type, int protocol, SOCKET socket[2]);
|
int socketpair (int af, int type, int protocol, SOCKET socket[2]);
|
||||||
const char * inet_ntop (int af, const void *src, char *dst, size_t cnt);
|
const char * inet_ntop (int af, const void *src, char *dst, size_t cnt);
|
||||||
|
int fcntl(int fd, int cmd, long arg);
|
||||||
|
|
|
@ -79,6 +79,12 @@ typedef struct
|
||||||
RPC_IF_ID *IfId[1];
|
RPC_IF_ID *IfId[1];
|
||||||
} RPC_IF_ID_VECTOR;
|
} RPC_IF_ID_VECTOR;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int Count;
|
||||||
|
unsigned long Stats[1];
|
||||||
|
} RPC_STATS_VECTOR;
|
||||||
|
|
||||||
typedef I_RPC_HANDLE *RPC_EP_INQ_HANDLE;
|
typedef I_RPC_HANDLE *RPC_EP_INQ_HANDLE;
|
||||||
|
|
||||||
#define RPC_C_EP_ALL_ELTS 0
|
#define RPC_C_EP_ALL_ELTS 0
|
||||||
|
|
|
@ -115,6 +115,12 @@ typedef unsigned char boolean;
|
||||||
#define NdrFcLong(s) (unsigned char)(s & 0xff), (unsigned char)((s & 0x0000ff00) >> 8), \
|
#define NdrFcLong(s) (unsigned char)(s & 0xff), (unsigned char)((s & 0x0000ff00) >> 8), \
|
||||||
(unsigned char)((s & 0x00ff0000) >> 16), (unsigned char)(s >> 24)
|
(unsigned char)((s & 0x00ff0000) >> 16), (unsigned char)(s >> 24)
|
||||||
|
|
||||||
|
#define RPC_BAD_STUB_DATA_EXCEPTION_FILTER \
|
||||||
|
((RpcExceptionCode() == STATUS_ACCESS_VIOLATION) || \
|
||||||
|
(RpcExceptionCode() == STATUS_DATATYPE_MISALIGNMENT) || \
|
||||||
|
(RpcExceptionCode() == RPC_X_BAD_STUB_DATA) || \
|
||||||
|
(RpcExceptionCode() == RPC_S_INVALID_BOUND))
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
void *pad[2];
|
void *pad[2];
|
||||||
|
@ -189,7 +195,7 @@ typedef struct _MIDL_STUB_MESSAGE
|
||||||
ULONG_PTR MaxCount;
|
ULONG_PTR MaxCount;
|
||||||
ULONG Offset;
|
ULONG Offset;
|
||||||
ULONG ActualCount;
|
ULONG ActualCount;
|
||||||
void * (__RPC_API *pfnAllocate)(size_t);
|
void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(size_t);
|
||||||
void (__RPC_API *pfnFree)(void *);
|
void (__RPC_API *pfnFree)(void *);
|
||||||
unsigned char *StackTop;
|
unsigned char *StackTop;
|
||||||
unsigned char *pPresentedType;
|
unsigned char *pPresentedType;
|
||||||
|
@ -316,7 +322,7 @@ typedef struct _USER_MARSHAL_CB
|
||||||
|
|
||||||
typedef struct _MALLOC_FREE_STRUCT
|
typedef struct _MALLOC_FREE_STRUCT
|
||||||
{
|
{
|
||||||
void * (__RPC_USER *pfnAllocate)(size_t);
|
void * (__WINE_ALLOC_SIZE(1) __RPC_USER *pfnAllocate)(size_t);
|
||||||
void (__RPC_USER *pfnFree)(void *);
|
void (__RPC_USER *pfnFree)(void *);
|
||||||
} MALLOC_FREE_STRUCT;
|
} MALLOC_FREE_STRUCT;
|
||||||
|
|
||||||
|
@ -329,7 +335,7 @@ typedef struct _COMM_FAULT_OFFSETS
|
||||||
typedef struct _MIDL_STUB_DESC
|
typedef struct _MIDL_STUB_DESC
|
||||||
{
|
{
|
||||||
void *RpcInterfaceInformation;
|
void *RpcInterfaceInformation;
|
||||||
void * (__RPC_API *pfnAllocate)(size_t);
|
void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(size_t);
|
||||||
void (__RPC_API *pfnFree)(void *);
|
void (__RPC_API *pfnFree)(void *);
|
||||||
union {
|
union {
|
||||||
handle_t *pAutoHandle;
|
handle_t *pAutoHandle;
|
||||||
|
@ -468,7 +474,7 @@ typedef struct _NDR_USER_MARSHAL_INFO_LEVEL1
|
||||||
{
|
{
|
||||||
void *Buffer;
|
void *Buffer;
|
||||||
ULONG BufferSize;
|
ULONG BufferSize;
|
||||||
void * (__RPC_API *pfnAllocate)(size_t);
|
void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(size_t);
|
||||||
void (__RPC_API *pfnFree)(void *);
|
void (__RPC_API *pfnFree)(void *);
|
||||||
struct IRpcChannelBuffer *pRpcChannelBuffer;
|
struct IRpcChannelBuffer *pRpcChannelBuffer;
|
||||||
ULONG_PTR Reserved[5];
|
ULONG_PTR Reserved[5];
|
||||||
|
@ -652,7 +658,7 @@ RPCRTAPI LONG RPC_ENTRY
|
||||||
NdrDcomAsyncStubCall( struct IRpcStubBuffer* pThis, struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase );
|
NdrDcomAsyncStubCall( struct IRpcStubBuffer* pThis, struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase );
|
||||||
|
|
||||||
RPCRTAPI void* RPC_ENTRY
|
RPCRTAPI void* RPC_ENTRY
|
||||||
NdrAllocate( PMIDL_STUB_MESSAGE pStubMsg, size_t Len );
|
NdrAllocate( PMIDL_STUB_MESSAGE pStubMsg, SIZE_T Len ) __WINE_ALLOC_SIZE(2);
|
||||||
|
|
||||||
RPCRTAPI void RPC_ENTRY
|
RPCRTAPI void RPC_ENTRY
|
||||||
NdrClearOutParameters( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, void *ArgAddr );
|
NdrClearOutParameters( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, void *ArgAddr );
|
||||||
|
@ -662,7 +668,7 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
|
||||||
ULONG *pFaultStatus, RPC_STATUS Status_ );
|
ULONG *pFaultStatus, RPC_STATUS Status_ );
|
||||||
|
|
||||||
RPCRTAPI void* RPC_ENTRY
|
RPCRTAPI void* RPC_ENTRY
|
||||||
NdrOleAllocate( size_t Size );
|
NdrOleAllocate( size_t Size ) __WINE_ALLOC_SIZE(1);
|
||||||
RPCRTAPI void RPC_ENTRY
|
RPCRTAPI void RPC_ENTRY
|
||||||
NdrOleFree( void* NodeToFree );
|
NdrOleFree( void* NodeToFree );
|
||||||
|
|
||||||
|
@ -723,11 +729,11 @@ RPCRTAPI void RPC_ENTRY
|
||||||
RPCRTAPI void RPC_ENTRY
|
RPCRTAPI void RPC_ENTRY
|
||||||
NdrRpcSmSetClientToOsf( PMIDL_STUB_MESSAGE pMessage );
|
NdrRpcSmSetClientToOsf( PMIDL_STUB_MESSAGE pMessage );
|
||||||
RPCRTAPI void * RPC_ENTRY
|
RPCRTAPI void * RPC_ENTRY
|
||||||
NdrRpcSmClientAllocate( size_t Size );
|
NdrRpcSmClientAllocate( size_t Size ) __WINE_ALLOC_SIZE(1);
|
||||||
RPCRTAPI void RPC_ENTRY
|
RPCRTAPI void RPC_ENTRY
|
||||||
NdrRpcSmClientFree( void *NodeToFree );
|
NdrRpcSmClientFree( void *NodeToFree );
|
||||||
RPCRTAPI void * RPC_ENTRY
|
RPCRTAPI void * RPC_ENTRY
|
||||||
NdrRpcSsDefaultAllocate( size_t Size );
|
NdrRpcSsDefaultAllocate( size_t Size ) __WINE_ALLOC_SIZE(1);
|
||||||
RPCRTAPI void RPC_ENTRY
|
RPCRTAPI void RPC_ENTRY
|
||||||
NdrRpcSsDefaultFree( void *NodeToFree );
|
NdrRpcSsDefaultFree( void *NodeToFree );
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,12 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
|
||||||
|
#define __WINE_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
|
||||||
|
#else
|
||||||
|
#define __WINE_ALLOC_SIZE(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FORCEINLINE
|
#ifndef FORCEINLINE
|
||||||
#if (_MSC_VER >= 1200)
|
#if (_MSC_VER >= 1200)
|
||||||
#define FORCEINLINE __forceinline
|
#define FORCEINLINE __forceinline
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue