mirror of
https://github.com/reactos/reactos.git
synced 2025-04-18 19:47:14 +00:00
- Update rpcrt4 to Wine-20080105, so it corresponds to the WIDL. Local changes applied.
svn path=/trunk/; revision=31631
This commit is contained in:
parent
07dce281aa
commit
ecdee48d72
26 changed files with 12518 additions and 11057 deletions
|
@ -16,7 +16,7 @@
|
|||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*
|
||||
* TODO: Handle non-i386 architectures
|
||||
*/
|
||||
|
||||
|
@ -173,7 +173,7 @@ HRESULT WINAPI StdProxy_Construct(REFIID riid,
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
This->PVtbl = vtbl->Vtbl;
|
||||
|
||||
This->lpVtbl = &StdProxy_Vtbl;
|
||||
|
|
|
@ -41,7 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|||
|
||||
static WINE_EXCEPTION_FILTER(stub_filter)
|
||||
{
|
||||
if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
|
||||
if (GetExceptionInformation()->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
@ -109,13 +109,15 @@ static CRITICAL_SECTION delegating_vtbl_section = { &critsect_debug, -1, 0, 0, 0
|
|||
typedef struct
|
||||
{
|
||||
DWORD ref;
|
||||
DWORD size;
|
||||
void **methods;
|
||||
IUnknownVtbl vtbl;
|
||||
/* remaining entries in vtbl */
|
||||
} ref_counted_vtbl;
|
||||
|
||||
static struct
|
||||
{
|
||||
ref_counted_vtbl *table;
|
||||
DWORD size;
|
||||
} current_vtbl;
|
||||
|
||||
|
||||
|
@ -156,7 +158,7 @@ typedef struct {
|
|||
} vtbl_method_t;
|
||||
#include "poppack.h"
|
||||
|
||||
static void fill_table(IUnknownVtbl *vtbl, DWORD num)
|
||||
static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num)
|
||||
{
|
||||
vtbl_method_t *method;
|
||||
void **entry;
|
||||
|
@ -166,7 +168,7 @@ static void fill_table(IUnknownVtbl *vtbl, DWORD num)
|
|||
vtbl->AddRef = delegating_AddRef;
|
||||
vtbl->Release = delegating_Release;
|
||||
|
||||
method = (vtbl_method_t*)((void **)vtbl + num);
|
||||
method = (vtbl_method_t*)methods;
|
||||
entry = (void**)(vtbl + 1);
|
||||
|
||||
for(i = 3; i < num; i++)
|
||||
|
@ -209,19 +211,25 @@ void create_delegating_vtbl(DWORD num_methods)
|
|||
}
|
||||
|
||||
EnterCriticalSection(&delegating_vtbl_section);
|
||||
if(num_methods > current_vtbl.size)
|
||||
if(!current_vtbl.table || num_methods > current_vtbl.table->size)
|
||||
{
|
||||
DWORD size;
|
||||
DWORD old_protect;
|
||||
if(current_vtbl.table && current_vtbl.table->ref == 0)
|
||||
{
|
||||
TRACE("freeing old table\n");
|
||||
VirtualFree(current_vtbl.table->methods,
|
||||
(current_vtbl.table->size - 3) * sizeof(vtbl_method_t),
|
||||
MEM_RELEASE);
|
||||
HeapFree(GetProcessHeap(), 0, current_vtbl.table);
|
||||
}
|
||||
size = sizeof(DWORD) + num_methods * sizeof(void*) + (num_methods - 3) * sizeof(vtbl_method_t);
|
||||
current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
fill_table(¤t_vtbl.table->vtbl, num_methods);
|
||||
size = (num_methods - 3) * sizeof(vtbl_method_t);
|
||||
current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*));
|
||||
current_vtbl.table->ref = 0;
|
||||
current_vtbl.size = num_methods;
|
||||
current_vtbl.table->size = num_methods;
|
||||
current_vtbl.table->methods = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
fill_table(¤t_vtbl.table->vtbl, current_vtbl.table->methods, num_methods);
|
||||
VirtualProtect(current_vtbl.table->methods, size, PAGE_EXECUTE_READ, &old_protect);
|
||||
}
|
||||
LeaveCriticalSection(&delegating_vtbl_section);
|
||||
}
|
||||
|
@ -247,6 +255,9 @@ static void release_delegating_vtbl(IUnknownVtbl *vtbl)
|
|||
if(table->ref == 0 && table != current_vtbl.table)
|
||||
{
|
||||
TRACE("... and we're not current so free'ing\n");
|
||||
VirtualFree(current_vtbl.table->methods,
|
||||
(current_vtbl.table->size - 3) * sizeof(vtbl_method_t),
|
||||
MEM_RELEASE);
|
||||
HeapFree(GetProcessHeap(), 0, table);
|
||||
}
|
||||
LeaveCriticalSection(&delegating_vtbl_section);
|
||||
|
@ -558,6 +569,9 @@ void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg,
|
|||
TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer);
|
||||
NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor);
|
||||
pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
|
||||
IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
|
||||
&pStubMsg->dwDestContext,
|
||||
&pStubMsg->pvDestContext);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -581,7 +595,5 @@ void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER iface,
|
|||
return;
|
||||
}
|
||||
|
||||
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart;
|
||||
pStubMsg->Buffer = pStubMsg->RpcMsg->Buffer;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#define EPM_PROTOCOL_DSP 0x16 /* AppleTalk Data Stream Protocol */
|
||||
#define EPM_PROTOCOL_DDP 0x17 /* AppleTalk Data Datagram Protocol */
|
||||
#define EPM_PROTOCOL_APPLETALK 0x18 /* AppleTalk */
|
||||
#define EPM_PROTOCOL_VINES_SPP 0x1a
|
||||
#define EPM_PROTOCOL_VINES_SPP 0x1a
|
||||
#define EPM_PROTOCOL_VINES_IPC 0x1b /* Inter Process Communication */
|
||||
#define EPM_PROTOCOL_STREETTALK 0x1c /* Vines Streettalk */
|
||||
#define EPM_PROTOCOL_HTTP 0x1f
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
/*
|
||||
* NCA Status definitions
|
||||
*
|
||||
* Copyright 2007 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define NCA_S_COMM_FAILURE 0x1C010001
|
||||
#define NCA_S_OP_RNG_ERROR 0x1C010002
|
||||
#define NCA_S_UNK_IF 0x1C010003
|
||||
#define NCA_S_WRONG_BOOT_TIME 0x1C010006
|
||||
#define NCA_S_YOU_CRASHED 0x1C010009
|
||||
#define NCA_S_PROTO_ERROR 0x1C01000B
|
||||
#define NCA_S_OUT_ARGS_TOO_BIG 0x1C010013
|
||||
#define NCA_S_SERVER_TOO_BUSY 0x1C010014
|
||||
#define NCA_S_FAULT_STRING_TOO_LONG 0x1C010015
|
||||
#define NCA_S_UNSUPPORTED_TYPE 0x1C010017
|
||||
|
||||
#define NCA_S_FAULT_INT_DIV_BY_ZERO 0x1C000001
|
||||
#define NCA_S_FAULT_ADDR_ERROR 0x1C000002
|
||||
#define NCA_S_FAULT_FP_DIV_ZERO 0x1C000003
|
||||
#define NCA_S_FAULT_FP_UNDERFLOW 0x1C000004
|
||||
#define NCA_S_FAULT_FP_OVERFLOW 0x1C000005
|
||||
#define NCA_S_FAULT_INVALID_TAG 0x1C000006
|
||||
#define NCA_S_FAULT_INVALID_BOUND 0x1C000007
|
||||
#define NCA_S_RPC_VERSION_MISMATCH 0x1C000008
|
||||
#define NCA_S_UNSPEC_REJECT 0x1C000009
|
||||
#define NCA_S_BAD_ACTID 0x1C00000A
|
||||
#define NCA_S_WHO_ARE_YOU_FAILED 0x1C00000B
|
||||
#define NCA_S_MANAGER_NOT_ENTERED 0x1C00000C
|
||||
#define NCA_S_FAULT_CANCEL 0x1C00000D
|
||||
#define NCA_S_FAULT_ILL_INST 0x1C00000E
|
||||
#define NCA_S_FAULT_FP_ERROR 0x1C00000F
|
||||
#define NCA_S_FAULT_INT_OVERFLOW 0x1C000010
|
||||
#define NCA_S_FAULT_UNSPEC 0x1C000012
|
||||
#define NCA_S_FAULT_REMOTE_COMM_FAILURE 0x1C000013
|
||||
#define NCA_S_FAULT_PIPE_EMPTY 0x1C000014
|
||||
#define NCA_S_FAULT_PIPE_CLOSED 0x1C000015
|
||||
#define NCA_S_FAULT_PIPE_ORDER 0x1C000016
|
||||
#define NCA_S_FAULT_PIPE_DISCIPLINE 0x1C000017
|
||||
#define NCA_S_FAULT_PIPE_COMM_ERROR 0x1C000018
|
||||
#define NCA_S_FAULT_PIPE_MEMORY 0x1C000019
|
||||
#define NCA_S_FAULT_CONTEXT_MISMATCH 0x1C00001A
|
||||
#define NCA_S_FAULT_REMOTE_NO_MEMORY 0x1C00001B
|
||||
#define NCA_S_INVALID_PRES_CONTEXT_ID 0x1C00001C
|
||||
#define NCA_S_UNSUPPORTED_AUTHN_LEVEL 0x1C00001D
|
||||
#define NCA_S_INVALID_CHECKSUM 0x1C00001F
|
||||
#define NCA_S_INVALID_CRC 0x1C000020
|
||||
#define NCA_S_FAULT_USER_DEFINED 0x1C000021
|
||||
#define NCA_S_FAULT_TX_OPEN_FAILED 0x1C000022
|
||||
#define NCA_S_FAULT_CODESET_CONV_ERROR 0x1C000023
|
||||
#define NCA_S_FAULT_OBJECT_NOT_FOUND 0x1C000024
|
||||
#define NCA_S_FAULT_NO_CLIENT_STUB 0x1C000025
|
||||
/*
|
||||
* NCA Status definitions
|
||||
*
|
||||
* Copyright 2007 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define NCA_S_COMM_FAILURE 0x1C010001
|
||||
#define NCA_S_OP_RNG_ERROR 0x1C010002
|
||||
#define NCA_S_UNK_IF 0x1C010003
|
||||
#define NCA_S_WRONG_BOOT_TIME 0x1C010006
|
||||
#define NCA_S_YOU_CRASHED 0x1C010009
|
||||
#define NCA_S_PROTO_ERROR 0x1C01000B
|
||||
#define NCA_S_OUT_ARGS_TOO_BIG 0x1C010013
|
||||
#define NCA_S_SERVER_TOO_BUSY 0x1C010014
|
||||
#define NCA_S_FAULT_STRING_TOO_LONG 0x1C010015
|
||||
#define NCA_S_UNSUPPORTED_TYPE 0x1C010017
|
||||
|
||||
#define NCA_S_FAULT_INT_DIV_BY_ZERO 0x1C000001
|
||||
#define NCA_S_FAULT_ADDR_ERROR 0x1C000002
|
||||
#define NCA_S_FAULT_FP_DIV_ZERO 0x1C000003
|
||||
#define NCA_S_FAULT_FP_UNDERFLOW 0x1C000004
|
||||
#define NCA_S_FAULT_FP_OVERFLOW 0x1C000005
|
||||
#define NCA_S_FAULT_INVALID_TAG 0x1C000006
|
||||
#define NCA_S_FAULT_INVALID_BOUND 0x1C000007
|
||||
#define NCA_S_RPC_VERSION_MISMATCH 0x1C000008
|
||||
#define NCA_S_UNSPEC_REJECT 0x1C000009
|
||||
#define NCA_S_BAD_ACTID 0x1C00000A
|
||||
#define NCA_S_WHO_ARE_YOU_FAILED 0x1C00000B
|
||||
#define NCA_S_MANAGER_NOT_ENTERED 0x1C00000C
|
||||
#define NCA_S_FAULT_CANCEL 0x1C00000D
|
||||
#define NCA_S_FAULT_ILL_INST 0x1C00000E
|
||||
#define NCA_S_FAULT_FP_ERROR 0x1C00000F
|
||||
#define NCA_S_FAULT_INT_OVERFLOW 0x1C000010
|
||||
#define NCA_S_FAULT_UNSPEC 0x1C000012
|
||||
#define NCA_S_FAULT_REMOTE_COMM_FAILURE 0x1C000013
|
||||
#define NCA_S_FAULT_PIPE_EMPTY 0x1C000014
|
||||
#define NCA_S_FAULT_PIPE_CLOSED 0x1C000015
|
||||
#define NCA_S_FAULT_PIPE_ORDER 0x1C000016
|
||||
#define NCA_S_FAULT_PIPE_DISCIPLINE 0x1C000017
|
||||
#define NCA_S_FAULT_PIPE_COMM_ERROR 0x1C000018
|
||||
#define NCA_S_FAULT_PIPE_MEMORY 0x1C000019
|
||||
#define NCA_S_FAULT_CONTEXT_MISMATCH 0x1C00001A
|
||||
#define NCA_S_FAULT_REMOTE_NO_MEMORY 0x1C00001B
|
||||
#define NCA_S_INVALID_PRES_CONTEXT_ID 0x1C00001C
|
||||
#define NCA_S_UNSUPPORTED_AUTHN_LEVEL 0x1C00001D
|
||||
#define NCA_S_INVALID_CHECKSUM 0x1C00001F
|
||||
#define NCA_S_INVALID_CRC 0x1C000020
|
||||
#define NCA_S_FAULT_USER_DEFINED 0x1C000021
|
||||
#define NCA_S_FAULT_TX_OPEN_FAILED 0x1C000022
|
||||
#define NCA_S_FAULT_CODESET_CONV_ERROR 0x1C000023
|
||||
#define NCA_S_FAULT_OBJECT_NOT_FOUND 0x1C000024
|
||||
#define NCA_S_FAULT_NO_CLIENT_STUB 0x1C000025
|
||||
|
|
|
@ -1,207 +1,227 @@
|
|||
/*
|
||||
* MIDL proxy/stub stuff
|
||||
*
|
||||
* Copyright 2002 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - figure out whether we *really* got this right
|
||||
* - check for errors and throw exceptions
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
/************************************************************************
|
||||
* NdrClientInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum )
|
||||
{
|
||||
TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n",
|
||||
pRpcMessage, pStubMsg, pStubDesc, ProcNum);
|
||||
|
||||
assert( pRpcMessage && pStubMsg && pStubDesc );
|
||||
|
||||
pRpcMessage->Handle = NULL;
|
||||
pRpcMessage->ProcNum = ProcNum;
|
||||
pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
|
||||
pRpcMessage->RpcFlags = 0;
|
||||
pRpcMessage->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
|
||||
|
||||
pStubMsg->RpcMsg = pRpcMessage;
|
||||
pStubMsg->BufferStart = NULL;
|
||||
pStubMsg->BufferEnd = NULL;
|
||||
pStubMsg->BufferLength = 0;
|
||||
pStubMsg->IsClient = TRUE;
|
||||
pStubMsg->ReuseBuffer = FALSE;
|
||||
pStubMsg->pAllocAllNodesContext = NULL;
|
||||
pStubMsg->pPointerQueueState = NULL;
|
||||
pStubMsg->IgnoreEmbeddedPointers = 0;
|
||||
pStubMsg->PointerBufferMark = NULL;
|
||||
pStubMsg->fBufferValid = 0;
|
||||
pStubMsg->uFlags = 0;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->StackTop = NULL;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->FullPtrRefId = 0;
|
||||
pStubMsg->PointerLength = 0;
|
||||
pStubMsg->fInDontFree = 0;
|
||||
pStubMsg->fDontCallFreeInst = 0;
|
||||
pStubMsg->fInOnlyParam = 0;
|
||||
pStubMsg->fHasReturn = 0;
|
||||
pStubMsg->fHasExtensions = 0;
|
||||
pStubMsg->fHasNewCorrDesc = 0;
|
||||
pStubMsg->fUnused = 0;
|
||||
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
|
||||
pStubMsg->pvDestContext = NULL;
|
||||
pStubMsg->pRpcChannelBuffer = NULL;
|
||||
pStubMsg->pArrayInfo = NULL;
|
||||
pStubMsg->dwStubPhase = 0;
|
||||
/* FIXME: LowStackMark */
|
||||
pStubMsg->pAsyncMsg = NULL;
|
||||
pStubMsg->pCorrInfo = NULL;
|
||||
pStubMsg->pCorrMemory = NULL;
|
||||
pStubMsg->pMemoryList = NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrServerInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc )
|
||||
{
|
||||
TRACE("(pRpcMsg == ^%p, pStubMsg == ^%p, pStubDesc == ^%p)\n", pRpcMsg, pStubMsg, pStubDesc);
|
||||
|
||||
assert( pRpcMsg && pStubMsg && pStubDesc );
|
||||
|
||||
/* not everyone allocates stack space for w2kReserved */
|
||||
memset(pStubMsg, 0, FIELD_OFFSET(MIDL_STUB_MESSAGE,pCSInfo));
|
||||
|
||||
pStubMsg->ReuseBuffer = TRUE;
|
||||
pStubMsg->IsClient = FALSE;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->RpcMsg = pRpcMsg;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart = pRpcMsg->Buffer;
|
||||
pStubMsg->BufferLength = pRpcMsg->BufferLength;
|
||||
pStubMsg->BufferEnd = pStubMsg->Buffer + pStubMsg->BufferLength;
|
||||
|
||||
/* FIXME: determine the proper return value */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrGetBuffer(PMIDL_STUB_MESSAGE stubmsg, ULONG buflen, RPC_BINDING_HANDLE handle)
|
||||
{
|
||||
TRACE("(stubmsg == ^%p, buflen == %u, handle == %p): wild guess.\n", stubmsg, buflen, handle);
|
||||
|
||||
assert( stubmsg && stubmsg->RpcMsg );
|
||||
|
||||
/* I guess this is our chance to put the binding handle into the RPC_MESSAGE */
|
||||
stubmsg->RpcMsg->Handle = handle;
|
||||
|
||||
stubmsg->RpcMsg->BufferLength = buflen;
|
||||
if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK)
|
||||
return NULL;
|
||||
|
||||
stubmsg->Buffer = stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
stubmsg->BufferEnd = stubmsg->Buffer + stubmsg->BufferLength;
|
||||
return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer);
|
||||
}
|
||||
/***********************************************************************
|
||||
* NdrFreeBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrFreeBuffer(PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
TRACE("(pStubMsg == ^%p): wild guess.\n", pStubMsg);
|
||||
I_RpcFreeBuffer(pStubMsg->RpcMsg);
|
||||
pStubMsg->BufferLength = 0;
|
||||
pStubMsg->Buffer = pStubMsg->BufferEnd = (unsigned char *)(pStubMsg->RpcMsg->Buffer = NULL);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrSendReceive [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrSendReceive( PMIDL_STUB_MESSAGE stubmsg, unsigned char *buffer )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);
|
||||
|
||||
/* FIXME: how to handle errors? (raise exception?) */
|
||||
if (!stubmsg) {
|
||||
ERR("NULL stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!stubmsg->RpcMsg) {
|
||||
ERR("RPC Message not present in stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stubmsg->RpcMsg->BufferLength = buffer - (unsigned char *)stubmsg->RpcMsg->Buffer;
|
||||
status = I_RpcSendReceive(stubmsg->RpcMsg);
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->BufferEnd = stubmsg->BufferStart + stubmsg->BufferLength;
|
||||
stubmsg->Buffer = stubmsg->BufferStart;
|
||||
|
||||
/* FIXME: is this the right return value? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrMapCommAndFaultStatus [RPCRT4.@]
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY NdrMapCommAndFaultStatus( PMIDL_STUB_MESSAGE pStubMsg,
|
||||
ULONG *pCommStatus,
|
||||
ULONG *pFaultStatus,
|
||||
RPC_STATUS Status )
|
||||
{
|
||||
FIXME("(%p, %p, %p, %ld): stub\n", pStubMsg, pCommStatus, pFaultStatus, Status);
|
||||
|
||||
*pCommStatus = 0;
|
||||
*pFaultStatus = 0;
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
/*
|
||||
* MIDL proxy/stub stuff
|
||||
*
|
||||
* Copyright 2002 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - figure out whether we *really* got this right
|
||||
* - check for errors and throw exceptions
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "rpcproxy.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
/************************************************************************
|
||||
* NdrClientInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum )
|
||||
{
|
||||
TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n",
|
||||
pRpcMessage, pStubMsg, pStubDesc, ProcNum);
|
||||
|
||||
pRpcMessage->Handle = NULL;
|
||||
pRpcMessage->ProcNum = ProcNum;
|
||||
pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
|
||||
pRpcMessage->RpcFlags = 0;
|
||||
pRpcMessage->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
|
||||
|
||||
pStubMsg->RpcMsg = pRpcMessage;
|
||||
pStubMsg->BufferStart = NULL;
|
||||
pStubMsg->BufferEnd = NULL;
|
||||
pStubMsg->BufferLength = 0;
|
||||
pStubMsg->IsClient = TRUE;
|
||||
pStubMsg->ReuseBuffer = FALSE;
|
||||
pStubMsg->pAllocAllNodesContext = NULL;
|
||||
pStubMsg->pPointerQueueState = NULL;
|
||||
pStubMsg->IgnoreEmbeddedPointers = 0;
|
||||
pStubMsg->PointerBufferMark = NULL;
|
||||
pStubMsg->fBufferValid = 0;
|
||||
pStubMsg->uFlags = 0;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->StackTop = NULL;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->FullPtrRefId = 0;
|
||||
pStubMsg->PointerLength = 0;
|
||||
pStubMsg->fInDontFree = 0;
|
||||
pStubMsg->fDontCallFreeInst = 0;
|
||||
pStubMsg->fInOnlyParam = 0;
|
||||
pStubMsg->fHasReturn = 0;
|
||||
pStubMsg->fHasExtensions = 0;
|
||||
pStubMsg->fHasNewCorrDesc = 0;
|
||||
pStubMsg->fUnused = 0;
|
||||
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
|
||||
pStubMsg->pvDestContext = NULL;
|
||||
pStubMsg->pRpcChannelBuffer = NULL;
|
||||
pStubMsg->pArrayInfo = NULL;
|
||||
pStubMsg->dwStubPhase = 0;
|
||||
/* FIXME: LowStackMark */
|
||||
pStubMsg->pAsyncMsg = NULL;
|
||||
pStubMsg->pCorrInfo = NULL;
|
||||
pStubMsg->pCorrMemory = NULL;
|
||||
pStubMsg->pMemoryList = NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrServerInitializeNew [RPCRT4.@]
|
||||
*/
|
||||
unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PMIDL_STUB_DESC pStubDesc )
|
||||
{
|
||||
TRACE("(pRpcMsg == ^%p, pStubMsg == ^%p, pStubDesc == ^%p)\n", pRpcMsg, pStubMsg, pStubDesc);
|
||||
|
||||
pStubMsg->RpcMsg = pRpcMsg;
|
||||
pStubMsg->Buffer = pStubMsg->BufferStart = pRpcMsg->Buffer;
|
||||
pStubMsg->BufferEnd = pStubMsg->Buffer + pRpcMsg->BufferLength;
|
||||
pStubMsg->BufferLength = pRpcMsg->BufferLength;
|
||||
pStubMsg->IsClient = FALSE;
|
||||
pStubMsg->ReuseBuffer = FALSE;
|
||||
pStubMsg->pAllocAllNodesContext = NULL;
|
||||
pStubMsg->pPointerQueueState = NULL;
|
||||
pStubMsg->IgnoreEmbeddedPointers = 0;
|
||||
pStubMsg->PointerBufferMark = NULL;
|
||||
pStubMsg->uFlags = 0;
|
||||
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
||||
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
||||
pStubMsg->StackTop = NULL;
|
||||
pStubMsg->StubDesc = pStubDesc;
|
||||
pStubMsg->FullPtrXlatTables = NULL;
|
||||
pStubMsg->FullPtrRefId = 0;
|
||||
pStubMsg->PointerLength = 0;
|
||||
pStubMsg->fInDontFree = 0;
|
||||
pStubMsg->fDontCallFreeInst = 0;
|
||||
pStubMsg->fInOnlyParam = 0;
|
||||
pStubMsg->fHasReturn = 0;
|
||||
pStubMsg->fHasExtensions = 0;
|
||||
pStubMsg->fHasNewCorrDesc = 0;
|
||||
pStubMsg->fUnused = 0;
|
||||
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
|
||||
pStubMsg->pvDestContext = NULL;
|
||||
pStubMsg->pRpcChannelBuffer = NULL;
|
||||
pStubMsg->pArrayInfo = NULL;
|
||||
pStubMsg->dwStubPhase = 0;
|
||||
/* FIXME: LowStackMark */
|
||||
pStubMsg->pAsyncMsg = NULL;
|
||||
pStubMsg->pCorrInfo = NULL;
|
||||
pStubMsg->pCorrMemory = NULL;
|
||||
pStubMsg->pMemoryList = NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrGetBuffer [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrGetBuffer(PMIDL_STUB_MESSAGE stubmsg, ULONG buflen, RPC_BINDING_HANDLE handle)
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(stubmsg == ^%p, buflen == %u, handle == %p)\n", stubmsg, buflen, handle);
|
||||
|
||||
stubmsg->RpcMsg->Handle = handle;
|
||||
stubmsg->RpcMsg->BufferLength = buflen;
|
||||
|
||||
status = I_RpcGetBuffer(stubmsg->RpcMsg);
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
|
||||
stubmsg->Buffer = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->fBufferValid = TRUE;
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
return stubmsg->Buffer;
|
||||
}
|
||||
/***********************************************************************
|
||||
* NdrFreeBuffer [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrFreeBuffer(PMIDL_STUB_MESSAGE pStubMsg)
|
||||
{
|
||||
TRACE("(pStubMsg == ^%p)\n", pStubMsg);
|
||||
if (pStubMsg->fBufferValid)
|
||||
{
|
||||
I_RpcFreeBuffer(pStubMsg->RpcMsg);
|
||||
pStubMsg->fBufferValid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrSendReceive [RPCRT4.@]
|
||||
*/
|
||||
unsigned char *WINAPI NdrSendReceive( PMIDL_STUB_MESSAGE stubmsg, unsigned char *buffer )
|
||||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);
|
||||
|
||||
/* FIXME: how to handle errors? (raise exception?) */
|
||||
if (!stubmsg) {
|
||||
ERR("NULL stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!stubmsg->RpcMsg) {
|
||||
ERR("RPC Message not present in stub message. No action taken.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stubmsg->RpcMsg->BufferLength = buffer - (unsigned char *)stubmsg->RpcMsg->Buffer;
|
||||
status = I_RpcSendReceive(stubmsg->RpcMsg);
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
|
||||
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
|
||||
stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
|
||||
stubmsg->BufferEnd = stubmsg->BufferStart + stubmsg->BufferLength;
|
||||
stubmsg->Buffer = stubmsg->BufferStart;
|
||||
|
||||
/* FIXME: is this the right return value? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* NdrMapCommAndFaultStatus [RPCRT4.@]
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY NdrMapCommAndFaultStatus( PMIDL_STUB_MESSAGE pStubMsg,
|
||||
ULONG *pCommStatus,
|
||||
ULONG *pFaultStatus,
|
||||
RPC_STATUS Status )
|
||||
{
|
||||
FIXME("(%p, %p, %p, %ld): stub\n", pStubMsg, pCommStatus, pFaultStatus, Status);
|
||||
|
||||
*pCommStatus = 0;
|
||||
*pFaultStatus = 0;
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
|
345
reactos/dll/win32/rpcrt4_new/ndr_contexthandle.c
Normal file
345
reactos/dll/win32/rpcrt4_new/ndr_contexthandle.c
Normal file
|
@ -0,0 +1,345 @@
|
|||
/*
|
||||
* NDR data marshalling
|
||||
*
|
||||
* Copyright 2006 Mike McCormack (for CodeWeavers)
|
||||
* Copyright 2006-2007 Robert Shearman (for CodeWeavers)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpc_assoc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#include "wine/rpcfc.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
#define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
|
||||
|
||||
typedef struct ndr_context_handle
|
||||
{
|
||||
ULONG attributes;
|
||||
GUID uuid;
|
||||
} ndr_context_handle;
|
||||
|
||||
struct context_handle_entry
|
||||
{
|
||||
struct list entry;
|
||||
DWORD magic;
|
||||
RPC_BINDING_HANDLE handle;
|
||||
ndr_context_handle wire_data;
|
||||
};
|
||||
|
||||
static struct list context_handle_list = LIST_INIT(context_handle_list);
|
||||
|
||||
static CRITICAL_SECTION ndr_context_cs;
|
||||
static CRITICAL_SECTION_DEBUG ndr_context_debug =
|
||||
{
|
||||
0, 0, &ndr_context_cs,
|
||||
{ &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
|
||||
};
|
||||
static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
|
||||
{
|
||||
struct context_handle_entry *che = (struct context_handle_entry*) CContext;
|
||||
|
||||
if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
|
||||
return NULL;
|
||||
return che;
|
||||
}
|
||||
|
||||
static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
|
||||
{
|
||||
struct context_handle_entry *che;
|
||||
LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
|
||||
if (IsEqualGUID(&che->wire_data.uuid, uuid))
|
||||
return che;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
|
||||
{
|
||||
struct context_handle_entry *che;
|
||||
RPC_BINDING_HANDLE handle = NULL;
|
||||
|
||||
TRACE("%p\n", CContext);
|
||||
|
||||
EnterCriticalSection(&ndr_context_cs);
|
||||
che = get_context_entry(CContext);
|
||||
if (che)
|
||||
handle = che->handle;
|
||||
LeaveCriticalSection(&ndr_context_cs);
|
||||
|
||||
if (!handle)
|
||||
RpcRaiseException(ERROR_INVALID_HANDLE);
|
||||
return handle;
|
||||
}
|
||||
|
||||
void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
|
||||
{
|
||||
struct context_handle_entry *che;
|
||||
|
||||
TRACE("%p %p\n", CContext, pBuff);
|
||||
|
||||
if (CContext)
|
||||
{
|
||||
EnterCriticalSection(&ndr_context_cs);
|
||||
che = get_context_entry(CContext);
|
||||
memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
|
||||
LeaveCriticalSection(&ndr_context_cs);
|
||||
}
|
||||
else
|
||||
{
|
||||
ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
|
||||
wire_data->attributes = 0;
|
||||
wire_data->uuid = GUID_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcSmDestroyClientContext [RPCRT4.@]
|
||||
*/
|
||||
RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
|
||||
{
|
||||
RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
|
||||
struct context_handle_entry *che = NULL;
|
||||
|
||||
TRACE("(%p)\n", ContextHandle);
|
||||
|
||||
EnterCriticalSection(&ndr_context_cs);
|
||||
che = get_context_entry(*ContextHandle);
|
||||
*ContextHandle = NULL;
|
||||
if (che)
|
||||
{
|
||||
status = RPC_S_OK;
|
||||
list_remove(&che->entry);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&ndr_context_cs);
|
||||
|
||||
if (che)
|
||||
{
|
||||
RpcBindingFree(&che->handle);
|
||||
HeapFree(GetProcessHeap(), 0, che);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RpcSsDestroyClientContext [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
|
||||
{
|
||||
RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
}
|
||||
|
||||
static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
|
||||
RPC_BINDING_HANDLE hBinding,
|
||||
const ndr_context_handle *chi)
|
||||
{
|
||||
struct context_handle_entry *che = NULL;
|
||||
|
||||
/* a null UUID means we should free the context handle */
|
||||
if (IsEqualGUID(&chi->uuid, &GUID_NULL))
|
||||
{
|
||||
if (*CContext)
|
||||
{
|
||||
che = get_context_entry(*CContext);
|
||||
if (!che)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
list_remove(&che->entry);
|
||||
RpcBindingFree(&che->handle);
|
||||
HeapFree(GetProcessHeap(), 0, che);
|
||||
che = NULL;
|
||||
}
|
||||
}
|
||||
/* if there's no existing entry matching the GUID, allocate one */
|
||||
else if (!(che = context_entry_from_guid(&chi->uuid)))
|
||||
{
|
||||
che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
|
||||
if (!che)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
che->magic = NDR_CONTEXT_HANDLE_MAGIC;
|
||||
RpcBindingCopy(hBinding, &che->handle);
|
||||
list_add_tail(&context_handle_list, &che->entry);
|
||||
memcpy(&che->wire_data, chi, sizeof *chi);
|
||||
}
|
||||
|
||||
*CContext = che;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRCContextUnmarshall [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
|
||||
RPC_BINDING_HANDLE hBinding,
|
||||
void *pBuff, ULONG DataRepresentation)
|
||||
{
|
||||
UINT r;
|
||||
|
||||
TRACE("*%p=(%p) %p %p %08x\n",
|
||||
CContext, *CContext, hBinding, pBuff, DataRepresentation);
|
||||
|
||||
EnterCriticalSection(&ndr_context_cs);
|
||||
r = ndr_update_context_handle(CContext, hBinding, pBuff);
|
||||
LeaveCriticalSection(&ndr_context_cs);
|
||||
if (r)
|
||||
RpcRaiseException(r);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRSContextMarshall [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NDRSContextMarshall(NDR_SCONTEXT SContext,
|
||||
void *pBuff,
|
||||
NDR_RUNDOWN userRunDownIn)
|
||||
{
|
||||
TRACE("(%p %p %p)\n", SContext, pBuff, userRunDownIn);
|
||||
NDRSContextMarshall2(I_RpcGetCurrentCallHandle(), SContext, pBuff, userRunDownIn, NULL, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRSContextMarshallEx [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
|
||||
NDR_SCONTEXT SContext,
|
||||
void *pBuff,
|
||||
NDR_RUNDOWN userRunDownIn)
|
||||
{
|
||||
TRACE("(%p %p %p %p)\n", hBinding, SContext, pBuff, userRunDownIn);
|
||||
NDRSContextMarshall2(hBinding, SContext, pBuff, userRunDownIn, NULL, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRSContextMarshall2 [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
|
||||
NDR_SCONTEXT SContext,
|
||||
void *pBuff,
|
||||
NDR_RUNDOWN userRunDownIn,
|
||||
void *CtxGuard, ULONG Flags)
|
||||
{
|
||||
RpcBinding *binding = hBinding;
|
||||
RPC_STATUS status;
|
||||
ndr_context_handle *ndr = pBuff;
|
||||
|
||||
TRACE("(%p %p %p %p %p %u)\n",
|
||||
hBinding, SContext, pBuff, userRunDownIn, CtxGuard, Flags);
|
||||
|
||||
if (!binding->server || !binding->Assoc)
|
||||
RpcRaiseException(ERROR_INVALID_HANDLE);
|
||||
|
||||
if (SContext->userContext)
|
||||
{
|
||||
status = RpcServerAssoc_UpdateContextHandle(binding->Assoc, SContext, CtxGuard, userRunDownIn);
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
ndr->attributes = 0;
|
||||
RpcContextHandle_GetUuid(SContext, &ndr->uuid);
|
||||
|
||||
RPCRT4_RemoveThreadContextHandle(SContext);
|
||||
RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!RpcContextHandle_IsGuardCorrect(SContext, CtxGuard))
|
||||
RpcRaiseException(ERROR_INVALID_HANDLE);
|
||||
memset(ndr, 0, sizeof(*ndr));
|
||||
|
||||
RPCRT4_RemoveThreadContextHandle(SContext);
|
||||
/* Note: release the context handle twice in this case to release
|
||||
* one ref being kept around for the data and one ref for the
|
||||
* unmarshall/marshall sequence */
|
||||
if (!RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE))
|
||||
return; /* this is to cope with the case of the data not being valid
|
||||
* before and so not having a further reference */
|
||||
RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRSContextUnmarshall [RPCRT4.@]
|
||||
*/
|
||||
NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
|
||||
ULONG DataRepresentation)
|
||||
{
|
||||
TRACE("(%p %08x)\n", pBuff, DataRepresentation);
|
||||
return NDRSContextUnmarshall2(I_RpcGetCurrentCallHandle(), pBuff, DataRepresentation, NULL, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRSContextUnmarshallEx [RPCRT4.@]
|
||||
*/
|
||||
NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
|
||||
void *pBuff,
|
||||
ULONG DataRepresentation)
|
||||
{
|
||||
TRACE("(%p %p %08x)\n", hBinding, pBuff, DataRepresentation);
|
||||
return NDRSContextUnmarshall2(hBinding, pBuff, DataRepresentation, NULL, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NDRSContextUnmarshall2 [RPCRT4.@]
|
||||
*/
|
||||
NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
|
||||
void *pBuff,
|
||||
ULONG DataRepresentation,
|
||||
void *CtxGuard, ULONG Flags)
|
||||
{
|
||||
RpcBinding *binding = hBinding;
|
||||
NDR_SCONTEXT SContext;
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(%p %p %08x %p %u)\n",
|
||||
hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
|
||||
|
||||
if (!binding->server || !binding->Assoc)
|
||||
RpcRaiseException(ERROR_INVALID_HANDLE);
|
||||
|
||||
if (!pBuff)
|
||||
status = RpcServerAssoc_AllocateContextHandle(binding->Assoc, CtxGuard,
|
||||
&SContext);
|
||||
else
|
||||
{
|
||||
const ndr_context_handle *context_ndr = pBuff;
|
||||
if (context_ndr->attributes)
|
||||
{
|
||||
ERR("non-null attributes 0x%x\n", context_ndr->attributes);
|
||||
status = ERROR_INVALID_HANDLE;
|
||||
}
|
||||
else
|
||||
status = RpcServerAssoc_FindContextHandle(binding->Assoc,
|
||||
&context_ndr->uuid,
|
||||
CtxGuard, Flags,
|
||||
&SContext);
|
||||
}
|
||||
|
||||
if (status != RPC_S_OK)
|
||||
RpcRaiseException(status);
|
||||
|
||||
RPCRT4_PushThreadContextHandle(SContext);
|
||||
return SContext;
|
||||
}
|
|
@ -1,233 +1,239 @@
|
|||
/*
|
||||
* Full Pointer Translation Routines
|
||||
*
|
||||
* Copyright 2006 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
PFULL_PTR_XLAT_TABLES WINAPI NdrFullPointerXlatInit(ULONG NumberOfPointers,
|
||||
XLAT_SIDE XlatSide)
|
||||
{
|
||||
ULONG NumberOfBuckets;
|
||||
PFULL_PTR_XLAT_TABLES pXlatTables = HeapAlloc(GetProcessHeap(), 0, sizeof(*pXlatTables));
|
||||
|
||||
TRACE("(%d, %d)\n", NumberOfPointers, XlatSide);
|
||||
|
||||
if (!NumberOfPointers) NumberOfPointers = 512;
|
||||
NumberOfBuckets = ((NumberOfPointers + 3) & ~3) - 1;
|
||||
|
||||
pXlatTables->RefIdToPointer.XlatTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(void *) * NumberOfPointers);
|
||||
pXlatTables->RefIdToPointer.StateTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(unsigned char) * NumberOfPointers);
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = NumberOfPointers;
|
||||
|
||||
TRACE("NumberOfBuckets = %d\n", NumberOfBuckets);
|
||||
pXlatTables->PointerToRefId.XlatTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(PFULL_PTR_TO_REFID_ELEMENT) * NumberOfBuckets);
|
||||
pXlatTables->PointerToRefId.NumberOfBuckets = NumberOfBuckets;
|
||||
pXlatTables->PointerToRefId.HashMask = NumberOfBuckets - 1;
|
||||
|
||||
pXlatTables->NextRefId = 1;
|
||||
pXlatTables->XlatSide = XlatSide;
|
||||
|
||||
return pXlatTables;
|
||||
}
|
||||
|
||||
void WINAPI NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables)
|
||||
{
|
||||
TRACE("(%p)\n", pXlatTables);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable);
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.StateTable);
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->PointerToRefId.XlatTable);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables);
|
||||
}
|
||||
|
||||
static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId)
|
||||
{
|
||||
if (RefId >= pXlatTables->RefIdToPointer.NumberOfEntries)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = RefId * 2;
|
||||
pXlatTables->RefIdToPointer.XlatTable =
|
||||
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
pXlatTables->RefIdToPointer.XlatTable,
|
||||
sizeof(void *) * pXlatTables->RefIdToPointer.NumberOfEntries);
|
||||
pXlatTables->RefIdToPointer.StateTable =
|
||||
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
pXlatTables->RefIdToPointer.StateTable,
|
||||
sizeof(unsigned char) * pXlatTables->RefIdToPointer.NumberOfEntries);
|
||||
|
||||
if (!pXlatTables->RefIdToPointer.XlatTable || !pXlatTables->RefIdToPointer.StateTable)
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
void *pPointer, unsigned char QueryType,
|
||||
ULONG *pRefId )
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
|
||||
TRACE("(%p, %p, %d, %p)\n", pXlatTables, pPointer, QueryType, pRefId);
|
||||
|
||||
if (!pPointer)
|
||||
{
|
||||
*pRefId = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(pPointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
|
||||
|
||||
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
|
||||
if (pPointer == XlatTableEntry->Pointer)
|
||||
{
|
||||
*pRefId = XlatTableEntry->RefId;
|
||||
if (XlatTableEntry->State & QueryType)
|
||||
return 1;
|
||||
XlatTableEntry->State |= QueryType;
|
||||
return 0;
|
||||
}
|
||||
|
||||
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
|
||||
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
XlatTableEntry->Pointer = pPointer;
|
||||
XlatTableEntry->RefId = *pRefId = pXlatTables->NextRefId++;
|
||||
XlatTableEntry->State = QueryType;
|
||||
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
|
||||
|
||||
/* insert pointer into mapping table */
|
||||
expand_pointer_table_if_necessary(pXlatTables, XlatTableEntry->RefId);
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > XlatTableEntry->RefId)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
|
||||
pXlatTables->RefIdToPointer.StateTable[XlatTableEntry->RefId] = QueryType;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
ULONG RefId, unsigned char QueryType,
|
||||
void **ppPointer)
|
||||
{
|
||||
TRACE("(%p, 0x%x, %d, %p)\n", pXlatTables, RefId, QueryType, ppPointer);
|
||||
|
||||
expand_pointer_table_if_necessary(pXlatTables, RefId);
|
||||
|
||||
pXlatTables->NextRefId = max(RefId + 1, pXlatTables->NextRefId);
|
||||
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
{
|
||||
*ppPointer = pXlatTables->RefIdToPointer.XlatTable[RefId];
|
||||
if (QueryType)
|
||||
{
|
||||
if (pXlatTables->RefIdToPointer.StateTable[RefId] & QueryType)
|
||||
return 1;
|
||||
pXlatTables->RefIdToPointer.StateTable[RefId] |= QueryType;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
*ppPointer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WINAPI NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
ULONG RefId, void *pPointer)
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
|
||||
TRACE("(%p, 0x%x, %p)\n", pXlatTables, RefId, pPointer);
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(pPointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
|
||||
|
||||
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
|
||||
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
XlatTableEntry->Pointer = pPointer;
|
||||
XlatTableEntry->RefId = RefId;
|
||||
XlatTableEntry->State = 0;
|
||||
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
|
||||
|
||||
/* insert pointer into mapping table */
|
||||
expand_pointer_table_if_necessary(pXlatTables, RefId);
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables, void *Pointer)
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
ULONG RefId = 0;
|
||||
|
||||
TRACE("(%p, %p)\n", pXlatTables, Pointer);
|
||||
|
||||
if (!Pointer)
|
||||
return 1;
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(Pointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&Pointer)[i];
|
||||
|
||||
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
|
||||
if (Pointer == XlatTableEntry->Pointer)
|
||||
{
|
||||
if (XlatTableEntry->State & 0x20)
|
||||
return 0;
|
||||
XlatTableEntry->State |= 0x20;
|
||||
RefId = XlatTableEntry->RefId;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!XlatTableEntry)
|
||||
return 0;
|
||||
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.StateTable[RefId] |= 0x20;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Full Pointer Translation Routines
|
||||
*
|
||||
* Copyright 2006 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
PFULL_PTR_XLAT_TABLES WINAPI NdrFullPointerXlatInit(ULONG NumberOfPointers,
|
||||
XLAT_SIDE XlatSide)
|
||||
{
|
||||
ULONG NumberOfBuckets;
|
||||
PFULL_PTR_XLAT_TABLES pXlatTables = HeapAlloc(GetProcessHeap(), 0, sizeof(*pXlatTables));
|
||||
|
||||
TRACE("(%d, %d)\n", NumberOfPointers, XlatSide);
|
||||
|
||||
if (!NumberOfPointers) NumberOfPointers = 512;
|
||||
NumberOfBuckets = ((NumberOfPointers + 3) & ~3) - 1;
|
||||
|
||||
pXlatTables->RefIdToPointer.XlatTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(void *) * NumberOfPointers);
|
||||
pXlatTables->RefIdToPointer.StateTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(unsigned char) * NumberOfPointers);
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = NumberOfPointers;
|
||||
|
||||
TRACE("NumberOfBuckets = %d\n", NumberOfBuckets);
|
||||
pXlatTables->PointerToRefId.XlatTable =
|
||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(PFULL_PTR_TO_REFID_ELEMENT) * NumberOfBuckets);
|
||||
pXlatTables->PointerToRefId.NumberOfBuckets = NumberOfBuckets;
|
||||
pXlatTables->PointerToRefId.HashMask = NumberOfBuckets - 1;
|
||||
|
||||
pXlatTables->NextRefId = 1;
|
||||
pXlatTables->XlatSide = XlatSide;
|
||||
|
||||
return pXlatTables;
|
||||
}
|
||||
|
||||
void WINAPI NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
TRACE("(%p)\n", pXlatTables);
|
||||
|
||||
/* free the entries in the table */
|
||||
for (i = 0; i < pXlatTables->RefIdToPointer.NumberOfEntries; i++)
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable[i]);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable);
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.StateTable);
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables->PointerToRefId.XlatTable);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pXlatTables);
|
||||
}
|
||||
|
||||
static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId)
|
||||
{
|
||||
if (RefId >= pXlatTables->RefIdToPointer.NumberOfEntries)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = RefId * 2;
|
||||
pXlatTables->RefIdToPointer.XlatTable =
|
||||
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
pXlatTables->RefIdToPointer.XlatTable,
|
||||
sizeof(void *) * pXlatTables->RefIdToPointer.NumberOfEntries);
|
||||
pXlatTables->RefIdToPointer.StateTable =
|
||||
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
pXlatTables->RefIdToPointer.StateTable,
|
||||
sizeof(unsigned char) * pXlatTables->RefIdToPointer.NumberOfEntries);
|
||||
|
||||
if (!pXlatTables->RefIdToPointer.XlatTable || !pXlatTables->RefIdToPointer.StateTable)
|
||||
pXlatTables->RefIdToPointer.NumberOfEntries = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
void *pPointer, unsigned char QueryType,
|
||||
ULONG *pRefId )
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
|
||||
TRACE("(%p, %p, %d, %p)\n", pXlatTables, pPointer, QueryType, pRefId);
|
||||
|
||||
if (!pPointer)
|
||||
{
|
||||
*pRefId = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(pPointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
|
||||
|
||||
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
|
||||
if (pPointer == XlatTableEntry->Pointer)
|
||||
{
|
||||
*pRefId = XlatTableEntry->RefId;
|
||||
if (XlatTableEntry->State & QueryType)
|
||||
return 1;
|
||||
XlatTableEntry->State |= QueryType;
|
||||
return 0;
|
||||
}
|
||||
|
||||
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
|
||||
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
XlatTableEntry->Pointer = pPointer;
|
||||
XlatTableEntry->RefId = *pRefId = pXlatTables->NextRefId++;
|
||||
XlatTableEntry->State = QueryType;
|
||||
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
|
||||
|
||||
/* insert pointer into mapping table */
|
||||
expand_pointer_table_if_necessary(pXlatTables, XlatTableEntry->RefId);
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > XlatTableEntry->RefId)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
|
||||
pXlatTables->RefIdToPointer.StateTable[XlatTableEntry->RefId] = QueryType;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
ULONG RefId, unsigned char QueryType,
|
||||
void **ppPointer)
|
||||
{
|
||||
TRACE("(%p, 0x%x, %d, %p)\n", pXlatTables, RefId, QueryType, ppPointer);
|
||||
|
||||
expand_pointer_table_if_necessary(pXlatTables, RefId);
|
||||
|
||||
pXlatTables->NextRefId = max(RefId + 1, pXlatTables->NextRefId);
|
||||
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
{
|
||||
*ppPointer = pXlatTables->RefIdToPointer.XlatTable[RefId];
|
||||
if (QueryType)
|
||||
{
|
||||
if (pXlatTables->RefIdToPointer.StateTable[RefId] & QueryType)
|
||||
return 1;
|
||||
pXlatTables->RefIdToPointer.StateTable[RefId] |= QueryType;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
*ppPointer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WINAPI NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
|
||||
ULONG RefId, void *pPointer)
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
|
||||
TRACE("(%p, 0x%x, %p)\n", pXlatTables, RefId, pPointer);
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(pPointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
|
||||
|
||||
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
|
||||
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
XlatTableEntry->Pointer = pPointer;
|
||||
XlatTableEntry->RefId = RefId;
|
||||
XlatTableEntry->State = 0;
|
||||
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
|
||||
|
||||
/* insert pointer into mapping table */
|
||||
expand_pointer_table_if_necessary(pXlatTables, RefId);
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
|
||||
}
|
||||
|
||||
int WINAPI NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables, void *Pointer)
|
||||
{
|
||||
ULONG Hash = 0;
|
||||
int i;
|
||||
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
|
||||
ULONG RefId = 0;
|
||||
|
||||
TRACE("(%p, %p)\n", pXlatTables, Pointer);
|
||||
|
||||
if (!Pointer)
|
||||
return 1;
|
||||
|
||||
/* simple hashing algorithm, don't know whether it matches native */
|
||||
for (i = 0; i < sizeof(Pointer); i++)
|
||||
Hash = (Hash * 3) ^ ((unsigned char *)&Pointer)[i];
|
||||
|
||||
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
|
||||
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
|
||||
if (Pointer == XlatTableEntry->Pointer)
|
||||
{
|
||||
if (XlatTableEntry->State & 0x20)
|
||||
return 0;
|
||||
XlatTableEntry->State |= 0x20;
|
||||
RefId = XlatTableEntry->RefId;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!XlatTableEntry)
|
||||
return 0;
|
||||
|
||||
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
|
||||
{
|
||||
pXlatTables->RefIdToPointer.StateTable[RefId] |= 0x20;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,65 +1,65 @@
|
|||
/*
|
||||
* NDR definitions
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_NDR_MISC_H
|
||||
#define __WINE_NDR_MISC_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
struct IPSFactoryBuffer;
|
||||
|
||||
PFORMAT_STRING ComputeConformanceOrVariance(
|
||||
MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount);
|
||||
|
||||
static inline PFORMAT_STRING ComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
return ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount);
|
||||
}
|
||||
|
||||
static inline PFORMAT_STRING ComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
PFORMAT_STRING ret;
|
||||
ULONG_PTR ActualCount = pStubMsg->ActualCount;
|
||||
|
||||
pStubMsg->Offset = 0;
|
||||
ret = ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &ActualCount);
|
||||
pStubMsg->ActualCount = (ULONG)ActualCount;
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef unsigned char* (WINAPI *NDR_MARSHALL) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
typedef unsigned char* (WINAPI *NDR_UNMARSHALL)(PMIDL_STUB_MESSAGE, unsigned char**,PFORMAT_STRING, unsigned char);
|
||||
typedef void (WINAPI *NDR_BUFFERSIZE)(PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
typedef ULONG (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
|
||||
typedef void (WINAPI *NDR_FREE) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
|
||||
extern const NDR_MARSHALL NdrMarshaller[];
|
||||
extern const NDR_UNMARSHALL NdrUnmarshaller[];
|
||||
extern const NDR_BUFFERSIZE NdrBufferSizer[];
|
||||
extern const NDR_MEMORYSIZE NdrMemorySizer[];
|
||||
extern const NDR_FREE NdrFreer[];
|
||||
|
||||
#endif /* __WINE_NDR_MISC_H */
|
||||
/*
|
||||
* NDR definitions
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_NDR_MISC_H
|
||||
#define __WINE_NDR_MISC_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
struct IPSFactoryBuffer;
|
||||
|
||||
PFORMAT_STRING ComputeConformanceOrVariance(
|
||||
MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount);
|
||||
|
||||
static inline PFORMAT_STRING ComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
return ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount);
|
||||
}
|
||||
|
||||
static inline PFORMAT_STRING ComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
|
||||
{
|
||||
PFORMAT_STRING ret;
|
||||
ULONG_PTR ActualCount = pStubMsg->ActualCount;
|
||||
|
||||
pStubMsg->Offset = 0;
|
||||
ret = ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &ActualCount);
|
||||
pStubMsg->ActualCount = (ULONG)ActualCount;
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef unsigned char* (WINAPI *NDR_MARSHALL) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
typedef unsigned char* (WINAPI *NDR_UNMARSHALL)(PMIDL_STUB_MESSAGE, unsigned char**,PFORMAT_STRING, unsigned char);
|
||||
typedef void (WINAPI *NDR_BUFFERSIZE)(PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
typedef ULONG (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
|
||||
typedef void (WINAPI *NDR_FREE) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
|
||||
|
||||
extern const NDR_MARSHALL NdrMarshaller[];
|
||||
extern const NDR_UNMARSHALL NdrUnmarshaller[];
|
||||
extern const NDR_BUFFERSIZE NdrBufferSizer[];
|
||||
extern const NDR_MEMORYSIZE NdrMemorySizer[];
|
||||
extern const NDR_FREE NdrFreer[];
|
||||
|
||||
#endif /* __WINE_NDR_MISC_H */
|
||||
|
|
|
@ -1,393 +1,393 @@
|
|||
/*
|
||||
* OLE32 callouts, COM interface marshalling
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - fix the wire-protocol to match MS/RPC
|
||||
* - finish RpcStream_Vtbl
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
#include "rpcproxy.h"
|
||||
#include "wine/rpcfc.h"
|
||||
#include "cpsf.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
static HMODULE hOLE;
|
||||
|
||||
static HRESULT (WINAPI *COM_GetMarshalSizeMax)(ULONG *,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD);
|
||||
static HRESULT (WINAPI *COM_MarshalInterface)(LPSTREAM,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD);
|
||||
static HRESULT (WINAPI *COM_UnmarshalInterface)(LPSTREAM,REFIID,LPVOID*);
|
||||
static HRESULT (WINAPI *COM_ReleaseMarshalData)(LPSTREAM);
|
||||
static HRESULT (WINAPI *COM_GetClassObject)(REFCLSID,DWORD,COSERVERINFO *,REFIID,LPVOID *);
|
||||
static HRESULT (WINAPI *COM_GetPSClsid)(REFIID,CLSID *);
|
||||
static LPVOID (WINAPI *COM_MemAlloc)(ULONG);
|
||||
static void (WINAPI *COM_MemFree)(LPVOID);
|
||||
|
||||
static HMODULE LoadCOM(void)
|
||||
{
|
||||
if (hOLE) return hOLE;
|
||||
hOLE = LoadLibraryA("OLE32.DLL");
|
||||
if (!hOLE) return 0;
|
||||
COM_GetMarshalSizeMax = (LPVOID)GetProcAddress(hOLE, "CoGetMarshalSizeMax");
|
||||
COM_MarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoMarshalInterface");
|
||||
COM_UnmarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoUnmarshalInterface");
|
||||
COM_ReleaseMarshalData = (LPVOID)GetProcAddress(hOLE, "CoReleaseMarshalData");
|
||||
COM_GetClassObject = (LPVOID)GetProcAddress(hOLE, "CoGetClassObject");
|
||||
COM_GetPSClsid = (LPVOID)GetProcAddress(hOLE, "CoGetPSClsid");
|
||||
COM_MemAlloc = (LPVOID)GetProcAddress(hOLE, "CoTaskMemAlloc");
|
||||
COM_MemFree = (LPVOID)GetProcAddress(hOLE, "CoTaskMemFree");
|
||||
return hOLE;
|
||||
}
|
||||
|
||||
/* CoMarshalInterface/CoUnmarshalInterface works on streams,
|
||||
* so implement a simple stream on top of the RPC buffer
|
||||
* (which also implements the MInterfacePointer structure) */
|
||||
typedef struct RpcStreamImpl
|
||||
{
|
||||
const IStreamVtbl *lpVtbl;
|
||||
DWORD RefCount;
|
||||
PMIDL_STUB_MESSAGE pMsg;
|
||||
LPDWORD size;
|
||||
char *data;
|
||||
DWORD pos;
|
||||
} RpcStreamImpl;
|
||||
|
||||
static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (IsEqualGUID(&IID_IUnknown, riid) ||
|
||||
IsEqualGUID(&IID_ISequentialStream, riid) ||
|
||||
IsEqualGUID(&IID_IStream, riid)) {
|
||||
*obj = This;
|
||||
This->RefCount++;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStream_AddRef(LPSTREAM iface)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
return ++(This->RefCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStream_Release(LPSTREAM iface)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (!--(This->RefCount)) {
|
||||
TRACE("size=%d\n", *This->size);
|
||||
This->pMsg->Buffer = (unsigned char*)This->data + *This->size;
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return 0;
|
||||
}
|
||||
return This->RefCount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Read(LPSTREAM iface,
|
||||
void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbRead)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
HRESULT hr = S_OK;
|
||||
if (This->pos + cb > *This->size)
|
||||
{
|
||||
cb = *This->size - This->pos;
|
||||
hr = S_FALSE;
|
||||
}
|
||||
if (cb) {
|
||||
memcpy(pv, This->data + This->pos, cb);
|
||||
This->pos += cb;
|
||||
}
|
||||
if (pcbRead) *pcbRead = cb;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Write(LPSTREAM iface,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (This->data + cb > (char *)This->pMsg->BufferEnd)
|
||||
return STG_E_MEDIUMFULL;
|
||||
memcpy(This->data + This->pos, pv, cb);
|
||||
This->pos += cb;
|
||||
if (This->pos > *This->size) *This->size = This->pos;
|
||||
if (pcbWritten) *pcbWritten = cb;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Seek(LPSTREAM iface,
|
||||
LARGE_INTEGER move,
|
||||
DWORD origin,
|
||||
ULARGE_INTEGER *newPos)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
switch (origin) {
|
||||
case STREAM_SEEK_SET:
|
||||
This->pos = move.u.LowPart;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
This->pos = This->pos + move.u.LowPart;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
This->pos = *This->size + move.u.LowPart;
|
||||
break;
|
||||
default:
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
if (newPos) {
|
||||
newPos->u.LowPart = This->pos;
|
||||
newPos->u.HighPart = 0;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_SetSize(LPSTREAM iface,
|
||||
ULARGE_INTEGER newSize)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
*This->size = newSize.u.LowPart;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IStreamVtbl RpcStream_Vtbl =
|
||||
{
|
||||
RpcStream_QueryInterface,
|
||||
RpcStream_AddRef,
|
||||
RpcStream_Release,
|
||||
RpcStream_Read,
|
||||
RpcStream_Write,
|
||||
RpcStream_Seek,
|
||||
RpcStream_SetSize,
|
||||
NULL, /* CopyTo */
|
||||
NULL, /* Commit */
|
||||
NULL, /* Revert */
|
||||
NULL, /* LockRegion */
|
||||
NULL, /* UnlockRegion */
|
||||
NULL, /* Stat */
|
||||
NULL /* Clone */
|
||||
};
|
||||
|
||||
static LPSTREAM RpcStream_Create(PMIDL_STUB_MESSAGE pStubMsg, BOOL init)
|
||||
{
|
||||
RpcStreamImpl *This;
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(RpcStreamImpl));
|
||||
if (!This) return NULL;
|
||||
This->lpVtbl = &RpcStream_Vtbl;
|
||||
This->RefCount = 1;
|
||||
This->pMsg = pStubMsg;
|
||||
This->size = (LPDWORD)pStubMsg->Buffer;
|
||||
This->data = (char*)(This->size + 1);
|
||||
This->pos = 0;
|
||||
if (init) *This->size = 0;
|
||||
TRACE("init size=%d\n", *This->size);
|
||||
return (LPSTREAM)This;
|
||||
}
|
||||
|
||||
static const IID* get_ip_iid(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid;
|
||||
if (!pFormat) return &IID_IUnknown;
|
||||
TRACE("format=%02x %02x\n", pFormat[0], pFormat[1]);
|
||||
if (pFormat[0] != RPC_FC_IP) FIXME("format=%d\n", pFormat[0]);
|
||||
if (pFormat[1] == RPC_FC_CONSTANT_IID) {
|
||||
riid = (const IID *)&pFormat[2];
|
||||
} else {
|
||||
ComputeConformance(pStubMsg, pMemory, pFormat+2, 0);
|
||||
riid = (const IID *)pStubMsg->MaxCount;
|
||||
}
|
||||
if (!riid) riid = &IID_IUnknown;
|
||||
TRACE("got %s\n", debugstr_guid(riid));
|
||||
return riid;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerMarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat);
|
||||
LPSTREAM stream;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
pStubMsg->MaxCount = 0;
|
||||
if (!LoadCOM()) return NULL;
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
stream = RpcStream_Create(pStubMsg, TRUE);
|
||||
if (stream) {
|
||||
if (pMemory)
|
||||
hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory,
|
||||
pStubMsg->dwDestContext, pStubMsg->pvDestContext,
|
||||
MSHLFLAGS_NORMAL);
|
||||
else
|
||||
hr = S_OK;
|
||||
|
||||
IStream_Release(stream);
|
||||
if (FAILED(hr))
|
||||
RpcRaiseException(hr);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerUnmarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char **ppMemory,
|
||||
PFORMAT_STRING pFormat,
|
||||
unsigned char fMustAlloc)
|
||||
{
|
||||
LPSTREAM stream;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
|
||||
if (!LoadCOM()) return NULL;
|
||||
*(LPVOID*)ppMemory = NULL;
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
stream = RpcStream_Create(pStubMsg, FALSE);
|
||||
if (!stream) RpcRaiseException(E_OUTOFMEMORY);
|
||||
if (*((RpcStreamImpl *)stream)->size != 0)
|
||||
hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory);
|
||||
else
|
||||
hr = S_OK;
|
||||
IStream_Release(stream);
|
||||
if (FAILED(hr))
|
||||
RpcRaiseException(hr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerBufferSize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat);
|
||||
ULONG size = 0;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
if (!LoadCOM()) return;
|
||||
hr = COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory,
|
||||
pStubMsg->dwDestContext, pStubMsg->pvDestContext,
|
||||
MSHLFLAGS_NORMAL);
|
||||
TRACE("size=%d\n", size);
|
||||
pStubMsg->BufferLength += sizeof(DWORD) + size;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerMemorySize [RPCRT4.@]
|
||||
*/
|
||||
ULONG WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG size;
|
||||
|
||||
TRACE("(%p,%p)\n", pStubMsg, pFormat);
|
||||
|
||||
size = *(ULONG *)pStubMsg->Buffer;
|
||||
pStubMsg->Buffer += 4;
|
||||
pStubMsg->MemorySize += 4;
|
||||
|
||||
pStubMsg->Buffer += size;
|
||||
|
||||
return pStubMsg->MemorySize;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerFree [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
LPUNKNOWN pUnk = (LPUNKNOWN)pMemory;
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
if (pUnk) IUnknown_Release(pUnk);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrOleAllocate [RPCRT4.@]
|
||||
*/
|
||||
void * WINAPI NdrOleAllocate(size_t Size)
|
||||
{
|
||||
if (!LoadCOM()) return NULL;
|
||||
return COM_MemAlloc(Size);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrOleFree [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrOleFree(void *NodeToFree)
|
||||
{
|
||||
if (!LoadCOM()) return;
|
||||
COM_MemFree(NodeToFree);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Helper function to create a stub.
|
||||
* This probably looks very much like NdrpCreateStub.
|
||||
*/
|
||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub)
|
||||
{
|
||||
CLSID clsid;
|
||||
IPSFactoryBuffer *psfac;
|
||||
HRESULT r;
|
||||
|
||||
if(!LoadCOM()) return E_FAIL;
|
||||
|
||||
r = COM_GetPSClsid( iid, &clsid );
|
||||
if(FAILED(r)) return r;
|
||||
|
||||
r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac );
|
||||
if(FAILED(r)) return r;
|
||||
|
||||
r = IPSFactoryBuffer_CreateStub(psfac, iid, pUnk, ppstub);
|
||||
|
||||
IPSFactoryBuffer_Release(psfac);
|
||||
return r;
|
||||
}
|
||||
/*
|
||||
* OLE32 callouts, COM interface marshalling
|
||||
*
|
||||
* Copyright 2001 Ove Kåven, TransGaming Technologies
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* TODO:
|
||||
* - fix the wire-protocol to match MS/RPC
|
||||
* - finish RpcStream_Vtbl
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "objbase.h"
|
||||
|
||||
#include "ndr_misc.h"
|
||||
#include "rpcndr.h"
|
||||
#include "rpcproxy.h"
|
||||
#include "wine/rpcfc.h"
|
||||
#include "cpsf.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
static HMODULE hOLE;
|
||||
|
||||
static HRESULT (WINAPI *COM_GetMarshalSizeMax)(ULONG *,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD);
|
||||
static HRESULT (WINAPI *COM_MarshalInterface)(LPSTREAM,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD);
|
||||
static HRESULT (WINAPI *COM_UnmarshalInterface)(LPSTREAM,REFIID,LPVOID*);
|
||||
static HRESULT (WINAPI *COM_ReleaseMarshalData)(LPSTREAM);
|
||||
static HRESULT (WINAPI *COM_GetClassObject)(REFCLSID,DWORD,COSERVERINFO *,REFIID,LPVOID *);
|
||||
static HRESULT (WINAPI *COM_GetPSClsid)(REFIID,CLSID *);
|
||||
static LPVOID (WINAPI *COM_MemAlloc)(ULONG);
|
||||
static void (WINAPI *COM_MemFree)(LPVOID);
|
||||
|
||||
static HMODULE LoadCOM(void)
|
||||
{
|
||||
if (hOLE) return hOLE;
|
||||
hOLE = LoadLibraryA("OLE32.DLL");
|
||||
if (!hOLE) return 0;
|
||||
COM_GetMarshalSizeMax = (LPVOID)GetProcAddress(hOLE, "CoGetMarshalSizeMax");
|
||||
COM_MarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoMarshalInterface");
|
||||
COM_UnmarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoUnmarshalInterface");
|
||||
COM_ReleaseMarshalData = (LPVOID)GetProcAddress(hOLE, "CoReleaseMarshalData");
|
||||
COM_GetClassObject = (LPVOID)GetProcAddress(hOLE, "CoGetClassObject");
|
||||
COM_GetPSClsid = (LPVOID)GetProcAddress(hOLE, "CoGetPSClsid");
|
||||
COM_MemAlloc = (LPVOID)GetProcAddress(hOLE, "CoTaskMemAlloc");
|
||||
COM_MemFree = (LPVOID)GetProcAddress(hOLE, "CoTaskMemFree");
|
||||
return hOLE;
|
||||
}
|
||||
|
||||
/* CoMarshalInterface/CoUnmarshalInterface works on streams,
|
||||
* so implement a simple stream on top of the RPC buffer
|
||||
* (which also implements the MInterfacePointer structure) */
|
||||
typedef struct RpcStreamImpl
|
||||
{
|
||||
const IStreamVtbl *lpVtbl;
|
||||
DWORD RefCount;
|
||||
PMIDL_STUB_MESSAGE pMsg;
|
||||
LPDWORD size;
|
||||
unsigned char *data;
|
||||
DWORD pos;
|
||||
} RpcStreamImpl;
|
||||
|
||||
static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface,
|
||||
REFIID riid,
|
||||
LPVOID *obj)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (IsEqualGUID(&IID_IUnknown, riid) ||
|
||||
IsEqualGUID(&IID_ISequentialStream, riid) ||
|
||||
IsEqualGUID(&IID_IStream, riid)) {
|
||||
*obj = This;
|
||||
This->RefCount++;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStream_AddRef(LPSTREAM iface)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
return ++(This->RefCount);
|
||||
}
|
||||
|
||||
static ULONG WINAPI RpcStream_Release(LPSTREAM iface)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (!--(This->RefCount)) {
|
||||
TRACE("size=%d\n", *This->size);
|
||||
This->pMsg->Buffer = (unsigned char*)This->data + *This->size;
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
return 0;
|
||||
}
|
||||
return This->RefCount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Read(LPSTREAM iface,
|
||||
void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbRead)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
HRESULT hr = S_OK;
|
||||
if (This->pos + cb > *This->size)
|
||||
{
|
||||
cb = *This->size - This->pos;
|
||||
hr = S_FALSE;
|
||||
}
|
||||
if (cb) {
|
||||
memcpy(pv, This->data + This->pos, cb);
|
||||
This->pos += cb;
|
||||
}
|
||||
if (pcbRead) *pcbRead = cb;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Write(LPSTREAM iface,
|
||||
const void *pv,
|
||||
ULONG cb,
|
||||
ULONG *pcbWritten)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
if (This->data + cb > (unsigned char *)This->pMsg->RpcMsg->Buffer + This->pMsg->BufferLength)
|
||||
return STG_E_MEDIUMFULL;
|
||||
memcpy(This->data + This->pos, pv, cb);
|
||||
This->pos += cb;
|
||||
if (This->pos > *This->size) *This->size = This->pos;
|
||||
if (pcbWritten) *pcbWritten = cb;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_Seek(LPSTREAM iface,
|
||||
LARGE_INTEGER move,
|
||||
DWORD origin,
|
||||
ULARGE_INTEGER *newPos)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
switch (origin) {
|
||||
case STREAM_SEEK_SET:
|
||||
This->pos = move.u.LowPart;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
This->pos = This->pos + move.u.LowPart;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
This->pos = *This->size + move.u.LowPart;
|
||||
break;
|
||||
default:
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
if (newPos) {
|
||||
newPos->u.LowPart = This->pos;
|
||||
newPos->u.HighPart = 0;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RpcStream_SetSize(LPSTREAM iface,
|
||||
ULARGE_INTEGER newSize)
|
||||
{
|
||||
RpcStreamImpl *This = (RpcStreamImpl *)iface;
|
||||
*This->size = newSize.u.LowPart;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IStreamVtbl RpcStream_Vtbl =
|
||||
{
|
||||
RpcStream_QueryInterface,
|
||||
RpcStream_AddRef,
|
||||
RpcStream_Release,
|
||||
RpcStream_Read,
|
||||
RpcStream_Write,
|
||||
RpcStream_Seek,
|
||||
RpcStream_SetSize,
|
||||
NULL, /* CopyTo */
|
||||
NULL, /* Commit */
|
||||
NULL, /* Revert */
|
||||
NULL, /* LockRegion */
|
||||
NULL, /* UnlockRegion */
|
||||
NULL, /* Stat */
|
||||
NULL /* Clone */
|
||||
};
|
||||
|
||||
static LPSTREAM RpcStream_Create(PMIDL_STUB_MESSAGE pStubMsg, BOOL init)
|
||||
{
|
||||
RpcStreamImpl *This;
|
||||
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(RpcStreamImpl));
|
||||
if (!This) return NULL;
|
||||
This->lpVtbl = &RpcStream_Vtbl;
|
||||
This->RefCount = 1;
|
||||
This->pMsg = pStubMsg;
|
||||
This->size = (LPDWORD)pStubMsg->Buffer;
|
||||
This->data = (unsigned char*)(This->size + 1);
|
||||
This->pos = 0;
|
||||
if (init) *This->size = 0;
|
||||
TRACE("init size=%d\n", *This->size);
|
||||
return (LPSTREAM)This;
|
||||
}
|
||||
|
||||
static const IID* get_ip_iid(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid;
|
||||
if (!pFormat) return &IID_IUnknown;
|
||||
TRACE("format=%02x %02x\n", pFormat[0], pFormat[1]);
|
||||
if (pFormat[0] != RPC_FC_IP) FIXME("format=%d\n", pFormat[0]);
|
||||
if (pFormat[1] == RPC_FC_CONSTANT_IID) {
|
||||
riid = (const IID *)&pFormat[2];
|
||||
} else {
|
||||
ComputeConformance(pStubMsg, pMemory, pFormat+2, 0);
|
||||
riid = (const IID *)pStubMsg->MaxCount;
|
||||
}
|
||||
if (!riid) riid = &IID_IUnknown;
|
||||
TRACE("got %s\n", debugstr_guid(riid));
|
||||
return riid;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerMarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat);
|
||||
LPSTREAM stream;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
pStubMsg->MaxCount = 0;
|
||||
if (!LoadCOM()) return NULL;
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
stream = RpcStream_Create(pStubMsg, TRUE);
|
||||
if (stream) {
|
||||
if (pMemory)
|
||||
hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory,
|
||||
pStubMsg->dwDestContext, pStubMsg->pvDestContext,
|
||||
MSHLFLAGS_NORMAL);
|
||||
else
|
||||
hr = S_OK;
|
||||
|
||||
IStream_Release(stream);
|
||||
if (FAILED(hr))
|
||||
RpcRaiseException(hr);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerUnmarshall [RPCRT4.@]
|
||||
*/
|
||||
unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char **ppMemory,
|
||||
PFORMAT_STRING pFormat,
|
||||
unsigned char fMustAlloc)
|
||||
{
|
||||
LPSTREAM stream;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
|
||||
if (!LoadCOM()) return NULL;
|
||||
*(LPVOID*)ppMemory = NULL;
|
||||
if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
|
||||
stream = RpcStream_Create(pStubMsg, FALSE);
|
||||
if (!stream) RpcRaiseException(E_OUTOFMEMORY);
|
||||
if (*((RpcStreamImpl *)stream)->size != 0)
|
||||
hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory);
|
||||
else
|
||||
hr = S_OK;
|
||||
IStream_Release(stream);
|
||||
if (FAILED(hr))
|
||||
RpcRaiseException(hr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerBufferSize [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat);
|
||||
ULONG size = 0;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
if (!LoadCOM()) return;
|
||||
hr = COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory,
|
||||
pStubMsg->dwDestContext, pStubMsg->pvDestContext,
|
||||
MSHLFLAGS_NORMAL);
|
||||
TRACE("size=%d\n", size);
|
||||
pStubMsg->BufferLength += sizeof(DWORD) + size;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerMemorySize [RPCRT4.@]
|
||||
*/
|
||||
ULONG WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
ULONG size;
|
||||
|
||||
TRACE("(%p,%p)\n", pStubMsg, pFormat);
|
||||
|
||||
size = *(ULONG *)pStubMsg->Buffer;
|
||||
pStubMsg->Buffer += 4;
|
||||
pStubMsg->MemorySize += 4;
|
||||
|
||||
pStubMsg->Buffer += size;
|
||||
|
||||
return pStubMsg->MemorySize;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrInterfacePointerFree [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg,
|
||||
unsigned char *pMemory,
|
||||
PFORMAT_STRING pFormat)
|
||||
{
|
||||
LPUNKNOWN pUnk = (LPUNKNOWN)pMemory;
|
||||
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
|
||||
if (pUnk) IUnknown_Release(pUnk);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrOleAllocate [RPCRT4.@]
|
||||
*/
|
||||
void * WINAPI NdrOleAllocate(size_t Size)
|
||||
{
|
||||
if (!LoadCOM()) return NULL;
|
||||
return COM_MemAlloc(Size);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NdrOleFree [RPCRT4.@]
|
||||
*/
|
||||
void WINAPI NdrOleFree(void *NodeToFree)
|
||||
{
|
||||
if (!LoadCOM()) return;
|
||||
COM_MemFree(NodeToFree);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Helper function to create a stub.
|
||||
* This probably looks very much like NdrpCreateStub.
|
||||
*/
|
||||
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub)
|
||||
{
|
||||
CLSID clsid;
|
||||
IPSFactoryBuffer *psfac;
|
||||
HRESULT r;
|
||||
|
||||
if(!LoadCOM()) return E_FAIL;
|
||||
|
||||
r = COM_GetPSClsid( iid, &clsid );
|
||||
if(FAILED(r)) return r;
|
||||
|
||||
r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac );
|
||||
if(FAILED(r)) return r;
|
||||
|
||||
r = IPSFactoryBuffer_CreateStub(psfac, iid, pUnk, ppstub);
|
||||
|
||||
IPSFactoryBuffer_Release(psfac);
|
||||
return r;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
236
reactos/dll/win32/rpcrt4_new/ndr_stubless.h
Normal file
236
reactos/dll/win32/rpcrt4_new/ndr_stubless.h
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* NDR -Oi,-Oif,-Oicf Interpreter
|
||||
*
|
||||
* Copyright 2007 Robert Shearman (for CodeWeavers)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* there can't be any alignment with the structures in this file */
|
||||
#include "pshpack1.h"
|
||||
|
||||
/* From http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/parameter_descriptors.asp */
|
||||
typedef struct _NDR_PROC_HEADER
|
||||
{
|
||||
/* type of handle to use:
|
||||
* RPC_FC_BIND_EXPLICIT = 0 - Explicit handle.
|
||||
* Handle is passed as a parameter to the function.
|
||||
* Indicates that explicit handle information follows the header,
|
||||
* which actually describes the handle.
|
||||
* RPC_FC_BIND_GENERIC = 31 - Implicit handle with custom binding routines
|
||||
* (MIDL_STUB_DESC::IMPLICIT_HANDLE_INFO::pGenericBindingInfo)
|
||||
* RPC_FC_BIND_PRIMITIVE = 32 - Implicit handle using handle_t created by
|
||||
* calling application
|
||||
* RPC_FC_AUTO_HANDLE = 33 - Automatic handle
|
||||
* RPC_FC_CALLBACK_HANDLE = 34 - undocmented
|
||||
*/
|
||||
unsigned char handle_type;
|
||||
|
||||
/* procedure flags:
|
||||
* Oi_FULL_PTR_USED = 0x01 - A full pointer can have the value NULL and can
|
||||
* change during the call from NULL to non-NULL and supports aliasing
|
||||
* and cycles. Indicates that the NdrFullPointerXlatInit function
|
||||
* should be called.
|
||||
* Oi_RPCSS_ALLOC_USED = 0x02 - Use RpcSS allocate/free routines instead of
|
||||
* normal allocate/free routines
|
||||
* Oi_OBJECT_PROC = 0x04 - Indicates a procedure that is part of an OLE
|
||||
* interface, rather than a DCE RPC interface.
|
||||
* Oi_HAS_RPCFLAGS = 0x08 - Indicates that the rpc_flags element is
|
||||
* present in the header.
|
||||
* Oi_HAS_COMM_OR_FAULT = 0x20 - If Oi_OBJECT_PROC not present only then
|
||||
* indicates that the procedure has the comm_status or fault_status
|
||||
* MIDL attribute.
|
||||
* Oi_OBJ_USE_V2_INTERPRETER = 0x20 - If Oi_OBJECT_PROC present only
|
||||
* then indicates that the format string is in -Oif or -Oicf format
|
||||
* Oi_USE_NEW_INIT_ROUTINES = 0x40 - Use NdrXInitializeNew instead of
|
||||
* NdrXInitialize?
|
||||
*/
|
||||
unsigned char Oi_flags;
|
||||
|
||||
/* the zero-based index of the procedure */
|
||||
unsigned short proc_num;
|
||||
|
||||
/* total size of all parameters on the stack, including any "this"
|
||||
* pointer and/or return value */
|
||||
unsigned short stack_size;
|
||||
} NDR_PROC_HEADER;
|
||||
|
||||
/* same as above struct except additional element rpc_flags */
|
||||
typedef struct _NDR_PROC_HEADER_RPC
|
||||
{
|
||||
unsigned char handle_type;
|
||||
unsigned char Oi_flags;
|
||||
|
||||
/*
|
||||
* RPCF_Idempotent = 0x0001 - [idempotent] MIDL attribute
|
||||
* RPCF_Broadcast = 0x0002 - [broadcast] MIDL attribute
|
||||
* RPCF_Maybe = 0x0004 - [maybe] MIDL attribute
|
||||
* Reserved = 0x0008 - 0x0080
|
||||
* RPCF_Message = 0x0100 - [message] MIDL attribute
|
||||
* Reserved = 0x0200 - 0x1000
|
||||
* RPCF_InputSynchronous = 0x2000 - unknown
|
||||
* RPCF_Asynchronous = 0x4000 - [async] MIDL attribute
|
||||
* Reserved = 0x8000
|
||||
*/
|
||||
unsigned long rpc_flags;
|
||||
unsigned short proc_num;
|
||||
unsigned short stack_size;
|
||||
|
||||
} NDR_PROC_HEADER_RPC;
|
||||
|
||||
typedef struct _NDR_PROC_PARTIAL_OIF_HEADER
|
||||
{
|
||||
/* the pre-computed client buffer size so that interpreter can skip all
|
||||
* or some (if the flag RPC_FC_PROC_OI2F_CLTMUSTSIZE is specified) of the
|
||||
* sizing pass */
|
||||
unsigned short constant_client_buffer_size;
|
||||
|
||||
/* the pre-computed server buffer size so that interpreter can skip all
|
||||
* or some (if the flag RPC_FC_PROC_OI2F_SRVMUSTSIZE is specified) of the
|
||||
* sizing pass */
|
||||
unsigned short constant_server_buffer_size;
|
||||
|
||||
INTERPRETER_OPT_FLAGS Oi2Flags;
|
||||
|
||||
/* number of params */
|
||||
unsigned char number_of_params;
|
||||
} NDR_PROC_PARTIAL_OIF_HEADER;
|
||||
|
||||
typedef struct _NDR_PARAM_OI_BASETYPE
|
||||
{
|
||||
/* parameter direction. One of:
|
||||
* FC_IN_PARAM_BASETYPE = 0x4e - an in param
|
||||
* FC_RETURN_PARAM_BASETYPE = 0x53 - a return param
|
||||
*/
|
||||
unsigned char param_direction;
|
||||
|
||||
/* One of: FC_BYTE,FC_CHAR,FC_SMALL,FC_USMALL,FC_WCHAR,FC_SHORT,FC_USHORT,
|
||||
* FC_LONG,FC_ULONG,FC_FLOAT,FC_HYPER,FC_DOUBLE,FC_ENUM16,FC_ENUM32,
|
||||
* FC_ERROR_STATUS_T,FC_INT3264,FC_UINT3264 */
|
||||
unsigned char type_format_char;
|
||||
} NDR_PARAM_OI_BASETYPE;
|
||||
|
||||
typedef struct _NDR_PARAM_OI_OTHER
|
||||
{
|
||||
/* One of:
|
||||
* FC_IN_PARAM = 0x4d - An in param
|
||||
* FC_IN_OUT_PARAM = 0x50 - An in/out param
|
||||
* FC_OUT_PARAM = 0x51 - An out param
|
||||
* FC_RETURN_PARAM = 0x52 - A return value
|
||||
* FC_IN_PARAM_NO_FREE_INST = 0x4f - A param for which no freeing is done
|
||||
*/
|
||||
unsigned char param_direction;
|
||||
|
||||
/* Size of param on stack in NUMBERS OF INTS */
|
||||
unsigned char stack_size;
|
||||
|
||||
/* offset in the type format string table */
|
||||
unsigned short type_offset;
|
||||
} NDR_PARAM_OI_OTHER;
|
||||
|
||||
typedef struct _NDR_PARAM_OIF_BASETYPE
|
||||
{
|
||||
PARAM_ATTRIBUTES param_attributes;
|
||||
|
||||
/* the offset on the calling stack where the parameter is located */
|
||||
unsigned short stack_offset;
|
||||
|
||||
/* see NDR_PARAM_OI_BASETYPE::type_format_char */
|
||||
unsigned char type_format_char;
|
||||
|
||||
/* always FC_PAD */
|
||||
unsigned char unused;
|
||||
} NDR_PARAM_OIF_BASETYPE;
|
||||
|
||||
typedef struct _NDR_PARAM_OIF_OTHER
|
||||
{
|
||||
PARAM_ATTRIBUTES param_attributes;
|
||||
|
||||
/* see NDR_PARAM_OIF_BASETYPE::stack_offset */
|
||||
unsigned short stack_offset;
|
||||
|
||||
/* offset into the provided type format string where the type for this
|
||||
* parameter starts */
|
||||
unsigned short type_offset;
|
||||
} NDR_PARAM_OIF_OTHER;
|
||||
|
||||
/* explicit handle description for FC_BIND_PRIMITIVE type */
|
||||
typedef struct _NDR_EHD_PRIMITIVE
|
||||
{
|
||||
/* FC_BIND_PRIMITIVE */
|
||||
unsigned char handle_type;
|
||||
|
||||
/* is the handle passed in via a pointer? */
|
||||
unsigned char flag;
|
||||
|
||||
/* offset from the beginning of the stack to the handle in bytes */
|
||||
unsigned short offset;
|
||||
} NDR_EHD_PRIMITIVE;
|
||||
|
||||
/* explicit handle description for FC_BIND_GENERIC type */
|
||||
typedef struct _NDR_EHD_GENERIC
|
||||
{
|
||||
/* FC_BIND_GENERIC */
|
||||
unsigned char handle_type;
|
||||
|
||||
/* upper 4bits is a flag indicating whether the handle is passed in
|
||||
* via a pointer. lower 4bits is the size of the user defined generic
|
||||
* handle type. the size must be less than or equal to the machine
|
||||
* register size */
|
||||
unsigned char flag_and_size;
|
||||
|
||||
/* offset from the beginning of the stack to the handle in bytes */
|
||||
unsigned short offset;
|
||||
|
||||
/* the index into the aGenericBindingRoutinesPairs field of MIDL_STUB_DESC
|
||||
* giving the bind and unbind routines for the handle */
|
||||
unsigned char binding_routine_pair_index;
|
||||
|
||||
/* FC_PAD */
|
||||
unsigned char unused;
|
||||
} NDR_EHD_GENERIC;
|
||||
|
||||
/* explicit handle description for FC_BIND_CONTEXT type */
|
||||
typedef struct _NDR_EHD_CONTEXT
|
||||
{
|
||||
/* FC_BIND_CONTEXT */
|
||||
unsigned char handle_type;
|
||||
|
||||
/* Any of the following flags:
|
||||
* NDR_CONTEXT_HANDLE_CANNOT_BE_NULL = 0x01
|
||||
* NDR_CONTEXT_HANDLE_SERIALIZE = 0x02
|
||||
* NDR_CONTEXT_HANDLE_NO_SERIALIZE = 0x04
|
||||
* NDR_STRICT_CONTEXT_HANDLE = 0x08
|
||||
* HANDLE_PARAM_IS_OUT = 0x20
|
||||
* HANDLE_PARAM_IS_RETURN = 0x21
|
||||
* HANDLE_PARAM_IS_IN = 0x40
|
||||
* HANDLE_PARAM_IS_VIA_PTR = 0x80
|
||||
*/
|
||||
unsigned char flags;
|
||||
|
||||
/* offset from the beginning of the stack to the handle in bytes */
|
||||
unsigned short offset;
|
||||
|
||||
/* zero-based index on rundown routine in apfnNdrRundownRoutines field
|
||||
* of MIDL_STUB_DESC */
|
||||
unsigned char context_rundown_routine_index;
|
||||
|
||||
/* varies depending on NDR version used.
|
||||
* V1: zero-based index into parameters
|
||||
* V2: zero-based index into handles that are parameters */
|
||||
unsigned char param_num;
|
||||
} NDR_EHD_CONTEXT;
|
||||
|
||||
#include "poppack.h"
|
539
reactos/dll/win32/rpcrt4_new/rpc_assoc.c
Normal file
539
reactos/dll/win32/rpcrt4_new/rpc_assoc.c
Normal file
|
@ -0,0 +1,539 @@
|
|||
/*
|
||||
* Associations
|
||||
*
|
||||
* Copyright 2007 Robert Shearman (for CodeWeavers)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
#include "winternl.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "rpc_assoc.h"
|
||||
#include "rpc_message.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
static CRITICAL_SECTION assoc_list_cs;
|
||||
static CRITICAL_SECTION_DEBUG assoc_list_cs_debug =
|
||||
{
|
||||
0, 0, &assoc_list_cs,
|
||||
{ &assoc_list_cs_debug.ProcessLocksList, &assoc_list_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": assoc_list_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION assoc_list_cs = { &assoc_list_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
static struct list client_assoc_list = LIST_INIT(client_assoc_list);
|
||||
static struct list server_assoc_list = LIST_INIT(server_assoc_list);
|
||||
|
||||
static LONG last_assoc_group_id;
|
||||
|
||||
typedef struct _RpcContextHandle
|
||||
{
|
||||
struct list entry;
|
||||
void *user_context;
|
||||
NDR_RUNDOWN rundown_routine;
|
||||
void *ctx_guard;
|
||||
UUID uuid;
|
||||
RTL_RWLOCK rw_lock;
|
||||
unsigned int refs;
|
||||
} RpcContextHandle;
|
||||
|
||||
static void RpcContextHandle_Destroy(RpcContextHandle *context_handle);
|
||||
|
||||
static RPC_STATUS RpcAssoc_Alloc(LPCSTR Protseq, LPCSTR NetworkAddr,
|
||||
LPCSTR Endpoint, LPCWSTR NetworkOptions,
|
||||
RpcAssoc **assoc_out)
|
||||
{
|
||||
RpcAssoc *assoc;
|
||||
assoc = HeapAlloc(GetProcessHeap(), 0, sizeof(*assoc));
|
||||
if (!assoc)
|
||||
return RPC_S_OUT_OF_RESOURCES;
|
||||
assoc->refs = 1;
|
||||
list_init(&assoc->free_connection_pool);
|
||||
list_init(&assoc->context_handle_list);
|
||||
InitializeCriticalSection(&assoc->cs);
|
||||
assoc->Protseq = RPCRT4_strdupA(Protseq);
|
||||
assoc->NetworkAddr = RPCRT4_strdupA(NetworkAddr);
|
||||
assoc->Endpoint = RPCRT4_strdupA(Endpoint);
|
||||
assoc->NetworkOptions = NetworkOptions ? RPCRT4_strdupW(NetworkOptions) : NULL;
|
||||
assoc->assoc_group_id = 0;
|
||||
list_init(&assoc->entry);
|
||||
*assoc_out = assoc;
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr,
|
||||
LPCSTR Endpoint, LPCWSTR NetworkOptions,
|
||||
RpcAssoc **assoc_out)
|
||||
{
|
||||
RpcAssoc *assoc;
|
||||
RPC_STATUS status;
|
||||
|
||||
EnterCriticalSection(&assoc_list_cs);
|
||||
LIST_FOR_EACH_ENTRY(assoc, &client_assoc_list, RpcAssoc, entry)
|
||||
{
|
||||
if (!strcmp(Protseq, assoc->Protseq) &&
|
||||
!strcmp(NetworkAddr, assoc->NetworkAddr) &&
|
||||
!strcmp(Endpoint, assoc->Endpoint) &&
|
||||
((!assoc->NetworkOptions && !NetworkOptions) || !strcmpW(NetworkOptions, assoc->NetworkOptions)))
|
||||
{
|
||||
assoc->refs++;
|
||||
*assoc_out = assoc;
|
||||
LeaveCriticalSection(&assoc_list_cs);
|
||||
TRACE("using existing assoc %p\n", assoc);
|
||||
return RPC_S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
status = RpcAssoc_Alloc(Protseq, NetworkAddr, Endpoint, NetworkOptions, &assoc);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
LeaveCriticalSection(&assoc_list_cs);
|
||||
return status;
|
||||
}
|
||||
list_add_head(&client_assoc_list, &assoc->entry);
|
||||
*assoc_out = assoc;
|
||||
|
||||
LeaveCriticalSection(&assoc_list_cs);
|
||||
|
||||
TRACE("new assoc %p\n", assoc);
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr,
|
||||
LPCSTR Endpoint, LPCWSTR NetworkOptions,
|
||||
unsigned long assoc_gid,
|
||||
RpcAssoc **assoc_out)
|
||||
{
|
||||
RpcAssoc *assoc;
|
||||
RPC_STATUS status;
|
||||
|
||||
EnterCriticalSection(&assoc_list_cs);
|
||||
if (assoc_gid)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY(assoc, &server_assoc_list, RpcAssoc, entry)
|
||||
{
|
||||
/* FIXME: NetworkAddr shouldn't be NULL */
|
||||
if (assoc->assoc_group_id == assoc_gid &&
|
||||
!strcmp(Protseq, assoc->Protseq) &&
|
||||
(!NetworkAddr || !assoc->NetworkAddr || !strcmp(NetworkAddr, assoc->NetworkAddr)) &&
|
||||
!strcmp(Endpoint, assoc->Endpoint) &&
|
||||
((!assoc->NetworkOptions == !NetworkOptions) &&
|
||||
(!NetworkOptions || !strcmpW(NetworkOptions, assoc->NetworkOptions))))
|
||||
{
|
||||
assoc->refs++;
|
||||
*assoc_out = assoc;
|
||||
LeaveCriticalSection(&assoc_list_cs);
|
||||
TRACE("using existing assoc %p\n", assoc);
|
||||
return RPC_S_OK;
|
||||
}
|
||||
}
|
||||
*assoc_out = NULL;
|
||||
LeaveCriticalSection(&assoc_list_cs);
|
||||
return RPC_S_NO_CONTEXT_AVAILABLE;
|
||||
}
|
||||
|
||||
status = RpcAssoc_Alloc(Protseq, NetworkAddr, Endpoint, NetworkOptions, &assoc);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
LeaveCriticalSection(&assoc_list_cs);
|
||||
return status;
|
||||
}
|
||||
assoc->assoc_group_id = InterlockedIncrement(&last_assoc_group_id);
|
||||
list_add_head(&server_assoc_list, &assoc->entry);
|
||||
*assoc_out = assoc;
|
||||
|
||||
LeaveCriticalSection(&assoc_list_cs);
|
||||
|
||||
TRACE("new assoc %p\n", assoc);
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
ULONG RpcAssoc_Release(RpcAssoc *assoc)
|
||||
{
|
||||
ULONG refs;
|
||||
|
||||
EnterCriticalSection(&assoc_list_cs);
|
||||
refs = --assoc->refs;
|
||||
if (!refs)
|
||||
list_remove(&assoc->entry);
|
||||
LeaveCriticalSection(&assoc_list_cs);
|
||||
|
||||
if (!refs)
|
||||
{
|
||||
RpcConnection *Connection, *cursor2;
|
||||
RpcContextHandle *context_handle, *context_handle_cursor;
|
||||
|
||||
TRACE("destroying assoc %p\n", assoc);
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(Connection, cursor2, &assoc->free_connection_pool, RpcConnection, conn_pool_entry)
|
||||
{
|
||||
list_remove(&Connection->conn_pool_entry);
|
||||
RPCRT4_DestroyConnection(Connection);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(context_handle, context_handle_cursor, &assoc->context_handle_list, RpcContextHandle, entry)
|
||||
RpcContextHandle_Destroy(context_handle);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, assoc->NetworkOptions);
|
||||
HeapFree(GetProcessHeap(), 0, assoc->Endpoint);
|
||||
HeapFree(GetProcessHeap(), 0, assoc->NetworkAddr);
|
||||
HeapFree(GetProcessHeap(), 0, assoc->Protseq);
|
||||
|
||||
DeleteCriticalSection(&assoc->cs);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, assoc);
|
||||
}
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
||||
#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
|
||||
|
||||
static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection *conn,
|
||||
const RPC_SYNTAX_IDENTIFIER *InterfaceId,
|
||||
const RPC_SYNTAX_IDENTIFIER *TransferSyntax)
|
||||
{
|
||||
RpcPktHdr *hdr;
|
||||
RpcPktHdr *response_hdr;
|
||||
RPC_MESSAGE msg;
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("sending bind request to server\n");
|
||||
|
||||
hdr = RPCRT4_BuildBindHeader(NDR_LOCAL_DATA_REPRESENTATION,
|
||||
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE,
|
||||
assoc->assoc_group_id,
|
||||
InterfaceId, TransferSyntax);
|
||||
|
||||
status = RPCRT4_Send(conn, hdr, NULL, 0);
|
||||
RPCRT4_FreeHeader(hdr);
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
status = RPCRT4_Receive(conn, &response_hdr, &msg);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
ERR("receive failed\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (response_hdr->common.ptype)
|
||||
{
|
||||
case PKT_BIND_ACK:
|
||||
{
|
||||
RpcAddressString *server_address = msg.Buffer;
|
||||
if ((msg.BufferLength >= FIELD_OFFSET(RpcAddressString, string[0])) ||
|
||||
(msg.BufferLength >= ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4)))
|
||||
{
|
||||
unsigned short remaining = msg.BufferLength -
|
||||
ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4);
|
||||
RpcResults *results = (RpcResults*)((ULONG_PTR)server_address +
|
||||
ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4));
|
||||
if ((results->num_results == 1) && (remaining >= sizeof(*results)))
|
||||
{
|
||||
switch (results->results[0].result)
|
||||
{
|
||||
case RESULT_ACCEPT:
|
||||
conn->assoc_group_id = response_hdr->bind_ack.assoc_gid;
|
||||
conn->MaxTransmissionSize = response_hdr->bind_ack.max_tsize;
|
||||
conn->ActiveInterface = *InterfaceId;
|
||||
break;
|
||||
case RESULT_PROVIDER_REJECTION:
|
||||
switch (results->results[0].reason)
|
||||
{
|
||||
case REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED:
|
||||
ERR("syntax %s, %d.%d not supported\n",
|
||||
debugstr_guid(&InterfaceId->SyntaxGUID),
|
||||
InterfaceId->SyntaxVersion.MajorVersion,
|
||||
InterfaceId->SyntaxVersion.MinorVersion);
|
||||
status = RPC_S_UNKNOWN_IF;
|
||||
break;
|
||||
case REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED:
|
||||
ERR("transfer syntax not supported\n");
|
||||
status = RPC_S_SERVER_UNAVAILABLE;
|
||||
break;
|
||||
case REASON_NONE:
|
||||
default:
|
||||
status = RPC_S_CALL_FAILED_DNE;
|
||||
}
|
||||
break;
|
||||
case RESULT_USER_REJECTION:
|
||||
default:
|
||||
ERR("rejection result %d\n", results->results[0].result);
|
||||
status = RPC_S_CALL_FAILED_DNE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("incorrect results size\n");
|
||||
status = RPC_S_CALL_FAILED_DNE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("bind ack packet too small (%d)\n", msg.BufferLength);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PKT_BIND_NACK:
|
||||
switch (response_hdr->bind_nack.reject_reason)
|
||||
{
|
||||
case REJECT_LOCAL_LIMIT_EXCEEDED:
|
||||
case REJECT_TEMPORARY_CONGESTION:
|
||||
ERR("server too busy\n");
|
||||
status = RPC_S_SERVER_TOO_BUSY;
|
||||
break;
|
||||
case REJECT_PROTOCOL_VERSION_NOT_SUPPORTED:
|
||||
ERR("protocol version not supported\n");
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
break;
|
||||
case REJECT_UNKNOWN_AUTHN_SERVICE:
|
||||
ERR("unknown authentication service\n");
|
||||
status = RPC_S_UNKNOWN_AUTHN_SERVICE;
|
||||
break;
|
||||
case REJECT_INVALID_CHECKSUM:
|
||||
ERR("invalid checksum\n");
|
||||
status = ERROR_ACCESS_DENIED;
|
||||
break;
|
||||
default:
|
||||
ERR("rejected bind for reason %d\n", response_hdr->bind_nack.reject_reason);
|
||||
status = RPC_S_CALL_FAILED_DNE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERR("wrong packet type received %d\n", response_hdr->common.ptype);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
I_RpcFreeBuffer(&msg);
|
||||
RPCRT4_FreeHeader(response_hdr);
|
||||
return status;
|
||||
}
|
||||
|
||||
static RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc,
|
||||
const RPC_SYNTAX_IDENTIFIER *InterfaceId,
|
||||
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RpcAuthInfo *AuthInfo,
|
||||
const RpcQualityOfService *QOS)
|
||||
{
|
||||
RpcConnection *Connection;
|
||||
EnterCriticalSection(&assoc->cs);
|
||||
/* try to find a compatible connection from the connection pool */
|
||||
LIST_FOR_EACH_ENTRY(Connection, &assoc->free_connection_pool, RpcConnection, conn_pool_entry)
|
||||
{
|
||||
if (!memcmp(&Connection->ActiveInterface, InterfaceId,
|
||||
sizeof(RPC_SYNTAX_IDENTIFIER)) &&
|
||||
RpcAuthInfo_IsEqual(Connection->AuthInfo, AuthInfo) &&
|
||||
RpcQualityOfService_IsEqual(Connection->QOS, QOS))
|
||||
{
|
||||
list_remove(&Connection->conn_pool_entry);
|
||||
LeaveCriticalSection(&assoc->cs);
|
||||
TRACE("got connection from pool %p\n", Connection);
|
||||
return Connection;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&assoc->cs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
|
||||
const RPC_SYNTAX_IDENTIFIER *InterfaceId,
|
||||
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo,
|
||||
RpcQualityOfService *QOS, RpcConnection **Connection)
|
||||
{
|
||||
RpcConnection *NewConnection;
|
||||
RPC_STATUS status;
|
||||
|
||||
*Connection = RpcAssoc_GetIdleConnection(assoc, InterfaceId, TransferSyntax, AuthInfo, QOS);
|
||||
if (*Connection)
|
||||
return RPC_S_OK;
|
||||
|
||||
/* create a new connection */
|
||||
status = RPCRT4_CreateConnection(&NewConnection, FALSE /* is this a server connection? */,
|
||||
assoc->Protseq, assoc->NetworkAddr,
|
||||
assoc->Endpoint, assoc->NetworkOptions,
|
||||
AuthInfo, QOS);
|
||||
if (status != RPC_S_OK)
|
||||
return status;
|
||||
|
||||
status = RPCRT4_OpenClientConnection(NewConnection);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
RPCRT4_DestroyConnection(NewConnection);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = RpcAssoc_BindConnection(assoc, NewConnection, InterfaceId, TransferSyntax);
|
||||
if (status != RPC_S_OK)
|
||||
{
|
||||
RPCRT4_DestroyConnection(NewConnection);
|
||||
return status;
|
||||
}
|
||||
|
||||
*Connection = NewConnection;
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection)
|
||||
{
|
||||
assert(!Connection->server);
|
||||
EnterCriticalSection(&assoc->cs);
|
||||
if (!assoc->assoc_group_id) assoc->assoc_group_id = Connection->assoc_group_id;
|
||||
list_add_head(&assoc->free_connection_pool, &Connection->conn_pool_entry);
|
||||
LeaveCriticalSection(&assoc->cs);
|
||||
}
|
||||
|
||||
RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard,
|
||||
NDR_SCONTEXT *SContext)
|
||||
{
|
||||
RpcContextHandle *context_handle;
|
||||
|
||||
context_handle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*context_handle));
|
||||
if (!context_handle)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
context_handle->ctx_guard = CtxGuard;
|
||||
RtlInitializeResource(&context_handle->rw_lock);
|
||||
context_handle->refs = 1;
|
||||
|
||||
/* lock here to mirror unmarshall, so we don't need to special-case the
|
||||
* freeing of a non-marshalled context handle */
|
||||
RtlAcquireResourceExclusive(&context_handle->rw_lock, TRUE);
|
||||
|
||||
EnterCriticalSection(&assoc->cs);
|
||||
list_add_tail(&assoc->context_handle_list, &context_handle->entry);
|
||||
LeaveCriticalSection(&assoc->cs);
|
||||
|
||||
*SContext = (NDR_SCONTEXT)context_handle;
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
BOOL RpcContextHandle_IsGuardCorrect(NDR_SCONTEXT SContext, void *CtxGuard)
|
||||
{
|
||||
RpcContextHandle *context_handle = (RpcContextHandle *)SContext;
|
||||
return context_handle->ctx_guard == CtxGuard;
|
||||
}
|
||||
|
||||
RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid,
|
||||
void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext)
|
||||
{
|
||||
RpcContextHandle *context_handle;
|
||||
|
||||
EnterCriticalSection(&assoc->cs);
|
||||
LIST_FOR_EACH_ENTRY(context_handle, &assoc->context_handle_list, RpcContextHandle, entry)
|
||||
{
|
||||
if (RpcContextHandle_IsGuardCorrect((NDR_SCONTEXT)context_handle, CtxGuard) &&
|
||||
!memcmp(&context_handle->uuid, uuid, sizeof(*uuid)))
|
||||
{
|
||||
*SContext = (NDR_SCONTEXT)context_handle;
|
||||
if (context_handle->refs++)
|
||||
{
|
||||
LeaveCriticalSection(&assoc->cs);
|
||||
TRACE("found %p\n", context_handle);
|
||||
RtlAcquireResourceExclusive(&context_handle->rw_lock, TRUE);
|
||||
return RPC_S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&assoc->cs);
|
||||
|
||||
ERR("no context handle found for uuid %s, guard %p\n",
|
||||
debugstr_guid(uuid), CtxGuard);
|
||||
return ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc,
|
||||
NDR_SCONTEXT SContext,
|
||||
void *CtxGuard,
|
||||
NDR_RUNDOWN rundown_routine)
|
||||
{
|
||||
RpcContextHandle *context_handle = (RpcContextHandle *)SContext;
|
||||
RPC_STATUS status;
|
||||
|
||||
if (!RpcContextHandle_IsGuardCorrect((NDR_SCONTEXT)context_handle, CtxGuard))
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
||||
EnterCriticalSection(&assoc->cs);
|
||||
if (UuidIsNil(&context_handle->uuid, &status))
|
||||
{
|
||||
/* add a ref for the data being valid */
|
||||
context_handle->refs++;
|
||||
UuidCreate(&context_handle->uuid);
|
||||
context_handle->rundown_routine = rundown_routine;
|
||||
TRACE("allocated uuid %s for context handle %p\n",
|
||||
debugstr_guid(&context_handle->uuid), context_handle);
|
||||
}
|
||||
LeaveCriticalSection(&assoc->cs);
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
void RpcContextHandle_GetUuid(NDR_SCONTEXT SContext, UUID *uuid)
|
||||
{
|
||||
RpcContextHandle *context_handle = (RpcContextHandle *)SContext;
|
||||
*uuid = context_handle->uuid;
|
||||
}
|
||||
|
||||
static void RpcContextHandle_Destroy(RpcContextHandle *context_handle)
|
||||
{
|
||||
TRACE("freeing %p\n", context_handle);
|
||||
|
||||
if (context_handle->user_context && context_handle->rundown_routine)
|
||||
{
|
||||
TRACE("calling rundown routine %p with user context %p\n",
|
||||
context_handle->rundown_routine, context_handle->user_context);
|
||||
context_handle->rundown_routine(context_handle->user_context);
|
||||
}
|
||||
|
||||
RtlDeleteResource(&context_handle->rw_lock);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, context_handle);
|
||||
}
|
||||
|
||||
unsigned int RpcServerAssoc_ReleaseContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, BOOL release_lock)
|
||||
{
|
||||
RpcContextHandle *context_handle = (RpcContextHandle *)SContext;
|
||||
unsigned int refs;
|
||||
|
||||
if (release_lock)
|
||||
RtlReleaseResource(&context_handle->rw_lock);
|
||||
|
||||
EnterCriticalSection(&assoc->cs);
|
||||
refs = --context_handle->refs;
|
||||
if (!refs)
|
||||
list_remove(&context_handle->entry);
|
||||
LeaveCriticalSection(&assoc->cs);
|
||||
|
||||
if (!refs)
|
||||
RpcContextHandle_Destroy(context_handle);
|
||||
|
||||
return refs;
|
||||
}
|
58
reactos/dll/win32/rpcrt4_new/rpc_assoc.h
Normal file
58
reactos/dll/win32/rpcrt4_new/rpc_assoc.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Associations
|
||||
*
|
||||
* Copyright 2007 Robert Shearman (for CodeWeavers)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
typedef struct _RpcAssoc
|
||||
{
|
||||
struct list entry; /* entry in the global list of associations */
|
||||
LONG refs;
|
||||
|
||||
LPSTR Protseq;
|
||||
LPSTR NetworkAddr;
|
||||
LPSTR Endpoint;
|
||||
LPWSTR NetworkOptions;
|
||||
|
||||
/* id of this association group */
|
||||
ULONG assoc_group_id;
|
||||
|
||||
CRITICAL_SECTION cs;
|
||||
|
||||
/* client-only */
|
||||
/* connections available to be used (protected by cs) */
|
||||
struct list free_connection_pool;
|
||||
|
||||
/* server-only */
|
||||
struct list context_handle_list; /* protected by cs */
|
||||
} RpcAssoc;
|
||||
|
||||
RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAssoc **assoc);
|
||||
RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, RpcConnection **Connection);
|
||||
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection);
|
||||
ULONG RpcAssoc_Release(RpcAssoc *assoc);
|
||||
RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, unsigned long assoc_gid, RpcAssoc **assoc_out);
|
||||
RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext);
|
||||
RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext);
|
||||
RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine);
|
||||
unsigned int RpcServerAssoc_ReleaseContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, BOOL release_lock);
|
||||
void RpcContextHandle_GetUuid(NDR_SCONTEXT SContext, UUID *uuid);
|
||||
BOOL RpcContextHandle_IsGuardCorrect(NDR_SCONTEXT SContext, void *CtxGuard);
|
|
@ -39,7 +39,7 @@
|
|||
#include "wine/debug.h"
|
||||
|
||||
#include "rpc_binding.h"
|
||||
#include "rpc_message.h"
|
||||
#include "rpc_assoc.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||
|
||||
|
@ -180,7 +180,7 @@ static RPC_STATUS RPCRT4_CompleteBindingW(RpcBinding* Binding, LPCWSTR NetworkAd
|
|||
{
|
||||
RPC_STATUS status;
|
||||
|
||||
TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding,
|
||||
TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding,
|
||||
debugstr_w(NetworkAddr), debugstr_w(Endpoint), debugstr_w(NetworkOptions));
|
||||
|
||||
RPCRT4_strfree(Binding->NetworkAddr);
|
||||
|
@ -226,7 +226,7 @@ RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint)
|
|||
|
||||
RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid)
|
||||
{
|
||||
TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding, debugstr_guid(ObjectUuid));
|
||||
TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding, debugstr_guid(ObjectUuid));
|
||||
if (ObjectUuid) memcpy(&Binding->ObjectUuid, ObjectUuid, sizeof(UUID));
|
||||
else UuidCreateNil(&Binding->ObjectUuid);
|
||||
return RPC_S_OK;
|
||||
|
@ -343,7 +343,7 @@ static LPWSTR RPCRT4_strconcatW(LPWSTR dst, LPCWSTR src)
|
|||
{
|
||||
DWORD len = strlenW(dst), slen = strlenW(src);
|
||||
LPWSTR ndst = HeapReAlloc(GetProcessHeap(), 0, dst, (len+slen+2)*sizeof(WCHAR));
|
||||
if (!ndst)
|
||||
if (!ndst)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, dst);
|
||||
return NULL;
|
||||
|
@ -527,7 +527,7 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU
|
|||
/* FIXME: this is kind of inefficient */
|
||||
*Options = (unsigned char*) RPCRT4_strconcatA( (char*)*Options, opt);
|
||||
HeapFree(GetProcessHeap(), 0, opt);
|
||||
} else
|
||||
} else
|
||||
*Options = (unsigned char*) opt;
|
||||
}
|
||||
}
|
||||
|
@ -536,7 +536,7 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU
|
|||
data = close+1;
|
||||
if (*data) goto fail;
|
||||
}
|
||||
else if (NetworkAddr)
|
||||
else if (NetworkAddr)
|
||||
*NetworkAddr = (unsigned char*)RPCRT4_strdupA(data);
|
||||
|
||||
return RPC_S_OK;
|
||||
|
@ -618,7 +618,7 @@ RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjU
|
|||
/* FIXME: this is kind of inefficient */
|
||||
*Options = RPCRT4_strconcatW(*Options, opt);
|
||||
HeapFree(GetProcessHeap(), 0, opt);
|
||||
} else
|
||||
} else
|
||||
*Options = opt;
|
||||
}
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjU
|
|||
|
||||
data = close+1;
|
||||
if (*data) goto fail;
|
||||
} else if (NetworkAddr)
|
||||
} else if (NetworkAddr)
|
||||
*NetworkAddr = RPCRT4_strdupW(data);
|
||||
|
||||
return RPC_S_OK;
|
||||
|
@ -651,7 +651,7 @@ RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding )
|
|||
if (status == RPC_S_OK) *Binding = 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RpcBindingVectorFree (RPCRT4.@)
|
||||
*/
|
||||
|
@ -668,7 +668,7 @@ RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector )
|
|||
*BindingVector = NULL;
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RpcBindingInqObject (RPCRT4.@)
|
||||
*/
|
||||
|
@ -680,7 +680,7 @@ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU
|
|||
memcpy(ObjectUuid, &bind->ObjectUuid, sizeof(UUID));
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RpcBindingSetObject (RPCRT4.@)
|
||||
*/
|
||||
|
@ -724,9 +724,9 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BIND
|
|||
RpcStringFreeA((unsigned char**)&Protseq);
|
||||
RpcStringFreeA((unsigned char**)&ObjectUuid);
|
||||
|
||||
if (ret == RPC_S_OK)
|
||||
if (ret == RPC_S_OK)
|
||||
*Binding = (RPC_BINDING_HANDLE)bind;
|
||||
else
|
||||
else
|
||||
RPCRT4_DestroyBinding(bind);
|
||||
|
||||
return ret;
|
||||
|
@ -770,7 +770,7 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BIND
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RpcBindingToStringBindingA (RPCRT4.@)
|
||||
*/
|
||||
|
@ -792,7 +792,7 @@ RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CS
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RpcBindingToStringBindingW (RPCRT4.@)
|
||||
*/
|
||||
|
@ -1001,7 +1001,7 @@ ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo)
|
|||
{
|
||||
HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->User);
|
||||
HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Domain);
|
||||
HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->User);
|
||||
HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Password);
|
||||
HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, AuthInfo);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define __WINE_RPC_BINDING_H
|
||||
|
||||
#include "wine/rpcss_shared.h"
|
||||
#include "rpcndr.h"
|
||||
#include "security.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
|
@ -49,37 +50,16 @@ typedef struct _RpcQualityOfService
|
|||
RPC_SECURITY_QOS_V2_W *qos;
|
||||
} RpcQualityOfService;
|
||||
|
||||
typedef struct _RpcAssoc
|
||||
{
|
||||
struct list entry; /* entry in the global list of associations */
|
||||
LONG refs;
|
||||
|
||||
LPSTR Protseq;
|
||||
LPSTR NetworkAddr;
|
||||
LPSTR Endpoint;
|
||||
LPWSTR NetworkOptions;
|
||||
|
||||
/* id of this association group */
|
||||
ULONG assoc_group_id;
|
||||
|
||||
CRITICAL_SECTION cs;
|
||||
struct list connection_pool;
|
||||
} RpcAssoc;
|
||||
|
||||
struct connection_ops;
|
||||
|
||||
typedef struct _RpcConnection
|
||||
{
|
||||
struct _RpcConnection* Next;
|
||||
BOOL server;
|
||||
LPSTR NetworkAddr;
|
||||
LPSTR Endpoint;
|
||||
LPWSTR NetworkOptions;
|
||||
const struct connection_ops *ops;
|
||||
USHORT MaxTransmissionSize;
|
||||
/* The active interface bound to server. */
|
||||
RPC_SYNTAX_IDENTIFIER ActiveInterface;
|
||||
USHORT NextCallId;
|
||||
|
||||
/* authentication */
|
||||
CtxtHandle ctx;
|
||||
|
@ -93,6 +73,13 @@ typedef struct _RpcConnection
|
|||
/* client-only */
|
||||
struct list conn_pool_entry;
|
||||
ULONG assoc_group_id; /* association group returned during binding */
|
||||
|
||||
/* server-only */
|
||||
/* The active interface bound to server. */
|
||||
RPC_SYNTAX_IDENTIFIER ActiveInterface;
|
||||
USHORT NextCallId;
|
||||
struct _RpcConnection* Next;
|
||||
struct _RpcBinding *server_binding;
|
||||
} RpcConnection;
|
||||
|
||||
struct connection_ops {
|
||||
|
@ -104,6 +91,7 @@ struct connection_ops {
|
|||
int (*read)(RpcConnection *conn, void *buffer, unsigned int len);
|
||||
int (*write)(RpcConnection *conn, const void *buffer, unsigned int len);
|
||||
int (*close)(RpcConnection *conn);
|
||||
void (*cancel_call)(RpcConnection *conn);
|
||||
size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint);
|
||||
RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint);
|
||||
};
|
||||
|
@ -122,7 +110,7 @@ typedef struct _RpcBinding
|
|||
RPC_BLOCKING_FN BlockingFn;
|
||||
ULONG ServerTid;
|
||||
RpcConnection* FromConn;
|
||||
RpcAssoc *Assoc;
|
||||
struct _RpcAssoc *Assoc;
|
||||
|
||||
/* authentication */
|
||||
RpcAuthInfo *AuthInfo;
|
||||
|
@ -145,11 +133,6 @@ ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos);
|
|||
ULONG RpcQualityOfService_Release(RpcQualityOfService *qos);
|
||||
BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQualityOfService *qos2);
|
||||
|
||||
RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAssoc **assoc);
|
||||
RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, RpcConnection **Connection);
|
||||
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection);
|
||||
ULONG RpcAssoc_Release(RpcAssoc *assoc);
|
||||
|
||||
RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS);
|
||||
RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection);
|
||||
RPC_STATUS RPCRT4_OpenClientConnection(RpcConnection* Connection);
|
||||
|
@ -190,6 +173,11 @@ static inline int rpcrt4_conn_close(RpcConnection *Connection)
|
|||
return Connection->ops->close(Connection);
|
||||
}
|
||||
|
||||
static inline void rpcrt4_conn_cancel_call(RpcConnection *Connection)
|
||||
{
|
||||
Connection->ops->cancel_call(Connection);
|
||||
}
|
||||
|
||||
static inline RPC_STATUS rpcrt4_conn_handoff(RpcConnection *old_conn, RpcConnection *new_conn)
|
||||
{
|
||||
return old_conn->ops->handoff(old_conn, new_conn);
|
||||
|
@ -199,4 +187,11 @@ static inline RPC_STATUS rpcrt4_conn_handoff(RpcConnection *old_conn, RpcConnect
|
|||
RPC_STATUS RpcTransport_GetTopOfTower(unsigned char *tower_data, size_t *tower_size, const char *protseq, const char *networkaddr, const char *endpoint);
|
||||
RPC_STATUS RpcTransport_ParseTopOfTower(const unsigned char *tower_data, size_t tower_size, char **protseq, char **networkaddr, char **endpoint);
|
||||
|
||||
void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection);
|
||||
void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding);
|
||||
RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void);
|
||||
void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext);
|
||||
void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext);
|
||||
NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -102,7 +102,7 @@ typedef struct
|
|||
unsigned short max_tsize; /* Maximum transmission fragment size */
|
||||
unsigned short max_rsize; /* Maximum receive fragment size */
|
||||
unsigned long assoc_gid; /* Associated group id */
|
||||
/*
|
||||
/*
|
||||
* Following this header are these fields:
|
||||
* RpcAddressString server_address;
|
||||
* [0 - 3 bytes of padding so that results is 4-byte aligned]
|
||||
|
|
|
@ -231,7 +231,7 @@ RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE
|
|||
msg.message_type = RPCSS_NP_MESSAGE_TYPEID_RESOLVEEPMSG;
|
||||
msg.message.resolveepmsg.iface = If->InterfaceId;
|
||||
msg.message.resolveepmsg.object = bind->ObjectUuid;
|
||||
|
||||
|
||||
msg.vardata_payload_size = strlen(bind->Protseq) + 1;
|
||||
|
||||
/* send the message */
|
||||
|
@ -241,7 +241,7 @@ RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE
|
|||
/* 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 */
|
||||
return RPCRT4_ResolveBinding(Binding, reply.as_string);
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
|
|||
0, 0, 0, 0, 0
|
||||
};
|
||||
ULONG ret = 0;
|
||||
|
||||
|
||||
if (Header->common.ptype < sizeof(header_sizes) / sizeof(header_sizes[0])) {
|
||||
ret = header_sizes[Header->common.ptype];
|
||||
if (ret == 0)
|
||||
|
@ -108,7 +108,7 @@ static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType
|
|||
Header->common.call_id = 1;
|
||||
Header->common.flags = 0;
|
||||
/* Flags and fragment length are computed in RPCRT4_Send. */
|
||||
}
|
||||
}
|
||||
|
||||
static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation,
|
||||
unsigned long BufferLength,
|
||||
|
@ -241,6 +241,7 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation,
|
|||
RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation,
|
||||
unsigned short MaxTransmissionSize,
|
||||
unsigned short MaxReceiveSize,
|
||||
unsigned long AssocGroupId,
|
||||
LPCSTR ServerAddress,
|
||||
unsigned long Result,
|
||||
unsigned long Reason,
|
||||
|
@ -266,6 +267,7 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation,
|
|||
header->common.frag_len = header_size;
|
||||
header->bind_ack.max_tsize = MaxTransmissionSize;
|
||||
header->bind_ack.max_rsize = MaxReceiveSize;
|
||||
header->bind_ack.assoc_gid = AssocGroupId;
|
||||
server_address = (RpcAddressString*)(&header->bind_ack + 1);
|
||||
server_address->length = strlen(ServerAddress) + 1;
|
||||
strcpy(server_address->string, ServerAddress);
|
||||
|
@ -415,7 +417,7 @@ static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection,
|
|||
sec_status = DecryptMessage(&Connection->ctx, &message, 0 /* FIXME */, 0);
|
||||
if (sec_status != SEC_E_OK)
|
||||
{
|
||||
ERR("EncryptMessage failed with 0x%08x\n", sec_status);
|
||||
ERR("DecryptMessage failed with 0x%08x\n", sec_status);
|
||||
return RPC_S_SEC_PKG_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -432,10 +434,10 @@ static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection,
|
|||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RPCRT4_SendAuth (internal)
|
||||
*
|
||||
*
|
||||
* Transmit a packet with authorization data over connection in acceptable fragments.
|
||||
*/
|
||||
static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
|
||||
|
@ -449,6 +451,8 @@ static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
|
|||
LONG alen;
|
||||
RPC_STATUS status;
|
||||
|
||||
RPCRT4_SetThreadCurrentConnection(Connection);
|
||||
|
||||
buffer_pos = Buffer;
|
||||
/* The packet building functions save the packet header size, so we can use it. */
|
||||
hdr_size = Header->common.frag_len;
|
||||
|
@ -518,6 +522,7 @@ static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
|
|||
if (status != RPC_S_OK)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, pkt);
|
||||
RPCRT4_SetThreadCurrentConnection(NULL);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
@ -528,7 +533,8 @@ write:
|
|||
HeapFree(GetProcessHeap(), 0, pkt);
|
||||
if (count<0) {
|
||||
WARN("rpcrt4_conn_write failed (auth)\n");
|
||||
return RPC_S_PROTOCOL_ERROR;
|
||||
RPCRT4_SetThreadCurrentConnection(NULL);
|
||||
return RPC_S_CALL_FAILED;
|
||||
}
|
||||
|
||||
buffer_pos += Header->common.frag_len - hdr_size - alen - auth_pad_len;
|
||||
|
@ -536,6 +542,7 @@ write:
|
|||
Header->common.flags &= ~RPC_FLG_FIRST;
|
||||
}
|
||||
|
||||
RPCRT4_SetThreadCurrentConnection(NULL);
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
|
@ -653,7 +660,7 @@ static RPC_STATUS RPCRT_AuthorizeConnection(RpcConnection* conn,
|
|||
|
||||
/***********************************************************************
|
||||
* RPCRT4_Send (internal)
|
||||
*
|
||||
*
|
||||
* Transmit a packet over connection in acceptable fragments.
|
||||
*/
|
||||
RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
|
||||
|
@ -677,7 +684,7 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
|
|||
|
||||
/***********************************************************************
|
||||
* RPCRT4_Receive (internal)
|
||||
*
|
||||
*
|
||||
* Receive a packet from connection and merge the fragments.
|
||||
*/
|
||||
RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
||||
|
@ -697,11 +704,13 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
|
||||
TRACE("(%p, %p, %p)\n", Connection, Header, pMsg);
|
||||
|
||||
RPCRT4_SetThreadCurrentConnection(Connection);
|
||||
|
||||
/* read packet common header */
|
||||
dwRead = rpcrt4_conn_read(Connection, &common_hdr, sizeof(common_hdr));
|
||||
if (dwRead != sizeof(common_hdr)) {
|
||||
WARN("Short read of header, %d bytes\n", dwRead);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
status = RPC_S_CALL_FAILED;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -727,7 +736,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
dwRead = rpcrt4_conn_read(Connection, &(*Header)->common + 1, hdr_length - sizeof(common_hdr));
|
||||
if (dwRead != hdr_length - sizeof(common_hdr)) {
|
||||
WARN("bad header length, %d bytes, hdr_length %d\n", dwRead, hdr_length);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
status = RPC_S_CALL_FAILED;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -753,7 +762,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
if (auth_length) {
|
||||
auth_data = HeapAlloc(GetProcessHeap(), 0, RPC_AUTH_VERIFIER_LEN(&common_hdr));
|
||||
if (!auth_data) {
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
status = RPC_S_OUT_OF_RESOURCES;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -799,7 +808,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
(unsigned char *)pMsg->Buffer + buffer_length, data_length);
|
||||
if (dwRead != data_length) {
|
||||
WARN("bad data length, %d/%ld\n", dwRead, data_length);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
status = RPC_S_CALL_FAILED;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -819,7 +828,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
if (dwRead != header_auth_len) {
|
||||
WARN("bad authentication data length, %d/%d\n", dwRead,
|
||||
header_auth_len);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
status = RPC_S_CALL_FAILED;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -828,12 +837,15 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
if ((common_hdr.ptype != PKT_BIND) &&
|
||||
(common_hdr.ptype != PKT_BIND_ACK) &&
|
||||
(common_hdr.ptype != PKT_AUTH3))
|
||||
{
|
||||
status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_RECEIVE,
|
||||
*Header, hdr_length,
|
||||
(unsigned char *)pMsg->Buffer + buffer_length, data_length,
|
||||
(RpcAuthVerifier *)auth_data,
|
||||
(unsigned char *)auth_data + sizeof(RpcAuthVerifier),
|
||||
header_auth_len - sizeof(RpcAuthVerifier));
|
||||
if (status != RPC_S_OK) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
buffer_length += data_length;
|
||||
|
@ -844,7 +856,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
dwRead = rpcrt4_conn_read(Connection, *Header, hdr_length);
|
||||
if (dwRead != hdr_length) {
|
||||
WARN("invalid packet header size (%d)\n", dwRead);
|
||||
status = RPC_S_PROTOCOL_ERROR;
|
||||
status = RPC_S_CALL_FAILED;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -869,6 +881,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
|
|||
status = RPC_S_OK;
|
||||
|
||||
fail:
|
||||
RPCRT4_SetThreadCurrentConnection(NULL);
|
||||
if (status != RPC_S_OK) {
|
||||
RPCRT4_FreeHeader(*Header);
|
||||
*Header = NULL;
|
||||
|
|
|
@ -30,7 +30,7 @@ RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS
|
|||
RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength);
|
||||
RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId);
|
||||
RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor);
|
||||
RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId);
|
||||
RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId);
|
||||
VOID RPCRT4_FreeHeader(RpcPktHdr *Header);
|
||||
RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength);
|
||||
RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "wine/exception.h"
|
||||
|
||||
#include "rpc_server.h"
|
||||
#include "rpc_assoc.h"
|
||||
#include "rpc_message.h"
|
||||
#include "rpc_defs.h"
|
||||
#include "ncastatus.h"
|
||||
|
@ -167,10 +168,13 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
|||
RpcServerInterface* sif;
|
||||
RPC_DISPATCH_FUNCTION func;
|
||||
UUID *object_uuid;
|
||||
RpcPktHdr *response;
|
||||
RpcPktHdr *response = NULL;
|
||||
void *buf = msg->Buffer;
|
||||
RPC_STATUS status;
|
||||
BOOL exception;
|
||||
NDR_SCONTEXT context_handle;
|
||||
|
||||
msg->Handle = (RPC_BINDING_HANDLE)conn->server_binding;
|
||||
|
||||
switch (hdr->common.ptype) {
|
||||
case PKT_BIND:
|
||||
|
@ -178,11 +182,21 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
|||
|
||||
/* FIXME: do more checks! */
|
||||
if (hdr->bind.max_tsize < RPC_MIN_PACKET_SIZE ||
|
||||
!UuidIsNil(&conn->ActiveInterface.SyntaxGUID, &status)) {
|
||||
!UuidIsNil(&conn->ActiveInterface.SyntaxGUID, &status) ||
|
||||
conn->server_binding) {
|
||||
TRACE("packet size less than min size, or active interface syntax guid non-null\n");
|
||||
sif = NULL;
|
||||
} else {
|
||||
sif = RPCRT4_find_interface(NULL, &hdr->bind.abstract, FALSE);
|
||||
/* create temporary binding */
|
||||
if (RPCRT4_MakeBinding(&conn->server_binding, conn) == RPC_S_OK &&
|
||||
RpcServerAssoc_GetAssociation(rpcrt4_conn_get_name(conn),
|
||||
conn->NetworkAddr, conn->Endpoint,
|
||||
conn->NetworkOptions,
|
||||
hdr->bind.assoc_gid,
|
||||
&conn->server_binding->Assoc) == RPC_S_OK)
|
||||
sif = RPCRT4_find_interface(NULL, &hdr->bind.abstract, FALSE);
|
||||
else
|
||||
sif = NULL;
|
||||
}
|
||||
if (sif == NULL) {
|
||||
TRACE("rejecting bind request on connection %p\n", conn);
|
||||
|
@ -197,6 +211,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
|||
response = RPCRT4_BuildBindAckHeader(NDR_LOCAL_DATA_REPRESENTATION,
|
||||
RPC_MAX_PACKET_SIZE,
|
||||
RPC_MAX_PACKET_SIZE,
|
||||
conn->server_binding->Assoc->assoc_group_id,
|
||||
conn->Endpoint,
|
||||
RESULT_ACCEPT, REASON_NONE,
|
||||
&sif->If->TransferSyntax);
|
||||
|
@ -272,13 +287,14 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
|||
|
||||
/* put in the drep. FIXME: is this more universally applicable?
|
||||
perhaps we should move this outward... */
|
||||
msg->DataRepresentation =
|
||||
msg->DataRepresentation =
|
||||
MAKELONG( MAKEWORD(hdr->common.drep[0], hdr->common.drep[1]),
|
||||
MAKEWORD(hdr->common.drep[2], hdr->common.drep[3]));
|
||||
|
||||
exception = FALSE;
|
||||
|
||||
/* dispatch */
|
||||
RPCRT4_SetThreadCurrentCallHandle(msg->Handle);
|
||||
__TRY {
|
||||
if (func) func(msg);
|
||||
} __EXCEPT(rpc_filter) {
|
||||
|
@ -290,6 +306,11 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
|
|||
response = RPCRT4_BuildFaultHeader(msg->DataRepresentation,
|
||||
RPC2NCA_STATUS(status));
|
||||
} __ENDTRY
|
||||
RPCRT4_SetThreadCurrentCallHandle(NULL);
|
||||
|
||||
/* release any unmarshalled context handles */
|
||||
while ((context_handle = RPCRT4_PopThreadContextHandle()) != NULL)
|
||||
RpcServerAssoc_ReleaseContextHandle(conn->server_binding->Assoc, context_handle, TRUE);
|
||||
|
||||
if (!exception)
|
||||
response = RPCRT4_BuildResponseHeader(msg->DataRepresentation,
|
||||
|
@ -318,7 +339,6 @@ fail:
|
|||
if (msg->Buffer == buf) msg->Buffer = NULL;
|
||||
TRACE("freeing Buffer=%p\n", buf);
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
RPCRT4_DestroyBinding(msg->Handle);
|
||||
msg->Handle = 0;
|
||||
I_RpcFreeBuffer(msg);
|
||||
msg->Buffer = NULL;
|
||||
|
@ -338,7 +358,6 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
|
|||
{
|
||||
RpcConnection* conn = (RpcConnection*)the_arg;
|
||||
RpcPktHdr *hdr;
|
||||
RpcBinding *pbind;
|
||||
RPC_MESSAGE *msg;
|
||||
RPC_STATUS status;
|
||||
RpcPacket *packet;
|
||||
|
@ -348,11 +367,6 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
|
|||
for (;;) {
|
||||
msg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RPC_MESSAGE));
|
||||
|
||||
/* create temporary binding for dispatch, it will be freed in
|
||||
* RPCRT4_process_packet */
|
||||
RPCRT4_MakeBinding(&pbind, conn);
|
||||
msg->Handle = (RPC_BINDING_HANDLE)pbind;
|
||||
|
||||
status = RPCRT4_Receive(conn, &hdr, msg);
|
||||
if (status != RPC_S_OK) {
|
||||
WARN("receive failed with error %lx\n", status);
|
||||
|
@ -503,7 +517,7 @@ static RPC_STATUS RPCRT4_start_listen(BOOL auto_listen)
|
|||
status = RPCRT4_start_listen_protseq(cps, TRUE);
|
||||
if (status != RPC_S_OK)
|
||||
break;
|
||||
|
||||
|
||||
/* make sure server is actually listening on the interface before
|
||||
* returning */
|
||||
RPCRT4_sync_with_server_thread(cps);
|
||||
|
@ -613,14 +627,14 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
|
|||
RPC_STATUS WINAPI RpcServerUseProtseqEpA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor )
|
||||
{
|
||||
RPC_POLICY policy;
|
||||
|
||||
|
||||
TRACE( "(%s,%u,%s,%p)\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor );
|
||||
|
||||
|
||||
/* This should provide the default behaviour */
|
||||
policy.Length = sizeof( policy );
|
||||
policy.EndpointFlags = 0;
|
||||
policy.NICFlags = 0;
|
||||
|
||||
|
||||
return RpcServerUseProtseqEpExA( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy );
|
||||
}
|
||||
|
||||
|
@ -630,14 +644,14 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpA( RPC_CSTR Protseq, UINT MaxCalls, RPC_C
|
|||
RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor )
|
||||
{
|
||||
RPC_POLICY policy;
|
||||
|
||||
|
||||
TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor );
|
||||
|
||||
|
||||
/* This should provide the default behaviour */
|
||||
policy.Length = sizeof( policy );
|
||||
policy.EndpointFlags = 0;
|
||||
policy.NICFlags = 0;
|
||||
|
||||
|
||||
return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy );
|
||||
}
|
||||
|
||||
|
@ -935,7 +949,7 @@ RPC_STATUS WINAPI RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid )
|
|||
if ((! TypeUuid) || UuidIsNil(TypeUuid, &dummy)) {
|
||||
/* ... and drop it from the list */
|
||||
if (map) {
|
||||
if (prev)
|
||||
if (prev)
|
||||
prev->next = map->next;
|
||||
else
|
||||
RpcObjTypeMaps = map->next;
|
||||
|
@ -966,7 +980,7 @@ RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( RPC_CSTR ServerPrincName, ULONG Au
|
|||
LPVOID Arg )
|
||||
{
|
||||
FIXME( "(%s,%u,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg );
|
||||
|
||||
|
||||
return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
|
||||
}
|
||||
|
||||
|
@ -977,7 +991,7 @@ RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( RPC_WSTR ServerPrincName, ULONG Au
|
|||
LPVOID Arg )
|
||||
{
|
||||
FIXME( "(%s,%u,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg );
|
||||
|
||||
|
||||
return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
|
||||
}
|
||||
|
||||
|
@ -1013,7 +1027,7 @@ RPC_STATUS WINAPI RpcMgmtWaitServerListen( void )
|
|||
LeaveCriticalSection(&listen_cs);
|
||||
return RPC_S_NOT_LISTENING;
|
||||
}
|
||||
|
||||
|
||||
LeaveCriticalSection(&listen_cs);
|
||||
|
||||
FIXME("not waiting for server calls to finish\n");
|
||||
|
@ -1032,7 +1046,7 @@ RPC_STATUS WINAPI RpcMgmtStopServerListening ( RPC_BINDING_HANDLE Binding )
|
|||
FIXME("client-side invocation not implemented.\n");
|
||||
return RPC_S_WRONG_KIND_OF_BINDING;
|
||||
}
|
||||
|
||||
|
||||
RPCRT4_stop_listen(FALSE);
|
||||
|
||||
return RPC_S_OK;
|
||||
|
@ -1114,3 +1128,12 @@ RPC_STATUS WINAPI RpcMgmtSetServerStackSize(ULONG ThreadStackSize)
|
|||
FIXME("(0x%x): stub\n", ThreadStackSize);
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* I_RpcGetCurrentCallHandle (RPCRT4.@)
|
||||
*/
|
||||
RPC_BINDING_HANDLE WINAPI I_RpcGetCurrentCallHandle(void)
|
||||
{
|
||||
TRACE("\n");
|
||||
return RPCRT4_GetThreadCurrentCallHandle();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -23,11 +23,13 @@
|
|||
<file>cproxy.c</file>
|
||||
<file>cpsf.c</file>
|
||||
<file>cstub.c</file>
|
||||
<file>ndr_contexthandle.c</file>
|
||||
<file>ndr_clientserver.c</file>
|
||||
<file>ndr_fullpointer.c</file>
|
||||
<file>ndr_marshall.c</file>
|
||||
<file>ndr_ole.c</file>
|
||||
<file>ndr_stubless.c</file>
|
||||
<file>rpc_assoc.c</file>
|
||||
<file>rpc_binding.c</file>
|
||||
<file>rpc_epmap.c</file>
|
||||
<file>rpc_message.c</file>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,7 +16,7 @@
|
|||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*
|
||||
* WINE RPC TODO's (and a few TODONT's)
|
||||
*
|
||||
* - Ove's decreasingly incomplete widl is an IDL compiler for wine. For widl
|
||||
|
@ -45,11 +45,11 @@
|
|||
*
|
||||
* - Some transports are not yet implemented. The existing transport implementations
|
||||
* are incomplete and may be bug-infested.
|
||||
*
|
||||
*
|
||||
* - The various transports that we do support ought to be supported in a more
|
||||
* object-oriented manner, as in DCE's RPC implementation, instead of cluttering
|
||||
* up the code with conditionals like we do now.
|
||||
*
|
||||
*
|
||||
* - Data marshalling: So far, only the beginnings of a full implementation
|
||||
* exist in wine. NDR protocol itself is documented, but the MS API's to
|
||||
* convert data-types in memory into NDR are not. This is challenging work,
|
||||
|
@ -59,7 +59,7 @@
|
|||
* use it to implement out-of-process OLE client/server communications.
|
||||
* ATM there is maybe a disconnect between the marshalling in the OLE DLLs
|
||||
* and the marshalling going on here [TODO: well, is there or not?]
|
||||
*
|
||||
*
|
||||
* - In-source API Documentation, at least for those functions which we have
|
||||
* implemented, but preferably for everything we can document, would be nice,
|
||||
* since some of this stuff is quite obscure.
|
||||
|
@ -100,6 +100,8 @@
|
|||
#include "winerror.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "winnt.h"
|
||||
#include "winternl.h"
|
||||
#include "iptypes.h"
|
||||
#include "iphlpapi.h"
|
||||
#include "wine/unicode.h"
|
||||
|
@ -133,6 +135,33 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
|
|||
};
|
||||
static CRITICAL_SECTION uuid_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
static CRITICAL_SECTION threaddata_cs;
|
||||
static CRITICAL_SECTION_DEBUG threaddata_cs_debug =
|
||||
{
|
||||
0, 0, &threaddata_cs,
|
||||
{ &threaddata_cs_debug.ProcessLocksList, &threaddata_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": threaddata_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION threaddata_cs = { &threaddata_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
struct list threaddata_list = LIST_INIT(threaddata_list);
|
||||
|
||||
struct context_handle_list
|
||||
{
|
||||
struct context_handle_list *next;
|
||||
NDR_SCONTEXT context_handle;
|
||||
};
|
||||
|
||||
struct threaddata
|
||||
{
|
||||
struct list entry;
|
||||
CRITICAL_SECTION cs;
|
||||
DWORD thread_id;
|
||||
RpcConnection *connection;
|
||||
RpcBinding *server_binding;
|
||||
struct context_handle_list *context_handle_list;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* DllMain
|
||||
*
|
||||
|
@ -148,14 +177,32 @@ static CRITICAL_SECTION uuid_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
|
|||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
struct threaddata *tdata;
|
||||
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
master_mutex = CreateMutexA( NULL, FALSE, RPCSS_MASTER_MUTEX_NAME);
|
||||
if (!master_mutex)
|
||||
ERR("Failed to create master mutex\n");
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
tdata = NtCurrentTeb()->ReservedForNtRpc;
|
||||
if (tdata)
|
||||
{
|
||||
EnterCriticalSection(&threaddata_cs);
|
||||
list_remove(&tdata->entry);
|
||||
LeaveCriticalSection(&threaddata_cs);
|
||||
|
||||
DeleteCriticalSection(&tdata->cs);
|
||||
if (tdata->connection)
|
||||
ERR("tdata->connection should be NULL but is still set to %p\n", tdata->connection);
|
||||
if (tdata->server_binding)
|
||||
ERR("tdata->server_binding should be NULL but is still set to %p\n", tdata->server_binding);
|
||||
HeapFree(GetProcessHeap(), 0, tdata);
|
||||
}
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
CloseHandle(master_mutex);
|
||||
master_mutex = NULL;
|
||||
|
@ -202,10 +249,12 @@ RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR* String)
|
|||
*
|
||||
* Raises an exception.
|
||||
*/
|
||||
void WINAPI RpcRaiseException(RPC_STATUS exception)
|
||||
void DECLSPEC_NORETURN WINAPI RpcRaiseException(RPC_STATUS exception)
|
||||
{
|
||||
/* FIXME: translate exception? */
|
||||
/* shouldn't return */
|
||||
RaiseException(exception, 0, 0, NULL);
|
||||
ERR("handler continued execution\n");
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -215,7 +264,7 @@ void WINAPI RpcRaiseException(RPC_STATUS exception)
|
|||
* UUID *Uuid1 [I] Uuid to compare
|
||||
* UUID *Uuid2 [I] Uuid to compare
|
||||
* RPC_STATUS *Status [O] returns RPC_S_OK
|
||||
*
|
||||
*
|
||||
* RETURNS
|
||||
* -1 if Uuid1 is less than Uuid2
|
||||
* 0 if Uuid1 and Uuid2 are equal
|
||||
|
@ -321,7 +370,7 @@ static void RPC_UuidGetSystemTime(ULONGLONG *time)
|
|||
*time += TICKS_15_OCT_1582_TO_1601;
|
||||
}
|
||||
|
||||
/* Assume that a hardware address is at least 6 bytes long */
|
||||
/* Assume that a hardware address is at least 6 bytes long */
|
||||
#define ADDRESS_BYTES_NEEDED 6
|
||||
|
||||
static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address)
|
||||
|
@ -368,9 +417,9 @@ static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address)
|
|||
* RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique.
|
||||
*
|
||||
* FIXME: No compensation for changes across reloading
|
||||
* this dll or across reboots (e.g. clock going
|
||||
* this dll or across reboots (e.g. clock going
|
||||
* backwards and swapped network cards). The RFC
|
||||
* suggests using NVRAM for storing persistent
|
||||
* suggests using NVRAM for storing persistent
|
||||
* values.
|
||||
*/
|
||||
RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
|
||||
|
@ -693,11 +742,11 @@ static BOOL RPCRT4_StartRPCSS(void)
|
|||
|
||||
/***********************************************************************
|
||||
* 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
|
||||
|
@ -728,7 +777,7 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC
|
|||
Sleep(200);
|
||||
client_handle = RPCRT4_RpcssNPConnect();
|
||||
if (INVALID_HANDLE_VALUE != client_handle) break;
|
||||
}
|
||||
}
|
||||
/* we are only willing to try twice */
|
||||
if (j++ >= 1) break;
|
||||
}
|
||||
|
@ -823,8 +872,154 @@ void WINAPI I_RpcFree(void *Object)
|
|||
/******************************************************************************
|
||||
* I_RpcMapWin32Status (rpcrt4.@)
|
||||
*/
|
||||
DWORD WINAPI I_RpcMapWin32Status(RPC_STATUS status)
|
||||
LONG WINAPI I_RpcMapWin32Status(RPC_STATUS status)
|
||||
{
|
||||
FIXME("(%ld): stub\n", status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RpcErrorStartEnumeration (rpcrt4.@)
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY RpcErrorStartEnumeration(RPC_ERROR_ENUM_HANDLE* EnumHandle)
|
||||
{
|
||||
FIXME("(%p): stub\n", EnumHandle);
|
||||
return RPC_S_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RpcMgmtSetCancelTimeout (rpcrt4.@)
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY RpcMgmtSetCancelTimeout(LONG Timeout)
|
||||
{
|
||||
FIXME("(%d): stub\n", Timeout);
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
||||
static struct threaddata *get_or_create_threaddata(void)
|
||||
{
|
||||
struct threaddata *tdata = NtCurrentTeb()->ReservedForNtRpc;
|
||||
if (!tdata)
|
||||
{
|
||||
tdata = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*tdata));
|
||||
if (!tdata) return NULL;
|
||||
|
||||
InitializeCriticalSection(&tdata->cs);
|
||||
tdata->thread_id = GetCurrentThreadId();
|
||||
|
||||
EnterCriticalSection(&threaddata_cs);
|
||||
list_add_tail(&threaddata_list, &tdata->entry);
|
||||
LeaveCriticalSection(&threaddata_cs);
|
||||
|
||||
NtCurrentTeb()->ReservedForNtRpc = tdata;
|
||||
return tdata;
|
||||
}
|
||||
return tdata;
|
||||
}
|
||||
|
||||
void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection)
|
||||
{
|
||||
struct threaddata *tdata = get_or_create_threaddata();
|
||||
if (!tdata) return;
|
||||
|
||||
EnterCriticalSection(&tdata->cs);
|
||||
tdata->connection = Connection;
|
||||
LeaveCriticalSection(&tdata->cs);
|
||||
}
|
||||
|
||||
void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding)
|
||||
{
|
||||
struct threaddata *tdata = get_or_create_threaddata();
|
||||
if (!tdata) return;
|
||||
|
||||
tdata->server_binding = Binding;
|
||||
}
|
||||
|
||||
RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void)
|
||||
{
|
||||
struct threaddata *tdata = get_or_create_threaddata();
|
||||
if (!tdata) return NULL;
|
||||
|
||||
return tdata->server_binding;
|
||||
}
|
||||
|
||||
void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext)
|
||||
{
|
||||
struct threaddata *tdata = get_or_create_threaddata();
|
||||
struct context_handle_list *context_handle_list;
|
||||
|
||||
if (!tdata) return;
|
||||
|
||||
context_handle_list = HeapAlloc(GetProcessHeap(), 0, sizeof(*context_handle_list));
|
||||
if (!context_handle_list) return;
|
||||
|
||||
context_handle_list->context_handle = SContext;
|
||||
context_handle_list->next = tdata->context_handle_list;
|
||||
tdata->context_handle_list = context_handle_list;
|
||||
}
|
||||
|
||||
void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext)
|
||||
{
|
||||
struct threaddata *tdata = get_or_create_threaddata();
|
||||
struct context_handle_list *current, *prev;
|
||||
|
||||
if (!tdata) return;
|
||||
|
||||
for (current = tdata->context_handle_list, prev = NULL; current; prev = current, current = current->next)
|
||||
{
|
||||
if (current->context_handle == SContext)
|
||||
{
|
||||
if (prev)
|
||||
prev->next = current->next;
|
||||
else
|
||||
tdata->context_handle_list = current->next;
|
||||
HeapFree(GetProcessHeap(), 0, current);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void)
|
||||
{
|
||||
struct threaddata *tdata = get_or_create_threaddata();
|
||||
struct context_handle_list *context_handle_list;
|
||||
NDR_SCONTEXT context_handle;
|
||||
|
||||
if (!tdata) return NULL;
|
||||
|
||||
context_handle_list = tdata->context_handle_list;
|
||||
if (!context_handle_list) return NULL;
|
||||
tdata->context_handle_list = context_handle_list->next;
|
||||
|
||||
context_handle = context_handle_list->context_handle;
|
||||
HeapFree(GetProcessHeap(), 0, context_handle_list);
|
||||
return context_handle;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RpcCancelThread (rpcrt4.@)
|
||||
*/
|
||||
RPC_STATUS RPC_ENTRY RpcCancelThread(void* ThreadHandle)
|
||||
{
|
||||
DWORD target_tid;
|
||||
struct threaddata *tdata;
|
||||
|
||||
TRACE("(%p)\n", ThreadHandle);
|
||||
|
||||
target_tid = GetThreadId(ThreadHandle);
|
||||
if (!target_tid)
|
||||
return RPC_S_INVALID_ARG;
|
||||
|
||||
EnterCriticalSection(&threaddata_cs);
|
||||
LIST_FOR_EACH_ENTRY(tdata, &threaddata_list, struct threaddata, entry)
|
||||
if (tdata->thread_id == target_tid)
|
||||
{
|
||||
EnterCriticalSection(&tdata->cs);
|
||||
if (tdata->connection) rpcrt4_conn_cancel_call(tdata->connection);
|
||||
LeaveCriticalSection(&tdata->cs);
|
||||
break;
|
||||
}
|
||||
LeaveCriticalSection(&threaddata_cs);
|
||||
|
||||
return RPC_S_OK;
|
||||
}
|
||||
|
|
|
@ -35,19 +35,19 @@ 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_ABANDONED:
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
case WAIT_FAILED:
|
||||
case WAIT_TIMEOUT:
|
||||
default:
|
||||
default:
|
||||
ERR("This should never happen: couldn't enter mutex.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -67,13 +67,13 @@ HANDLE RPCRT4_RpcssNPConnect(void)
|
|||
break;
|
||||
|
||||
if (GetLastError() != ERROR_PIPE_BUSY) {
|
||||
WARN("Unable to open named pipe %s (assuming unavailable).\n",
|
||||
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");
|
||||
|
||||
|
@ -122,7 +122,7 @@ BOOL RPCRT4_SendReceiveNPMsg(HANDLE np, PRPCSS_NP_MESSAGE msg, char *vardata, PR
|
|||
/* 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;
|
||||
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);
|
||||
|
@ -136,7 +136,7 @@ BOOL RPCRT4_SendReceiveNPMsg(HANDLE np, PRPCSS_NP_MESSAGE msg, char *vardata, PR
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (! ReadFile(np, reply, sizeof(RPCSS_NP_REPLY), &count, NULL)) {
|
||||
ERR("read failed.\n");
|
||||
return FALSE;
|
||||
|
|
Loading…
Reference in a new issue