- Update rpcrt4 to Wine-20080105, so it corresponds to the WIDL. Local changes applied.

svn path=/trunk/; revision=31631
This commit is contained in:
Aleksey Bragin 2008-01-06 16:18:31 +00:00
parent 07dce281aa
commit ecdee48d72
26 changed files with 12518 additions and 11057 deletions

View file

@ -16,7 +16,7 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* *
* TODO: Handle non-i386 architectures * TODO: Handle non-i386 architectures
*/ */
@ -173,7 +173,7 @@ HRESULT WINAPI StdProxy_Construct(REFIID riid,
} }
} }
} }
else else
This->PVtbl = vtbl->Vtbl; This->PVtbl = vtbl->Vtbl;
This->lpVtbl = &StdProxy_Vtbl; This->lpVtbl = &StdProxy_Vtbl;

View file

@ -41,7 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
static WINE_EXCEPTION_FILTER(stub_filter) static WINE_EXCEPTION_FILTER(stub_filter)
{ {
if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) if (GetExceptionInformation()->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
return EXCEPTION_EXECUTE_HANDLER; return EXCEPTION_EXECUTE_HANDLER;
} }
@ -109,13 +109,15 @@ static CRITICAL_SECTION delegating_vtbl_section = { &critsect_debug, -1, 0, 0, 0
typedef struct typedef struct
{ {
DWORD ref; DWORD ref;
DWORD size;
void **methods;
IUnknownVtbl vtbl; IUnknownVtbl vtbl;
/* remaining entries in vtbl */
} ref_counted_vtbl; } ref_counted_vtbl;
static struct static struct
{ {
ref_counted_vtbl *table; ref_counted_vtbl *table;
DWORD size;
} current_vtbl; } current_vtbl;
@ -156,7 +158,7 @@ typedef struct {
} vtbl_method_t; } vtbl_method_t;
#include "poppack.h" #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; vtbl_method_t *method;
void **entry; void **entry;
@ -166,7 +168,7 @@ static void fill_table(IUnknownVtbl *vtbl, DWORD num)
vtbl->AddRef = delegating_AddRef; vtbl->AddRef = delegating_AddRef;
vtbl->Release = delegating_Release; vtbl->Release = delegating_Release;
method = (vtbl_method_t*)((void **)vtbl + num); method = (vtbl_method_t*)methods;
entry = (void**)(vtbl + 1); entry = (void**)(vtbl + 1);
for(i = 3; i < num; i++) for(i = 3; i < num; i++)
@ -209,19 +211,25 @@ void create_delegating_vtbl(DWORD num_methods)
} }
EnterCriticalSection(&delegating_vtbl_section); EnterCriticalSection(&delegating_vtbl_section);
if(num_methods > current_vtbl.size) if(!current_vtbl.table || num_methods > current_vtbl.table->size)
{ {
DWORD size; DWORD size;
DWORD old_protect;
if(current_vtbl.table && current_vtbl.table->ref == 0) if(current_vtbl.table && current_vtbl.table->ref == 0)
{ {
TRACE("freeing old table\n"); TRACE("freeing old table\n");
VirtualFree(current_vtbl.table->methods,
(current_vtbl.table->size - 3) * sizeof(vtbl_method_t),
MEM_RELEASE);
HeapFree(GetProcessHeap(), 0, current_vtbl.table); HeapFree(GetProcessHeap(), 0, current_vtbl.table);
} }
size = sizeof(DWORD) + num_methods * sizeof(void*) + (num_methods - 3) * sizeof(vtbl_method_t); size = (num_methods - 3) * sizeof(vtbl_method_t);
current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, size); current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*));
fill_table(&current_vtbl.table->vtbl, num_methods);
current_vtbl.table->ref = 0; 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(&current_vtbl.table->vtbl, current_vtbl.table->methods, num_methods);
VirtualProtect(current_vtbl.table->methods, size, PAGE_EXECUTE_READ, &old_protect);
} }
LeaveCriticalSection(&delegating_vtbl_section); LeaveCriticalSection(&delegating_vtbl_section);
} }
@ -247,6 +255,9 @@ static void release_delegating_vtbl(IUnknownVtbl *vtbl)
if(table->ref == 0 && table != current_vtbl.table) if(table->ref == 0 && table != current_vtbl.table)
{ {
TRACE("... and we're not current so free'ing\n"); TRACE("... and we're not current so free'ing\n");
VirtualFree(current_vtbl.table->methods,
(current_vtbl.table->size - 3) * sizeof(vtbl_method_t),
MEM_RELEASE);
HeapFree(GetProcessHeap(), 0, table); HeapFree(GetProcessHeap(), 0, table);
} }
LeaveCriticalSection(&delegating_vtbl_section); LeaveCriticalSection(&delegating_vtbl_section);
@ -558,6 +569,9 @@ void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg,
TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer); TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer);
NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor); NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor);
pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer; pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer;
IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer,
&pStubMsg->dwDestContext,
&pStubMsg->pvDestContext);
} }
/*********************************************************************** /***********************************************************************
@ -581,7 +595,5 @@ void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER iface,
return; return;
} }
pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; pStubMsg->Buffer = pStubMsg->RpcMsg->Buffer;
pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
pStubMsg->Buffer = pStubMsg->BufferStart;
} }

View file

@ -39,7 +39,7 @@
#define EPM_PROTOCOL_DSP 0x16 /* AppleTalk Data Stream Protocol */ #define EPM_PROTOCOL_DSP 0x16 /* AppleTalk Data Stream Protocol */
#define EPM_PROTOCOL_DDP 0x17 /* AppleTalk Data Datagram Protocol */ #define EPM_PROTOCOL_DDP 0x17 /* AppleTalk Data Datagram Protocol */
#define EPM_PROTOCOL_APPLETALK 0x18 /* AppleTalk */ #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_VINES_IPC 0x1b /* Inter Process Communication */
#define EPM_PROTOCOL_STREETTALK 0x1c /* Vines Streettalk */ #define EPM_PROTOCOL_STREETTALK 0x1c /* Vines Streettalk */
#define EPM_PROTOCOL_HTTP 0x1f #define EPM_PROTOCOL_HTTP 0x1f

View file

