mirror of https://github.com/lianthony/NT4.0
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.
309 lines
7.1 KiB
309 lines
7.1 KiB
/* --------------------------------------------------------------------
|
|
|
|
Microsoft OS/2 LAN Manager
|
|
Copyright(c) Microsoft Corp., 1991
|
|
|
|
-------------------------------------------------------------------- */
|
|
/* --------------------------------------------------------------------
|
|
|
|
Description :
|
|
|
|
Provides RPC client side stub context management
|
|
|
|
History :
|
|
|
|
stevez 01-15-91 First bits into the bucket.
|
|
|
|
-------------------------------------------------------------------- */
|
|
|
|
#ifdef NTENV
|
|
|
|
extern "C"
|
|
{
|
|
#include <sysinc.h>
|
|
}
|
|
|
|
#else // NTENV
|
|
|
|
#include <sysinc.h>
|
|
|
|
#endif // NTENV
|
|
|
|
#include <rpc.h>
|
|
#include <rpcdcep.h>
|
|
#include <rpcndr.h>
|
|
#include <util.hxx>
|
|
#include <osfpcket.hxx>
|
|
|
|
#ifdef NTENV
|
|
#include <memory.h>
|
|
#endif // NTENV
|
|
|
|
#ifdef WIN
|
|
#define memset _fmemset
|
|
#define memcpy _fmemcpy
|
|
#define memcmp _fmemcmp
|
|
#endif // WIN
|
|
|
|
// The NDR format of a context is a (GUID, long) instead of a pointer
|
|
// in the server address space due history. Anyway, we just save this
|
|
// cookie, which is sent on the and mapped to and from a pointer
|
|
// on the server side.
|
|
|
|
#define CONTEXT_MAGIC_VALUE 0xFEDCBA98
|
|
|
|
typedef struct _WIRE_CONTEXT
|
|
{
|
|
unsigned long ContextType;
|
|
UUID ContextUuid;
|
|
} WIRE_CONTEXT;
|
|
|
|
typedef struct _CCONTEXT {
|
|
|
|
RPC_BINDING_HANDLE hRPC; // binding handle assoicated with context
|
|
|
|
unsigned long MagicValue;
|
|
WIRE_CONTEXT NDR;
|
|
|
|
} CCONTEXT, *PCCONTEXT;
|
|
|
|
static unsigned char NilContext[20];
|
|
|
|
|
|
RPC_BINDING_HANDLE RPC_ENTRY
|
|
NDRCContextBinding (
|
|
IN NDR_CCONTEXT CContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Given a client context handle, we need to extract the binding from it.
|
|
If an addressing exception occurs, we need to return invalid handle
|
|
rather than GP-fault.
|
|
|
|
Arguments:
|
|
|
|
CContext - Supplies the client context handle.
|
|
|
|
Return Value:
|
|
|
|
The binding handle associated with the supplied client context handle
|
|
will be returned. If the client context handle is invalid, then we
|
|
raise the RPC_X_SS_CONTEXT_MISMATCH exception.
|
|
|
|
--*/
|
|
{
|
|
#ifdef NTENV
|
|
|
|
RpcTryExcept
|
|
{
|
|
if ( ((CCONTEXT PAPI *) CContext)->MagicValue != CONTEXT_MAGIC_VALUE )
|
|
{
|
|
RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
|
|
}
|
|
}
|
|
RpcExcept( ( RpcExceptionCode() == STATUS_ACCESS_VIOLATION )
|
|
|| ( RpcExceptionCode() == STATUS_DATATYPE_MISALIGNMENT ) )
|
|
{
|
|
RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
|
|
}
|
|
RpcEndExcept
|
|
|
|
#else // NTENV
|
|
|
|
if ( ( CContext == 0 )
|
|
|| ( ((CCONTEXT PAPI *) CContext)->MagicValue != CONTEXT_MAGIC_VALUE ) )
|
|
{
|
|
RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
|
|
}
|
|
|
|
#endif // NTENV
|
|
|
|
return(((CCONTEXT PAPI *) CContext)->hRPC);
|
|
}
|
|
|
|
|
|
void RPC_ENTRY
|
|
NDRCContextMarshall ( // copy a context to a buffer
|
|
|
|
IN NDR_CCONTEXT hCC, // context to marshell
|
|
OUT void PAPI *pBuff // buffer to marshell to
|
|
|
|
// Copy the interal representation of a context into a buffer
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
#define hCContext ((CCONTEXT PAPI *) hCC) // cast opeqe pointer to internal
|
|
|
|
if (!hCContext)
|
|
memset(pBuff, 0, cbNDRContext);
|
|
else
|
|
{
|
|
|
|
// Check the magic value to see if this is a legit context
|
|
|
|
RpcTryExcept
|
|
{
|
|
if ( ((CCONTEXT PAPI *) hCContext)->MagicValue != CONTEXT_MAGIC_VALUE )
|
|
{
|
|
RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
|
|
}
|
|
}
|
|
RpcExcept(1)
|
|
{
|
|
RpcRaiseException(RPC_X_SS_CONTEXT_MISMATCH);
|
|
}
|
|
RpcEndExcept
|
|
|
|
memcpy(pBuff, &hCContext->NDR, sizeof(hCContext->NDR));
|
|
}
|
|
|
|
#undef hCContext
|
|
}
|
|
|
|
|
|
static void
|
|
ByteSwapWireContext(
|
|
IN WIRE_CONTEXT PAPI * WireContext,
|
|
IN unsigned long PAPI * DataRepresentation
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
If necessary, the wire context will be byte swapped in place.
|
|
|
|
Arguments:
|
|
|
|
WireContext - Supplies the wire context be byte swapped and returns the
|
|
resulting byte swapped context.
|
|
|
|
DataRepresentation - Supplies the data representation of the supplied wire
|
|
context.
|
|
|
|
--*/
|
|
{
|
|
if ( (*DataRepresentation & NDR_LITTLE_ENDIAN)
|
|
!= NDR_LOCAL_ENDIAN )
|
|
{
|
|
ByteSwapLong(WireContext->ContextType);
|
|
ByteSwapLong(WireContext->ContextUuid.Data1);
|
|
ByteSwapShort(WireContext->ContextUuid.Data2);
|
|
ByteSwapShort(WireContext->ContextUuid.Data3);
|
|
}
|
|
}
|
|
|
|
void RPC_ENTRY
|
|
NDRCContextUnmarshall ( // process returned context
|
|
|
|
OUT NDR_CCONTEXT PAPI *phCContext,// stub context to update
|
|
IN RPC_BINDING_HANDLE hRPC, // binding handle to associate with
|
|
IN void PAPI *pBuff, // pointer to NDR wire format
|
|
IN unsigned long DataRepresentation // pointer to NDR data rep
|
|
|
|
// Update the users context handle from the servers NDR wire format.
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
PCCONTEXT hCC = (PCCONTEXT) ((long) *phCContext);
|
|
|
|
// destory this context if the server returned none
|
|
|
|
ByteSwapWireContext((WIRE_CONTEXT PAPI *) pBuff,
|
|
(unsigned long PAPI *) &DataRepresentation);
|
|
|
|
ASSERT( !RpcpCheckHeap() );
|
|
|
|
if (memcmp(pBuff, NilContext, cbNDRContext) == 0)
|
|
{
|
|
if (hCC)
|
|
{
|
|
if (hCC->hRPC)
|
|
RpcBindingFree(&(hCC->hRPC)); // discard duplicated binding
|
|
|
|
hCC->MagicValue = 0;
|
|
I_RpcFree(hCC);
|
|
}
|
|
|
|
*phCContext = Nil;
|
|
return;
|
|
}
|
|
|
|
PCCONTEXT hCCtemp = 0;
|
|
|
|
if (! hCC) // allocate new if none existed
|
|
{
|
|
hCCtemp = (PCCONTEXT) I_RpcAllocate(sizeof(CCONTEXT));
|
|
|
|
if (hCCtemp == 0)
|
|
{
|
|
RpcRaiseException(RPC_S_OUT_OF_MEMORY);
|
|
}
|
|
|
|
hCCtemp->MagicValue = CONTEXT_MAGIC_VALUE;
|
|
}
|
|
else if (memcmp(&hCC->NDR, pBuff, sizeof(hCC->NDR)) == 0)
|
|
{
|
|
// the returned context is the same as the app's context.
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
RPC_BINDING_HANDLE hBindtemp ;
|
|
|
|
if( I_RpcBindingCopy(hRPC, &hBindtemp) != RPC_S_OK )
|
|
{
|
|
ASSERT( !RpcpCheckHeap() );
|
|
I_RpcFree( hCCtemp );
|
|
RpcRaiseException(RPC_S_OUT_OF_MEMORY);
|
|
}
|
|
|
|
if ( hCCtemp )
|
|
hCC = hCCtemp;
|
|
else
|
|
RpcBindingFree(&(hCC->hRPC));
|
|
|
|
memcpy(&hCC->NDR, pBuff, sizeof(hCC->NDR));
|
|
hCC->hRPC = hBindtemp;
|
|
|
|
ASSERT( !RpcpCheckHeap() );
|
|
|
|
*phCContext = (NDR_CCONTEXT)hCC;
|
|
}
|
|
|
|
|
|
void RPC_ENTRY
|
|
RpcSsDestroyClientContext (
|
|
IN OUT void PAPI * PAPI * ContextHandle
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
A client application will use this routine to destroy a context handle
|
|
which it no longer needs. This will work without having to contact the
|
|
server.
|
|
|
|
Arguments:
|
|
|
|
ContextHandle - Supplies the context handle to be destroyed. It will
|
|
be set to zero before this routine returns.
|
|
|
|
Exceptions:
|
|
|
|
If the context handle is invalid, then the RPC_X_SS_CONTEXT_MISMATCH
|
|
exception will be raised.
|
|
|
|
--*/
|
|
{
|
|
RPC_BINDING_HANDLE BindingHandle;
|
|
RPC_STATUS RpcStatus;
|
|
|
|
BindingHandle = NDRCContextBinding(*ContextHandle);
|
|
|
|
RpcStatus = RpcBindingFree(&BindingHandle);
|
|
// ASSERT( RpcStatus == RPC_S_OK );
|
|
|
|
I_RpcFree(*ContextHandle);
|
|
*ContextHandle = 0;
|
|
}
|