3029 lines
76 KiB
C
3029 lines
76 KiB
C
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
||
Copyright (c) 1993 Microsoft Corporation
|
||
|
||
Module Name :
|
||
|
||
endian.c
|
||
|
||
Abstract :
|
||
|
||
This file contains the routines called by MIDL 2.0 stubs and the
|
||
interpreter to perform endian, floating pointer, and character conversions.
|
||
|
||
Author :
|
||
|
||
David Kays dkays December 1993.
|
||
|
||
Revision History :
|
||
|
||
---------------------------------------------------------------------*/
|
||
|
||
#include "cvt.h"
|
||
#include "ndrp.h"
|
||
#include "interp2.h"
|
||
|
||
//
|
||
// Conversion routine table.
|
||
//
|
||
const
|
||
PCONVERT_ROUTINE ConvertRoutinesTable[] =
|
||
{
|
||
NdrPointerConvert,
|
||
NdrPointerConvert,
|
||
NdrPointerConvert,
|
||
NdrPointerConvert,
|
||
|
||
NdrSimpleStructConvert,
|
||
NdrSimpleStructConvert,
|
||
NdrConformantStructConvert,
|
||
NdrConformantStructConvert,
|
||
NdrConformantStructConvert, // same as FC_CARRAY
|
||
|
||
NdrComplexStructConvert,
|
||
|
||
NdrConformantArrayConvert,
|
||
NdrConformantVaryingArrayConvert,
|
||
NdrFixedArrayConvert,
|
||
NdrFixedArrayConvert,
|
||
NdrVaryingArrayConvert,
|
||
NdrVaryingArrayConvert,
|
||
|
||
NdrComplexArrayConvert,
|
||
|
||
NdrConformantStringConvert,
|
||
NdrConformantStringConvert,
|
||
NdrConformantStringConvert,
|
||
NdrConformantStringConvert,
|
||
|
||
NdrNonConformantStringConvert,
|
||
NdrNonConformantStringConvert,
|
||
NdrNonConformantStringConvert,
|
||
NdrNonConformantStringConvert,
|
||
|
||
NdrEncapsulatedUnionConvert,
|
||
NdrNonEncapsulatedUnionConvert,
|
||
|
||
NdrByteCountPointerConvert,
|
||
|
||
NdrXmitOrRepAsConvert, // transmit as
|
||
NdrXmitOrRepAsConvert, // represent as
|
||
|
||
NdrInterfacePointerConvert,
|
||
|
||
NdrContextHandleConvert,
|
||
|
||
NdrHardStructConvert,
|
||
|
||
NdrXmitOrRepAsConvert, // transmit as ptr
|
||
NdrXmitOrRepAsConvert, // represent as ptr
|
||
|
||
NdrUserMarshalConvert
|
||
|
||
};
|
||
|
||
const
|
||
PCONVERT_ROUTINE * pfnConvertRoutines = &ConvertRoutinesTable[-FC_RP];
|
||
|
||
//
|
||
// Array for ebcdic to ascii conversions. Use ebcdic value as index into
|
||
// array whose corresponding value is the correct ascii value.
|
||
//
|
||
unsigned char EbcdicToAscii[] =
|
||
{
|
||
0x20, 0x01, 0x02, 0x03, 0x3f, 0x09, 0x3f, 0x10,
|
||
0x3f, 0x3f, 0x3f, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||
0x10, 0x11, 0x12, 0x13, 0x3f, 0x3f, 0x08, 0x3f,
|
||
0x18, 0x19, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x3f, 0x3f, 0x1c, 0x3f, 0x3f, 0x3f, 0x17, 0x1b,
|
||
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x05, 0x06, 0x07,
|
||
0x00, 0x00, 0x16, 0x00, 0x3f, 0x1e, 0x3f, 0x04,
|
||
0x3f, 0x3f, 0x3f, 0x3f, 0x14, 0x15, 0x00, 0x1a,
|
||
0x20, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x3f, 0x3f, 0x3f, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
|
||
0x26, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x3f, 0x3f, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e,
|
||
0x2d, 0x2f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x3f, 0x3f, 0x3f, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
|
||
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x3f, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
|
||
0x3f, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||
0x68, 0x69, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x3f, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
|
||
0x71, 0x72, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x3f, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
|
||
0x79, 0x7a, 0x3f, 0x3f, 0x3f, 0x5b, 0x3f, 0x3f,
|
||
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x5d, 0x3f, 0x3f,
|
||
0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||
0x48, 0x49, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
||
0x51, 0x52, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x5c, 0x3f, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
||
0x59, 0x5a, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
|
||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||
0x38, 0x39, 0x7c, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f
|
||
};
|
||
|
||
#if defined( DOS ) || defined( WIN )
|
||
#pragma code_seg( "NDR_1" )
|
||
#endif
|
||
|
||
|
||
void RPC_ENTRY
|
||
NdrConvert2(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
long NumberParams )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
This is the new stub and interpreter entry point for endian conversion.
|
||
This routine handles the conversion of all parameters in a procedure.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Format string description of procedure's parameters.
|
||
NumberParams - The number of parameters in the procedure.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
uchar * pBuffer;
|
||
PFORMAT_STRING pFormatComplex;
|
||
PFORMAT_STRING pFormatTypes;
|
||
PPARAM_DESCRIPTION Params;
|
||
int fClientSide;
|
||
long n;
|
||
|
||
//
|
||
// Check if we need to do any converting.
|
||
//
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation & (unsigned long)0X0000FFFF) ==
|
||
NDR_LOCAL_DATA_REPRESENTATION )
|
||
return;
|
||
|
||
// Save the original buffer pointer to restore later.
|
||
pBuffer = pStubMsg->Buffer;
|
||
|
||
// Get the type format string.
|
||
pFormatTypes = pStubMsg->StubDesc->pFormatTypes;
|
||
|
||
fClientSide = pStubMsg->IsClient;
|
||
|
||
Params = (PPARAM_DESCRIPTION) pFormat;
|
||
|
||
for ( n = 0; n < NumberParams; n++ )
|
||
{
|
||
if ( fClientSide )
|
||
{
|
||
if ( ! Params[n].ParamAttr.IsOut )
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
if ( ! Params[n].ParamAttr.IsIn )
|
||
continue;
|
||
}
|
||
|
||
if ( Params[n].ParamAttr.IsPipe )
|
||
continue;
|
||
|
||
if ( Params[n].ParamAttr.IsBasetype )
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, Params[n].SimpleType.Type );
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// Complex type or pointer to complex type.
|
||
//
|
||
pFormatComplex = pFormatTypes + Params[n].TypeOffset;
|
||
|
||
(*pfnConvertRoutines[ROUTINE_INDEX(*pFormatComplex)])
|
||
( pStubMsg,
|
||
pFormatComplex,
|
||
FALSE );
|
||
}
|
||
|
||
pStubMsg->Buffer = pBuffer;
|
||
}
|
||
|
||
|
||
void RPC_ENTRY
|
||
NdrConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
This is the stub and interpreter entry point for endian conversion.
|
||
This routine handles the conversion of all parameters in a procedure.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Format string description of procedure's parameters.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
uchar * pBuffer;
|
||
PFORMAT_STRING pFormatComplex;
|
||
PFORMAT_STRING pFormatTypes;
|
||
int fClientSide;
|
||
|
||
//
|
||
// Check if we need to do any converting.
|
||
//
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation & (unsigned long)0X0000FFFF) ==
|
||
NDR_LOCAL_DATA_REPRESENTATION )
|
||
return;
|
||
|
||
// Save the original buffer pointer to restore later.
|
||
pBuffer = pStubMsg->Buffer;
|
||
|
||
// Get the type format string.
|
||
pFormatTypes = pStubMsg->StubDesc->pFormatTypes;
|
||
|
||
fClientSide = pStubMsg->IsClient;
|
||
|
||
for ( ;; )
|
||
{
|
||
switch ( *pFormat )
|
||
{
|
||
case FC_IN_PARAM :
|
||
case FC_IN_PARAM_NO_FREE_INST :
|
||
if ( fClientSide )
|
||
{
|
||
pFormat += 4;
|
||
continue;
|
||
}
|
||
|
||
break;
|
||
|
||
case FC_IN_PARAM_BASETYPE :
|
||
if ( ! fClientSide )
|
||
NdrSimpleTypeConvert( pStubMsg, pFormat[1] );
|
||
|
||
pFormat += 2;
|
||
continue;
|
||
|
||
case FC_IN_OUT_PARAM :
|
||
break;
|
||
|
||
case FC_OUT_PARAM :
|
||
if ( ! fClientSide )
|
||
{
|
||
pFormat += 4;
|
||
continue;
|
||
}
|
||
|
||
break;
|
||
|
||
case FC_RETURN_PARAM :
|
||
if ( ! fClientSide )
|
||
{
|
||
pStubMsg->Buffer = pBuffer;
|
||
return;
|
||
}
|
||
|
||
break;
|
||
|
||
case FC_RETURN_PARAM_BASETYPE :
|
||
if ( fClientSide )
|
||
NdrSimpleTypeConvert( pStubMsg, pFormat[1] );
|
||
|
||
// We're done. Fall through.
|
||
|
||
default :
|
||
pStubMsg->Buffer = pBuffer;
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Complex type or pointer to complex type.
|
||
//
|
||
pFormatComplex = pFormatTypes + *((ushort *)(pFormat + 2));
|
||
|
||
(*pfnConvertRoutines[ROUTINE_INDEX(*pFormatComplex)])
|
||
( pStubMsg,
|
||
pFormatComplex,
|
||
FALSE );
|
||
|
||
if ( *pFormat == FC_RETURN_PARAM )
|
||
{
|
||
pStubMsg->Buffer = pBuffer;
|
||
return;
|
||
}
|
||
|
||
pFormat += 4;
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrSimpleTypeConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
uchar FormatChar )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a simple type.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
FormatChar - Simple type format character.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
switch ( FormatChar )
|
||
{
|
||
case FC_CHAR :
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_CHAR_REP_MASK) ==
|
||
NDR_EBCDIC_CHAR )
|
||
*(pStubMsg->Buffer) = EbcdicToAscii[*(pStubMsg->Buffer)];
|
||
|
||
pStubMsg->Buffer += 1;
|
||
break;
|
||
|
||
case FC_BYTE :
|
||
case FC_SMALL :
|
||
case FC_USMALL :
|
||
pStubMsg->Buffer++;
|
||
break;
|
||
|
||
case FC_SHORT :
|
||
case FC_USHORT :
|
||
case FC_WCHAR :
|
||
case FC_ENUM16 :
|
||
ALIGN(pStubMsg->Buffer,1);
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_INT_REP_MASK) !=
|
||
NDR_LOCAL_ENDIAN )
|
||
{
|
||
ushort temp;
|
||
|
||
temp = (*((ushort *)pStubMsg->Buffer) & MASK_A_) >> 8 |
|
||
(*((ushort *)pStubMsg->Buffer) & MASK__B) << 8 ;
|
||
|
||
*((ushort *)pStubMsg->Buffer) = temp;
|
||
}
|
||
|
||
pStubMsg->Buffer += 2;
|
||
break;
|
||
|
||
case FC_LONG :
|
||
case FC_ULONG :
|
||
case FC_POINTER :
|
||
case FC_ENUM32 :
|
||
case FC_ERROR_STATUS_T:
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_INT_REP_MASK) !=
|
||
NDR_LOCAL_ENDIAN )
|
||
{
|
||
ulong temp;
|
||
|
||
//
|
||
// First apply the transformation: ABCD => BADC
|
||
//
|
||
temp = (*((ulong *)pStubMsg->Buffer) & MASK_A_C_) >> 8 |
|
||
(*((ulong *)pStubMsg->Buffer) & MASK__B_D) << 8 ;
|
||
|
||
//
|
||
// Now swap the left and right halves of the target long word
|
||
// achieving full swap: BADC => DCBA
|
||
//
|
||
temp = (temp & MASK_AB__) >> 16 | (temp & MASK___CD) << 16;
|
||
|
||
*((ulong *)pStubMsg->Buffer) = temp;
|
||
}
|
||
|
||
pStubMsg->Buffer += 4;
|
||
break;
|
||
|
||
case FC_HYPER :
|
||
ALIGN(pStubMsg->Buffer,7);
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_INT_REP_MASK) !=
|
||
NDR_LOCAL_ENDIAN )
|
||
{
|
||
ulong temp[2];
|
||
|
||
//
|
||
//.. We are doing ABCDEFGH -> HGFEDCBA
|
||
//.. We start with ABCD going as DCBA into second word of Target
|
||
//
|
||
|
||
//
|
||
// First apply the transformation: ABCD => BADC
|
||
//
|
||
temp[0] = (*((ulong *)pStubMsg->Buffer) & MASK_A_C_) >> 8 |
|
||
(*((ulong *)pStubMsg->Buffer) & MASK__B_D) << 8 ;
|
||
|
||
//
|
||
// Now swap the left and right halves of the Target long word
|
||
// achieving full swap: BADC => DCBA
|
||
//
|
||
temp[1] = (temp[0] & MASK_AB__) >> 16 |
|
||
(temp[0] & MASK___CD) << 16 ;
|
||
|
||
//
|
||
//.. What's left is EFGH going into first word at Target
|
||
//
|
||
|
||
//
|
||
// First apply the transformation: EFGH => FEHG
|
||
//
|
||
temp[0] =
|
||
(*((ulong *)(pStubMsg->Buffer + 4)) & MASK_A_C_) >> 8 |
|
||
(*((ulong *)(pStubMsg->Buffer + 4)) & MASK__B_D) << 8 ;
|
||
|
||
//
|
||
// Now swap the left and right halves of the Target long word
|
||
// achieving full swap: FEHG => HGFE
|
||
//
|
||
temp[0] = (temp[0] & MASK_AB__) >> 16 |
|
||
(temp[0] & MASK___CD) << 16 ;
|
||
|
||
//
|
||
// Now copy the new hyper into the buffer.
|
||
//
|
||
*((ulong *)pStubMsg->Buffer) = temp[0];
|
||
*((ulong *)(pStubMsg->Buffer + 4)) = temp[1];
|
||
}
|
||
|
||
pStubMsg->Buffer += 8;
|
||
break;
|
||
|
||
//
|
||
// VAX floating point conversions is the only one supported.
|
||
//
|
||
|
||
case FC_FLOAT :
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_FLOAT_INT_MASK)
|
||
!= NDR_LOCAL_ENDIAN_IEEE_REP )
|
||
{
|
||
BOOL fEndianessDone = FALSE;
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation &
|
||
NDR_INT_REP_MASK) != NDR_LOCAL_ENDIAN )
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
fEndianessDone = TRUE;
|
||
}
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation &
|
||
NDR_FLOAT_REP_MASK) != NDR_IEEE_FLOAT )
|
||
{
|
||
if ( fEndianessDone )
|
||
pStubMsg->Buffer -= 4;
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation &
|
||
NDR_FLOAT_REP_MASK) == NDR_VAX_FLOAT )
|
||
{
|
||
cvt_vax_f_to_ieee_single( pStubMsg->Buffer,
|
||
0,
|
||
pStubMsg->Buffer );
|
||
pStubMsg->Buffer += 4;
|
||
}
|
||
else
|
||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||
}
|
||
}
|
||
else
|
||
pStubMsg->Buffer += 4;
|
||
|
||
break;
|
||
|
||
case FC_DOUBLE :
|
||
ALIGN(pStubMsg->Buffer,7);
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation & NDR_FLOAT_INT_MASK)
|
||
!= NDR_LOCAL_ENDIAN_IEEE_REP )
|
||
{
|
||
BOOL fEndianessDone = FALSE;
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation &
|
||
NDR_INT_REP_MASK) != NDR_LOCAL_ENDIAN )
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_HYPER );
|
||
fEndianessDone = TRUE;
|
||
}
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation &
|
||
NDR_FLOAT_REP_MASK) != NDR_IEEE_FLOAT )
|
||
{
|
||
if ( fEndianessDone )
|
||
pStubMsg->Buffer -= 8;
|
||
|
||
if ( (pStubMsg->RpcMsg->DataRepresentation &
|
||
NDR_FLOAT_REP_MASK) == NDR_VAX_FLOAT )
|
||
{
|
||
cvt_vax_g_to_ieee_double( pStubMsg->Buffer,
|
||
0,
|
||
pStubMsg->Buffer );
|
||
pStubMsg->Buffer += 8;
|
||
}
|
||
else
|
||
RpcRaiseException(RPC_X_BAD_STUB_DATA);
|
||
}
|
||
}
|
||
else
|
||
pStubMsg->Buffer += 8;
|
||
|
||
break;
|
||
|
||
case FC_IGNORE:
|
||
break;
|
||
|
||
default :
|
||
NDR_ASSERT(0,"NdrSimpleTypeConvert : Bad format type");
|
||
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrPointerConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a top level pointer and the data it points to.
|
||
Pointers embedded in structures, arrays, or unions call
|
||
NdrpPointerConvert directly.
|
||
|
||
Used for FC_RP, FC_UP, FC_FP, FC_OP.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Pointer's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
uchar * pBufferMark;
|
||
|
||
if ( *pFormat != FC_RP )
|
||
{
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
pBufferMark = pStubMsg->Buffer;
|
||
|
||
if ( fEmbeddedPointerPass )
|
||
pStubMsg->Buffer += 4;
|
||
else
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
}
|
||
else
|
||
pBufferMark = 0;
|
||
|
||
NdrpPointerConvert( pStubMsg,
|
||
pBufferMark,
|
||
pFormat );
|
||
}
|
||
|
||
|
||
void
|
||
NdrpPointerConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
uchar * pBufferMark,
|
||
PFORMAT_STRING pFormat )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Private routine for converting a pointer and the data it points to.
|
||
This is the entry point for pointers embedded in structures, arrays,
|
||
and unions.
|
||
|
||
Used for FC_RP, FC_UP, FC_FP, FC_OP.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Pointer's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
switch ( *pFormat )
|
||
{
|
||
case FC_RP :
|
||
break;
|
||
|
||
case FC_UP :
|
||
case FC_OP :
|
||
if ( ! *((long *)pBufferMark) )
|
||
return;
|
||
|
||
break;
|
||
|
||
case FC_FP :
|
||
//
|
||
// Check if we have already seen this full pointer ref id during
|
||
// endian coversion. If so then we are finished with this pointer.
|
||
//
|
||
//
|
||
if ( NdrFullPointerQueryRefId( pStubMsg->FullPtrXlatTables,
|
||
*((ulong *)pBufferMark),
|
||
FULL_POINTER_CONVERTED,
|
||
0 ) )
|
||
return;
|
||
|
||
break;
|
||
|
||
default :
|
||
NDR_ASSERT(0,"NdrpPointerConvert : Bad format type");
|
||
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Pointer to complex type.
|
||
//
|
||
if ( ! SIMPLE_POINTER(pFormat[1]) )
|
||
{
|
||
pFormat += 2;
|
||
|
||
//
|
||
// Get the pointee format string.
|
||
// Cast must be to a signed short since some offsets are negative.
|
||
//
|
||
pFormat += *((signed short *)pFormat);
|
||
}
|
||
else
|
||
{
|
||
switch ( pFormat[2] )
|
||
{
|
||
case FC_C_CSTRING :
|
||
case FC_C_BSTRING :
|
||
case FC_C_WSTRING :
|
||
case FC_C_SSTRING :
|
||
// Get to the string's description.
|
||
pFormat += 2;
|
||
break;
|
||
|
||
default :
|
||
// Else it's a pointer to a simple type.
|
||
NdrSimpleTypeConvert( pStubMsg,
|
||
pFormat[2] );
|
||
return;
|
||
}
|
||
}
|
||
|
||
//
|
||
// Now lookup the proper conversion routine.
|
||
//
|
||
(*pfnConvertRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
|
||
pFormat,
|
||
FALSE );
|
||
}
|
||
|
||
|
||
void
|
||
NdrSimpleStructConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a simple structure.
|
||
|
||
Used for FC_STRUCT and FC_PSTRUCT.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Structure's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
uchar * pBufferMark;
|
||
PFORMAT_STRING pFormatLayout;
|
||
|
||
ALIGN(pStubMsg->Buffer,pFormat[1]);
|
||
|
||
// Remember where the struct starts in the buffer.
|
||
pBufferMark = pStubMsg->Buffer;
|
||
|
||
pFormat += 4;
|
||
|
||
if ( *pFormat == FC_PP )
|
||
pFormatLayout = NdrpSkipPointerLayout( pFormat );
|
||
else
|
||
pFormatLayout = pFormat;
|
||
|
||
//
|
||
// Convert or skip the flat part of the structure.
|
||
//
|
||
NdrpStructConvert( pStubMsg,
|
||
pFormatLayout,
|
||
0,
|
||
fEmbeddedPointerPass );
|
||
|
||
//
|
||
// Convert the pointers. This will do nothing if
|
||
// pStubMsg->IgnoreEmbeddedPointers is TRUE.
|
||
//
|
||
if ( *pFormat == FC_PP )
|
||
{
|
||
pStubMsg->BufferMark = pBufferMark;
|
||
|
||
NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrConformantStructConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a conformant or conformant varying structure.
|
||
|
||
Used for FC_CSTRUCT, FC_CPSTRUCT and FC_CVSTRUCT.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Structure's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PPRIVATE_CONVERT_ROUTINE pfnConvert;
|
||
uchar * pBufferMark;
|
||
PFORMAT_STRING pFormatArray;
|
||
PFORMAT_STRING pFormatLayout;
|
||
long MaxCount;
|
||
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
//
|
||
// Convert conformance count if needed.
|
||
//
|
||
if ( fEmbeddedPointerPass )
|
||
pStubMsg->Buffer += 4;
|
||
else
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
|
||
// Get the conformance count.
|
||
MaxCount = *((long *)(pStubMsg->Buffer - 4));
|
||
|
||
ALIGN(pStubMsg->Buffer,pFormat[1]);
|
||
|
||
// Remember where the struct starts in the buffer.
|
||
pBufferMark = pStubMsg->Buffer;
|
||
|
||
pFormat += 4;
|
||
|
||
// Get the array description.
|
||
pFormatArray = pFormat + *((signed short *)pFormat);
|
||
|
||
pFormat += 2;
|
||
|
||
if ( *pFormat == FC_PP )
|
||
pFormatLayout = NdrpSkipPointerLayout( pFormat );
|
||
else
|
||
pFormatLayout = pFormat;
|
||
|
||
//
|
||
// Convert or skip the flat part of the structure.
|
||
//
|
||
NdrpStructConvert( pStubMsg,
|
||
pFormatLayout,
|
||
0,
|
||
fEmbeddedPointerPass );
|
||
|
||
switch ( *pFormatArray )
|
||
{
|
||
case FC_CARRAY :
|
||
pfnConvert = NdrpConformantArrayConvert;
|
||
break;
|
||
case FC_CVARRAY :
|
||
pfnConvert = NdrpConformantVaryingArrayConvert;
|
||
break;
|
||
default :
|
||
//
|
||
// Conformant strings, but use the non-conformant string conversion
|
||
// routine since we've already converted the conformant size.
|
||
//
|
||
NdrNonConformantStringConvert( pStubMsg,
|
||
pFormatArray,
|
||
fEmbeddedPointerPass );
|
||
goto CheckPointers;
|
||
}
|
||
|
||
pStubMsg->MaxCount = MaxCount;
|
||
|
||
(*pfnConvert)( pStubMsg,
|
||
pFormatArray,
|
||
fEmbeddedPointerPass );
|
||
|
||
CheckPointers:
|
||
|
||
//
|
||
// Convert the pointers. This will do nothing if
|
||
// pStubMsg->IgnoreEmbeddedPointers is TRUE.
|
||
//
|
||
if ( *pFormat == FC_PP )
|
||
{
|
||
pStubMsg->BufferMark = pBufferMark;
|
||
|
||
NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrHardStructConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a hard structure.
|
||
|
||
Used for FC_HARD_STRUCT.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Structure's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
Notes:
|
||
|
||
pStubMsg->PointerBufferMark
|
||
! NULL indicates embedding in a complex struct.
|
||
NULL indicates top level or embedding in something else
|
||
|
||
So the algoritm here is
|
||
if the hard struct is in a complex struct, then the complex
|
||
struct is issuing two calls, first with FALSE, then with TRUE.
|
||
if the hard struct is NOT in a complex struct then there is only
|
||
one call and the union has to be called explicitely.
|
||
--*/
|
||
{
|
||
uchar * BufferSaved;
|
||
|
||
ALIGN(pStubMsg->Buffer,pFormat[1]);
|
||
|
||
// Remember where the struct starts in the buffer.
|
||
BufferSaved = pStubMsg->Buffer;
|
||
|
||
//
|
||
// Convert or skip the flat part of the structure.
|
||
//
|
||
NdrpStructConvert( pStubMsg,
|
||
pFormat + 16,
|
||
0, // no pointer layout
|
||
fEmbeddedPointerPass );
|
||
|
||
if ( ! pStubMsg->PointerBufferMark )
|
||
{
|
||
//
|
||
// Convert the pointers. This will do nothing if
|
||
// pStubMsg->IgnoreEmbeddedPointers is TRUE.
|
||
//
|
||
// See if we have a union, as the pointer may be only there.
|
||
//
|
||
pFormat += 14;
|
||
if ( *((short *)pFormat) )
|
||
{
|
||
//
|
||
// Set the pointer to the beginning of the union:
|
||
// the copy size is the struct buffer size without the union.
|
||
//
|
||
|
||
pStubMsg->Buffer = BufferSaved + *((short *)&pFormat[-4]);
|
||
|
||
pFormat += *((short *)pFormat);
|
||
|
||
(*pfnConvertRoutines[ ROUTINE_INDEX( *pFormat )])
|
||
( pStubMsg,
|
||
pFormat,
|
||
TRUE ); // convert the pointer only, if any.
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrComplexStructConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a complex structure.
|
||
|
||
Used for FC_BOGUS_STRUCT.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Structure's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
uchar * pBuffer;
|
||
uchar * pBufferMark;
|
||
PFORMAT_STRING pFormatSave;
|
||
PFORMAT_STRING pFormatArray;
|
||
PFORMAT_STRING pFormatPointers;
|
||
uchar Alignment;
|
||
BOOL fComplexEntry;
|
||
|
||
pFormatSave = pFormat;
|
||
|
||
// Remember the beginning of the structure in the buffer.
|
||
pBuffer = pStubMsg->Buffer;
|
||
|
||
Alignment = pFormat[1];
|
||
|
||
pFormat += 4;
|
||
|
||
// Get conformant array description.
|
||
if ( *((ushort *)pFormat) )
|
||
{
|
||
long Dimensions;
|
||
long i;
|
||
|
||
pFormatArray = pFormat + *((signed short *)pFormat);
|
||
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
// Mark the conformance start.
|
||
pBufferMark = pStubMsg->Buffer;
|
||
|
||
Dimensions = NdrpArrayDimensions( pFormatArray, FALSE );
|
||
|
||
if ( ! fEmbeddedPointerPass )
|
||
{
|
||
for ( i = 0; i < Dimensions; i++ )
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
}
|
||
else
|
||
pStubMsg->Buffer += Dimensions * 4;
|
||
}
|
||
else
|
||
{
|
||
pFormatArray = 0;
|
||
pBufferMark = 0;
|
||
}
|
||
|
||
pFormat += 2;
|
||
|
||
// Get pointer layout description.
|
||
if ( *((ushort *)pFormat) )
|
||
pFormatPointers = pFormat + *((ushort *)pFormat);
|
||
else
|
||
pFormatPointers = 0;
|
||
|
||
pFormat += 2;
|
||
|
||
ALIGN(pStubMsg->Buffer,Alignment);
|
||
|
||
//
|
||
// Check if we are not embedded inside of another complex struct or array.
|
||
//
|
||
if ( fComplexEntry = (pStubMsg->PointerBufferMark == 0) )
|
||
{
|
||
//
|
||
// Mark PointerBufferMark with a non-null value so complex array's
|
||
// or struct's which we embed will get fComplexEntry = false.
|
||
//
|
||
pStubMsg->PointerBufferMark = (uchar *) 0xffffffff;
|
||
}
|
||
|
||
//
|
||
// Convert the flat part of the structure.
|
||
//
|
||
NdrpStructConvert( pStubMsg,
|
||
pFormat,
|
||
pFormatPointers,
|
||
fEmbeddedPointerPass );
|
||
|
||
//
|
||
// Convert any conformant array, if present.
|
||
//
|
||
if ( pFormatArray )
|
||
{
|
||
PPRIVATE_CONVERT_ROUTINE pfnConvert;
|
||
uchar fOldIgnore;
|
||
|
||
switch ( *pFormatArray )
|
||
{
|
||
case FC_CARRAY :
|
||
pfnConvert = NdrpConformantArrayConvert;
|
||
break;
|
||
|
||
case FC_CVARRAY :
|
||
pfnConvert = NdrpConformantVaryingArrayConvert;
|
||
break;
|
||
|
||
case FC_BOGUS_ARRAY :
|
||
pfnConvert = NdrpComplexArrayConvert;
|
||
break;
|
||
|
||
// case FC_C_CSTRING :
|
||
// case FC_C_BSTRING :
|
||
// case FC_C_SSTRING :
|
||
// case FC_C_WSTRING :
|
||
|
||
default :
|
||
//
|
||
// Call the non-conformant string routine since we've
|
||
// already handled the conformance count.
|
||
//
|
||
NdrNonConformantStringConvert( pStubMsg,
|
||
pFormatArray,
|
||
fEmbeddedPointerPass );
|
||
goto ComplexConvertPointers;
|
||
}
|
||
|
||
fOldIgnore = pStubMsg->IgnoreEmbeddedPointers;
|
||
|
||
//
|
||
// Ignore embedded pointers if fEmbeddedPointerPass is false.
|
||
//
|
||
pStubMsg->IgnoreEmbeddedPointers = ! fEmbeddedPointerPass;
|
||
|
||
// Get the outermost max count for unidimensional arrays.
|
||
pStubMsg->MaxCount = *((ulong *)pBufferMark);
|
||
|
||
// Mark where conformance count(s) are.
|
||
pStubMsg->BufferMark = pBufferMark;
|
||
|
||
(*pfnConvert)( pStubMsg,
|
||
pFormatArray,
|
||
fEmbeddedPointerPass );
|
||
|
||
pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
|
||
}
|
||
|
||
ComplexConvertPointers:
|
||
|
||
//
|
||
// Now start a conversion pass for embedded pointers for the complex
|
||
// struct if we're not embedded inside of another complex struct or array.
|
||
//
|
||
if ( ! fEmbeddedPointerPass && fComplexEntry )
|
||
{
|
||
pStubMsg->PointerBufferMark = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pBuffer;
|
||
|
||
NdrComplexStructConvert( pStubMsg,
|
||
pFormatSave,
|
||
TRUE );
|
||
|
||
pStubMsg->Buffer = pStubMsg->PointerBufferMark;
|
||
|
||
pStubMsg->PointerBufferMark = 0;
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrpStructConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
PFORMAT_STRING pFormatPointers,
|
||
uchar fEmbeddedPointerPass )
|
||
/*++
|
||
|
||
Routine description :
|
||
|
||
Converts any type of structure given a structure layout.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Structure layout format string description.
|
||
pFormatPointers - Pointer layout if the structure is complex,
|
||
otherwise 0.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PFORMAT_STRING pFormatComplex;
|
||
uchar fOldIgnore;
|
||
|
||
fOldIgnore = pStubMsg->IgnoreEmbeddedPointers;
|
||
|
||
//
|
||
// We set this to TRUE during our first pass over the structure in which
|
||
// we convert the flat part of the structure and ignore embedded pointers.
|
||
// This will make any embedded ok structs or ok arrays ignore their
|
||
// embedded pointers until the second pass to convert embedded pointers
|
||
// (at which point we'll have the correct buffer pointer to where the
|
||
// pointees are).
|
||
//
|
||
pStubMsg->IgnoreEmbeddedPointers = ! fEmbeddedPointerPass;
|
||
|
||
//
|
||
// Convert the structure member by member.
|
||
//
|
||
for ( ; ; pFormat++ )
|
||
{
|
||
switch ( *pFormat )
|
||
{
|
||
//
|
||
// simple types
|
||
//
|
||
case FC_CHAR :
|
||
case FC_BYTE :
|
||
case FC_SMALL :
|
||
case FC_WCHAR :
|
||
case FC_SHORT :
|
||
case FC_LONG :
|
||
case FC_FLOAT :
|
||
case FC_HYPER :
|
||
case FC_DOUBLE :
|
||
case FC_ENUM16 :
|
||
case FC_ENUM32 :
|
||
if ( fEmbeddedPointerPass )
|
||
{
|
||
ALIGN(pStubMsg->Buffer,SIMPLE_TYPE_ALIGNMENT(*pFormat));
|
||
pStubMsg->Buffer += SIMPLE_TYPE_BUFSIZE(*pFormat);
|
||
}
|
||
else
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg,
|
||
*pFormat );
|
||
}
|
||
break;
|
||
|
||
case FC_IGNORE :
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
pStubMsg->Buffer += 4;
|
||
break;
|
||
|
||
case FC_POINTER :
|
||
//
|
||
// We can only get an FC_POINTER in a complex struct's layout.
|
||
// Pointers show up as FC_LONG in ok struct's layouts.
|
||
//
|
||
if ( fEmbeddedPointerPass )
|
||
{
|
||
uchar * pBuffer;
|
||
|
||
NDR_ASSERT(pFormatPointers != 0,"Internal error");
|
||
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
pBuffer = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pStubMsg->PointerBufferMark;
|
||
|
||
pStubMsg->PointerBufferMark = 0;
|
||
|
||
NdrpPointerConvert( pStubMsg,
|
||
pBuffer,
|
||
pFormatPointers );
|
||
|
||
pStubMsg->PointerBufferMark = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pBuffer + 4;
|
||
|
||
pFormatPointers += 4;
|
||
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg,
|
||
(uchar) FC_LONG );
|
||
}
|
||
break;
|
||
|
||
//
|
||
// Embedded structures
|
||
//
|
||
case FC_EMBEDDED_COMPLEX :
|
||
pFormat += 2;
|
||
|
||
// Get the type's description.
|
||
pFormatComplex = pFormat + *((signed short UNALIGNED *)pFormat);
|
||
|
||
(*pfnConvertRoutines[ROUTINE_INDEX(*pFormatComplex)])
|
||
( pStubMsg,
|
||
pFormatComplex,
|
||
fEmbeddedPointerPass );
|
||
|
||
// Increment the main format string one byte. The loop
|
||
// will increment it one more byte past the offset field.
|
||
pFormat++;
|
||
|
||
break;
|
||
|
||
//
|
||
// Unused for endian conversion.
|
||
//
|
||
case FC_ALIGNM2 :
|
||
case FC_ALIGNM4 :
|
||
case FC_ALIGNM8 :
|
||
break;
|
||
|
||
case FC_STRUCTPAD1 :
|
||
case FC_STRUCTPAD2 :
|
||
case FC_STRUCTPAD3 :
|
||
case FC_STRUCTPAD4 :
|
||
case FC_STRUCTPAD5 :
|
||
case FC_STRUCTPAD6 :
|
||
case FC_STRUCTPAD7 :
|
||
//
|
||
// Only appears at end of struct description, so ignore it.
|
||
//
|
||
break;
|
||
|
||
case FC_PAD :
|
||
break;
|
||
|
||
//
|
||
// Done with layout.
|
||
//
|
||
case FC_END :
|
||
pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
|
||
return;
|
||
|
||
default :
|
||
NDR_ASSERT(0,"NdrpStructConvert : Bad format type");
|
||
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrFixedArrayConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a fixed array of any number of dimensions.
|
||
|
||
Used for FC_SMFARRAY and FC_LGFARRAY.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Array's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PFORMAT_STRING pFormatLayout;
|
||
uchar * pBufferMark;
|
||
long Elements;
|
||
uchar fOldIgnore;
|
||
|
||
ALIGN(pStubMsg->Buffer,pFormat[1]);
|
||
|
||
pBufferMark = pStubMsg->Buffer;
|
||
|
||
// Get the number of array elements.
|
||
Elements = NdrpArrayElements( pStubMsg,
|
||
0,
|
||
pFormat );
|
||
|
||
pFormat += (*pFormat == FC_SMFARRAY) ? 4 : 6;
|
||
|
||
if ( *pFormat == FC_PP )
|
||
pFormatLayout = NdrpSkipPointerLayout( pFormat );
|
||
else
|
||
pFormatLayout = pFormat;
|
||
|
||
fOldIgnore = pStubMsg->IgnoreEmbeddedPointers;
|
||
|
||
pStubMsg->IgnoreEmbeddedPointers = TRUE;
|
||
|
||
NdrpArrayConvert( pStubMsg,
|
||
pFormatLayout,
|
||
Elements,
|
||
fEmbeddedPointerPass );
|
||
|
||
pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
|
||
|
||
if ( *pFormat == FC_PP )
|
||
{
|
||
pStubMsg->BufferMark = pBufferMark;
|
||
|
||
NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrConformantArrayConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts top level a one dimensional conformant array.
|
||
|
||
Used for FC_CARRAY.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Array's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
if ( fEmbeddedPointerPass )
|
||
pStubMsg->Buffer += 4;
|
||
else
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
|
||
pStubMsg->MaxCount = *((long *)(pStubMsg->Buffer - 4));
|
||
|
||
NdrpConformantArrayConvert( pStubMsg,
|
||
pFormat,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
|
||
|
||
void
|
||
NdrpConformantArrayConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Private routine for converting a one dimensional conformant array.
|
||
This is the entry point for an embedded conformant array.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Array's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PFORMAT_STRING pFormatLayout;
|
||
uchar * pBufferMark;
|
||
long Elements;
|
||
uchar fOldIgnore;
|
||
|
||
Elements = pStubMsg->MaxCount;
|
||
|
||
if ( ! Elements )
|
||
return;
|
||
|
||
ALIGN(pStubMsg->Buffer,pFormat[1]);
|
||
|
||
pBufferMark = pStubMsg->Buffer;
|
||
|
||
pFormat += 8;
|
||
|
||
if ( *pFormat == FC_PP )
|
||
pFormatLayout = NdrpSkipPointerLayout( pFormat );
|
||
else
|
||
pFormatLayout = pFormat;
|
||
|
||
fOldIgnore = pStubMsg->IgnoreEmbeddedPointers;
|
||
|
||
pStubMsg->IgnoreEmbeddedPointers = TRUE;
|
||
|
||
NdrpArrayConvert( pStubMsg,
|
||
pFormatLayout,
|
||
Elements,
|
||
fEmbeddedPointerPass );
|
||
|
||
pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
|
||
|
||
if ( *pFormat == FC_PP )
|
||
{
|
||
pStubMsg->BufferMark = pBufferMark;
|
||
|
||
pStubMsg->MaxCount = Elements;
|
||
|
||
NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrConformantVaryingArrayConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a top level one dimensional conformant varying array.
|
||
|
||
Used for FC_CVARRAY.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Array's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
if ( fEmbeddedPointerPass )
|
||
pStubMsg->Buffer += 4;
|
||
else
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
|
||
// We don't care about the max count.
|
||
|
||
NdrpConformantVaryingArrayConvert( pStubMsg,
|
||
pFormat,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
|
||
|
||
void
|
||
NdrpConformantVaryingArrayConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Private routine for converting a one dimensional conformant varying array.
|
||
This is the entry point for converting an embedded conformant varying
|
||
array.
|
||
|
||
Used for FC_CVARRAY.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Array's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PFORMAT_STRING pFormatLayout;
|
||
uchar * pBufferMark;
|
||
long Elements;
|
||
uchar fOldIgnore;
|
||
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
// Convert offset and actual count.
|
||
if ( fEmbeddedPointerPass )
|
||
pStubMsg->Buffer += 8;
|
||
else
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
}
|
||
|
||
Elements = *((long *)(pStubMsg->Buffer - 4));
|
||
|
||
if ( ! Elements )
|
||
return;
|
||
|
||
ALIGN(pStubMsg->Buffer,pFormat[1]);
|
||
|
||
pBufferMark = pStubMsg->Buffer;
|
||
|
||
pFormat += 12;
|
||
|
||
if ( *pFormat == FC_PP )
|
||
pFormatLayout = NdrpSkipPointerLayout( pFormat );
|
||
else
|
||
pFormatLayout = pFormat;
|
||
|
||
fOldIgnore = pStubMsg->IgnoreEmbeddedPointers;
|
||
|
||
pStubMsg->IgnoreEmbeddedPointers = TRUE;
|
||
|
||
NdrpArrayConvert( pStubMsg,
|
||
pFormatLayout,
|
||
Elements,
|
||
fEmbeddedPointerPass );
|
||
|
||
pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
|
||
|
||
if ( *pFormat == FC_PP )
|
||
{
|
||
pStubMsg->BufferMark = pBufferMark;
|
||
|
||
pStubMsg->MaxCount = Elements;
|
||
|
||
NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrVaryingArrayConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a top level or embedded varying array.
|
||
|
||
Used for FC_SMVARRAY and FC_LGVARRAY.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Array's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PFORMAT_STRING pFormatLayout;
|
||
uchar * pBufferMark;
|
||
long Elements;
|
||
uchar fOldIgnore;
|
||
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
// Convert offset and actual count.
|
||
if ( fEmbeddedPointerPass )
|
||
pStubMsg->Buffer += 8;
|
||
else
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
}
|
||
|
||
Elements = *((long *)(pStubMsg->Buffer - 4));
|
||
|
||
if ( ! Elements )
|
||
return;
|
||
|
||
ALIGN(pStubMsg->Buffer,pFormat[1]);
|
||
|
||
pBufferMark = pStubMsg->Buffer;
|
||
|
||
pFormat += (*pFormat == FC_SMVARRAY) ? 12 : 16;
|
||
|
||
if ( *pFormat == FC_PP )
|
||
pFormatLayout = NdrpSkipPointerLayout( pFormat );
|
||
else
|
||
pFormatLayout = pFormat;
|
||
|
||
fOldIgnore = pStubMsg->IgnoreEmbeddedPointers;
|
||
|
||
pStubMsg->IgnoreEmbeddedPointers = TRUE;
|
||
|
||
NdrpArrayConvert( pStubMsg,
|
||
pFormatLayout,
|
||
Elements,
|
||
fEmbeddedPointerPass );
|
||
|
||
pStubMsg->IgnoreEmbeddedPointers = fOldIgnore;
|
||
|
||
if ( *pFormat == FC_PP )
|
||
{
|
||
pStubMsg->BufferMark = pBufferMark;
|
||
|
||
pStubMsg->MaxCount = Elements;
|
||
|
||
NdrpEmbeddedPointerConvert( pStubMsg, pFormat );
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrComplexArrayConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a top level complex array.
|
||
|
||
Used for FC_BOGUS_STRUCT.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Array's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
long Dimensions;
|
||
long i;
|
||
|
||
if ( ( *((long UNALIGNED *)(pFormat + 4)) != 0xffffffff ) &&
|
||
( pStubMsg->pArrayInfo == 0 ) )
|
||
{
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
// Mark where conformance is.
|
||
pStubMsg->BufferMark = pStubMsg->Buffer;
|
||
|
||
Dimensions = NdrpArrayDimensions( pFormat, FALSE );
|
||
|
||
if ( ! fEmbeddedPointerPass )
|
||
{
|
||
for ( i = 0; i < Dimensions; i++ )
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
}
|
||
else
|
||
pStubMsg->Buffer += Dimensions * 4;
|
||
}
|
||
|
||
NdrpComplexArrayConvert( pStubMsg,
|
||
pFormat,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
|
||
|
||
void
|
||
NdrpComplexArrayConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Private routine for converting a complex array. This is the entry
|
||
point for converting an embedded complex array.
|
||
|
||
Used for FC_BOGUS_ARRAY.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Array's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
ARRAY_INFO ArrayInfo;
|
||
PARRAY_INFO pArrayInfo;
|
||
PFORMAT_STRING pFormatSave;
|
||
uchar * pBuffer;
|
||
ulong MaxCountSave;
|
||
long Elements;
|
||
long Dimension;
|
||
uchar Alignment;
|
||
BOOL fComplexEntry;
|
||
|
||
//
|
||
// Setup if we are the outer dimension.
|
||
//
|
||
if ( ! pStubMsg->pArrayInfo )
|
||
{
|
||
pStubMsg->pArrayInfo = &ArrayInfo;
|
||
|
||
ArrayInfo.Dimension = 0;
|
||
ArrayInfo.BufferConformanceMark = (unsigned long *)pStubMsg->BufferMark;
|
||
ArrayInfo.BufferVarianceMark = 0;
|
||
}
|
||
|
||
pFormatSave = pFormat;
|
||
|
||
pArrayInfo = pStubMsg->pArrayInfo;
|
||
|
||
Dimension = pArrayInfo->Dimension;
|
||
|
||
// Remember the start of the array in the buffer.
|
||
pBuffer = pStubMsg->Buffer;
|
||
|
||
// Get the array alignment.
|
||
Alignment = pFormat[1];
|
||
|
||
pFormat += 2;
|
||
|
||
// Get number of elements (0 if conformance present).
|
||
Elements = *((ushort *)pFormat)++;
|
||
|
||
//
|
||
// Check for conformance description.
|
||
//
|
||
if ( *((long UNALIGNED *)pFormat) != 0xffffffff )
|
||
{
|
||
Elements = pArrayInfo->BufferConformanceMark[Dimension];
|
||
pStubMsg->MaxCount = Elements;
|
||
}
|
||
|
||
MaxCountSave = pStubMsg->MaxCount;
|
||
|
||
pFormat += 4;
|
||
|
||
//
|
||
// Check for variance description.
|
||
//
|
||
if ( *((long UNALIGNED *)pFormat) != 0xffffffff )
|
||
{
|
||
long TotalDimensions;
|
||
long i;
|
||
|
||
if ( Dimension == 0 )
|
||
{
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
pArrayInfo->BufferVarianceMark = (unsigned long *)pStubMsg->Buffer;
|
||
|
||
TotalDimensions = NdrpArrayDimensions( pFormatSave, TRUE );
|
||
|
||
if ( ! fEmbeddedPointerPass )
|
||
{
|
||
//
|
||
// Convert offsets and lengths.
|
||
//
|
||
for ( i = 0; i < TotalDimensions; i++ )
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
}
|
||
}
|
||
else
|
||
pStubMsg->Buffer += TotalDimensions * 8;
|
||
}
|
||
|
||
// Overwrite Elements with the actual count.
|
||
Elements = pArrayInfo->BufferVarianceMark[(Dimension * 2) + 1];
|
||
}
|
||
|
||
pFormat += 4;
|
||
|
||
if ( ! Elements )
|
||
goto ComplexArrayConvertEnd;
|
||
|
||
ALIGN(pStubMsg->Buffer,Alignment);
|
||
|
||
//
|
||
// Check if we are not embedded inside of another complex struct or array.
|
||
//
|
||
if ( fComplexEntry = (pStubMsg->PointerBufferMark == 0) )
|
||
{
|
||
//
|
||
// Mark PointerBufferMark with a non-null value so complex array's
|
||
// or struct's which we embed will get fComplexEntry = false.
|
||
//
|
||
pStubMsg->PointerBufferMark = (uchar *) 0xffffffff;
|
||
}
|
||
|
||
NdrpArrayConvert( pStubMsg,
|
||
pFormat,
|
||
Elements,
|
||
fEmbeddedPointerPass );
|
||
|
||
pArrayInfo->Dimension = Dimension;
|
||
|
||
//
|
||
// Now convert pointers in the array members.
|
||
//
|
||
if ( ! fEmbeddedPointerPass && fComplexEntry )
|
||
{
|
||
pStubMsg->PointerBufferMark = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pBuffer;
|
||
|
||
// Restore BufferMark to handle multiD arrays.
|
||
pStubMsg->BufferMark = (uchar *) ArrayInfo.BufferConformanceMark;
|
||
|
||
// Restore the original max count if we had one.
|
||
pStubMsg->MaxCount = MaxCountSave;
|
||
|
||
NdrpComplexArrayConvert( pStubMsg,
|
||
pFormatSave,
|
||
TRUE );
|
||
|
||
pStubMsg->Buffer = pStubMsg->PointerBufferMark;
|
||
|
||
pStubMsg->PointerBufferMark = 0;
|
||
}
|
||
|
||
ComplexArrayConvertEnd:
|
||
|
||
// pArrayInfo must be zero when not valid.
|
||
pStubMsg->pArrayInfo = (Dimension == 0) ? 0 : pArrayInfo;
|
||
}
|
||
|
||
|
||
void
|
||
NdrpArrayConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
long Elements,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Private routine for converting any kind of array.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Array's element format string description.
|
||
Elements - Number of elements in the array.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PCONVERT_ROUTINE pfnConvert;
|
||
uchar * pBufferSave;
|
||
long Dimension;
|
||
long i;
|
||
|
||
// Used for FC_RP only.
|
||
pBufferSave = 0;
|
||
|
||
switch ( *pFormat )
|
||
{
|
||
case FC_EMBEDDED_COMPLEX :
|
||
//
|
||
// Get the complex type description.
|
||
//
|
||
pFormat += 2;
|
||
pFormat += *((signed short UNALIGNED *)pFormat);
|
||
|
||
pfnConvert = pfnConvertRoutines[ROUTINE_INDEX(*pFormat)];
|
||
break;
|
||
|
||
case FC_RP :
|
||
case FC_UP :
|
||
case FC_FP :
|
||
case FC_OP :
|
||
case FC_IP :
|
||
if ( ! fEmbeddedPointerPass )
|
||
return;
|
||
|
||
if ( pStubMsg->PointerBufferMark )
|
||
{
|
||
pBufferSave = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pStubMsg->PointerBufferMark;
|
||
|
||
pStubMsg->PointerBufferMark = 0;
|
||
}
|
||
|
||
pfnConvert = (*pFormat == FC_RP) ?
|
||
(PCONVERT_ROUTINE) NdrpPointerConvert :
|
||
NdrInterfacePointerConvert;
|
||
break;
|
||
|
||
default :
|
||
//
|
||
// Simple type.
|
||
//
|
||
if ( fEmbeddedPointerPass )
|
||
{
|
||
pStubMsg->Buffer += Elements * SIMPLE_TYPE_BUFSIZE(*pFormat);
|
||
return;
|
||
}
|
||
|
||
for ( i = 0; i < Elements; i++ )
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg,
|
||
*pFormat );
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
if ( ! IS_ARRAY_OR_STRING(*pFormat) )
|
||
{
|
||
pStubMsg->pArrayInfo = 0;
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// If we're dealing with a multidimensional fixed array, then pArrayInfo will
|
||
// be NULL. For non-fixed multidimensional arrays it will be valid.
|
||
//
|
||
if ( pStubMsg->pArrayInfo )
|
||
Dimension = pStubMsg->pArrayInfo->Dimension;
|
||
}
|
||
|
||
if ( pfnConvert == (PCONVERT_ROUTINE) NdrpPointerConvert )
|
||
{
|
||
for ( i = 0; i < Elements; i++ )
|
||
{
|
||
NdrpPointerConvert( pStubMsg,
|
||
0,
|
||
pFormat );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for ( i = 0; i < Elements; i++ )
|
||
{
|
||
if ( IS_ARRAY_OR_STRING(*pFormat) && pStubMsg->pArrayInfo )
|
||
pStubMsg->pArrayInfo->Dimension = Dimension + 1;
|
||
|
||
(*pfnConvert)( pStubMsg,
|
||
pFormat,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
}
|
||
|
||
if ( pBufferSave )
|
||
{
|
||
pStubMsg->PointerBufferMark = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pBufferSave;
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrConformantStringConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a top level conformant string.
|
||
|
||
Used for FC_C_CSTRING, FC_C_WSTRING, FC_C_SSTRING, and FC_C_BSTRING
|
||
(NT Beta2 compatability only).
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - String's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
//
|
||
// If this is not part of a multidimensional array then we check if we
|
||
// have to convert the max count.
|
||
//
|
||
if ( pStubMsg->pArrayInfo == 0 )
|
||
{
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
if ( fEmbeddedPointerPass )
|
||
pStubMsg->Buffer += 4;
|
||
else
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
}
|
||
|
||
NdrNonConformantStringConvert( pStubMsg,
|
||
pFormat,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
|
||
|
||
void
|
||
NdrNonConformantStringConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a non conformant string. This routine is also used to convert
|
||
conformant strings and is also the entry point for an embeded conformant
|
||
string.
|
||
|
||
Used for FC_CSTRING, FC_WSTRING, FC_SSTRING, FC_BSTRING (NT Beta2
|
||
compatability only), FC_C_CSTRING, FC_C_WSTRING, FC_C_SSTRING, and
|
||
FC_C_BSTRING (NT Beta2 compatability only).
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - String's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
uchar * pBuffer;
|
||
long Elements;
|
||
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
|
||
if ( fEmbeddedPointerPass )
|
||
pStubMsg->Buffer += 8;
|
||
else
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
}
|
||
|
||
Elements = *((long *)(pStubMsg->Buffer - 4));
|
||
|
||
pBuffer = pStubMsg->Buffer;
|
||
|
||
//
|
||
// Convert string. Remember that NdrConformantStringConvert calls this
|
||
// routine too.
|
||
//
|
||
switch ( *pFormat )
|
||
{
|
||
case FC_C_CSTRING :
|
||
case FC_C_BSTRING :
|
||
case FC_CSTRING :
|
||
case FC_BSTRING :
|
||
if ( ((pStubMsg->RpcMsg->DataRepresentation & NDR_CHAR_REP_MASK) ==
|
||
NDR_EBCDIC_CHAR) && ! fEmbeddedPointerPass )
|
||
{
|
||
for ( ; Elements-- > 0; )
|
||
*pBuffer++ = EbcdicToAscii[*pBuffer];
|
||
}
|
||
else
|
||
pBuffer += Elements;
|
||
|
||
break;
|
||
|
||
case FC_C_WSTRING :
|
||
case FC_WSTRING :
|
||
if ( ((pStubMsg->RpcMsg->DataRepresentation & NDR_INT_REP_MASK) !=
|
||
NDR_LOCAL_ENDIAN) && ! fEmbeddedPointerPass )
|
||
{
|
||
for ( ; Elements-- > 0; )
|
||
*((ushort *)pBuffer)++ =
|
||
(*((ushort *)pBuffer) & MASK_A_) >> 8 |
|
||
(*((ushort *)pBuffer) & MASK__B) << 8 ;
|
||
}
|
||
else
|
||
pBuffer += Elements * 2;
|
||
|
||
break;
|
||
|
||
case FC_C_SSTRING :
|
||
case FC_SSTRING :
|
||
// Never anything to convert.
|
||
pBuffer += Elements * pFormat[1];
|
||
break;
|
||
|
||
default :
|
||
NDR_ASSERT(0,"NdrNonConformantStringConvert : bad format char");
|
||
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
||
return;
|
||
}
|
||
|
||
pStubMsg->Buffer = pBuffer;
|
||
}
|
||
|
||
|
||
void
|
||
NdrEncapsulatedUnionConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts an encapsulated union.
|
||
|
||
Used for FC_ENCAPSULATED_UNION.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Union's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
uchar SwitchType;
|
||
|
||
SwitchType = LOW_NIBBLE(pFormat[1]);
|
||
|
||
NdrpUnionConvert( pStubMsg,
|
||
pFormat + 4,
|
||
SwitchType,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
|
||
|
||
void
|
||
NdrNonEncapsulatedUnionConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts an non-encapsulated union.
|
||
|
||
Used for FC_NON_ENCAPSULATED_UNION.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Union's format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
uchar SwitchType;
|
||
|
||
SwitchType = pFormat[1];
|
||
|
||
pFormat += 6;
|
||
pFormat += *((signed short *)pFormat);
|
||
|
||
pFormat += 2;
|
||
|
||
NdrpUnionConvert( pStubMsg,
|
||
pFormat,
|
||
SwitchType,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
|
||
|
||
void
|
||
NdrpUnionConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar SwitchType,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Private routine for converting a union shared by encapsulated and
|
||
non-encapsulated unions.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Union's format string description.
|
||
SwitchType - Union's format char switch type.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
long SwitchIs;
|
||
long Arms;
|
||
uchar Alignment;
|
||
|
||
//
|
||
// Convert the switch_is().
|
||
//
|
||
if ( fEmbeddedPointerPass )
|
||
{
|
||
ALIGN(pStubMsg->Buffer,SIMPLE_TYPE_ALIGNMENT(SwitchType));
|
||
pStubMsg->Buffer += SIMPLE_TYPE_BUFSIZE(SwitchType);
|
||
}
|
||
else
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg,
|
||
SwitchType );
|
||
}
|
||
|
||
switch ( SwitchType )
|
||
{
|
||
case FC_SMALL :
|
||
case FC_CHAR :
|
||
SwitchIs = (long) *((char *)(pStubMsg->Buffer - 1));
|
||
break;
|
||
case FC_USMALL :
|
||
SwitchIs = (long) *((uchar *)(pStubMsg->Buffer - 1));
|
||
break;
|
||
case FC_SHORT :
|
||
case FC_ENUM16 :
|
||
SwitchIs = (long) *((short *)(pStubMsg->Buffer - 2));
|
||
break;
|
||
case FC_USHORT :
|
||
case FC_WCHAR :
|
||
SwitchIs = (long) *((ushort *)(pStubMsg->Buffer - 2));
|
||
break;
|
||
case FC_LONG :
|
||
case FC_ULONG :
|
||
case FC_ENUM32 :
|
||
SwitchIs = *((long *)(pStubMsg->Buffer - 4));
|
||
break;
|
||
default :
|
||
NDR_ASSERT(0,"NdrpUnionConvert : bad switch value");
|
||
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
||
return;
|
||
}
|
||
|
||
//
|
||
// We're at the union_arms<2> field now, which contains both the
|
||
// Microsoft union aligment value and the number of union arms.
|
||
//
|
||
|
||
//
|
||
// Get the union alignment (0 if this is a DCE union).
|
||
//
|
||
Alignment = (uchar) ( *((ushort *)pFormat) >> 12 );
|
||
|
||
ALIGN(pStubMsg->Buffer,Alignment);
|
||
|
||
//
|
||
// Number of arms is the lower 12 bits.
|
||
//
|
||
Arms = (long) ( *((ushort *)pFormat)++ & 0x0fff);
|
||
|
||
for ( ; Arms; Arms-- )
|
||
{
|
||
if ( *((long UNALIGNED *)pFormat)++ == SwitchIs )
|
||
{
|
||
//
|
||
// Found the right arm, break out.
|
||
//
|
||
break;
|
||
}
|
||
|
||
// Else increment format string.
|
||
pFormat += 2;
|
||
}
|
||
|
||
//
|
||
// Check if we took the default arm and no default arm is specified.
|
||
//
|
||
if ( ! Arms && (*((ushort *)pFormat) == (ushort) 0xffff) )
|
||
{
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Return if the arm has no description.
|
||
//
|
||
if ( ! *((ushort *)pFormat) )
|
||
return;
|
||
|
||
//
|
||
// Get the arm's description.
|
||
//
|
||
// We need a real solution after beta for simple type arms. This could
|
||
// break if we have a format string larger than about 32K.
|
||
//
|
||
if ( IS_MAGIC_UNION_BYTE(pFormat) )
|
||
{
|
||
// Convert an arm of a simple type
|
||
|
||
#if defined(__RPC_MAC__)
|
||
#define ARM_TYPE_CODE pFormat[1]
|
||
#else
|
||
#define ARM_TYPE_CODE pFormat[0]
|
||
#endif
|
||
|
||
if ( fEmbeddedPointerPass )
|
||
pStubMsg->Buffer += SIMPLE_TYPE_BUFSIZE( ARM_TYPE_CODE );
|
||
else
|
||
NdrSimpleTypeConvert( pStubMsg, ARM_TYPE_CODE );
|
||
|
||
return;
|
||
}
|
||
|
||
pFormat += *((signed short *)pFormat);
|
||
|
||
//
|
||
// We have to do special things for a union arm which is a pointer when
|
||
// we have a union embedded in a complex struct or array.
|
||
//
|
||
if ( IS_BASIC_POINTER(*pFormat) && pStubMsg->PointerBufferMark )
|
||
{
|
||
uchar * pBufferMark;
|
||
|
||
//
|
||
// If we're not in the embedded pointer pass then just convert the
|
||
// pointer value.
|
||
//
|
||
if ( ! fEmbeddedPointerPass )
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, (uchar) FC_LONG );
|
||
return;
|
||
}
|
||
|
||
pBufferMark = pStubMsg->Buffer;
|
||
|
||
// Align pBufferMark.
|
||
ALIGN(pBufferMark,3);
|
||
|
||
pStubMsg->Buffer = pStubMsg->PointerBufferMark;
|
||
|
||
pStubMsg->PointerBufferMark = 0;
|
||
|
||
//
|
||
// We must call the private pointer conversion routine.
|
||
//
|
||
NdrpPointerConvert( pStubMsg,
|
||
pBufferMark,
|
||
pFormat );
|
||
|
||
pStubMsg->PointerBufferMark = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pBufferMark + 4;
|
||
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Union arm of a complex type.
|
||
//
|
||
(*pfnConvertRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
|
||
pFormat,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
|
||
|
||
void
|
||
NdrByteCountPointerConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a byte count pointer.
|
||
|
||
Used for FC_BYTE_COUNT_POINTER.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Byte count pointer format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
if ( pFormat[1] != FC_PAD )
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, pFormat[1] );
|
||
return;
|
||
}
|
||
|
||
pFormat += 6;
|
||
pFormat += *((short *)pFormat);
|
||
|
||
(*pfnConvertRoutines[ROUTINE_INDEX(*pFormat)])( pStubMsg,
|
||
pFormat,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
|
||
|
||
void
|
||
NdrXmitOrRepAsConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a transmit as or represent as transmited object.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - s format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PFORMAT_STRING pTransFormat;
|
||
|
||
// Transmitted type cannot have pointers in it, as of now,
|
||
// so if this is a embedded pointer pass, just return.
|
||
|
||
if ( fEmbeddedPointerPass )
|
||
return;
|
||
|
||
// Go to the transmitted type and convert it.
|
||
|
||
pFormat += 8;
|
||
pTransFormat = pFormat + *(short *)pFormat;
|
||
|
||
if ( IS_SIMPLE_TYPE( *pTransFormat ) )
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, *pTransFormat );
|
||
}
|
||
else
|
||
{
|
||
(*pfnConvertRoutines[ ROUTINE_INDEX( *pTransFormat) ])
|
||
( pStubMsg,
|
||
pTransFormat,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrUserMarshalConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a user_marshal object using the transmissible type description.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - not used
|
||
fEmbeddedPointerPass - not used
|
||
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PFORMAT_STRING pTransFormat;
|
||
|
||
// Go to the transmissible type and convert it.
|
||
|
||
pFormat += 8;
|
||
pTransFormat = pFormat + *(short *)pFormat;
|
||
|
||
if ( IS_SIMPLE_TYPE( *pTransFormat ) )
|
||
{
|
||
if ( fEmbeddedPointerPass )
|
||
return;
|
||
|
||
NdrSimpleTypeConvert( pStubMsg, *pTransFormat );
|
||
}
|
||
else
|
||
{
|
||
// It may have pointers in it.
|
||
|
||
if ( IS_POINTER_TYPE(*pTransFormat) && pStubMsg->PointerBufferMark )
|
||
{
|
||
// Embedded case and the type is a pointer type.
|
||
|
||
if ( fEmbeddedPointerPass )
|
||
{
|
||
uchar * BufferSave = pStubMsg->Buffer;
|
||
|
||
// Get the pointee type and convert it.
|
||
|
||
pStubMsg->Buffer = pStubMsg->PointerBufferMark;
|
||
|
||
pTransFormat += 2;
|
||
pTransFormat += *(short *)pTransFormat;
|
||
|
||
if ( IS_SIMPLE_TYPE( *pTransFormat ) )
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, *pTransFormat );
|
||
}
|
||
else
|
||
{
|
||
// Convert the pointee as if not embedded.
|
||
|
||
pStubMsg->PointerBufferMark = 0;
|
||
(*pfnConvertRoutines[ ROUTINE_INDEX( *pTransFormat) ])
|
||
( pStubMsg,
|
||
pTransFormat,
|
||
FALSE );
|
||
|
||
// Set the pointee marker behind the converted whole.
|
||
|
||
pStubMsg->PointerBufferMark = pStubMsg->Buffer;
|
||
}
|
||
|
||
// Now step over the original pointer.
|
||
|
||
pStubMsg->Buffer = BufferSave;
|
||
|
||
ALIGN(pStubMsg->Buffer,3);
|
||
pStubMsg->Buffer += 4;
|
||
}
|
||
else
|
||
{
|
||
// Convert the pointer itself only.
|
||
// We can't call ptr convert routine because of the pointee.
|
||
|
||
NdrSimpleTypeConvert( pStubMsg, FC_LONG );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Non embedded pointer type or
|
||
// (embedded or not) a non-pointer or a non-simple type.
|
||
// Just call the appropriate conversion routine.
|
||
|
||
(*pfnConvertRoutines[ ROUTINE_INDEX( *pTransFormat) ])
|
||
( pStubMsg,
|
||
pTransFormat,
|
||
fEmbeddedPointerPass );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
unsigned char __RPC_FAR * RPC_ENTRY
|
||
NdrUserMarshalSimpleTypeConvert(
|
||
unsigned long * pFlags,
|
||
unsigned char * pBuffer,
|
||
unsigned char FormatChar )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts a simple type supplied from a user_marshal unmarshaled routine.
|
||
|
||
Note that this is *not* supposed to be called when the NDR engine walks
|
||
the wire type description to convert.
|
||
|
||
Arguments :
|
||
|
||
pFlags - flags as for user_marshal routines: data rep, context.
|
||
pBuffer - current buffer pointer supplied by the user
|
||
FormatChar - specifies the type
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
MIDL_STUB_MESSAGE StubMsg;
|
||
RPC_MESSAGE RpcMsg;
|
||
|
||
StubMsg.Buffer = pBuffer;
|
||
StubMsg.RpcMsg = & RpcMsg;
|
||
RpcMsg.DataRepresentation = (((USER_MARSHAL_CB *)pFlags)->Flags) >> 16;
|
||
|
||
NdrSimpleTypeConvert( & StubMsg, FormatChar );
|
||
|
||
return ( StubMsg.Buffer );
|
||
}
|
||
|
||
|
||
void
|
||
NdrInterfacePointerConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Converts an interface pointer.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Xmit/Rep as format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
uchar * pBufferSave;
|
||
unsigned long *pLength;
|
||
|
||
// Align for getting the pointer's node id.
|
||
ALIGN( pStubMsg->Buffer, 0x3 );
|
||
|
||
//
|
||
// If we're ignoring embedded pointers then we simply convert the pointer's
|
||
// node id and return. Otherwise, we skip the pointer's node id and
|
||
// continue on to convert the actuall interface pointer.
|
||
//
|
||
if ( ! fEmbeddedPointerPass )
|
||
{
|
||
NdrSimpleTypeConvert( pStubMsg, FC_LONG );
|
||
|
||
if ( pStubMsg->PointerBufferMark != 0 )
|
||
return;
|
||
|
||
pStubMsg->Buffer -= 4;
|
||
}
|
||
|
||
// Skip the pointer's node id, which will already have been converted.
|
||
//
|
||
// Also, we don't have the pointee if the pointer itself is null;
|
||
// An interface pointer behaves like a unique pointer.
|
||
|
||
if ( *((long *)pStubMsg->Buffer)++ == 0 )
|
||
return;
|
||
|
||
//
|
||
// Check if we're handling pointers in a complex struct, and re-set the
|
||
// Buffer pointer if so.
|
||
//
|
||
if ( pStubMsg->PointerBufferMark )
|
||
{
|
||
pBufferSave = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pStubMsg->PointerBufferMark;
|
||
|
||
pStubMsg->PointerBufferMark = 0;
|
||
}
|
||
else
|
||
pBufferSave = 0;
|
||
|
||
//
|
||
// Convert the conformant size and the count field.
|
||
//
|
||
NdrSimpleTypeConvert( pStubMsg, FC_LONG );
|
||
|
||
pLength = (unsigned long *) pStubMsg->Buffer;
|
||
NdrSimpleTypeConvert( pStubMsg, FC_LONG );
|
||
|
||
// Skip over the marshalled interface pointer.
|
||
|
||
pStubMsg->Buffer += *pLength;
|
||
|
||
//
|
||
// Re-set the buffer pointer if needed.
|
||
//
|
||
if ( pBufferSave )
|
||
{
|
||
pStubMsg->PointerBufferMark = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pBufferSave;
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
NdrContextHandleConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat,
|
||
uchar fEmbeddedPointerPass )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Conversion routine for context handles, only increments the buffer.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Format string description.
|
||
fEmbeddedPointerPass - TRUE if a pass is being to convert only embedded
|
||
pointers in a struct/array.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
ALIGN(pStubMsg->Buffer,0x3);
|
||
pStubMsg->Buffer += 20;
|
||
}
|
||
|
||
|
||
void
|
||
NdrpEmbeddedPointerConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Private routine for converting an array's or a structure's embedded
|
||
pointers.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Pointer layout format string description.
|
||
|
||
Return :
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
uchar * pBufferMark;
|
||
uchar * pBufferPointer;
|
||
uchar * pBufferSave;
|
||
long MaxCountSave;
|
||
|
||
MaxCountSave = pStubMsg->MaxCount;
|
||
|
||
//
|
||
// Return if we're ignoring embedded pointers.
|
||
//
|
||
if ( pStubMsg->IgnoreEmbeddedPointers )
|
||
return;
|
||
|
||
//
|
||
// Check if we're handling pointers in a complex struct, and re-set the
|
||
// Buffer pointer if so.
|
||
//
|
||
if ( pStubMsg->PointerBufferMark )
|
||
{
|
||
pBufferSave = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pStubMsg->PointerBufferMark;
|
||
|
||
pStubMsg->PointerBufferMark = 0;
|
||
}
|
||
else
|
||
pBufferSave = 0;
|
||
|
||
pBufferMark = pStubMsg->BufferMark;
|
||
|
||
//
|
||
// Increment past the FC_PP and pad.
|
||
//
|
||
pFormat += 2;
|
||
|
||
for (;;)
|
||
{
|
||
if ( *pFormat == FC_END )
|
||
{
|
||
if ( pBufferSave )
|
||
{
|
||
pStubMsg->PointerBufferMark = pStubMsg->Buffer;
|
||
|
||
pStubMsg->Buffer = pBufferSave;
|
||
}
|
||
return;
|
||
}
|
||
|
||
// Check for a repeat pointer.
|
||
if ( *pFormat != FC_NO_REPEAT )
|
||
{
|
||
pStubMsg->MaxCount = MaxCountSave;
|
||
|
||
pFormat = NdrpEmbeddedRepeatPointerConvert( pStubMsg, pFormat );
|
||
|
||
// Continue to the next pointer.
|
||
continue;
|
||
}
|
||
|
||
// Increment to the buffer pointer offset.
|
||
pFormat += 4;
|
||
|
||
pBufferPointer = pBufferMark + *((signed short *)pFormat)++;
|
||
|
||
NdrpPointerConvert( pStubMsg,
|
||
pBufferPointer,
|
||
pFormat );
|
||
|
||
// Increment past the pointer description.
|
||
pFormat += 4;
|
||
}
|
||
}
|
||
|
||
|
||
PFORMAT_STRING
|
||
NdrpEmbeddedRepeatPointerConvert(
|
||
PMIDL_STUB_MESSAGE pStubMsg,
|
||
PFORMAT_STRING pFormat )
|
||
/*--
|
||
|
||
Routine description :
|
||
|
||
Private routine for converting an array's embedded pointers.
|
||
|
||
Arguments :
|
||
|
||
pStubMsg - Pointer to stub message.
|
||
pFormat - Pointer layout format string description.
|
||
|
||
Return :
|
||
|
||
Format string pointer past the array's pointer layout description.
|
||
|
||
--*/
|
||
{
|
||
uchar * pBufPtr;
|
||
uchar * pBufferMark;
|
||
PFORMAT_STRING pFormatSave;
|
||
ulong RepeatCount, RepeatIncrement, Pointers, PointersSave;
|
||
|
||
pBufferMark = pStubMsg->BufferMark;
|
||
|
||
// Get the repeat count.
|
||
switch ( *pFormat )
|
||
{
|
||
case FC_FIXED_REPEAT :
|
||
pFormat += 2;
|
||
|
||
RepeatCount = *((ushort *)pFormat);
|
||
|
||
break;
|
||
|
||
case FC_VARIABLE_REPEAT :
|
||
RepeatCount = pStubMsg->MaxCount;
|
||
|
||
break;
|
||
|
||
default :
|
||
NDR_ASSERT(0,"NdrpEmbeddedRepeatPointerConvert : bad format");
|
||
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
||
return 0;
|
||
}
|
||
|
||
pFormat += 2;
|
||
|
||
RepeatIncrement = *((ushort *)pFormat)++;
|
||
|
||
// array_offset is ignored
|
||
pFormat += 2;
|
||
|
||
// Get number of pointers.
|
||
Pointers = *((ushort *)pFormat)++;
|
||
|
||
pFormatSave = pFormat;
|
||
PointersSave = Pointers;
|
||
|
||
for ( ; RepeatCount--;
|
||
pBufferMark += RepeatIncrement )
|
||
{
|
||
pFormat = pFormatSave;
|
||
Pointers = PointersSave;
|
||
|
||
for ( ; Pointers--; )
|
||
{
|
||
pFormat += 2;
|
||
|
||
pBufPtr = pBufferMark + *((signed short *)pFormat)++;
|
||
|
||
NdrpPointerConvert( pStubMsg,
|
||
pBufPtr,
|
||
pFormat );
|
||
|
||
// Increment past the pointer description.
|
||
pFormat += 4;
|
||
}
|
||
}
|
||
|
||
return pFormatSave + PointersSave * 8;
|
||
}
|
||
|
||
|