@ -1,66 +1,66 @@
/* /*
* NCA Status definitions * NCA Status definitions
* *
* Copyright 2007 Robert Shearman * Copyright 2007 Robert Shearman
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#define NCA_S_COMM_FAILURE 0x1C010001 #define NCA_S_COMM_FAILURE 0x1C010001
#define NCA_S_OP_RNG_ERROR 0x1C010002 #define NCA_S_OP_RNG_ERROR 0x1C010002
#define NCA_S_UNK_IF 0x1C010003 #define NCA_S_UNK_IF 0x1C010003
#define NCA_S_WRONG_BOOT_TIME 0x1C010006 #define NCA_S_WRONG_BOOT_TIME 0x1C010006
#define NCA_S_YOU_CRASHED 0x1C010009 #define NCA_S_YOU_CRASHED 0x1C010009
#define NCA_S_PROTO_ERROR 0x1C01000B #define NCA_S_PROTO_ERROR 0x1C01000B
#define NCA_S_OUT_ARGS_TOO_BIG 0x1C010013 #define NCA_S_OUT_ARGS_TOO_BIG 0x1C010013
#define NCA_S_SERVER_TOO_BUSY 0x1C010014 #define NCA_S_SERVER_TOO_BUSY 0x1C010014
#define NCA_S_FAULT_STRING_TOO_LONG 0x1C010015 #define NCA_S_FAULT_STRING_TOO_LONG 0x1C010015
#define NCA_S_UNSUPPORTED_TYPE 0x1C010017 #define NCA_S_UNSUPPORTED_TYPE 0x1C010017
#define NCA_S_FAULT_INT_DIV_BY_ZERO 0x1C000001 #define NCA_S_FAULT_INT_DIV_BY_ZERO 0x1C000001
#define NCA_S_FAULT_ADDR_ERROR 0x1C000002 #define NCA_S_FAULT_ADDR_ERROR 0x1C000002
#define NCA_S_FAULT_FP_DIV_ZERO 0x1C000003 #define NCA_S_FAULT_FP_DIV_ZERO 0x1C000003
#define NCA_S_FAULT_FP_UNDERFLOW 0x1C000004 #define NCA_S_FAULT_FP_UNDERFLOW 0x1C000004
#define NCA_S_FAULT_FP_OVERFLOW 0x1C000005 #define NCA_S_FAULT_FP_OVERFLOW 0x1C000005
#define NCA_S_FAULT_INVALID_TAG 0x1C000006 #define NCA_S_FAULT_INVALID_TAG 0x1C000006
#define NCA_S_FAULT_INVALID_BOUND 0x1C000007 #define NCA_S_FAULT_INVALID_BOUND 0x1C000007
#define NCA_S_RPC_VERSION_MISMATCH 0x1C000008 #define NCA_S_RPC_VERSION_MISMATCH 0x1C000008
#define NCA_S_UNSPEC_REJECT 0x1C000009 #define NCA_S_UNSPEC_REJECT 0x1C000009
#define NCA_S_BAD_ACTID 0x1C00000A #define NCA_S_BAD_ACTID 0x1C00000A
#define NCA_S_WHO_ARE_YOU_FAILED 0x1C00000B #define NCA_S_WHO_ARE_YOU_FAILED 0x1C00000B
#define NCA_S_MANAGER_NOT_ENTERED 0x1C00000C #define NCA_S_MANAGER_NOT_ENTERED 0x1C00000C
#define NCA_S_FAULT_CANCEL 0x1C00000D #define NCA_S_FAULT_CANCEL 0x1C00000D
#define NCA_S_FAULT_ILL_INST 0x1C00000E #define NCA_S_FAULT_ILL_INST 0x1C00000E
#define NCA_S_FAULT_FP_ERROR 0x1C00000F #define NCA_S_FAULT_FP_ERROR 0x1C00000F
#define NCA_S_FAULT_INT_OVERFLOW 0x1C000010 #define NCA_S_FAULT_INT_OVERFLOW 0x1C000010
#define NCA_S_FAULT_UNSPEC 0x1C000012 #define NCA_S_FAULT_UNSPEC 0x1C000012
#define NCA_S_FAULT_REMOTE_COMM_FAILURE 0x1C000013 #define NCA_S_FAULT_REMOTE_COMM_FAILURE 0x1C000013
#define NCA_S_FAULT_PIPE_EMPTY 0x1C000014 #define NCA_S_FAULT_PIPE_EMPTY 0x1C000014
#define NCA_S_FAULT_PIPE_CLOSED 0x1C000015 #define NCA_S_FAULT_PIPE_CLOSED 0x1C000015
#define NCA_S_FAULT_PIPE_ORDER 0x1C000016 #define NCA_S_FAULT_PIPE_ORDER 0x1C000016
#define NCA_S_FAULT_PIPE_DISCIPLINE 0x1C000017 #define NCA_S_FAULT_PIPE_DISCIPLINE 0x1C000017
#define NCA_S_FAULT_PIPE_COMM_ERROR 0x1C000018 #define NCA_S_FAULT_PIPE_COMM_ERROR 0x1C000018
#define NCA_S_FAULT_PIPE_MEMORY 0x1C000019 #define NCA_S_FAULT_PIPE_MEMORY 0x1C000019
#define NCA_S_FAULT_CONTEXT_MISMATCH 0x1C00001A #define NCA_S_FAULT_CONTEXT_MISMATCH 0x1C00001A
#define NCA_S_FAULT_REMOTE_NO_MEMORY 0x1C00001B #define NCA_S_FAULT_REMOTE_NO_MEMORY 0x1C00001B
#define NCA_S_INVALID_PRES_CONTEXT_ID 0x1C00001C #define NCA_S_INVALID_PRES_CONTEXT_ID 0x1C00001C
#define NCA_S_UNSUPPORTED_AUTHN_LEVEL 0x1C00001D #define NCA_S_UNSUPPORTED_AUTHN_LEVEL 0x1C00001D
#define NCA_S_INVALID_CHECKSUM 0x1C00001F #define NCA_S_INVALID_CHECKSUM 0x1C00001F
#define NCA_S_INVALID_CRC 0x1C000020 #define NCA_S_INVALID_CRC 0x1C000020
#define NCA_S_FAULT_USER_DEFINED 0x1C000021 #define NCA_S_FAULT_USER_DEFINED 0x1C000021
#define NCA_S_FAULT_TX_OPEN_FAILED 0x1C000022 #define NCA_S_FAULT_TX_OPEN_FAILED 0x1C000022
#define NCA_S_FAULT_CODESET_CONV_ERROR 0x1C000023 #define NCA_S_FAULT_CODESET_CONV_ERROR 0x1C000023
#define NCA_S_FAULT_OBJECT_NOT_FOUND 0x1C000024 #define NCA_S_FAULT_OBJECT_NOT_FOUND 0x1C000024
#define NCA_S_FAULT_NO_CLIENT_STUB 0x1C000025 #define NCA_S_FAULT_NO_CLIENT_STUB 0x1C000025

View file

@ -1,207 +1,227 @@
/* /*
* MIDL proxy/stub stuff * MIDL proxy/stub stuff
* *
* Copyright 2002 Ove Kåven, TransGaming Technologies * Copyright 2002 Ove Kåven, TransGaming Technologies
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* *
* TODO: * TODO:
* - figure out whether we *really* got this right * - figure out whether we *really* got this right
* - check for errors and throw exceptions * - check for errors and throw exceptions
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#define COBJMACROS #define COBJMACROS
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winerror.h" #include "winerror.h"
#include "objbase.h" #include "objbase.h"
#include "rpcproxy.h" #include "rpcproxy.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "ndr_misc.h" #include "ndr_misc.h"
#include "rpcndr.h" #include "rpcndr.h"
WINE_DEFAULT_DEBUG_CHANNEL(rpc); WINE_DEFAULT_DEBUG_CHANNEL(rpc);
/************************************************************************ /************************************************************************
* NdrClientInitializeNew [RPCRT4.@] * NdrClientInitializeNew [RPCRT4.@]
*/ */
void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg, void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum ) PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum )
{ {
TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n", TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n",
pRpcMessage, pStubMsg, pStubDesc, ProcNum); pRpcMessage, pStubMsg, pStubDesc, ProcNum);
assert( pRpcMessage && pStubMsg && pStubDesc ); pRpcMessage->Handle = NULL;
pRpcMessage->ProcNum = ProcNum;
pRpcMessage->Handle = NULL; pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation;
pRpcMessage->ProcNum = ProcNum; pRpcMessage->RpcFlags = 0;
pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation; pRpcMessage->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
pRpcMessage->RpcFlags = 0;
pRpcMessage->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION; pStubMsg->RpcMsg = pRpcMessage;
pStubMsg->BufferStart = NULL;
pStubMsg->RpcMsg = pRpcMessage; pStubMsg->BufferEnd = NULL;
pStubMsg->BufferStart = NULL; pStubMsg->BufferLength = 0;
pStubMsg->BufferEnd = NULL; pStubMsg->IsClient = TRUE;
pStubMsg->BufferLength = 0; pStubMsg->ReuseBuffer = FALSE;
pStubMsg->IsClient = TRUE; pStubMsg->pAllocAllNodesContext = NULL;
pStubMsg->ReuseBuffer = FALSE; pStubMsg->pPointerQueueState = NULL;
pStubMsg->pAllocAllNodesContext = NULL; pStubMsg->IgnoreEmbeddedPointers = 0;
pStubMsg->pPointerQueueState = NULL; pStubMsg->PointerBufferMark = NULL;
pStubMsg->IgnoreEmbeddedPointers = 0; pStubMsg->fBufferValid = 0;
pStubMsg->PointerBufferMark = NULL; pStubMsg->uFlags = 0;
pStubMsg->fBufferValid = 0; pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
pStubMsg->uFlags = 0; pStubMsg->pfnFree = pStubDesc->pfnFree;
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate; pStubMsg->StackTop = NULL;
pStubMsg->pfnFree = pStubDesc->pfnFree; pStubMsg->StubDesc = pStubDesc;
pStubMsg->StackTop = NULL; pStubMsg->FullPtrRefId = 0;
pStubMsg->StubDesc = pStubDesc; pStubMsg->PointerLength = 0;
pStubMsg->FullPtrRefId = 0; pStubMsg->fInDontFree = 0;
pStubMsg->PointerLength = 0; pStubMsg->fDontCallFreeInst = 0;
pStubMsg->fInDontFree = 0; pStubMsg->fInOnlyParam = 0;
pStubMsg->fDontCallFreeInst = 0; pStubMsg->fHasReturn = 0;
pStubMsg->fInOnlyParam = 0; pStubMsg->fHasExtensions = 0;
pStubMsg->fHasReturn = 0; pStubMsg->fHasNewCorrDesc = 0;
pStubMsg->fHasExtensions = 0; pStubMsg->fUnused = 0;
pStubMsg->fHasNewCorrDesc = 0; pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
pStubMsg->fUnused = 0; pStubMsg->pvDestContext = NULL;
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE; pStubMsg->pRpcChannelBuffer = NULL;
pStubMsg->pvDestContext = NULL; pStubMsg->pArrayInfo = NULL;
pStubMsg->pRpcChannelBuffer = NULL; pStubMsg->dwStubPhase = 0;
pStubMsg->pArrayInfo = NULL; /* FIXME: LowStackMark */
pStubMsg->dwStubPhase = 0; pStubMsg->pAsyncMsg = NULL;
/* FIXME: LowStackMark */ pStubMsg->pCorrInfo = NULL;
pStubMsg->pAsyncMsg = NULL; pStubMsg->pCorrMemory = NULL;
pStubMsg->pCorrInfo = NULL; pStubMsg->pMemoryList = NULL;
pStubMsg->pCorrMemory = NULL; }
pStubMsg->pMemoryList = NULL;
} /***********************************************************************
* NdrServerInitializeNew [RPCRT4.@]
/*********************************************************************** */
* NdrServerInitializeNew [RPCRT4.@] unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg,
*/ PMIDL_STUB_DESC pStubDesc )
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);
{
TRACE("(pRpcMsg == ^%p, pStubMsg == ^%p, pStubDesc == ^%p)\n", pRpcMsg, pStubMsg, pStubDesc); pStubMsg->RpcMsg = pRpcMsg;
pStubMsg->Buffer = pStubMsg->BufferStart = pRpcMsg->Buffer;
assert( pRpcMsg && pStubMsg && pStubDesc ); pStubMsg->BufferEnd = pStubMsg->Buffer + pRpcMsg->BufferLength;
pStubMsg->BufferLength = pRpcMsg->BufferLength;
/* not everyone allocates stack space for w2kReserved */ pStubMsg->IsClient = FALSE;
memset(pStubMsg, 0, FIELD_OFFSET(MIDL_STUB_MESSAGE,pCSInfo)); pStubMsg->ReuseBuffer = FALSE;
pStubMsg->pAllocAllNodesContext = NULL;
pStubMsg->ReuseBuffer = TRUE; pStubMsg->pPointerQueueState = NULL;
pStubMsg->IsClient = FALSE; pStubMsg->IgnoreEmbeddedPointers = 0;
pStubMsg->StubDesc = pStubDesc; pStubMsg->PointerBufferMark = NULL;
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate; pStubMsg->uFlags = 0;
pStubMsg->pfnFree = pStubDesc->pfnFree; pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
pStubMsg->RpcMsg = pRpcMsg; pStubMsg->pfnFree = pStubDesc->pfnFree;
pStubMsg->Buffer = pStubMsg->BufferStart = pRpcMsg->Buffer; pStubMsg->StackTop = NULL;
pStubMsg->BufferLength = pRpcMsg->BufferLength; pStubMsg->StubDesc = pStubDesc;
pStubMsg->BufferEnd = pStubMsg->Buffer + pStubMsg->BufferLength; pStubMsg->FullPtrXlatTables = NULL;
pStubMsg->FullPtrRefId = 0;
/* FIXME: determine the proper return value */ pStubMsg->PointerLength = 0;
return NULL; pStubMsg->fInDontFree = 0;
} pStubMsg->fDontCallFreeInst = 0;
pStubMsg->fInOnlyParam = 0;
/*********************************************************************** pStubMsg->fHasReturn = 0;
* NdrGetBuffer [RPCRT4.@] pStubMsg->fHasExtensions = 0;
*/ pStubMsg->fHasNewCorrDesc = 0;
unsigned char *WINAPI NdrGetBuffer(PMIDL_STUB_MESSAGE stubmsg, ULONG buflen, RPC_BINDING_HANDLE handle) pStubMsg->fUnused = 0;
{ pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
TRACE("(stubmsg == ^%p, buflen == %u, handle == %p): wild guess.\n", stubmsg, buflen, handle); pStubMsg->pvDestContext = NULL;
pStubMsg->pRpcChannelBuffer = NULL;
assert( stubmsg && stubmsg->RpcMsg ); pStubMsg->pArrayInfo = NULL;
pStubMsg->dwStubPhase = 0;
/* I guess this is our chance to put the binding handle into the RPC_MESSAGE */ /* FIXME: LowStackMark */
stubmsg->RpcMsg->Handle = handle; pStubMsg->pAsyncMsg = NULL;
pStubMsg->pCorrInfo = NULL;
stubmsg->RpcMsg->BufferLength = buflen; pStubMsg->pCorrMemory = NULL;
if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK) pStubMsg->pMemoryList = NULL;
return NULL;
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); * NdrGetBuffer [RPCRT4.@]
} */
/*********************************************************************** unsigned char *WINAPI NdrGetBuffer(PMIDL_STUB_MESSAGE stubmsg, ULONG buflen, RPC_BINDING_HANDLE handle)
* NdrFreeBuffer [RPCRT4.@] {
*/ RPC_STATUS status;
void WINAPI NdrFreeBuffer(PMIDL_STUB_MESSAGE pStubMsg)
{ TRACE("(stubmsg == ^%p, buflen == %u, handle == %p)\n", stubmsg, buflen, handle);
TRACE("(pStubMsg == ^%p): wild guess.\n", pStubMsg);
I_RpcFreeBuffer(pStubMsg->RpcMsg); stubmsg->RpcMsg->Handle = handle;
pStubMsg->BufferLength = 0; stubmsg->RpcMsg->BufferLength = buflen;
pStubMsg->Buffer = pStubMsg->BufferEnd = (unsigned char *)(pStubMsg->RpcMsg->Buffer = NULL);
} status = I_RpcGetBuffer(stubmsg->RpcMsg);
if (status != RPC_S_OK)
/************************************************************************ RpcRaiseException(status);
* NdrSendReceive [RPCRT4.@]
*/ stubmsg->Buffer = stubmsg->RpcMsg->Buffer;
unsigned char *WINAPI NdrSendReceive( PMIDL_STUB_MESSAGE stubmsg, unsigned char *buffer ) stubmsg->fBufferValid = TRUE;
{ stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
RPC_STATUS status; return stubmsg->Buffer;
}
TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer); /***********************************************************************
* NdrFreeBuffer [RPCRT4.@]
/* FIXME: how to handle errors? (raise exception?) */ */
if (!stubmsg) { void WINAPI NdrFreeBuffer(PMIDL_STUB_MESSAGE pStubMsg)
ERR("NULL stub message. No action taken.\n"); {
return NULL; TRACE("(pStubMsg == ^%p)\n", pStubMsg);
} if (pStubMsg->fBufferValid)
if (!stubmsg->RpcMsg) { {
ERR("RPC Message not present in stub message. No action taken.\n"); I_RpcFreeBuffer(pStubMsg->RpcMsg);
return NULL; pStubMsg->fBufferValid = FALSE;
} }
}
stubmsg->RpcMsg->BufferLength = buffer - (unsigned char *)stubmsg->RpcMsg->Buffer;
status = I_RpcSendReceive(stubmsg->RpcMsg); /************************************************************************
if (status != RPC_S_OK) * NdrSendReceive [RPCRT4.@]
RpcRaiseException(status); */
unsigned char *WINAPI NdrSendReceive( PMIDL_STUB_MESSAGE stubmsg, unsigned char *buffer )
stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength; {
stubmsg->BufferStart = stubmsg->RpcMsg->Buffer; RPC_STATUS status;
stubmsg->BufferEnd = stubmsg->BufferStart + stubmsg->BufferLength;
stubmsg->Buffer = stubmsg->BufferStart; TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);
/* FIXME: is this the right return value? */ /* FIXME: how to handle errors? (raise exception?) */
return NULL; if (!stubmsg) {
} ERR("NULL stub message. No action taken.\n");
return NULL;
/************************************************************************ }
* NdrMapCommAndFaultStatus [RPCRT4.@] if (!stubmsg->RpcMsg) {
*/ ERR("RPC Message not present in stub message. No action taken.\n");
RPC_STATUS RPC_ENTRY NdrMapCommAndFaultStatus( PMIDL_STUB_MESSAGE pStubMsg, return NULL;
ULONG *pCommStatus, }
ULONG *pFaultStatus,
RPC_STATUS Status ) stubmsg->RpcMsg->BufferLength = buffer - (unsigned char *)stubmsg->RpcMsg->Buffer;
{ status = I_RpcSendReceive(stubmsg->RpcMsg);
FIXME("(%p, %p, %p, %ld): stub\n", pStubMsg, pCommStatus, pFaultStatus, Status); if (status != RPC_S_OK)
RpcRaiseException(status);
*pCommStatus = 0;
*pFaultStatus = 0; stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
return RPC_S_OK; 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;
}

