Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1639 lines
37 KiB

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1993 Microsoft Corporation
Module Name :
auxilary.c
Abstract :
This file contains auxilary routines used for initialization of the
RPC and stub messages and the offline batching of common code sequences
needed by the stubs.
Author :
David Kays dkays September 1993.
Revision History :
---------------------------------------------------------------------*/
#define _OLE32_
#include "ndrp.h"
#include "ndrole.h"
#include "limits.h"
#include "pipendr.h"
#if defined(_MPPC_)
#include <errors.h>
#include <codefrag.h>
HRESULT MapMacErrorsToHresult( OSErr );
#endif
#if defined( DOS ) && !defined( WIN )
#pragma code_seg( "NDR20_2" )
#endif
void NdrpSetRpcSsDefaults(RPC_CLIENT_ALLOC *pfnAlloc,
RPC_CLIENT_FREE *pfnFree);
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Static data for NS library operations
---------------------------------------------------------------------*/
typedef
RPC_STATUS ( __RPC_FAR RPC_ENTRY *RPC_NS_GET_BUFFER_ROUTINE)(
IN PRPC_MESSAGE Message
);
typedef
RPC_STATUS ( __RPC_FAR RPC_ENTRY *RPC_NS_SEND_RECEIVE_ROUTINE)(
IN PRPC_MESSAGE Message,
OUT RPC_BINDING_HANDLE __RPC_FAR * Handle
);
int NsDllLoaded = 0;
RPC_NS_GET_BUFFER_ROUTINE pRpcNsGetBuffer;
RPC_NS_SEND_RECEIVE_ROUTINE pRpcNsSendReceive;
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
OLE routines for interface pointer marshalling
---------------------------------------------------------------------*/
#if defined( NDR_OLE_SUPPORT )
#if defined(_MPPC_)
ConnectionID hOle32 = 0;
#else
HINSTANCE hOle32 = 0;
#endif
RPC_GET_CLASS_OBJECT_ROUTINE NdrCoGetClassObject;
RPC_GET_CLASS_OBJECT_ROUTINE * pfnCoGetClassObject = &NdrCoGetClassObject;
RPC_GET_MARSHAL_SIZE_MAX_ROUTINE NdrCoGetMarshalSizeMax;
RPC_GET_MARSHAL_SIZE_MAX_ROUTINE * pfnCoGetMarshalSizeMax = &NdrCoGetMarshalSizeMax;
RPC_MARSHAL_INTERFACE_ROUTINE NdrCoMarshalInterface;
RPC_MARSHAL_INTERFACE_ROUTINE * pfnCoMarshalInterface = &NdrCoMarshalInterface;
RPC_UNMARSHAL_INTERFACE_ROUTINE NdrCoUnmarshalInterface;
RPC_UNMARSHAL_INTERFACE_ROUTINE * pfnCoUnmarshalInterface = &NdrCoUnmarshalInterface;
RPC_STRING_FROM_IID OleStringFromIID;
RPC_STRING_FROM_IID * pfnStringFromIID = &OleStringFromIID;
RPC_GET_PS_CLSID NdrCoGetPSClsid;
RPC_GET_PS_CLSID * pfnCoGetPSClsid = &NdrCoGetPSClsid;
RPC_CLIENT_ALLOC NdrCoTaskMemAlloc;
RPC_CLIENT_ALLOC * pfnCoTaskMemAlloc = &NdrCoTaskMemAlloc;
RPC_CLIENT_FREE NdrCoTaskMemFree;
RPC_CLIENT_FREE * pfnCoTaskMemFree = &NdrCoTaskMemFree;
#if defined(_MPPC_)
RPC_GET_MALLOC * pfnCoGetMalloc;
#endif
HRESULT NdrLoadOleRoutines()
{
#if defined(_MPPC_)
// Power Mac specifics.
OSErr macErr;
Ptr mainAddr, pTempRoutine;
Str255 errName;
SymClass symClass;
if ( hOle32 == 0)
{
macErr = GetSharedLibrary(
PASCAL_STR("ole2.dll"), // OLE32 equivalent
kPowerPCArch, // architecture
kLoadLib, // load if not loaded flag
& hOle32, // library handle
& mainAddr, // main addr of import lib
errName ); // error string
NDR_ASSERT( hOle32 != 0, "NdrLoadOleRoutines: Ole2.dll didn't load" );
if ( macErr != fragNoErr )
return( HRESULT_FROM_MAC( macErr ));
}
// No delegation: don't load
// - CoGetClassObject
// - CoGetPSClsID
// - OleStringFromIID
// Ole32 doesn't export CoGetMarshalSizeMax, so don't load it yet.
// pfnCoGetMarshalSizeMax points to NdrCoGetMarshalSizeMax which
// has a copy of that routine for now.
//
//macErr = FindSymbol( hOle32,
// PASCAL_STR( "CoGetMarshalSizeMax" ),
// & pTempRoutine,
// & symClass );
//
//if ( macErr != fragNoErr )
// return( HRESULT_FROM_MAC( macErr ));
//else
// pfnCoGetMarshalSizeMax = (RPC_GET_MARSHAL_SIZE_MAX_ROUTINE*) pTempRoutine;
macErr = FindSymbol( hOle32,
PASCAL_STR( "CoMarshalInterface" ),
& pTempRoutine,
& symClass );
if ( macErr != fragNoErr )
return( HRESULT_FROM_MAC( macErr ));
else
pfnCoMarshalInterface = (RPC_MARSHAL_INTERFACE_ROUTINE*) pTempRoutine;
macErr = FindSymbol( hOle32,
PASCAL_STR( "CoUnmarshalInterface" ),
& pTempRoutine,
& symClass );
if ( macErr != fragNoErr )
return( HRESULT_FROM_MAC( macErr ));
else
pfnCoUnmarshalInterface = (RPC_UNMARSHAL_INTERFACE_ROUTINE*) pTempRoutine;
// Ole32 doesn't export CoTaskMemAlloc and CoTaskMemFree
// so, we load CoGetMalloc instead to be used in our own code
// for these two routines.
// For now, we supply a copy of CoTaskMemAlloc and CoTaskMemFree.
macErr = FindSymbol( hOle32,
PASCAL_STR( "CoGetMalloc" ),
& pTempRoutine,
& symClass );
if ( macErr != fragNoErr )
return( HRESULT_FROM_MAC( macErr ));
else
{
pfnCoGetMalloc = (RPC_GET_MALLOC*) pTempRoutine;
pfnCoTaskMemAlloc = (RPC_CLIENT_ALLOC*) CoTaskMemAlloc;
pfnCoTaskMemFree = (RPC_CLIENT_FREE*) CoTaskMemFree;
}
#else // other than PowerMac
void * pTempRoutine;
//Load ole32.dll
if(hOle32 == 0)
{
#ifdef DOSWIN32RPC
hOle32 = LoadLibraryA("OLE32");
#else
hOle32 = LoadLibraryW(L"OLE32");
#endif // DOSWIN32C
if(hOle32 == 0)
return HRESULT_FROM_WIN32(GetLastError());
}
pTempRoutine = GetProcAddress(hOle32, "CoGetClassObject");
if(pTempRoutine == 0)
return HRESULT_FROM_WIN32(GetLastError());
else
pfnCoGetClassObject = (RPC_GET_CLASS_OBJECT_ROUTINE*) pTempRoutine;
pTempRoutine = GetProcAddress(hOle32, "CoGetMarshalSizeMax");
if(pTempRoutine == 0)
return HRESULT_FROM_WIN32(GetLastError());
else
pfnCoGetMarshalSizeMax = (RPC_GET_MARSHAL_SIZE_MAX_ROUTINE*) pTempRoutine;
pTempRoutine = GetProcAddress(hOle32, "CoMarshalInterface");
if(pTempRoutine == 0)
return HRESULT_FROM_WIN32(GetLastError());
else
pfnCoMarshalInterface = (RPC_MARSHAL_INTERFACE_ROUTINE*) pTempRoutine;
pTempRoutine = GetProcAddress(hOle32, "CoUnmarshalInterface");
if(pTempRoutine == 0)
return HRESULT_FROM_WIN32(GetLastError());
else
pfnCoUnmarshalInterface = (RPC_UNMARSHAL_INTERFACE_ROUTINE*) pTempRoutine;
pTempRoutine = GetProcAddress(hOle32, "StringFromIID");
if(pTempRoutine == 0)
return HRESULT_FROM_WIN32(GetLastError());
else
pfnStringFromIID = (RPC_STRING_FROM_IID*) pTempRoutine;
pTempRoutine = GetProcAddress(hOle32, "CoGetPSClsid");
if(pTempRoutine == 0)
return HRESULT_FROM_WIN32(GetLastError());
else
pfnCoGetPSClsid = (RPC_GET_PS_CLSID*) pTempRoutine;
pTempRoutine = GetProcAddress(hOle32, "CoTaskMemAlloc");
if(pTempRoutine == 0)
return HRESULT_FROM_WIN32(GetLastError());
else
pfnCoTaskMemAlloc = (RPC_CLIENT_ALLOC*) pTempRoutine;
pTempRoutine = GetProcAddress(hOle32, "CoTaskMemFree");
if(pTempRoutine == 0)
return HRESULT_FROM_WIN32(GetLastError());
else
pfnCoTaskMemFree = (RPC_CLIENT_FREE*) pTempRoutine;
#endif // PowerMac vs. the rest
}
HRESULT STDAPICALLTYPE
NdrCoGetClassObject(
REFCLSID rclsid,
DWORD dwClsContext,
void *pvReserved,
REFIID riid,
void **ppv)
/*++
Routine Description:
Loads a class factory. This function forwards the call to ole32.dll.
Arguments:
rclsid - Supplies the CLSID of the class to be loaded.
dwClsContext - Supplies the context in which to load the code.
pvReserved - Must be NULL.
riid - Supplies the IID of the desired interface.
ppv - Returns a pointer to the class factory.
Return Value:
S_OK
--*/
{
#if defined(_MPPC_)
// Delegation not implemented
RpcRaiseException( RPC_S_INTERNAL_ERROR );
return( E_FAIL );
#else
HRESULT hr;
if ( FAILED(hr = NdrLoadOleRoutines()) )
return hr;
return (*pfnCoGetClassObject)(rclsid, dwClsContext, pvReserved, riid, ppv);
#endif
}
HRESULT STDAPICALLTYPE
NdrCoGetMarshalSizeMax(
ULONG * pulSize,
REFIID riid,
LPUNKNOWN pUnk,
DWORD dwDestContext,
LPVOID pvDestContext,
DWORD mshlflags)
/*++
Routine Description:
Calculates the maximum size of a marshalled interface pointer.
This function forwards the call to ole32.dll.
Arguments:
pulSize - Returns an upper bound for the size of a marshalled interface pointer.
riid - Supplies the IID of the interface to be marshalled.
pUnk - Supplies a pointer to the object to be marshalled.
dwDestContext - Supplies the destination of the marshalled interface pointer.
pvDestContext
mshlflags - Flags. See the MSHFLAGS enumeration.
Return Value:
S_OK
--*/
{
#if defined(_MPPC_)
// Temporary .., OLE32 doesn't export this.
// And we don't have to load anything for this entry.
HRESULT hr;
IMarshal *pMarshal;
DWORD cb = 0;
hr = pUnk->lpVtbl->QueryInterface( pUnk,
& IID_IMarshal,
(void **)&pMarshal );
if(SUCCEEDED(hr))
{
//Use custom marshalling.
hr = pMarshal->lpVtbl->GetMarshalSizeMax( pMarshal,
riid,
0,
dwDestContext,
pvDestContext,
mshlflags,
& cb );
pMarshal->lpVtbl->Release(pMarshal);
cb += 40;
}
else
{
//Use standard marshalling.
cb = 40;
hr = S_OK;
}
*pulSize = cb;
return hr;
#else
HRESULT hr;
if ( FAILED(hr = NdrLoadOleRoutines()) )
return hr;
return (*pfnCoGetMarshalSizeMax)(pulSize, riid, pUnk, dwDestContext, pvDestContext, mshlflags);
#endif
}
HRESULT STDAPICALLTYPE
NdrCoMarshalInterface(
LPSTREAM pStm,
REFIID riid,
LPUNKNOWN pUnk,
DWORD dwDestContext,
LPVOID pvDestContext,
DWORD mshlflags)
/*++
Routine Description:
Marshals an interface pointer.
This function forwards the call to ole32.dll.
Arguments:
pStm - Supplies the target stream.
riid - Supplies the IID of the interface to be marshalled.
pUnk - Supplies a pointer to the object to be marshalled.
dwDestContext - Specifies the destination context
pvDestContext
mshlflags - Flags. See the MSHFLAGS enumeration.
Return Value:
S_OK
--*/
{
HRESULT hr;
if ( FAILED(hr = NdrLoadOleRoutines()) )
return hr;
return (*pfnCoMarshalInterface)(pStm, riid, pUnk, dwDestContext, pvDestContext, mshlflags);
}
HRESULT STDAPICALLTYPE
NdrCoUnmarshalInterface(
LPSTREAM pStm,
REFIID riid,
void ** ppv)
/*++
Routine Description:
Unmarshals an interface pointer from a stream.
This function forwards the call to ole32.dll.
Arguments:
pStm - Supplies the stream containing the marshalled interface pointer.
riid - Supplies the IID of the interface pointer to be unmarshalled.
ppv - Returns the unmarshalled interface pointer.
Return Value:
S_OK
--*/
{
HRESULT hr;
if ( FAILED(hr = NdrLoadOleRoutines()) )
return hr;
return (*pfnCoUnmarshalInterface)(pStm, riid, ppv);
}
HRESULT STDAPICALLTYPE OleStringFromIID(
REFIID rclsid,
LPOLESTR FAR* lplpsz)
/*++
Routine Description:
Converts an IID into a string.
This function forwards the call to ole32.dll.
Arguments:
rclsid - Supplies the clsid to convert to string form.
lplpsz - Returns the string form of the clsid (with "{}" around it).
Return Value:
S_OK
--*/
{
#if defined(_MPPC_)
// Delegation not implemented
RpcRaiseException( RPC_S_INTERNAL_ERROR );
return( E_FAIL );
#else
HRESULT hr;
if ( FAILED(hr = NdrLoadOleRoutines()) )
return hr;
return (*pfnStringFromIID)(rclsid, lplpsz);
#endif
}
STDAPI NdrCoGetPSClsid(
REFIID iid,
LPCLSID lpclsid)
/*++
Routine Description:
Converts an IID into a string.
This function forwards the call to ole32.dll.
Arguments:
rclsid - Supplies the clsid to convert to string form.
lplpsz - Returns the string form of the clsid (with "{}" around it).
Return Value:
S_OK
--*/
{
#if defined(_MPPC_)
// Delegation not implemented
RpcRaiseException( RPC_S_INTERNAL_ERROR );
return( E_FAIL );
#else
HRESULT hr;
if ( FAILED(hr = NdrLoadOleRoutines()) )
return hr;
return (*pfnCoGetPSClsid)(iid, lpclsid);
#endif
}
#if defined(_MPPC_)
// Temporary defnitions for CoTaskMemAlloc and Free as OLE32 doesn't export.
LPVOID STDAPICALLTYPE CoTaskMemAlloc(ULONG cb)
{
LPVOID pv = 0;
HRESULT hr;
IMalloc *pMalloc;
hr = (*pfnCoGetMalloc)(1, &pMalloc);
if(SUCCEEDED(hr))
{
pv = pMalloc->lpVtbl->Alloc(pMalloc, cb);
pMalloc->lpVtbl->Release(pMalloc);
}
return pv;
}
void STDAPICALLTYPE CoTaskMemFree(LPVOID pv)
{
HRESULT hr;
IMalloc *pMalloc;
hr = (*pfnCoGetMalloc)(1, &pMalloc);
if(SUCCEEDED(hr))
{
pMalloc->lpVtbl->Free(pMalloc, pv);
pMalloc->lpVtbl->Release(pMalloc);
}
}
#endif
void * STDAPICALLTYPE
NdrCoTaskMemAlloc(
UINT cb)
/*++
Routine Description:
Allocate memory using OLE task memory allocator.
This function forwards the call to ole32.dll.
Arguments:
cb - Specifies the amount of memory to be allocated.
Return Value:
This function returns a pointer to the allocated memory.
If an error occurs, this function returns zero.
--*/
{
if ( FAILED(NdrLoadOleRoutines()) )
return 0;
return (*pfnCoTaskMemAlloc)(cb);
}
void STDAPICALLTYPE
NdrCoTaskMemFree(
void * pMemory)
/*++
Routine Description:
Free memory using OLE task memory allocator.
This function forwards the call to ole32.dll.
Arguments:
pMemory - Supplies a pointer to the memory to be freed.
Return Value:
None.
--*/
{
if ( FAILED(NdrLoadOleRoutines()) )
return;
(*pfnCoTaskMemFree)(pMemory);
}
void * RPC_ENTRY NdrOleAllocate(size_t size)
/*++
Routine Description:
Allocate memory via OLE task allocator.
Arguments:
size - Specifies the amount of memory to be allocated.
Return Value:
This function returns a pointer to the allocated memory.
If an error occurs, this function raises an exception.
--*/
{
void *pMemory;
pMemory = (*pfnCoTaskMemAlloc)(size);
if(pMemory == 0)
RpcRaiseException(E_OUTOFMEMORY);
return pMemory;
}
void RPC_ENTRY NdrOleFree(void *pMemory)
/*++
Routine Description:
Free memory using OLE task allocator.
Arguments:
None.
Return Value:
None.
--*/
{
(*pfnCoTaskMemFree)(pMemory);
}
#if !defined(_MPPC_)
HRESULT STDAPICALLTYPE NdrStringFromIID(
REFIID rclsid,
char * lpsz)
/*++
Routine Description:
Converts an IID into a string.
This function forwards the call to ole32.dll.
Arguments:
rclsid - Supplies the clsid to convert to string form.
lplpsz - Returns the string form of the clsid (with "{}" around it).
Return Value:
S_OK
--*/
{
HRESULT hr;
wchar_t * olestr;
hr = (*pfnStringFromIID)(rclsid, &olestr);
if(SUCCEEDED(hr))
{
WideCharToMultiByte(CP_ACP,
0,
(LPCWSTR)olestr,
-1,
(LPSTR)lpsz,
50,
NULL,
NULL);
NdrOleFree(olestr);
}
return hr;
}
#endif
#endif // NDR_OLE_SUPPORT
void RPC_ENTRY
NdrClientInitializeNew(
PRPC_MESSAGE pRpcMsg,
PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDescriptor,
unsigned int ProcNum
)
/*++
Routine Description :
This routine is called by client side stubs to initialize the RPC message
and stub message, and to get the RPC buffer.
Arguments :
pRpcMsg - pointer to RPC message structure
pStubMsg - pointer to stub message structure
pStubDescriptor - pointer to stub descriptor structure
HandleType - type of binding handle
ProcNum - remote procedure number
--*/
{
NdrClientInitialize( pRpcMsg,
pStubMsg,
pStubDescriptor,
ProcNum );
//
// This is where we can mess with any of the stub message reserved
// fields if we use them.
//
if ( pStubDescriptor->pMallocFreeStruct )
{
MALLOC_FREE_STRUCT *pMFS = pStubDescriptor->pMallocFreeStruct;
NdrpSetRpcSsDefaults(pMFS->pfnAllocate, pMFS->pfnFree);
}
if ( NDR_VERSION_2_0 <= pStubDescriptor->Version )
{
pStubMsg->pPipeDesc = 0;
}
// This exception should be raised after initializing StubMsg.
if ( pStubDescriptor->Version > NDR_VERSION )
{
NDR_ASSERT( 0, "ClientInitialize : Bad version number" );
RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
}
}
void RPC_ENTRY
NdrClientInitialize(
PRPC_MESSAGE pRpcMsg,
PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDescriptor,
unsigned int ProcNum )
/*++
Routine Description :
This routine is called by client side stubs to initialize the RPC message
and stub message, and to get the RPC buffer.
Arguments :
pRpcMsg - pointer to RPC message structure
pStubMsg - pointer to stub message structure
pStubDescriptor - pointer to stub descriptor structure
HandleType - type of binding handle
ProcNum - remote procedure number
--*/
{
//
// Initialize RPC message fields.
//
// The leftmost bit of the procnum field is supposed to be set to 1 inr
// order for the runtime to know if it is talking to the older stubs or
// not.
//
pRpcMsg->RpcInterfaceInformation = pStubDescriptor->RpcInterfaceInformation;
pRpcMsg->ProcNum = ProcNum | RPC_FLAGS_VALID_BIT;
pRpcMsg->RpcFlags = 0;
pRpcMsg->Handle = 0;
//
// Initialize the Stub messsage fields.
//
pStubMsg->RpcMsg = pRpcMsg;
pStubMsg->StubDesc = pStubDescriptor;
pStubMsg->pfnAllocate = pStubDescriptor->pfnAllocate;
pStubMsg->pfnFree = pStubDescriptor->pfnFree;
pStubMsg->fCheckBounds = pStubDescriptor->fCheckBounds;
pStubMsg->IsClient = TRUE;
pStubMsg->BufferLength = 0;
pStubMsg->BufferStart = 0;
pStubMsg->BufferEnd = 0;
pStubMsg->fBufferValid = FALSE;
pStubMsg->ReuseBuffer = FALSE;
pStubMsg->StackTop = 0;
pStubMsg->IgnoreEmbeddedPointers = FALSE;
pStubMsg->PointerBufferMark = 0;
pStubMsg->AllocAllNodesMemory = 0;
pStubMsg->FullPtrRefId = 0;
#if defined(__RPC_WIN32__)
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
#else
pStubMsg->dwDestContext = 2; // different machine,
#endif
pStubMsg->pvDestContext = 0;
pStubMsg->pArrayInfo = 0;
pStubMsg->dwStubPhase = 0;
}
void
MakeSureWeHaveNonPipeArgs(
PMIDL_STUB_MESSAGE pStubMsg,
PRPC_MESSAGE pRpcMsg,
unsigned long BufferSize )
/*
Routine description:
This routine is called for pipe calls at the server.
After the runtime dispatched to the stub with the first packet,
it makes sure that we have a portion of the buffer big enough
to keep all the non-pipe args.
Arguments:
BufferSize - a pipe call: addtional number of bytes over what we have.
Note:
The buffer location may change from before to after the call.
*/
{
RPC_STATUS Status;
if ( !(pRpcMsg->RpcFlags & RPC_BUFFER_COMPLETE ) )
{
// May be the args fit into the first packet.
if ( BufferSize <= pRpcMsg->BufferLength )
return;
// Set the partial flag to get the non-pipe args.
// For a partial call with the "extra", the meaning of the size
// arg is the addition required above what we have already.
pRpcMsg->RpcFlags |= (RPC_BUFFER_PARTIAL | RPC_BUFFER_EXTRA);
// We will receive at least BufferSize.
// (buffer location may change)
BufferSize -= pRpcMsg->BufferLength;
Status = I_RpcReceive( pRpcMsg, (unsigned int) BufferSize );
if ( Status != RPC_S_OK )
RpcRaiseException( Status );
// In case this is a new buffer
pStubMsg->Buffer = pRpcMsg->Buffer;
pStubMsg->BufferStart = pRpcMsg->Buffer;
pStubMsg->BufferEnd = pStubMsg->BufferStart + pRpcMsg->BufferLength;
}
}
unsigned char __RPC_FAR * RPC_ENTRY
NdrServerInitializeNew(
PRPC_MESSAGE pRpcMsg,
PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDescriptor
)
/*++
Routine Description :
This routine is called by the server stubs before unmarshalling.
It initializes the stub message fields.
Aruguments :
pStubMsg - pointer to the stub message structure
pStubDescriptor - pointer to the stub descriptor structure
pBuffer - pointer to the beginning of the RPC message buffer
Note.
NdrServerInitializeNew is almost identical to NdrServerInitializePartial.
NdrServerInitializeNew is generated for non-pipes and is backward comp.
NdrServerInitializePartial is generated for routines with pipes args.
--*/
{
NdrServerInitialize( pRpcMsg,
pStubMsg,
pStubDescriptor );
//
// This is where we can mess with any of the stub message reserved
// fields if we use them.
//
if ( pStubDescriptor->pMallocFreeStruct )
{
MALLOC_FREE_STRUCT *pMFS = pStubDescriptor->pMallocFreeStruct;
NdrpSetRpcSsDefaults(pMFS->pfnAllocate, pMFS->pfnFree);
}
if ( NDR_VERSION_2_0 <= pStubDescriptor->Version )
{
pStubMsg->pPipeDesc = 0;
}
// This exception should be raised after initializing StubMsg.
if ( pStubDescriptor->Version > NDR_VERSION )
{
NDR_ASSERT( 0, "ServerInitialize : bad version number" );
RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
}
if ( !(pRpcMsg->RpcFlags & RPC_BUFFER_COMPLETE ) )
{
// A non-pipe call with an incomplete buffer.
// This can happen only for non-pipe calls in an interface that
// has some pipe calls.
RPC_STATUS Status;
pRpcMsg->RpcFlags = RPC_BUFFER_EXTRA;
// The size argument is ignored, we will get everything.
Status = I_RpcReceive( pRpcMsg, 0 );
if ( Status != RPC_S_OK )
RpcRaiseException( Status );
// In case this is a new buffer
pStubMsg->Buffer = pRpcMsg->Buffer;
pStubMsg->BufferStart = pRpcMsg->Buffer;
pStubMsg->BufferEnd = pStubMsg->BufferStart + pRpcMsg->BufferLength;
}
return 0;
}
unsigned char __RPC_FAR * RPC_ENTRY
NdrServerInitialize(
PRPC_MESSAGE pRpcMsg,
PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDescriptor )
/*++
Routine Description :
This routine is called by the server stubs before unmarshalling.
It initializes the stub message fields.
Aruguments :
pStubMsg - pointer to the stub message structure
pStubDescriptor - pointer to the stub descriptor structure
pBuffer - pointer to the beginning of the RPC message buffer
Note :
This is a core server-side initializer, called by everybody,
pipes or not.
--*/
{
pStubMsg->IsClient = FALSE;
pStubMsg->AllocAllNodesMemory = 0;
pStubMsg->IgnoreEmbeddedPointers = FALSE;
pStubMsg->PointerBufferMark = 0;
pStubMsg->BufferLength = 0;
pStubMsg->StackTop = 0;
pStubMsg->FullPtrXlatTables = 0;
pStubMsg->FullPtrRefId = 0;
pStubMsg->fDontCallFreeInst = 0;
pStubMsg->fInDontFree = 0;
#if defined(__RPC_WIN32__)
pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE;
#else
pStubMsg->dwDestContext = 2; // different machine,
#endif
pStubMsg->pvDestContext = 0;
pStubMsg->pArrayInfo = 0;
pStubMsg->RpcMsg = pRpcMsg;
pStubMsg->Buffer = pRpcMsg->Buffer;
//
// Set BufferStart and BufferEnd before unmarshalling.
// NdrPointerFree uses these values to detect pointers into the
// rpc message buffer.
//
pStubMsg->BufferStart = pRpcMsg->Buffer;
pStubMsg->BufferEnd = pStubMsg->BufferStart + pRpcMsg->BufferLength;
pStubMsg->pfnAllocate = pStubDescriptor->pfnAllocate;
pStubMsg->pfnFree = pStubDescriptor->pfnFree;
pStubMsg->StubDesc = pStubDescriptor;
pStubMsg->ReuseBuffer = TRUE;
pStubMsg->fCheckBounds = pStubDescriptor->fCheckBounds;
pStubMsg->dwStubPhase = 0;
return(0);
}
void RPC_ENTRY
NdrServerInitializePartial(
PRPC_MESSAGE pRpcMsg,
PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDescriptor,
unsigned long RequestedBufferSize
)
/*++
Routine Description :
This routine is called by the server stubs for pipes.
It is almost identical to NdrServerInitializeNew, except that
it calls NdrpServerInitialize.
Aruguments :
pStubMsg - pointer to the stub message structure
pStubDescriptor - pointer to the stub descriptor structure
pBuffer - pointer to the beginning of the RPC message buffer
--*/
{
NdrServerInitialize( pRpcMsg,
pStubMsg,
pStubDescriptor );
//
// This is where we can mess with any of the stub message reserved
// fields if we use them.
//
if ( pStubDescriptor->pMallocFreeStruct )
{
MALLOC_FREE_STRUCT *pMFS = pStubDescriptor->pMallocFreeStruct;
NdrpSetRpcSsDefaults(pMFS->pfnAllocate, pMFS->pfnFree);
}
if ( NDR_VERSION_2_0 <= pStubDescriptor->Version )
{
pStubMsg->pPipeDesc = 0;
}
// This exception should be raised after initializing StubMsg.
if ( pStubDescriptor->Version > NDR_VERSION )
{
NDR_ASSERT( 0, "ServerInitialize : bad version number" );
RpcRaiseException( RPC_X_WRONG_STUB_VERSION );
}
// Last but not least...
MakeSureWeHaveNonPipeArgs( pStubMsg, pRpcMsg, RequestedBufferSize );
}
unsigned char __RPC_FAR * RPC_ENTRY
NdrGetBuffer(
PMIDL_STUB_MESSAGE pStubMsg,
unsigned long BufferLength,
RPC_BINDING_HANDLE Handle )
/*++
Routine Description :
Performs an RpcGetBuffer.
Arguments :
pStubMsg - Pointer to stub message structure.
BufferLength - Length of requested rpc message buffer.
Handle - Bound handle.
--*/
{
RPC_STATUS Status;
if ( pStubMsg->IsClient )
pStubMsg->RpcMsg->Handle = pStubMsg->SavedHandle = Handle;
#if defined(__RPC_DOS__) || defined(__RPC_WIN16__)
if ( BufferLength > UINT_MAX )
RpcRaiseException( RPC_X_BAD_STUB_DATA );
#endif
pStubMsg->RpcMsg->BufferLength = BufferLength;
Status = I_RpcGetBuffer( pStubMsg->RpcMsg );
if ( Status )
RpcRaiseException( Status );
NDR_ASSERT( ! ((unsigned long)pStubMsg->RpcMsg->Buffer & 0x7),
"marshaling buffer misaligned" );
pStubMsg->Buffer = (uchar *) pStubMsg->RpcMsg->Buffer;
pStubMsg->fBufferValid = TRUE;
return pStubMsg->Buffer;
}
void
EnsureNSLoaded()
/*++
Routine Description :
Guarantee that the RpcNs4 DLL is loaded. Throw exception if unable
to load it.
Will load the RpcNs4 DLL if not already loaded
Arguments :
--*/
{
#ifdef __RPC_DOS__
pRpcNsSendReceive = &I_RpcNsSendReceive;
pRpcNsGetBuffer = &I_RpcNsGetBuffer;
return;
#elif defined (__RPC_WIN16__)
RPC_CHAR __RPC_FAR * DllName;
HINSTANCE DllHandle;
LPSTR EntryName;
if ( NsDllLoaded )
return;
DllName = RPC_CONST_STRING("RPCNS1.DLL");
DllHandle = (HINSTANCE) (ulong) LoadLibrary( DllName );
if ( DllHandle == 0 )
{
RpcRaiseException (RPC_S_INVALID_BINDING);
}
EntryName = "I_RPCNSGETBUFFER";
pRpcNsGetBuffer = (RPC_NS_GET_BUFFER_ROUTINE)
GetProcAddress( DllHandle,
EntryName);
if ( pRpcNsGetBuffer == 0 )
{
RpcRaiseException (RPC_S_INVALID_BINDING);
}
EntryName = "I_RPCNSSENDRECEIVE";
pRpcNsSendReceive = (RPC_NS_SEND_RECEIVE_ROUTINE)
GetProcAddress( DllHandle,
EntryName);
if ( pRpcNsSendReceive == 0 )
{
RpcRaiseException (RPC_S_INVALID_BINDING);
}
NsDllLoaded = 1;
#elif defined(__RPC_MAC__)
// MACBUGBUG - No name service -> no autohandles.
NsDllLoaded = 0;
#else // NT
HINSTANCE DllHandle;
LPSTR EntryName;
if ( NsDllLoaded )
return;
#ifdef DOSWIN32RPC
DllHandle = LoadLibraryA( "RPCNS4" );
#else
DllHandle = LoadLibraryW( L"RPCNS4" );
#endif // DOSWIN32RPC
if ( DllHandle == 0 )
{
RpcRaiseException (RPC_S_INVALID_BINDING);
}
EntryName = "I_RpcNsGetBuffer";
pRpcNsGetBuffer = (RPC_NS_GET_BUFFER_ROUTINE)
GetProcAddress( DllHandle,
EntryName);
if ( pRpcNsGetBuffer == 0 )
{
RpcRaiseException (RPC_S_INVALID_BINDING);
}
EntryName = "I_RpcNsSendReceive";
pRpcNsSendReceive = (RPC_NS_SEND_RECEIVE_ROUTINE)
GetProcAddress( DllHandle,
EntryName);
if ( pRpcNsSendReceive == 0 )
{
RpcRaiseException (RPC_S_INVALID_BINDING);
}
NsDllLoaded = 1;
#endif /* defined(__RPC_DOS__) */
}
unsigned char __RPC_FAR * RPC_ENTRY
NdrNsGetBuffer( PMIDL_STUB_MESSAGE pStubMsg,
unsigned long BufferLength,
RPC_BINDING_HANDLE Handle )
/*++
Routine Description :
Performs an RpcNsGetBuffer.
Will load the RpcNs4 DLL if not already loaded
Arguments :
pStubMsg - Pointer to stub message structure.
BufferLength - Length of requested rpc message buffer.
Handle - Bound handle
--*/
{
RPC_STATUS Status;
if( pStubMsg->IsClient == TRUE )
pStubMsg->RpcMsg->Handle = pStubMsg->SavedHandle = Handle;
#if defined(__RPC_DOS__) || defined(__RPC_WIN16__)
if ( BufferLength > UINT_MAX )
RpcRaiseException( RPC_X_BAD_STUB_DATA );
#endif
EnsureNSLoaded();
pStubMsg->RpcMsg->BufferLength = BufferLength;
Status = (*pRpcNsGetBuffer)( pStubMsg->RpcMsg );
if ( Status )
RpcRaiseException( Status );
NDR_ASSERT( ! ((unsigned long)pStubMsg->RpcMsg->Buffer & 0x7),
"marshaling buffer misaligned" );
pStubMsg->Buffer = (uchar *) pStubMsg->RpcMsg->Buffer;
pStubMsg->fBufferValid = TRUE;
return pStubMsg->Buffer;
}
unsigned char __RPC_FAR * RPC_ENTRY
NdrSendReceive(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pBufferEnd )
/*++
Routine Description :
Performs an RpcSendRecieve.
This routine is executed for the non-pipe calls only.
It returns a whole marshaling buffer.
Arguments :
pStubMsg - Pointer to stub message structure.
pBufferEnd - End of the rpc message buffer being sent.
Return :
The new message buffer pointer returned from the runtime after the
SendReceive call to the server.
--*/
{
RPC_STATUS Status;
PRPC_MESSAGE pRpcMsg;
pRpcMsg = pStubMsg->RpcMsg;
if ( pRpcMsg->BufferLength <
(uint)(pBufferEnd - (uchar *)pRpcMsg->Buffer))
{
NDR_ASSERT( 0, "NdrSendReceive : buffer overflow" );
RpcRaiseException( RPC_S_INTERNAL_ERROR );
}
pRpcMsg->BufferLength = pBufferEnd - (uchar *) pRpcMsg->Buffer;
pStubMsg->fBufferValid = FALSE;
Status = I_RpcSendReceive( pRpcMsg );
if ( Status )
RpcRaiseException(Status);
NDR_ASSERT( ! ((unsigned long)pRpcMsg->Buffer & 0x7),
"marshaling buffer misaligned" );
pStubMsg->fBufferValid = TRUE;
pStubMsg->Buffer = pRpcMsg->Buffer;
return 0;
}
unsigned char __RPC_FAR * RPC_ENTRY
NdrNsSendReceive(
PMIDL_STUB_MESSAGE pStubMsg,
uchar * pBufferEnd,
RPC_BINDING_HANDLE * pAutoHandle )
/*++
Routine Description :
Performs an RpcNsSendRecieve for a procedure which uses an auto handle.
Will load the RpcNs4 DLL if not already loaded
Arguments :
pStubMsg - Pointer to stub message structure.
pBufferEnd - End of the rpc message buffer being sent.
pAutoHandle - Pointer to the auto handle used in the call.
Return :
The new message buffer pointer returned from the runtime after the
SendReceive call to the server.
--*/
{
RPC_STATUS Status;
PRPC_MESSAGE pRpcMsg;
EnsureNSLoaded();
pRpcMsg = pStubMsg->RpcMsg;
if ( pRpcMsg->BufferLength <
(uint)(pBufferEnd - (uchar *)pRpcMsg->Buffer) )
{
NDR_ASSERT( 0, "NdrNsSendReceive : buffer overflow" );
RpcRaiseException( RPC_S_INTERNAL_ERROR );
}
pRpcMsg->BufferLength = pBufferEnd - (uchar *) pRpcMsg->Buffer;
pStubMsg->fBufferValid = FALSE;
Status = (*pRpcNsSendReceive)( pRpcMsg, pAutoHandle );
if ( Status )
RpcRaiseException(Status);
else
pStubMsg->fBufferValid = TRUE;
pStubMsg->Buffer = pRpcMsg->Buffer;
return pStubMsg->Buffer;
}
void RPC_ENTRY
NdrFreeBuffer(
PMIDL_STUB_MESSAGE pStubMsg )
/*++
Routine Description :
Performs an RpcFreeBuffer.
Arguments :
pStubMsg - pointer to stub message structure
Return :
None.
--*/
{
RPC_STATUS Status;
if ( ! pStubMsg->fBufferValid )
return;
if( ! pStubMsg->RpcMsg->Handle )
return;
Status = I_RpcFreeBuffer( pStubMsg->RpcMsg );
pStubMsg->fBufferValid = FALSE;
if ( Status )
RpcRaiseException(Status);
}
void __RPC_FAR * RPC_ENTRY
NdrAllocate(
PMIDL_STUB_MESSAGE pStubMsg,
size_t Len )
/*++
Routine Description :
Private allocator. Handles allocate all nodes cases.
Arguments :
pStubMsg - Pointer to stub message structure.
Len - Number of bytes to allocate.
Return :
Valid memory pointer.
--*/
{
void __RPC_FAR * pMemory;
if ( pStubMsg->AllocAllNodesMemory )
{
//
// We must guarantee 4 byte alignment on NT and MAC and then
// 2 byte alignment on win16/dos for all memory pointers.
// This has nothing to do
// with the soon to be obsolete allocate_all_nodes_aligned.
//
#if defined(__RPC_WIN32__) || defined(__RPC_MAC__)
ALIGN(pStubMsg->AllocAllNodesMemory,3);
#else
ALIGN(pStubMsg->AllocAllNodesMemory,1);
#endif
// Get the pointer.
pMemory = pStubMsg->AllocAllNodesMemory;
// Increment the block pointer.
pStubMsg->AllocAllNodesMemory += Len;
//
// Check for memory allocs past the end of our allocated buffer.
//
NDR_ASSERT( pStubMsg->AllocAllNodesMemory <=
pStubMsg->AllocAllNodesMemoryEnd,
"Not enough alloc all nodes memory!" );
return pMemory;
}
else
{
if ( ! (pMemory = (*pStubMsg->pfnAllocate)(Len)) )
RpcRaiseException( RPC_S_OUT_OF_MEMORY );
return pMemory;
}
}
unsigned char __RPC_FAR * RPC_ENTRY
NdrServerInitializeUnmarshall (
PMIDL_STUB_MESSAGE pStubMsg,
PMIDL_STUB_DESC pStubDescriptor,
PRPC_MESSAGE pRpcMsg )
/*++
Routine Description :
Old NT Beta2 (build 683) server stub initialization routine. Used for
backward compatability only.
Aruguments :
pStubMsg - Pointer to the stub message structure.
pStubDescriptor - Pointer to the stub descriptor structure.
pBuffer - Pointer to the beginning of the RPC message buffer.
--*/
{
return NdrServerInitialize( pRpcMsg,
pStubMsg,
pStubDescriptor );
}
void RPC_ENTRY
NdrServerInitializeMarshall (
PRPC_MESSAGE pRpcMsg,
PMIDL_STUB_MESSAGE pStubMsg )
/*++
Routine Description :
Old NT Beta2 (build 683) server stub initialization routine. Used for
backward compatability only.
Arguments :
pRpcMsg - Pointer to the RPC message structure.
pStubMsg - Pointer to the stub message structure.
--*/
{
}
#if defined(_MPPC_)
HRESULT
MapMacErrorsToHresult( OSErr macErr )
/*
As it says.
There is no official mapping function, so we do some mapping ourselves.
*/
{
HRESULT hr;
switch( macErr )
{
case fragNoErr:
hr = S_OK;
break;
case paramErr:
hr = E_INVALIDARG;
break;
case fragNoMem:
hr = E_OUTOFMEMORY;
break;
case fragNoAddrSpace:
hr = E_OUTOFMEMORY;
break;
default:
hr = E_FAIL;
break;
}
return( hr );
}
long
NdrInterlockedIncrement( long * p )
{
*p += 1;
return *p;
}
long
NdrInterlockedDecrement( long * p )
{
*p += -1;
return *p;
}
long
NdrInterlockedExchange( long * p, long l )
{
long temp = *p;
*p = l;
return temp;
}
//
// No context handle support on power mac, so these are just
// convenient plugs.
//
void RPC_ENTRY
NDRSContextMarshall (
IN NDR_SCONTEXT CContext,
OUT void __RPC_FAR *pBuff,
IN NDR_RUNDOWN userRunDownIn
)
{
;
}
NDR_SCONTEXT RPC_ENTRY
NDRSContextUnmarshall (
IN void __RPC_FAR *pBuff,
IN unsigned long DataRepresentation
)
{
NDR_SCONTEXT pSC = (NDR_SCONTEXT) I_RpcAllocate( 8 );
return(pSC );
}
#endif