View 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;
}

View file

@ -1,233 +1,239 @@
/* /*
* Full Pointer Translation Routines * Full Pointer Translation Routines
* *
* Copyright 2006 Robert Shearman * Copyright 2006 Robert Shearman
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <stdarg.h> #include <stdarg.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "rpc.h" #include "rpc.h"
#include "rpcndr.h" #include "rpcndr.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(rpc); WINE_DEFAULT_DEBUG_CHANNEL(rpc);
PFULL_PTR_XLAT_TABLES WINAPI NdrFullPointerXlatInit(ULONG NumberOfPointers, PFULL_PTR_XLAT_TABLES WINAPI NdrFullPointerXlatInit(ULONG NumberOfPointers,
XLAT_SIDE XlatSide) XLAT_SIDE XlatSide)
{ {
ULONG NumberOfBuckets; ULONG NumberOfBuckets;
PFULL_PTR_XLAT_TABLES pXlatTables = HeapAlloc(GetProcessHeap(), 0, sizeof(*pXlatTables)); PFULL_PTR_XLAT_TABLES pXlatTables = HeapAlloc(GetProcessHeap(), 0, sizeof(*pXlatTables));
TRACE("(%d, %d)\n", NumberOfPointers, XlatSide); TRACE("(%d, %d)\n", NumberOfPointers, XlatSide);
if (!NumberOfPointers) NumberOfPointers = 512; if (!NumberOfPointers) NumberOfPointers = 512;
NumberOfBuckets = ((NumberOfPointers + 3) & ~3) - 1; NumberOfBuckets = ((NumberOfPointers + 3) & ~3) - 1;
pXlatTables->RefIdToPointer.XlatTable = pXlatTables->RefIdToPointer.XlatTable =
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(void *) * NumberOfPointers); sizeof(void *) * NumberOfPointers);
pXlatTables->RefIdToPointer.StateTable = pXlatTables->RefIdToPointer.StateTable =
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(unsigned char) * NumberOfPointers); sizeof(unsigned char) * NumberOfPointers);
pXlatTables->RefIdToPointer.NumberOfEntries = NumberOfPointers; pXlatTables->RefIdToPointer.NumberOfEntries = NumberOfPointers;
TRACE("NumberOfBuckets = %d\n", NumberOfBuckets); TRACE("NumberOfBuckets = %d\n", NumberOfBuckets);
pXlatTables->PointerToRefId.XlatTable = pXlatTables->PointerToRefId.XlatTable =
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(PFULL_PTR_TO_REFID_ELEMENT) * NumberOfBuckets); sizeof(PFULL_PTR_TO_REFID_ELEMENT) * NumberOfBuckets);
pXlatTables->PointerToRefId.NumberOfBuckets = NumberOfBuckets; pXlatTables->PointerToRefId.NumberOfBuckets = NumberOfBuckets;
pXlatTables->PointerToRefId.HashMask = NumberOfBuckets - 1; pXlatTables->PointerToRefId.HashMask = NumberOfBuckets - 1;
pXlatTables->NextRefId = 1; pXlatTables->NextRefId = 1;
pXlatTables->XlatSide = XlatSide; pXlatTables->XlatSide = XlatSide;
return pXlatTables; return pXlatTables;
} }
void WINAPI NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables) void WINAPI NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables)
{ {
TRACE("(%p)\n", pXlatTables); ULONG i;
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable); TRACE("(%p)\n", pXlatTables);
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.StateTable);
HeapFree(GetProcessHeap(), 0, pXlatTables->PointerToRefId.XlatTable); /* free the entries in the table */
for (i = 0; i < pXlatTables->RefIdToPointer.NumberOfEntries; i++)
HeapFree(GetProcessHeap(), 0, pXlatTables); HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable[i]);
}
HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable);
static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId) HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.StateTable);
{ HeapFree(GetProcessHeap(), 0, pXlatTables->PointerToRefId.XlatTable);
if (RefId >= pXlatTables->RefIdToPointer.NumberOfEntries)
{ HeapFree(GetProcessHeap(), 0, pXlatTables);
pXlatTables->RefIdToPointer.NumberOfEntries = RefId * 2; }
pXlatTables->RefIdToPointer.XlatTable =
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables, ULONG RefId)
pXlatTables->RefIdToPointer.XlatTable, {
sizeof(void *) * pXlatTables->RefIdToPointer.NumberOfEntries); if (RefId >= pXlatTables->RefIdToPointer.NumberOfEntries)
pXlatTables->RefIdToPointer.StateTable = {
HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pXlatTables->RefIdToPointer.NumberOfEntries = RefId * 2;
pXlatTables->RefIdToPointer.StateTable, pXlatTables->RefIdToPointer.XlatTable =
sizeof(unsigned char) * pXlatTables->RefIdToPointer.NumberOfEntries); HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
pXlatTables->RefIdToPointer.XlatTable,
if (!pXlatTables->RefIdToPointer.XlatTable || !pXlatTables->RefIdToPointer.StateTable) sizeof(void *) * pXlatTables->RefIdToPointer.NumberOfEntries);
pXlatTables->RefIdToPointer.NumberOfEntries = 0; pXlatTables->RefIdToPointer.StateTable =
} HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
} pXlatTables->RefIdToPointer.StateTable,
sizeof(unsigned char) * pXlatTables->RefIdToPointer.NumberOfEntries);
int WINAPI NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables,
void *pPointer, unsigned char QueryType, if (!pXlatTables->RefIdToPointer.XlatTable || !pXlatTables->RefIdToPointer.StateTable)
ULONG *pRefId ) pXlatTables->RefIdToPointer.NumberOfEntries = 0;
{ }
ULONG Hash = 0; }
int i;
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry; int WINAPI NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables,
void *pPointer, unsigned char QueryType,
TRACE("(%p, %p, %d, %p)\n", pXlatTables, pPointer, QueryType, pRefId); ULONG *pRefId )
{
if (!pPointer) ULONG Hash = 0;
{ int i;
*pRefId = 0; PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
return 1;
} TRACE("(%p, %p, %d, %p)\n", pXlatTables, pPointer, QueryType, pRefId);
/* simple hashing algorithm, don't know whether it matches native */ if (!pPointer)
for (i = 0; i < sizeof(pPointer); i++) {
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i]; *pRefId = 0;
return 1;
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask]; }
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
if (pPointer == XlatTableEntry->Pointer) /* simple hashing algorithm, don't know whether it matches native */
{ for (i = 0; i < sizeof(pPointer); i++)
*pRefId = XlatTableEntry->RefId; Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
if (XlatTableEntry->State & QueryType)
return 1; XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
XlatTableEntry->State |= QueryType; for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
return 0; if (pPointer == XlatTableEntry->Pointer)
} {
*pRefId = XlatTableEntry->RefId;
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry)); if (XlatTableEntry->State & QueryType)
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask]; return 1;
XlatTableEntry->Pointer = pPointer; XlatTableEntry->State |= QueryType;
XlatTableEntry->RefId = *pRefId = pXlatTables->NextRefId++; return 0;
XlatTableEntry->State = QueryType; }
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
/* insert pointer into mapping table */ XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
expand_pointer_table_if_necessary(pXlatTables, XlatTableEntry->RefId); XlatTableEntry->Pointer = pPointer;
if (pXlatTables->RefIdToPointer.NumberOfEntries > XlatTableEntry->RefId) XlatTableEntry->RefId = *pRefId = pXlatTables->NextRefId++;
{ XlatTableEntry->State = QueryType;
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer; pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
pXlatTables->RefIdToPointer.StateTable[XlatTableEntry->RefId] = QueryType;
} /* insert pointer into mapping table */
expand_pointer_table_if_necessary(pXlatTables, XlatTableEntry->RefId);
return 0; if (pXlatTables->RefIdToPointer.NumberOfEntries > XlatTableEntry->RefId)
} {
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
int WINAPI NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables, pXlatTables->RefIdToPointer.StateTable[XlatTableEntry->RefId] = QueryType;
ULONG RefId, unsigned char QueryType, }
void **ppPointer)
{ return 0;
TRACE("(%p, 0x%x, %d, %p)\n", pXlatTables, RefId, QueryType, ppPointer); }
expand_pointer_table_if_necessary(pXlatTables, RefId); int WINAPI NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
ULONG RefId, unsigned char QueryType,
pXlatTables->NextRefId = max(RefId + 1, pXlatTables->NextRefId); void **ppPointer)
{
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId) TRACE("(%p, 0x%x, %d, %p)\n", pXlatTables, RefId, QueryType, ppPointer);
{
*ppPointer = pXlatTables->RefIdToPointer.XlatTable[RefId]; expand_pointer_table_if_necessary(pXlatTables, RefId);
if (QueryType)
{ pXlatTables->NextRefId = max(RefId + 1, pXlatTables->NextRefId);
if (pXlatTables->RefIdToPointer.StateTable[RefId] & QueryType)
return 1; if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
pXlatTables->RefIdToPointer.StateTable[RefId] |= QueryType; {
return 0; *ppPointer = pXlatTables->RefIdToPointer.XlatTable[RefId];
} if (QueryType)
else {
return 0; if (pXlatTables->RefIdToPointer.StateTable[RefId] & QueryType)
} return 1;
*ppPointer = NULL; pXlatTables->RefIdToPointer.StateTable[RefId] |= QueryType;
return 0; return 0;
} }
else
void WINAPI NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables, return 0;
ULONG RefId, void *pPointer) }
{ *ppPointer = NULL;
ULONG Hash = 0; return 0;
int i; }
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
void WINAPI NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
TRACE("(%p, 0x%x, %p)\n", pXlatTables, RefId, pPointer); ULONG RefId, void *pPointer)
{
/* simple hashing algorithm, don't know whether it matches native */ ULONG Hash = 0;
for (i = 0; i < sizeof(pPointer); i++) int i;
Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i]; PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry)); TRACE("(%p, 0x%x, %p)\n", pXlatTables, RefId, pPointer);
XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
XlatTableEntry->Pointer = pPointer; /* simple hashing algorithm, don't know whether it matches native */
XlatTableEntry->RefId = RefId; for (i = 0; i < sizeof(pPointer); i++)
XlatTableEntry->State = 0; Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
/* insert pointer into mapping table */ XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
expand_pointer_table_if_necessary(pXlatTables, RefId); XlatTableEntry->Pointer = pPointer;
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId) XlatTableEntry->RefId = RefId;
pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer; XlatTableEntry->State = 0;
} pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
int WINAPI NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables, void *Pointer) /* insert pointer into mapping table */
{ expand_pointer_table_if_necessary(pXlatTables, RefId);
ULONG Hash = 0; if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
int i; pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry; }
ULONG RefId = 0;
int WINAPI NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables, void *Pointer)
TRACE("(%p, %p)\n", pXlatTables, Pointer); {
ULONG Hash = 0;
if (!Pointer) int i;
return 1; PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
ULONG RefId = 0;
/* simple hashing algorithm, don't know whether it matches native */
for (i = 0; i < sizeof(Pointer); i++) TRACE("(%p, %p)\n", pXlatTables, Pointer);
Hash = (Hash * 3) ^ ((unsigned char *)&Pointer)[i];
if (!Pointer)
XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask]; return 1;
for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
if (Pointer == XlatTableEntry->Pointer) /* simple hashing algorithm, don't know whether it matches native */
{ for (i = 0; i < sizeof(Pointer); i++)
if (XlatTableEntry->State & 0x20) Hash = (Hash * 3) ^ ((unsigned char *)&Pointer)[i];
return 0;
XlatTableEntry->State |= 0x20; XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
RefId = XlatTableEntry->RefId; for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
break; if (Pointer == XlatTableEntry->Pointer)
} {
if (XlatTableEntry->State & 0x20)
if (!XlatTableEntry) return 0;
return 0; XlatTableEntry->State |= 0x20;
RefId = XlatTableEntry->RefId;
if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId) break;
{ }
pXlatTables->RefIdToPointer.StateTable[RefId] |= 0x20;
return 1; if (!XlatTableEntry)
} return 0;
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

View file

@ -1,65 +1,65 @@
/* /*
* NDR definitions * NDR definitions
* *
* Copyright 2001 Ove Kåven, TransGaming Technologies * Copyright 2001 Ove Kåven, TransGaming Technologies
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#ifndef __WINE_NDR_MISC_H #ifndef __WINE_NDR_MISC_H
#define __WINE_NDR_MISC_H #define __WINE_NDR_MISC_H
#include <stdarg.h> #include <stdarg.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "rpc.h" #include "rpc.h"
#include "rpcndr.h" #include "rpcndr.h"
struct IPSFactoryBuffer; struct IPSFactoryBuffer;
PFORMAT_STRING ComputeConformanceOrVariance( PFORMAT_STRING ComputeConformanceOrVariance(
MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount); PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount);
static inline PFORMAT_STRING ComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def) 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); 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) static inline PFORMAT_STRING ComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def)
{ {
PFORMAT_STRING ret; PFORMAT_STRING ret;
ULONG_PTR ActualCount = pStubMsg->ActualCount; ULONG_PTR ActualCount = pStubMsg->ActualCount;
pStubMsg->Offset = 0; pStubMsg->Offset = 0;
ret = ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &ActualCount); ret = ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &ActualCount);
pStubMsg->ActualCount = (ULONG)ActualCount; pStubMsg->ActualCount = (ULONG)ActualCount;
return ret; return ret;
} }
typedef unsigned char* (WINAPI *NDR_MARSHALL) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING); 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 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 void (WINAPI *NDR_BUFFERSIZE)(PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
typedef ULONG (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING); typedef ULONG (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
typedef void (WINAPI *NDR_FREE) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING); typedef void (WINAPI *NDR_FREE) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
extern const NDR_MARSHALL NdrMarshaller[]; extern const NDR_MARSHALL NdrMarshaller[];
extern const NDR_UNMARSHALL NdrUnmarshaller[]; extern const NDR_UNMARSHALL NdrUnmarshaller[];
extern const NDR_BUFFERSIZE NdrBufferSizer[]; extern const NDR_BUFFERSIZE NdrBufferSizer[];
extern const NDR_MEMORYSIZE NdrMemorySizer[]; extern const NDR_MEMORYSIZE NdrMemorySizer[];
extern const NDR_FREE NdrFreer[]; extern const NDR_FREE NdrFreer[];
#endif /* __WINE_NDR_MISC_H */ #endif /* __WINE_NDR_MISC_H */

View file

@ -1,393 +1,393 @@
/* /*
* OLE32 callouts, COM interface marshalling * OLE32 callouts, COM interface marshalling
* *
* Copyright 2001 Ove Kåven, TransGaming Technologies * Copyright 2001 Ove Kåven, TransGaming Technologies
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* *
* TODO: * TODO:
* - fix the wire-protocol to match MS/RPC * - fix the wire-protocol to match MS/RPC
* - finish RpcStream_Vtbl * - finish RpcStream_Vtbl
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#define COBJMACROS #define COBJMACROS
#define NONAMELESSUNION #define NONAMELESSUNION
#define NONAMELESSSTRUCT #define NONAMELESSSTRUCT
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winerror.h" #include "winerror.h"
#include "objbase.h" #include "objbase.h"
#include "ndr_misc.h" #include "ndr_misc.h"
#include "rpcndr.h" #include "rpcndr.h"
#include "rpcproxy.h" #include "rpcproxy.h"
#include "wine/rpcfc.h" #include "wine/rpcfc.h"
#include "cpsf.h" #include "cpsf.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole); WINE_DEFAULT_DEBUG_CHANNEL(ole);
static HMODULE hOLE; static HMODULE hOLE;
static HRESULT (WINAPI *COM_GetMarshalSizeMax)(ULONG *,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD); 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_MarshalInterface)(LPSTREAM,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD);
static HRESULT (WINAPI *COM_UnmarshalInterface)(LPSTREAM,REFIID,LPVOID*); static HRESULT (WINAPI *COM_UnmarshalInterface)(LPSTREAM,REFIID,LPVOID*);
static HRESULT (WINAPI *COM_ReleaseMarshalData)(LPSTREAM); static HRESULT (WINAPI *COM_ReleaseMarshalData)(LPSTREAM);
static HRESULT (WINAPI *COM_GetClassObject)(REFCLSID,DWORD,COSERVERINFO *,REFIID,LPVOID *); static HRESULT (WINAPI *COM_GetClassObject)(REFCLSID,DWORD,COSERVERINFO *,REFIID,LPVOID *);
static HRESULT (WINAPI *COM_GetPSClsid)(REFIID,CLSID *); static HRESULT (WINAPI *COM_GetPSClsid)(REFIID,CLSID *);
static LPVOID (WINAPI *COM_MemAlloc)(ULONG); static LPVOID (WINAPI *COM_MemAlloc)(ULONG);
static void (WINAPI *COM_MemFree)(LPVOID); static void (WINAPI *COM_MemFree)(LPVOID);
static HMODULE LoadCOM(void) static HMODULE LoadCOM(void)
{ {
if (hOLE) return hOLE; if (hOLE) return hOLE;
hOLE = LoadLibraryA("OLE32.DLL"); hOLE = LoadLibraryA("OLE32.DLL");
if (!hOLE) return 0; if (!hOLE) return 0;
COM_GetMarshalSizeMax = (LPVOID)GetProcAddress(hOLE, "CoGetMarshalSizeMax"); COM_GetMarshalSizeMax = (LPVOID)GetProcAddress(hOLE, "CoGetMarshalSizeMax");
COM_MarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoMarshalInterface"); COM_MarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoMarshalInterface");
COM_UnmarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoUnmarshalInterface"); COM_UnmarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoUnmarshalInterface");
COM_ReleaseMarshalData = (LPVOID)GetProcAddress(hOLE, "CoReleaseMarshalData"); COM_ReleaseMarshalData = (LPVOID)GetProcAddress(hOLE, "CoReleaseMarshalData");
COM_GetClassObject = (LPVOID)GetProcAddress(hOLE, "CoGetClassObject"); COM_GetClassObject = (LPVOID)GetProcAddress(hOLE, "CoGetClassObject");
COM_GetPSClsid = (LPVOID)GetProcAddress(hOLE, "CoGetPSClsid"); COM_GetPSClsid = (LPVOID)GetProcAddress(hOLE, "CoGetPSClsid");
COM_MemAlloc = (LPVOID)GetProcAddress(hOLE, "CoTaskMemAlloc"); COM_MemAlloc = (LPVOID)GetProcAddress(hOLE, "CoTaskMemAlloc");
COM_MemFree = (LPVOID)GetProcAddress(hOLE, "CoTaskMemFree"); COM_MemFree = (LPVOID)GetProcAddress(hOLE, "CoTaskMemFree");
return hOLE; return hOLE;
} }
/* CoMarshalInterface/CoUnmarshalInterface works on streams, /* CoMarshalInterface/CoUnmarshalInterface works on streams,
* so implement a simple stream on top of the RPC buffer * so implement a simple stream on top of the RPC buffer
* (which also implements the MInterfacePointer structure) */ * (which also implements the MInterfacePointer structure) */
typedef struct RpcStreamImpl typedef struct RpcStreamImpl
{ {
const IStreamVtbl *lpVtbl; const IStreamVtbl *lpVtbl;
DWORD RefCount; DWORD RefCount;
PMIDL_STUB_MESSAGE pMsg; PMIDL_STUB_MESSAGE pMsg;
LPDWORD size; LPDWORD size;
char *data; unsigned char *data;
DWORD pos; DWORD pos;
} RpcStreamImpl; } RpcStreamImpl;
static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface, static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface,
REFIID riid, REFIID riid,
LPVOID *obj) LPVOID *obj)
{ {
RpcStreamImpl *This = (RpcStreamImpl *)iface; RpcStreamImpl *This = (RpcStreamImpl *)iface;
if (IsEqualGUID(&IID_IUnknown, riid) || if (IsEqualGUID(&IID_IUnknown, riid) ||
IsEqualGUID(&IID_ISequentialStream, riid) || IsEqualGUID(&IID_ISequentialStream, riid) ||
IsEqualGUID(&IID_IStream, riid)) { IsEqualGUID(&IID_IStream, riid)) {
*obj = This; *obj = This;
This->RefCount++; This->RefCount++;
return S_OK; return S_OK;
} }
return E_NOINTERFACE; return E_NOINTERFACE;
} }
static ULONG WINAPI RpcStream_AddRef(LPSTREAM iface) static ULONG WINAPI RpcStream_AddRef(LPSTREAM iface)
{ {
RpcStreamImpl *This = (RpcStreamImpl *)iface; RpcStreamImpl *This = (RpcStreamImpl *)iface;
return ++(This->RefCount); return ++(This->RefCount);
} }
static ULONG WINAPI RpcStream_Release(LPSTREAM iface) static ULONG WINAPI RpcStream_Release(LPSTREAM iface)
{ {
RpcStreamImpl *This = (RpcStreamImpl *)iface; RpcStreamImpl *This = (RpcStreamImpl *)iface;
if (!--(This->RefCount)) { if (!--(This->RefCount)) {
TRACE("size=%d\n", *This->size); TRACE("size=%d\n", *This->size);
This->pMsg->Buffer = (unsigned char*)This->data + *This->size; This->pMsg->Buffer = (unsigned char*)This->data + *This->size;
HeapFree(GetProcessHeap(),0,This); HeapFree(GetProcessHeap(),0,This);
return 0; return 0;
} }
return This->RefCount; return This->RefCount;
} }
static HRESULT WINAPI RpcStream_Read(LPSTREAM iface, static HRESULT WINAPI RpcStream_Read(LPSTREAM iface,
void *pv, void *pv,
ULONG cb, ULONG cb,
ULONG *pcbRead) ULONG *pcbRead)
{ {
RpcStreamImpl *This = (RpcStreamImpl *)iface; RpcStreamImpl *This = (RpcStreamImpl *)iface;
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (This->pos + cb > *This->size) if (This->pos + cb > *This->size)
{ {
cb = *This->size - This->pos; cb = *This->size - This->pos;
hr = S_FALSE; hr = S_FALSE;
} }
if (cb) { if (cb) {
memcpy(pv, This->data + This->pos, cb); memcpy(pv, This->data + This->pos, cb);
This->pos += cb; This->pos += cb;
} }
if (pcbRead) *pcbRead = cb; if (pcbRead) *pcbRead = cb;
return hr; return hr;
} }
static HRESULT WINAPI RpcStream_Write(LPSTREAM iface, static HRESULT WINAPI RpcStream_Write(LPSTREAM iface,
const void *pv, const void *pv,
ULONG cb, ULONG cb,
ULONG *pcbWritten) ULONG *pcbWritten)
{ {
RpcStreamImpl *This = (RpcStreamImpl *)iface; RpcStreamImpl *This = (RpcStreamImpl *)iface;
if (This->data + cb > (char *)This->pMsg->BufferEnd) if (This->data + cb > (unsigned char *)This->pMsg->RpcMsg->Buffer + This->pMsg->BufferLength)
return STG_E_MEDIUMFULL; return STG_E_MEDIUMFULL;
memcpy(This->data + This->pos, pv, cb); memcpy(This->data + This->pos, pv, cb);
This->pos += cb; This->pos += cb;
if (This->pos > *This->size) *This->size = This->pos; if (This->pos > *This->size) *This->size = This->pos;
if (pcbWritten) *pcbWritten = cb; if (pcbWritten) *pcbWritten = cb;
return S_OK; return S_OK;
} }
static HRESULT WINAPI RpcStream_Seek(LPSTREAM iface, static HRESULT WINAPI RpcStream_Seek(LPSTREAM iface,
LARGE_INTEGER move, LARGE_INTEGER move,
DWORD origin, DWORD origin,
ULARGE_INTEGER *newPos) ULARGE_INTEGER *newPos)
{ {
RpcStreamImpl *This = (RpcStreamImpl *)iface; RpcStreamImpl *This = (RpcStreamImpl *)iface;
switch (origin) { switch (origin) {
case STREAM_SEEK_SET: case STREAM_SEEK_SET:
This->pos = move.u.LowPart; This->pos = move.u.LowPart;
break; break;
case STREAM_SEEK_CUR: case STREAM_SEEK_CUR:
This->pos = This->pos + move.u.LowPart; This->pos = This->pos + move.u.LowPart;
break; break;
case STREAM_SEEK_END: case STREAM_SEEK_END:
This->pos = *This->size + move.u.LowPart; This->pos = *This->size + move.u.LowPart;
break; break;
default: default:
return STG_E_INVALIDFUNCTION; return STG_E_INVALIDFUNCTION;
} }
if (newPos) { if (newPos) {
newPos->u.LowPart = This->pos; newPos->u.LowPart = This->pos;
newPos->u.HighPart = 0; newPos->u.HighPart = 0;
} }
return S_OK; return S_OK;
} }
static HRESULT WINAPI RpcStream_SetSize(LPSTREAM iface, static HRESULT WINAPI RpcStream_SetSize(LPSTREAM iface,
ULARGE_INTEGER newSize) ULARGE_INTEGER newSize)
{ {
RpcStreamImpl *This = (RpcStreamImpl *)iface; RpcStreamImpl *This = (RpcStreamImpl *)iface;
*This->size = newSize.u.LowPart; *This->size = newSize.u.LowPart;
return S_OK; return S_OK;
} }
static const IStreamVtbl RpcStream_Vtbl = static const IStreamVtbl RpcStream_Vtbl =
{ {
RpcStream_QueryInterface, RpcStream_QueryInterface,
RpcStream_AddRef, RpcStream_AddRef,
RpcStream_Release, RpcStream_Release,
RpcStream_Read, RpcStream_Read,
RpcStream_Write, RpcStream_Write,
RpcStream_Seek, RpcStream_Seek,
RpcStream_SetSize, RpcStream_SetSize,
NULL, /* CopyTo */ NULL, /* CopyTo */
NULL, /* Commit */ NULL, /* Commit */
NULL, /* Revert */ NULL, /* Revert */
NULL, /* LockRegion */ NULL, /* LockRegion */
NULL, /* UnlockRegion */ NULL, /* UnlockRegion */
NULL, /* Stat */ NULL, /* Stat */
NULL /* Clone */ NULL /* Clone */
}; };
static LPSTREAM RpcStream_Create(PMIDL_STUB_MESSAGE pStubMsg, BOOL init) static LPSTREAM RpcStream_Create(PMIDL_STUB_MESSAGE pStubMsg, BOOL init)
{ {
RpcStreamImpl *This; RpcStreamImpl *This;
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(RpcStreamImpl)); This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(RpcStreamImpl));
if (!This) return NULL; if (!This) return NULL;
This->lpVtbl = &RpcStream_Vtbl; This->lpVtbl = &RpcStream_Vtbl;
This->RefCount = 1; This->RefCount = 1;
This->pMsg = pStubMsg; This->pMsg = pStubMsg;
This->size = (LPDWORD)pStubMsg->Buffer; This->size = (LPDWORD)pStubMsg->Buffer;
This->data = (char*)(This->size + 1); This->data = (unsigned char*)(This->size + 1);
This->pos = 0; This->pos = 0;
if (init) *This->size = 0; if (init) *This->size = 0;
TRACE("init size=%d\n", *This->size); TRACE("init size=%d\n", *This->size);
return (LPSTREAM)This; return (LPSTREAM)This;
} }
static const IID* get_ip_iid(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) static const IID* get_ip_iid(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
{ {
const IID *riid; const IID *riid;
if (!pFormat) return &IID_IUnknown; if (!pFormat) return &IID_IUnknown;
TRACE("format=%02x %02x\n", pFormat[0], pFormat[1]); TRACE("format=%02x %02x\n", pFormat[0], pFormat[1]);
if (pFormat[0] != RPC_FC_IP) FIXME("format=%d\n", pFormat[0]); if (pFormat[0] != RPC_FC_IP) FIXME("format=%d\n", pFormat[0]);
if (pFormat[1] == RPC_FC_CONSTANT_IID) { if (pFormat[1] == RPC_FC_CONSTANT_IID) {
riid = (const IID *)&pFormat[2]; riid = (const IID *)&pFormat[2];
} else { } else {
ComputeConformance(pStubMsg, pMemory, pFormat+2, 0); ComputeConformance(pStubMsg, pMemory, pFormat+2, 0);
riid = (const IID *)pStubMsg->MaxCount; riid = (const IID *)pStubMsg->MaxCount;
} }
if (!riid) riid = &IID_IUnknown; if (!riid) riid = &IID_IUnknown;
TRACE("got %s\n", debugstr_guid(riid)); TRACE("got %s\n", debugstr_guid(riid));
return riid; return riid;
} }
/*********************************************************************** /***********************************************************************
* NdrInterfacePointerMarshall [RPCRT4.@] * NdrInterfacePointerMarshall [RPCRT4.@]
*/ */
unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char *pMemory, unsigned char *pMemory,
PFORMAT_STRING pFormat) PFORMAT_STRING pFormat)
{ {
const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat); const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat);
LPSTREAM stream; LPSTREAM stream;
HRESULT hr; HRESULT hr;
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
pStubMsg->MaxCount = 0; pStubMsg->MaxCount = 0;
if (!LoadCOM()) return NULL; if (!LoadCOM()) return NULL;
if (pStubMsg->Buffer + sizeof(DWORD) <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { if (pStubMsg->Buffer + sizeof(DWORD) <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
stream = RpcStream_Create(pStubMsg, TRUE); stream = RpcStream_Create(pStubMsg, TRUE);
if (stream) { if (stream) {
if (pMemory) if (pMemory)
hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory, hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory,
pStubMsg->dwDestContext, pStubMsg->pvDestContext, pStubMsg->dwDestContext, pStubMsg->pvDestContext,
MSHLFLAGS_NORMAL); MSHLFLAGS_NORMAL);
else else
hr = S_OK; hr = S_OK;
IStream_Release(stream); IStream_Release(stream);
if (FAILED(hr)) if (FAILED(hr))
RpcRaiseException(hr); RpcRaiseException(hr);
} }
} }
return NULL; return NULL;
} }
/*********************************************************************** /***********************************************************************
* NdrInterfacePointerUnmarshall [RPCRT4.@] * NdrInterfacePointerUnmarshall [RPCRT4.@]
*/ */
unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char **ppMemory, unsigned char **ppMemory,
PFORMAT_STRING pFormat, PFORMAT_STRING pFormat,
unsigned char fMustAlloc) unsigned char fMustAlloc)
{ {
LPSTREAM stream; LPSTREAM stream;
HRESULT hr; HRESULT hr;
TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
if (!LoadCOM()) return NULL; if (!LoadCOM()) return NULL;
*(LPVOID*)ppMemory = NULL; *(LPVOID*)ppMemory = NULL;
if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
stream = RpcStream_Create(pStubMsg, FALSE); stream = RpcStream_Create(pStubMsg, FALSE);
if (!stream) RpcRaiseException(E_OUTOFMEMORY); if (!stream) RpcRaiseException(E_OUTOFMEMORY);
if (*((RpcStreamImpl *)stream)->size != 0) if (*((RpcStreamImpl *)stream)->size != 0)
hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory); hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory);
else else
hr = S_OK; hr = S_OK;
IStream_Release(stream); IStream_Release(stream);
if (FAILED(hr)) if (FAILED(hr))
RpcRaiseException(hr); RpcRaiseException(hr);
} }
return NULL; return NULL;
} }
/*********************************************************************** /***********************************************************************
* NdrInterfacePointerBufferSize [RPCRT4.@] * NdrInterfacePointerBufferSize [RPCRT4.@]
*/ */
void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char *pMemory, unsigned char *pMemory,
PFORMAT_STRING pFormat) PFORMAT_STRING pFormat)
{ {
const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat); const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat);
ULONG size = 0; ULONG size = 0;
HRESULT hr; HRESULT hr;
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
if (!LoadCOM()) return; if (!LoadCOM()) return;
hr = COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory, hr = COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory,
pStubMsg->dwDestContext, pStubMsg->pvDestContext, pStubMsg->dwDestContext, pStubMsg->pvDestContext,
MSHLFLAGS_NORMAL); MSHLFLAGS_NORMAL);
TRACE("size=%d\n", size); TRACE("size=%d\n", size);
pStubMsg->BufferLength += sizeof(DWORD) + size; pStubMsg->BufferLength += sizeof(DWORD) + size;
} }
/*********************************************************************** /***********************************************************************
* NdrInterfacePointerMemorySize [RPCRT4.@] * NdrInterfacePointerMemorySize [RPCRT4.@]
*/ */
ULONG WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, ULONG WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
PFORMAT_STRING pFormat) PFORMAT_STRING pFormat)
{ {
ULONG size; ULONG size;
TRACE("(%p,%p)\n", pStubMsg, pFormat); TRACE("(%p,%p)\n", pStubMsg, pFormat);
size = *(ULONG *)pStubMsg->Buffer; size = *(ULONG *)pStubMsg->Buffer;
pStubMsg->Buffer += 4; pStubMsg->Buffer += 4;
pStubMsg->MemorySize += 4; pStubMsg->MemorySize += 4;
pStubMsg->Buffer += size; pStubMsg->Buffer += size;
return pStubMsg->MemorySize; return pStubMsg->MemorySize;
} }
/*********************************************************************** /***********************************************************************
* NdrInterfacePointerFree [RPCRT4.@] * NdrInterfacePointerFree [RPCRT4.@]
*/ */
void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg, void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char *pMemory, unsigned char *pMemory,
PFORMAT_STRING pFormat) PFORMAT_STRING pFormat)
{ {
LPUNKNOWN pUnk = (LPUNKNOWN)pMemory; LPUNKNOWN pUnk = (LPUNKNOWN)pMemory;
TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
if (pUnk) IUnknown_Release(pUnk); if (pUnk) IUnknown_Release(pUnk);
} }
/*********************************************************************** /***********************************************************************
* NdrOleAllocate [RPCRT4.@] * NdrOleAllocate [RPCRT4.@]
*/ */
void * WINAPI NdrOleAllocate(size_t Size) void * WINAPI NdrOleAllocate(size_t Size)
{ {
if (!LoadCOM()) return NULL; if (!LoadCOM()) return NULL;
return COM_MemAlloc(Size); return COM_MemAlloc(Size);
} }
/*********************************************************************** /***********************************************************************
* NdrOleFree [RPCRT4.@] * NdrOleFree [RPCRT4.@]
*/ */
void WINAPI NdrOleFree(void *NodeToFree) void WINAPI NdrOleFree(void *NodeToFree)
{ {
if (!LoadCOM()) return; if (!LoadCOM()) return;
COM_MemFree(NodeToFree); COM_MemFree(NodeToFree);
} }
/*********************************************************************** /***********************************************************************
* Helper function to create a stub. * Helper function to create a stub.
* This probably looks very much like NdrpCreateStub. * This probably looks very much like NdrpCreateStub.
*/ */
HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub) HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub)
{ {
CLSID clsid; CLSID clsid;
IPSFactoryBuffer *psfac; IPSFactoryBuffer *psfac;
HRESULT r; HRESULT r;
if(!LoadCOM()) return E_FAIL; if(!LoadCOM()) return E_FAIL;
r = COM_GetPSClsid( iid, &clsid ); r = COM_GetPSClsid( iid, &clsid );
if(FAILED(r)) return r; if(FAILED(r)) return r;
r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac ); r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac );
if(FAILED(r)) return r; if(FAILED(r)) return r;
r = IPSFactoryBuffer_CreateStub(psfac, iid, pUnk, ppstub); r = IPSFactoryBuffer_CreateStub(psfac, iid, pUnk, ppstub);
IPSFactoryBuffer_Release(psfac); IPSFactoryBuffer_Release(psfac);
return r; return r;
} }

File diff suppressed because it is too large Load diff

View 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"

View 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;
}

View 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);

View file

@ -39,7 +39,7 @@
#include "wine/debug.h" #include "wine/debug.h"
#include "rpc_binding.h" #include "rpc_binding.h"
#include "rpc_message.h" #include "rpc_assoc.h"
WINE_DEFAULT_DEBUG_CHANNEL(rpc); WINE_DEFAULT_DEBUG_CHANNEL(rpc);
@ -180,7 +180,7 @@ static RPC_STATUS RPCRT4_CompleteBindingW(RpcBinding* Binding, LPCWSTR NetworkAd
{ {
RPC_STATUS status; 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)); debugstr_w(NetworkAddr), debugstr_w(Endpoint), debugstr_w(NetworkOptions));
RPCRT4_strfree(Binding->NetworkAddr); 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) 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)); if (ObjectUuid) memcpy(&Binding->ObjectUuid, ObjectUuid, sizeof(UUID));
else UuidCreateNil(&Binding->ObjectUuid); else UuidCreateNil(&Binding->ObjectUuid);
return RPC_S_OK; return RPC_S_OK;
@ -343,7 +343,7 @@ static LPWSTR RPCRT4_strconcatW(LPWSTR dst, LPCWSTR src)
{ {
DWORD len = strlenW(dst), slen = strlenW(src); DWORD len = strlenW(dst), slen = strlenW(src);
LPWSTR ndst = HeapReAlloc(GetProcessHeap(), 0, dst, (len+slen+2)*sizeof(WCHAR)); LPWSTR ndst = HeapReAlloc(GetProcessHeap(), 0, dst, (len+slen+2)*sizeof(WCHAR));
if (!ndst) if (!ndst)
{ {
HeapFree(GetProcessHeap(), 0, dst); HeapFree(GetProcessHeap(), 0, dst);
return NULL; return NULL;
@ -527,7 +527,7 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU
/* FIXME: this is kind of inefficient */ /* FIXME: this is kind of inefficient */
*Options = (unsigned char*) RPCRT4_strconcatA( (char*)*Options, opt); *Options = (unsigned char*) RPCRT4_strconcatA( (char*)*Options, opt);
HeapFree(GetProcessHeap(), 0, opt); HeapFree(GetProcessHeap(), 0, opt);
} else } else
*Options = (unsigned char*) opt; *Options = (unsigned char*) opt;
} }
} }
@ -536,7 +536,7 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU
data = close+1; data = close+1;
if (*data) goto fail; if (*data) goto fail;
} }
else if (NetworkAddr) else if (NetworkAddr)
*NetworkAddr = (unsigned char*)RPCRT4_strdupA(data); *NetworkAddr = (unsigned char*)RPCRT4_strdupA(data);
return RPC_S_OK; return RPC_S_OK;
@ -618,7 +618,7 @@ RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjU
/* FIXME: this is kind of inefficient */ /* FIXME: this is kind of inefficient */
*Options = RPCRT4_strconcatW(*Options, opt); *Options = RPCRT4_strconcatW(*Options, opt);
HeapFree(GetProcessHeap(), 0, opt); HeapFree(GetProcessHeap(), 0, opt);
} else } else
*Options = opt; *Options = opt;
} }
} }
@ -626,7 +626,7 @@ RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjU
data = close+1; data = close+1;
if (*data) goto fail; if (*data) goto fail;
} else if (NetworkAddr) } else if (NetworkAddr)
*NetworkAddr = RPCRT4_strdupW(data); *NetworkAddr = RPCRT4_strdupW(data);
return RPC_S_OK; return RPC_S_OK;
@ -651,7 +651,7 @@ RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding )
if (status == RPC_S_OK) *Binding = 0; if (status == RPC_S_OK) *Binding = 0;
return status; return status;
} }
/*********************************************************************** /***********************************************************************
* RpcBindingVectorFree (RPCRT4.@) * RpcBindingVectorFree (RPCRT4.@)
*/ */
@ -668,7 +668,7 @@ RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector )
*BindingVector = NULL; *BindingVector = NULL;
return RPC_S_OK; return RPC_S_OK;
} }
/*********************************************************************** /***********************************************************************
* RpcBindingInqObject (RPCRT4.@) * RpcBindingInqObject (RPCRT4.@)
*/ */
@ -680,7 +680,7 @@ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU
memcpy(ObjectUuid, &bind->ObjectUuid, sizeof(UUID)); memcpy(ObjectUuid, &bind->ObjectUuid, sizeof(UUID));
return RPC_S_OK; return RPC_S_OK;
} }
/*********************************************************************** /***********************************************************************
* RpcBindingSetObject (RPCRT4.@) * RpcBindingSetObject (RPCRT4.@)
*/ */
@ -724,9 +724,9 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BIND
RpcStringFreeA((unsigned char**)&Protseq); RpcStringFreeA((unsigned char**)&Protseq);
RpcStringFreeA((unsigned char**)&ObjectUuid); RpcStringFreeA((unsigned char**)&ObjectUuid);
if (ret == RPC_S_OK) if (ret == RPC_S_OK)
*Binding = (RPC_BINDING_HANDLE)bind; *Binding = (RPC_BINDING_HANDLE)bind;
else else
RPCRT4_DestroyBinding(bind); RPCRT4_DestroyBinding(bind);
return ret; return ret;
@ -770,7 +770,7 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BIND
return ret; return ret;
} }
/*********************************************************************** /***********************************************************************
* RpcBindingToStringBindingA (RPCRT4.@) * RpcBindingToStringBindingA (RPCRT4.@)
*/ */
@ -792,7 +792,7 @@ RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CS
return ret; return ret;
} }
/*********************************************************************** /***********************************************************************
* RpcBindingToStringBindingW (RPCRT4.@) * RpcBindingToStringBindingW (RPCRT4.@)
*/ */
@ -1001,7 +1001,7 @@ ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo)
{ {
HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->User); HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->User);
HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Domain); 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->nt_identity);
} }
HeapFree(GetProcessHeap(), 0, AuthInfo); HeapFree(GetProcessHeap(), 0, AuthInfo);

View file

@ -22,6 +22,7 @@
#define __WINE_RPC_BINDING_H #define __WINE_RPC_BINDING_H
#include "wine/rpcss_shared.h" #include "wine/rpcss_shared.h"
#include "rpcndr.h"
#include "security.h" #include "security.h"
#include "wine/list.h" #include "wine/list.h"
@ -49,37 +50,16 @@ typedef struct _RpcQualityOfService
RPC_SECURITY_QOS_V2_W *qos; RPC_SECURITY_QOS_V2_W *qos;
} RpcQualityOfService; } 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; struct connection_ops;
typedef struct _RpcConnection typedef struct _RpcConnection
{ {
struct _RpcConnection* Next;
BOOL server; BOOL server;
LPSTR NetworkAddr; LPSTR NetworkAddr;
LPSTR Endpoint; LPSTR Endpoint;
LPWSTR NetworkOptions; LPWSTR NetworkOptions;
const struct connection_ops *ops; const struct connection_ops *ops;
USHORT MaxTransmissionSize; USHORT MaxTransmissionSize;
/* The active interface bound to server. */
RPC_SYNTAX_IDENTIFIER ActiveInterface;
USHORT NextCallId;
/* authentication */ /* authentication */
CtxtHandle ctx; CtxtHandle ctx;
@ -93,6 +73,13 @@ typedef struct _RpcConnection
/* client-only */ /* client-only */
struct list conn_pool_entry; struct list conn_pool_entry;
ULONG assoc_group_id; /* association group returned during binding */ 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; } RpcConnection;
struct connection_ops { struct connection_ops {
@ -104,6 +91,7 @@ struct connection_ops {
int (*read)(RpcConnection *conn, void *buffer, unsigned int len); int (*read)(RpcConnection *conn, void *buffer, unsigned int len);
int (*write)(RpcConnection *conn, const void *buffer, unsigned int len); int (*write)(RpcConnection *conn, const void *buffer, unsigned int len);
int (*close)(RpcConnection *conn); 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); size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint);
RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint); RPC_STATUS (*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; RPC_BLOCKING_FN BlockingFn;
ULONG ServerTid; ULONG ServerTid;
RpcConnection* FromConn; RpcConnection* FromConn;
RpcAssoc *Assoc; struct _RpcAssoc *Assoc;
/* authentication */ /* authentication */
RpcAuthInfo *AuthInfo; RpcAuthInfo *AuthInfo;
@ -145,11 +133,6 @@ ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos);
ULONG RpcQualityOfService_Release(RpcQualityOfService *qos); ULONG RpcQualityOfService_Release(RpcQualityOfService *qos);
BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQualityOfService *qos2); 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_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_DestroyConnection(RpcConnection* Connection);
RPC_STATUS RPCRT4_OpenClientConnection(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); 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) static inline RPC_STATUS rpcrt4_conn_handoff(RpcConnection *old_conn, RpcConnection *new_conn)
{ {
return old_conn->ops->handoff(old_conn, 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_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); 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 #endif

View file

@ -102,7 +102,7 @@ typedef struct
unsigned short max_tsize; /* Maximum transmission fragment size */ unsigned short max_tsize; /* Maximum transmission fragment size */
unsigned short max_rsize; /* Maximum receive fragment size */ unsigned short max_rsize; /* Maximum receive fragment size */
unsigned long assoc_gid; /* Associated group id */ unsigned long assoc_gid; /* Associated group id */
/* /*
* Following this header are these fields: * Following this header are these fields:
* RpcAddressString server_address; * RpcAddressString server_address;
* [0 - 3 bytes of padding so that results is 4-byte aligned] * [0 - 3 bytes of padding so that results is 4-byte aligned]

View file

@ -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_type = RPCSS_NP_MESSAGE_TYPEID_RESOLVEEPMSG;
msg.message.resolveepmsg.iface = If->InterfaceId; msg.message.resolveepmsg.iface = If->InterfaceId;
msg.message.resolveepmsg.object = bind->ObjectUuid; msg.message.resolveepmsg.object = bind->ObjectUuid;
msg.vardata_payload_size = strlen(bind->Protseq) + 1; msg.vardata_payload_size = strlen(bind->Protseq) + 1;
/* send the message */ /* send the message */
@ -241,7 +241,7 @@ RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE
/* empty-string result means not registered */ /* empty-string result means not registered */
if (reply.as_string[0] == '\0') if (reply.as_string[0] == '\0')
return EPT_S_NOT_REGISTERED; return EPT_S_NOT_REGISTERED;
/* otherwise we fully bind the handle & return RPC_S_OK */ /* otherwise we fully bind the handle & return RPC_S_OK */
return RPCRT4_ResolveBinding(Binding, reply.as_string); return RPCRT4_ResolveBinding(Binding, reply.as_string);
} }

View file

@ -67,7 +67,7 @@ static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
0, 0, 0, 0, 0 0, 0, 0, 0, 0
}; };
ULONG ret = 0; ULONG ret = 0;
if (Header->common.ptype < sizeof(header_sizes) / sizeof(header_sizes[0])) { if (Header->common.ptype < sizeof(header_sizes) / sizeof(header_sizes[0])) {
ret = header_sizes[Header->common.ptype]; ret = header_sizes[Header->common.ptype];
if (ret == 0) if (ret == 0)
@ -108,7 +108,7 @@ static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType
Header->common.call_id = 1; Header->common.call_id = 1;
Header->common.flags = 0; Header->common.flags = 0;
/* Flags and fragment length are computed in RPCRT4_Send. */ /* Flags and fragment length are computed in RPCRT4_Send. */
} }
static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation, static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation,
unsigned long BufferLength, unsigned long BufferLength,
@ -241,6 +241,7 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation,
RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation,
unsigned short MaxTransmissionSize, unsigned short MaxTransmissionSize,
unsigned short MaxReceiveSize, unsigned short MaxReceiveSize,
unsigned long AssocGroupId,
LPCSTR ServerAddress, LPCSTR ServerAddress,
unsigned long Result, unsigned long Result,
unsigned long Reason, unsigned long Reason,
@ -266,6 +267,7 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation,
header->common.frag_len = header_size; header->common.frag_len = header_size;
header->bind_ack.max_tsize = MaxTransmissionSize; header->bind_ack.max_tsize = MaxTransmissionSize;
header->bind_ack.max_rsize = MaxReceiveSize; header->bind_ack.max_rsize = MaxReceiveSize;
header->bind_ack.assoc_gid = AssocGroupId;
server_address = (RpcAddressString*)(&header->bind_ack + 1); server_address = (RpcAddressString*)(&header->bind_ack + 1);
server_address->length = strlen(ServerAddress) + 1; server_address->length = strlen(ServerAddress) + 1;
strcpy(server_address->string, ServerAddress); 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); sec_status = DecryptMessage(&Connection->ctx, &message, 0 /* FIXME */, 0);
if (sec_status != SEC_E_OK) 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; return RPC_S_SEC_PKG_ERROR;
} }
} }
@ -432,10 +434,10 @@ static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection,
return RPC_S_OK; return RPC_S_OK;
} }
/*********************************************************************** /***********************************************************************
* RPCRT4_SendAuth (internal) * RPCRT4_SendAuth (internal)
* *
* Transmit a packet with authorization data over connection in acceptable fragments. * Transmit a packet with authorization data over connection in acceptable fragments.
*/ */
static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header, static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
@ -449,6 +451,8 @@ static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
LONG alen; LONG alen;
RPC_STATUS status; RPC_STATUS status;
RPCRT4_SetThreadCurrentConnection(Connection);
buffer_pos = Buffer; buffer_pos = Buffer;
/* The packet building functions save the packet header size, so we can use it. */ /* The packet building functions save the packet header size, so we can use it. */
hdr_size = Header->common.frag_len; hdr_size = Header->common.frag_len;
@ -518,6 +522,7 @@ static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
if (status != RPC_S_OK) if (status != RPC_S_OK)
{ {
HeapFree(GetProcessHeap(), 0, pkt); HeapFree(GetProcessHeap(), 0, pkt);
RPCRT4_SetThreadCurrentConnection(NULL);
return status; return status;
} }
} }
@ -528,7 +533,8 @@ write:
HeapFree(GetProcessHeap(), 0, pkt); HeapFree(GetProcessHeap(), 0, pkt);
if (count<0) { if (count<0) {
WARN("rpcrt4_conn_write failed (auth)\n"); 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; buffer_pos += Header->common.frag_len - hdr_size - alen - auth_pad_len;
@ -536,6 +542,7 @@ write:
Header->common.flags &= ~RPC_FLG_FIRST; Header->common.flags &= ~RPC_FLG_FIRST;
} }
RPCRT4_SetThreadCurrentConnection(NULL);
return RPC_S_OK; return RPC_S_OK;
} }
@ -653,7 +660,7 @@ static RPC_STATUS RPCRT_AuthorizeConnection(RpcConnection* conn,
/*********************************************************************** /***********************************************************************
* RPCRT4_Send (internal) * RPCRT4_Send (internal)
* *
* Transmit a packet over connection in acceptable fragments. * Transmit a packet over connection in acceptable fragments.
*/ */
RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
@ -677,7 +684,7 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
/*********************************************************************** /***********************************************************************
* RPCRT4_Receive (internal) * RPCRT4_Receive (internal)
* *
* Receive a packet from connection and merge the fragments. * Receive a packet from connection and merge the fragments.
*/ */
RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, 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); TRACE("(%p, %p, %p)\n", Connection, Header, pMsg);
RPCRT4_SetThreadCurrentConnection(Connection);
/* read packet common header */ /* read packet common header */
dwRead = rpcrt4_conn_read(Connection, &common_hdr, sizeof(common_hdr)); dwRead = rpcrt4_conn_read(Connection, &common_hdr, sizeof(common_hdr));
if (dwRead != sizeof(common_hdr)) { if (dwRead != sizeof(common_hdr)) {
WARN("Short read of header, %d bytes\n", dwRead); WARN("Short read of header, %d bytes\n", dwRead);
status = RPC_S_PROTOCOL_ERROR; status = RPC_S_CALL_FAILED;
goto fail; 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)); dwRead = rpcrt4_conn_read(Connection, &(*Header)->common + 1, hdr_length - sizeof(common_hdr));
if (dwRead != 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); 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; goto fail;
} }
@ -753,7 +762,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
if (auth_length) { if (auth_length) {
auth_data = HeapAlloc(GetProcessHeap(), 0, RPC_AUTH_VERIFIER_LEN(&common_hdr)); auth_data = HeapAlloc(GetProcessHeap(), 0, RPC_AUTH_VERIFIER_LEN(&common_hdr));
if (!auth_data) { if (!auth_data) {
status = RPC_S_PROTOCOL_ERROR; status = RPC_S_OUT_OF_RESOURCES;
goto fail; goto fail;
} }
} }
@ -799,7 +808,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
(unsigned char *)pMsg->Buffer + buffer_length, data_length); (unsigned char *)pMsg->Buffer + buffer_length, data_length);
if (dwRead != data_length) { if (dwRead != data_length) {
WARN("bad data length, %d/%ld\n", 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; goto fail;
} }
@ -819,7 +828,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
if (dwRead != header_auth_len) { if (dwRead != header_auth_len) {
WARN("bad authentication data length, %d/%d\n", dwRead, WARN("bad authentication data length, %d/%d\n", dwRead,
header_auth_len); header_auth_len);
status = RPC_S_PROTOCOL_ERROR; status = RPC_S_CALL_FAILED;
goto fail; goto fail;
} }
@ -828,12 +837,15 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
if ((common_hdr.ptype != PKT_BIND) && if ((common_hdr.ptype != PKT_BIND) &&
(common_hdr.ptype != PKT_BIND_ACK) && (common_hdr.ptype != PKT_BIND_ACK) &&
(common_hdr.ptype != PKT_AUTH3)) (common_hdr.ptype != PKT_AUTH3))
{
status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_RECEIVE, status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_RECEIVE,
*Header, hdr_length, *Header, hdr_length,
(unsigned char *)pMsg->Buffer + buffer_length, data_length, (unsigned char *)pMsg->Buffer + buffer_length, data_length,
(RpcAuthVerifier *)auth_data, (RpcAuthVerifier *)auth_data,
(unsigned char *)auth_data + sizeof(RpcAuthVerifier), (unsigned char *)auth_data + sizeof(RpcAuthVerifier),
header_auth_len - sizeof(RpcAuthVerifier)); header_auth_len - sizeof(RpcAuthVerifier));
if (status != RPC_S_OK) goto fail;
}
} }
buffer_length += data_length; buffer_length += data_length;
@ -844,7 +856,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
dwRead = rpcrt4_conn_read(Connection, *Header, hdr_length); dwRead = rpcrt4_conn_read(Connection, *Header, hdr_length);
if (dwRead != hdr_length) { if (dwRead != hdr_length) {
WARN("invalid packet header size (%d)\n", dwRead); WARN("invalid packet header size (%d)\n", dwRead);
status = RPC_S_PROTOCOL_ERROR; status = RPC_S_CALL_FAILED;
goto fail; goto fail;
} }
@ -869,6 +881,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
status = RPC_S_OK; status = RPC_S_OK;
fail: fail:
RPCRT4_SetThreadCurrentConnection(NULL);
if (status != RPC_S_OK) { if (status != RPC_S_OK) {
RPCRT4_FreeHeader(*Header); RPCRT4_FreeHeader(*Header);
*Header = NULL; *Header = NULL;

View file

@ -30,7 +30,7 @@ RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS
RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength); 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_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_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); VOID RPCRT4_FreeHeader(RpcPktHdr *Header);
RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength); RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength);
RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg); RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg);

View file

@ -42,6 +42,7 @@
#include "wine/exception.h" #include "wine/exception.h"
#include "rpc_server.h" #include "rpc_server.h"
#include "rpc_assoc.h"
#include "rpc_message.h" #include "rpc_message.h"
#include "rpc_defs.h" #include "rpc_defs.h"
#include "ncastatus.h" #include "ncastatus.h"
@ -167,10 +168,13 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
RpcServerInterface* sif; RpcServerInterface* sif;
RPC_DISPATCH_FUNCTION func; RPC_DISPATCH_FUNCTION func;
UUID *object_uuid; UUID *object_uuid;
RpcPktHdr *response; RpcPktHdr *response = NULL;
void *buf = msg->Buffer; void *buf = msg->Buffer;
RPC_STATUS status; RPC_STATUS status;
BOOL exception; BOOL exception;
NDR_SCONTEXT context_handle;
msg->Handle = (RPC_BINDING_HANDLE)conn->server_binding;
switch (hdr->common.ptype) { switch (hdr->common.ptype) {
case PKT_BIND: case PKT_BIND:
@ -178,11 +182,21 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
/* FIXME: do more checks! */ /* FIXME: do more checks! */
if (hdr->bind.max_tsize < RPC_MIN_PACKET_SIZE || 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"); TRACE("packet size less than min size, or active interface syntax guid non-null\n");
sif = NULL; sif = NULL;
} else { } 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) { if (sif == NULL) {
TRACE("rejecting bind request on connection %p\n", conn); 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, response = RPCRT4_BuildBindAckHeader(NDR_LOCAL_DATA_REPRESENTATION,
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE,
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE,
conn->server_binding->Assoc->assoc_group_id,
conn->Endpoint, conn->Endpoint,
RESULT_ACCEPT, REASON_NONE, RESULT_ACCEPT, REASON_NONE,
&sif->If->TransferSyntax); &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? /* put in the drep. FIXME: is this more universally applicable?
perhaps we should move this outward... */ perhaps we should move this outward... */
msg->DataRepresentation = msg->DataRepresentation =
MAKELONG( MAKEWORD(hdr->common.drep[0], hdr->common.drep[1]), MAKELONG( MAKEWORD(hdr->common.drep[0], hdr->common.drep[1]),
MAKEWORD(hdr->common.drep[2], hdr->common.drep[3])); MAKEWORD(hdr->common.drep[2], hdr->common.drep[3]));
exception = FALSE; exception = FALSE;
/* dispatch */ /* dispatch */
RPCRT4_SetThreadCurrentCallHandle(msg->Handle);
__TRY { __TRY {
if (func) func(msg); if (func) func(msg);
} __EXCEPT(rpc_filter) { } __EXCEPT(rpc_filter) {
@ -290,6 +306,11 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
response = RPCRT4_BuildFaultHeader(msg->DataRepresentation, response = RPCRT4_BuildFaultHeader(msg->DataRepresentation,
RPC2NCA_STATUS(status)); RPC2NCA_STATUS(status));
} __ENDTRY } __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) if (!exception)
response = RPCRT4_BuildResponseHeader(msg->DataRepresentation, response = RPCRT4_BuildResponseHeader(msg->DataRepresentation,
@ -318,7 +339,6 @@ fail:
if (msg->Buffer == buf) msg->Buffer = NULL; if (msg->Buffer == buf) msg->Buffer = NULL;
TRACE("freeing Buffer=%p\n", buf); TRACE("freeing Buffer=%p\n", buf);
HeapFree(GetProcessHeap(), 0, buf); HeapFree(GetProcessHeap(), 0, buf);
RPCRT4_DestroyBinding(msg->Handle);
msg->Handle = 0; msg->Handle = 0;
I_RpcFreeBuffer(msg); I_RpcFreeBuffer(msg);
msg->Buffer = NULL; msg->Buffer = NULL;
@ -338,7 +358,6 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
{ {
RpcConnection* conn = (RpcConnection*)the_arg; RpcConnection* conn = (RpcConnection*)the_arg;
RpcPktHdr *hdr; RpcPktHdr *hdr;
RpcBinding *pbind;
RPC_MESSAGE *msg; RPC_MESSAGE *msg;
RPC_STATUS status; RPC_STATUS status;
RpcPacket *packet; RpcPacket *packet;
@ -348,11 +367,6 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
for (;;) { for (;;) {
msg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RPC_MESSAGE)); 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); status = RPCRT4_Receive(conn, &hdr, msg);
if (status != RPC_S_OK) { if (status != RPC_S_OK) {
WARN("receive failed with error %lx\n", status); 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); status = RPCRT4_start_listen_protseq(cps, TRUE);
if (status != RPC_S_OK) if (status != RPC_S_OK)
break; break;
/* make sure server is actually listening on the interface before /* make sure server is actually listening on the interface before
* returning */ * returning */
RPCRT4_sync_with_server_thread(cps); 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_STATUS WINAPI RpcServerUseProtseqEpA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor )
{ {
RPC_POLICY policy; RPC_POLICY policy;
TRACE( "(%s,%u,%s,%p)\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor ); TRACE( "(%s,%u,%s,%p)\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor );
/* This should provide the default behaviour */ /* This should provide the default behaviour */
policy.Length = sizeof( policy ); policy.Length = sizeof( policy );
policy.EndpointFlags = 0; policy.EndpointFlags = 0;
policy.NICFlags = 0; policy.NICFlags = 0;
return RpcServerUseProtseqEpExA( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy ); 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_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor )
{ {
RPC_POLICY policy; RPC_POLICY policy;
TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor ); TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor );
/* This should provide the default behaviour */ /* This should provide the default behaviour */
policy.Length = sizeof( policy ); policy.Length = sizeof( policy );
policy.EndpointFlags = 0; policy.EndpointFlags = 0;
policy.NICFlags = 0; policy.NICFlags = 0;
return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy ); return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy );
} }
@ -935,7 +949,7 @@ RPC_STATUS WINAPI RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid )
if ((! TypeUuid) || UuidIsNil(TypeUuid, &dummy)) { if ((! TypeUuid) || UuidIsNil(TypeUuid, &dummy)) {
/* ... and drop it from the list */ /* ... and drop it from the list */
if (map) { if (map) {
if (prev) if (prev)
prev->next = map->next; prev->next = map->next;
else else
RpcObjTypeMaps = map->next; RpcObjTypeMaps = map->next;
@ -966,7 +980,7 @@ RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( RPC_CSTR ServerPrincName, ULONG Au
LPVOID Arg ) LPVOID Arg )
{ {
FIXME( "(%s,%u,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, 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 */ 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 ) LPVOID Arg )
{ {
FIXME( "(%s,%u,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, 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 */ 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); LeaveCriticalSection(&listen_cs);
return RPC_S_NOT_LISTENING; return RPC_S_NOT_LISTENING;
} }
LeaveCriticalSection(&listen_cs); LeaveCriticalSection(&listen_cs);
FIXME("not waiting for server calls to finish\n"); 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"); FIXME("client-side invocation not implemented.\n");
return RPC_S_WRONG_KIND_OF_BINDING; return RPC_S_WRONG_KIND_OF_BINDING;
} }
RPCRT4_stop_listen(FALSE); RPCRT4_stop_listen(FALSE);
return RPC_S_OK; return RPC_S_OK;
@ -1114,3 +1128,12 @@ RPC_STATUS WINAPI RpcMgmtSetServerStackSize(ULONG ThreadStackSize)
FIXME("(0x%x): stub\n", ThreadStackSize); FIXME("(0x%x): stub\n", ThreadStackSize);
return RPC_S_OK; 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

View file

@ -23,11 +23,13 @@
<file>cproxy.c</file> <file>cproxy.c</file>
<file>cpsf.c</file> <file>cpsf.c</file>
<file>cstub.c</file> <file>cstub.c</file>
<file>ndr_contexthandle.c</file>
<file>ndr_clientserver.c</file> <file>ndr_clientserver.c</file>
<file>ndr_fullpointer.c</file> <file>ndr_fullpointer.c</file>
<file>ndr_marshall.c</file> <file>ndr_marshall.c</file>
<file>ndr_ole.c</file> <file>ndr_ole.c</file>
<file>ndr_stubless.c</file> <file>ndr_stubless.c</file>
<file>rpc_assoc.c</file>
<file>rpc_binding.c</file> <file>rpc_binding.c</file>
<file>rpc_epmap.c</file> <file>rpc_epmap.c</file>
<file>rpc_message.c</file> <file>rpc_message.c</file>

File diff suppressed because it is too large Load diff

View file

@ -16,7 +16,7 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* *
* WINE RPC TODO's (and a few TODONT's) * WINE RPC TODO's (and a few TODONT's)
* *
* - Ove's decreasingly incomplete widl is an IDL compiler for wine. For widl * - 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 * - Some transports are not yet implemented. The existing transport implementations
* are incomplete and may be bug-infested. * are incomplete and may be bug-infested.
* *
* - The various transports that we do support ought to be supported in a more * - 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 * object-oriented manner, as in DCE's RPC implementation, instead of cluttering
* up the code with conditionals like we do now. * up the code with conditionals like we do now.
* *
* - Data marshalling: So far, only the beginnings of a full implementation * - 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 * 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, * 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. * use it to implement out-of-process OLE client/server communications.
* ATM there is maybe a disconnect between the marshalling in the OLE DLLs * 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?] * and the marshalling going on here [TODO: well, is there or not?]
* *
* - In-source API Documentation, at least for those functions which we have * - In-source API Documentation, at least for those functions which we have
* implemented, but preferably for everything we can document, would be nice, * implemented, but preferably for everything we can document, would be nice,
* since some of this stuff is quite obscure. * since some of this stuff is quite obscure.
@ -100,6 +100,8 @@
#include "winerror.h" #include "winerror.h"
#include "winbase.h" #include "winbase.h"
#include "winuser.h" #include "winuser.h"
#include "winnt.h"
#include "winternl.h"
#include "iptypes.h" #include "iptypes.h"
#include "iphlpapi.h" #include "iphlpapi.h"
#include "wine/unicode.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 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 * 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) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{ {
struct threaddata *tdata;
switch (fdwReason) { switch (fdwReason) {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
master_mutex = CreateMutexA( NULL, FALSE, RPCSS_MASTER_MUTEX_NAME); master_mutex = CreateMutexA( NULL, FALSE, RPCSS_MASTER_MUTEX_NAME);
if (!master_mutex) if (!master_mutex)
ERR("Failed to create master mutex\n"); ERR("Failed to create master mutex\n");
break; 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: case DLL_PROCESS_DETACH:
CloseHandle(master_mutex); CloseHandle(master_mutex);
master_mutex = NULL; master_mutex = NULL;
@ -202,10 +249,12 @@ RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR* String)
* *
* Raises an exception. * 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); 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 *Uuid1 [I] Uuid to compare
* UUID *Uuid2 [I] Uuid to compare * UUID *Uuid2 [I] Uuid to compare
* RPC_STATUS *Status [O] returns RPC_S_OK * RPC_STATUS *Status [O] returns RPC_S_OK
* *
* RETURNS * RETURNS
* -1 if Uuid1 is less than Uuid2 * -1 if Uuid1 is less than Uuid2
* 0 if Uuid1 and Uuid2 are equal * 0 if Uuid1 and Uuid2 are equal
@ -321,7 +370,7 @@ static void RPC_UuidGetSystemTime(ULONGLONG *time)
*time += TICKS_15_OCT_1582_TO_1601; *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 #define ADDRESS_BYTES_NEEDED 6
static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address) 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. * RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique.
* *
* FIXME: No compensation for changes across reloading * 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 * backwards and swapped network cards). The RFC
* suggests using NVRAM for storing persistent * suggests using NVRAM for storing persistent
* values. * values.
*/ */
RPC_STATUS WINAPI UuidCreate(UUID *Uuid) RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
@ -693,11 +742,11 @@ static BOOL RPCRT4_StartRPCSS(void)
/*********************************************************************** /***********************************************************************
* RPCRT4_RPCSSOnDemandCall (internal) * RPCRT4_RPCSSOnDemandCall (internal)
* *
* Attempts to send a message to the RPCSS process * Attempts to send a message to the RPCSS process
* on the local machine, invoking it if necessary. * on the local machine, invoking it if necessary.
* For remote RPCSS calls, use.... your imagination. * For remote RPCSS calls, use.... your imagination.
* *
* PARAMS * PARAMS
* msg [I] pointer to the RPCSS message * msg [I] pointer to the RPCSS message
* vardata_payload [I] pointer vardata portion of 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); Sleep(200);
client_handle = RPCRT4_RpcssNPConnect(); client_handle = RPCRT4_RpcssNPConnect();
if (INVALID_HANDLE_VALUE != client_handle) break; if (INVALID_HANDLE_VALUE != client_handle) break;
} }
/* we are only willing to try twice */ /* we are only willing to try twice */
if (j++ >= 1) break; if (j++ >= 1) break;
} }
@ -823,8 +872,154 @@ void WINAPI I_RpcFree(void *Object)
/****************************************************************************** /******************************************************************************
* I_RpcMapWin32Status (rpcrt4.@) * I_RpcMapWin32Status (rpcrt4.@)
*/ */
DWORD WINAPI I_RpcMapWin32Status(RPC_STATUS status) LONG WINAPI I_RpcMapWin32Status(RPC_STATUS status)
{ {
FIXME("(%ld): stub\n", status); FIXME("(%ld): stub\n", status);
return 0; 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;
}

View file

@ -35,19 +35,19 @@ HANDLE RPCRT4_RpcssNPConnect(void)
HANDLE the_pipe; HANDLE the_pipe;
DWORD dwmode, wait_result; DWORD dwmode, wait_result;
HANDLE master_mutex = RPCRT4_GetMasterMutex(); HANDLE master_mutex = RPCRT4_GetMasterMutex();
TRACE("\n"); TRACE("\n");
while (TRUE) { while (TRUE) {
wait_result = WaitForSingleObject(master_mutex, MASTER_MUTEX_TIMEOUT); wait_result = WaitForSingleObject(master_mutex, MASTER_MUTEX_TIMEOUT);
switch (wait_result) { switch (wait_result) {
case WAIT_ABANDONED: case WAIT_ABANDONED:
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
break; break;
case WAIT_FAILED: case WAIT_FAILED:
case WAIT_TIMEOUT: case WAIT_TIMEOUT:
default: default:
ERR("This should never happen: couldn't enter mutex.\n"); ERR("This should never happen: couldn't enter mutex.\n");
return NULL; return NULL;
} }
@ -67,13 +67,13 @@ HANDLE RPCRT4_RpcssNPConnect(void)
break; break;
if (GetLastError() != ERROR_PIPE_BUSY) { 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)); debugstr_a(NAME_RPCSS_NAMED_PIPE));
break; break;
} }
WARN("Named pipe busy (will wait)\n"); WARN("Named pipe busy (will wait)\n");
if (!ReleaseMutex(master_mutex)) if (!ReleaseMutex(master_mutex))
ERR("Failed to release master mutex. Expect deadlock.\n"); 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 */ /* process the vardata payload if necessary */
vardata_payload_msg.message_type = RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG; vardata_payload_msg.message_type = RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG;
vardata_payload_msg.vardata_payload_size = 0; /* meaningless */ 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 ) { payload_offset += VARDATA_PAYLOAD_BYTES ) {
TRACE("sending vardata payload. vd=%p, po=%d, ps=%d\n", vardata, TRACE("sending vardata payload. vd=%p, po=%d, ps=%d\n", vardata,
payload_offset, msg->vardata_payload_size); payload_offset, msg->vardata_payload_size);
@ -136,7 +136,7 @@ BOOL RPCRT4_SendReceiveNPMsg(HANDLE np, PRPCSS_NP_MESSAGE msg, char *vardata, PR
return FALSE; return FALSE;
} }
} }
if (! ReadFile(np, reply, sizeof(RPCSS_NP_REPLY), &count, NULL)) { if (! ReadFile(np, reply, sizeof(RPCSS_NP_REPLY), &count, NULL)) {
ERR("read failed.\n"); ERR("read failed.\n");
return FALSE; return FALSE;