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.
671 lines
14 KiB
671 lines
14 KiB
/* --------------------------------------------------------------------
|
|
|
|
Microsoft OS/2 LAN Manager
|
|
Copyright(c) Microsoft Corp., 1991
|
|
|
|
-------------------------------------------------------------------- */
|
|
/* --------------------------------------------------------------------
|
|
|
|
Description :
|
|
|
|
Provides helper functions for data format conversion
|
|
|
|
History :
|
|
|
|
stevez 04-10-91 First bits into the bucket.
|
|
|
|
-------------------------------------------------------------------- */
|
|
|
|
#include "rpc.h"
|
|
#include "ndrhelp.h"
|
|
|
|
int _fstrlen(void far *);
|
|
void _pascal NDRcopy(void far *, void far *, int);
|
|
|
|
void PAPI * MIDL_user_allocate(unsigned int);
|
|
extern char near ebcdic_to_ascii[];
|
|
|
|
#define SWAPSHORT(s) { \
|
|
/* _asm mov ax, s */ \
|
|
_asm xchg ah,al \
|
|
_asm mov s,ax \
|
|
}
|
|
|
|
#define SWAPLONG(l) { \
|
|
/* _asm mov ax, word ptr l */ \
|
|
_asm xchg ah,al \
|
|
/* _asm mov dx, word ptr l+2*/ \
|
|
_asm xchg dh,dl \
|
|
_asm mov word ptr l+2,ax \
|
|
_asm mov word ptr l,dx \
|
|
}
|
|
|
|
#if 0
|
|
#define SWAPSHORT(s) s = (((unsigned char *)&s)[1]<<8 | ((unsigned char *)&s)[0])
|
|
#define SWAPLONG(l) l = ( ((long) ((unsigned char *)&ret)[3]<<24) | ((long) ((unsigned char *)&ret)[2]<<16) | \
|
|
((long) ((unsigned char *)&ret)[1]<<8) | ((long) ((unsigned char *)&ret)[0]))
|
|
#endif
|
|
|
|
#define Nilp(p) (*((int _far *)&p+1) == 0)
|
|
|
|
#define NEAR _near
|
|
|
|
#ifndef THREADS
|
|
|
|
#define GET_POINTER
|
|
|
|
#define pBuffCur (&BuffCur)
|
|
|
|
static NDR_BUFF NEAR BuffCur; // global static for no thread case
|
|
|
|
#else
|
|
|
|
PNDR_BUFF fetNDRCur(void);
|
|
|
|
#define GET_POINTER PNDR_BUFF pBuffCur = fetNDRCur();
|
|
|
|
#endif
|
|
|
|
#define fSelfLittleEndian 1
|
|
|
|
#define fEBCDIC (pBuffCur->dataType & 0x0f)
|
|
#define fSWAP ((pBuffCur->dataType & 0xf0) != fSelfLittleEndian)
|
|
#define fFloatType (*(((char *)&pBuffCur->dataType)+1))
|
|
|
|
enum {F_IEEE, F_VAX, F_CRAY, F_IBM };
|
|
|
|
static TypeAlign NEAR a1 = {0, 0, 0};
|
|
static TypeAlign NEAR a2 = {2-1, 2-1, 2-1};
|
|
static TypeAlign NEAR a4 = {2-1, 4-1, 4-1};
|
|
|
|
static TypeAlign NEAR *mAlignType[] = {0, &a1, &a2, 0, &a4};
|
|
|
|
#define GET_END_LIST ( (void PAPI *) -1)
|
|
typedef void PAPI * PAPI * PP;
|
|
|
|
|
|
|
|
void NDR_Put_Init ( // Initialize global objects for marshelling
|
|
|
|
PRPC_MESSAGE Message,
|
|
void PAPI * pParam
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
pBuffCur->pSource = pBuffCur->pCur = pParam;
|
|
pBuffCur->pTarget = Message->Buffer;
|
|
pBuffCur->alignment = mAlignType[sizeof(int)];
|
|
}
|
|
|
|
void NDR_Get_Init ( // Initialize global objects for unmarshelling
|
|
|
|
PRPC_MESSAGE Message,
|
|
void PAPI * pParam
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
pBuffCur->dataType = Message->DataRepresentation;
|
|
pBuffCur->fSwap = fSWAP;
|
|
pBuffCur->pSource = Message->Buffer;
|
|
pBuffCur->pCur = Message->Buffer;
|
|
pBuffCur->pPushLast = (PP)Message->Buffer;
|
|
pBuffCur->pTarget = pParam;
|
|
pBuffCur->pTargetRoot = 0;
|
|
|
|
pBuffCur->pAllocator = MIDL_user_allocate;
|
|
pBuffCur->alignment = mAlignType[sizeof(int)];
|
|
}
|
|
|
|
void NDR_Register_Unique(
|
|
|
|
void PAPI *(PAPI * pAllocator)(unsigned int)
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
pBuffCur->pAllocator = pAllocator;
|
|
}
|
|
|
|
|
|
void NDR_Pack_1 ( // Set the alignment to 1
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
pBuffCur->alignment = &a1;
|
|
}
|
|
|
|
void NDR_Pack_2 ( // Set the alignment to 2
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
pBuffCur->alignment = &a2;
|
|
}
|
|
|
|
void NDR_Pack_4 ( // Set the alignment to 4
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
pBuffCur->alignment = &a4;
|
|
}
|
|
|
|
|
|
|
|
#define ALIGN(ptr, byte) pBuffCur->ptr += (byte)-1; \
|
|
*(int *)&pBuffCur->ptr &= ~((byte)-1);
|
|
|
|
#define ALIGNCUR(ptr, TYPE) pBuffCur->ptr += pBuffCur->alignment->a##TYPE; \
|
|
*(int *)&pBuffCur->ptr &= ~pBuffCur->alignment->a##TYPE;
|
|
|
|
void NDR_Align_2 ( // Align the Target buffer to 2 byte boundary
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
ALIGN(pTarget, 2);
|
|
}
|
|
|
|
|
|
void NDR_Align_4 ( // Align the Target buffer to 4 byte boundary
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
ALIGN(pTarget, 4);
|
|
}
|
|
|
|
|
|
void NDR_Align_8 ( // Align the Target buffer to 8 byte boundary
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
ALIGN(pTarget, 8);
|
|
}
|
|
|
|
|
|
void NDR_Put_Set_Arg ( // set the source cursor to a value
|
|
|
|
void PAPI *pNew
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
// if at the root level, save the next pointer
|
|
|
|
if (Nilp(pBuffCur->pCur))
|
|
pBuffCur->pCur = pBuffCur->pSource;
|
|
|
|
pBuffCur->pSource = pNew;
|
|
}
|
|
|
|
void NDR_Put_Next_Arg ( // move the cursor to the next base argment
|
|
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
pBuffCur->pSource = pBuffCur->pCur;
|
|
pBuffCur->pCur = 0;
|
|
}
|
|
|
|
|
|
void NDR_Skip_B_Long ( // Skip past a long in the Target Buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
pBuffCur->pTarget += 4;
|
|
}
|
|
|
|
void NDR_Skip_M_Long ( // Skip past a long in the Source Buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
pBuffCur->pSource += 4;
|
|
}
|
|
|
|
|
|
void NDR_Put_B_Short ( // Put an immediate Short
|
|
short immediate // value to put
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
ALIGN(pTarget, 2);
|
|
|
|
*(short PAPI *) pBuffCur->pTarget = immediate;
|
|
pBuffCur->pTarget += 2;
|
|
|
|
}
|
|
|
|
void NDR_Put_B_Long ( // Put an immediate Long
|
|
long immediate // value to put
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
ALIGN(pTarget, 4);
|
|
|
|
*(long PAPI *) pBuffCur->pTarget = immediate;
|
|
pBuffCur->pTarget += 4;
|
|
|
|
}
|
|
|
|
|
|
void NDR_Put_Char ( // Put a char from the Target to Source
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
|
|
*(char PAPI *) pBuffCur->pTarget = *(char PAPI *) pBuffCur->pSource;
|
|
|
|
pBuffCur->pTarget += 1;
|
|
pBuffCur->pSource += 1;
|
|
|
|
}
|
|
|
|
|
|
void NDR_Put_Short ( // Put a short from the Target to Source
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
ALIGN(pTarget, 2);
|
|
ALIGNCUR(pSource, short);
|
|
|
|
*(short PAPI *) pBuffCur->pTarget = *(short PAPI *) pBuffCur->pSource;
|
|
|
|
pBuffCur->pTarget += 2;
|
|
pBuffCur->pSource += 2;
|
|
|
|
}
|
|
|
|
|
|
void NDR_Put_Long ( // Put a from the Target to Source
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
ALIGN(pTarget, 4);
|
|
ALIGNCUR(pSource, long);
|
|
|
|
*(long PAPI *) pBuffCur->pTarget = *(long PAPI *) pBuffCur->pSource;
|
|
|
|
pBuffCur->pTarget += 4;
|
|
pBuffCur->pSource += 4;
|
|
|
|
}
|
|
|
|
|
|
void NDR_Put_String ( // Put a 0 terminated from the Target to Source
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
short cbString;
|
|
GET_POINTER;
|
|
|
|
ALIGN(pTarget, 2);
|
|
ALIGNCUR(pSource, short);
|
|
|
|
*(short PAPI *) pBuffCur->pTarget = cbString = _fstrlen(*(char PAPI * PAPI *) pBuffCur->pTarget);
|
|
pBuffCur->pTarget += 2;
|
|
|
|
NDRcopy(pBuffCur->pTarget, pBuffCur->pTarget, cbString);
|
|
pBuffCur->pSource += cbString;
|
|
|
|
}
|
|
|
|
void NDR_Put_Memory ( // Put a block of memory from the Target to Source
|
|
unsigned int cb
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
NDRcopy(pBuffCur->pTarget, pBuffCur->pTarget, cb);
|
|
pBuffCur->pSource += cb;
|
|
pBuffCur->pTarget += cb;
|
|
|
|
}
|
|
|
|
|
|
short NDR_Get_B_Short ( // Return a short from the marshell buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
short ret;
|
|
GET_POINTER;
|
|
|
|
ALIGN(pSource, 2);
|
|
|
|
ret = *(short PAPI *) pBuffCur->pSource;
|
|
pBuffCur->pSource += 2;
|
|
|
|
if (pBuffCur->fSwap)
|
|
return (((unsigned char *)&ret)[1]<<8 | ((unsigned char *)&ret)[0]);
|
|
else
|
|
return(ret);
|
|
|
|
}
|
|
|
|
long NDR_Get_B_Long ( // Return a long from the marshell buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
long lval;
|
|
GET_POINTER;
|
|
|
|
ALIGN(pSource, 4);
|
|
|
|
lval = *(long PAPI *) pBuffCur->pSource;
|
|
pBuffCur->pSource += 4;
|
|
|
|
if (pBuffCur->fSwap)
|
|
SWAPLONG(lval)
|
|
|
|
return(lval);
|
|
|
|
}
|
|
|
|
void NDR_Get_Byte( // Copy a byte from the marshell buffer to the output buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
*(char PAPI *) pBuffCur->pTarget = *(char PAPI *) pBuffCur->pSource;
|
|
|
|
pBuffCur->pTarget += 1;
|
|
pBuffCur->pSource += 1;
|
|
|
|
}
|
|
|
|
void NDR_Get_Char( // Copy a char from the marshell buffer to the output buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
unsigned char c;
|
|
GET_POINTER;
|
|
|
|
c = *(char PAPI *) pBuffCur->pSource;
|
|
if (fEBCDIC)
|
|
c = ebcdic_to_ascii[c];
|
|
|
|
*(char PAPI *) pBuffCur->pTarget = c;
|
|
|
|
pBuffCur->pTarget += 1;
|
|
pBuffCur->pSource += 1;
|
|
|
|
}
|
|
|
|
void NDR_Get_Short( // Copy a short from the marshell buffer to the output buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
short sval;
|
|
GET_POINTER;
|
|
|
|
ALIGN(pSource, 2);
|
|
ALIGNCUR(pTarget, short);
|
|
|
|
sval = *(short PAPI *) pBuffCur->pSource;
|
|
if (pBuffCur->fSwap)
|
|
SWAPSHORT(sval);
|
|
|
|
*(short PAPI *) pBuffCur->pTarget = sval;
|
|
|
|
pBuffCur->pSource += 2;
|
|
pBuffCur->pTarget += 2;
|
|
}
|
|
|
|
|
|
void NDR_Get_Long( // Copy a long from the marshell buffer to the output buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
long lval;
|
|
GET_POINTER;
|
|
|
|
ALIGN(pSource, 4);
|
|
ALIGNCUR(pTarget, long);
|
|
|
|
lval = *(long PAPI *) pBuffCur->pSource;
|
|
if (pBuffCur->fSwap)
|
|
SWAPLONG(lval);
|
|
|
|
*(long PAPI *) pBuffCur->pTarget = lval;
|
|
|
|
pBuffCur->pSource += 4;
|
|
pBuffCur->pTarget += 4;
|
|
}
|
|
|
|
|
|
void NDR_Get_Float( // Copy a float from the marshell buffer to the output buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
long lval;
|
|
GET_POINTER;
|
|
|
|
ALIGN(pSource, 4);
|
|
ALIGNCUR(pTarget, long);
|
|
|
|
lval = *(long PAPI *) pBuffCur->pSource;
|
|
if (pBuffCur->fSwap)
|
|
SWAPLONG(lval);
|
|
|
|
switch(fFloatType) {
|
|
|
|
case F_IEEE:
|
|
break;
|
|
|
|
case F_VAX:
|
|
case F_CRAY:
|
|
case F_IBM:
|
|
;
|
|
}
|
|
*(long PAPI *) pBuffCur->pTarget = lval;
|
|
|
|
pBuffCur->pSource += 4;
|
|
pBuffCur->pTarget += 4;
|
|
}
|
|
|
|
void NDR_Get_Double( // Copy a double from the marshell buffer to the output buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
long lval[2];
|
|
GET_POINTER;
|
|
|
|
ALIGN(pSource, 4);
|
|
ALIGNCUR(pTarget, long);
|
|
|
|
if (pBuffCur->fSwap) {
|
|
|
|
lval[1] = *(long PAPI *) pBuffCur->pSource;
|
|
SWAPLONG(lval[1]);
|
|
|
|
lval[0] = *((long PAPI *) pBuffCur->pSource + 1);
|
|
SWAPLONG(lval[0]);
|
|
}
|
|
else {
|
|
lval[0] = *(long PAPI *) pBuffCur->pSource;
|
|
lval[1] = *((long PAPI *) pBuffCur->pSource + 1);
|
|
}
|
|
|
|
switch(fFloatType) {
|
|
|
|
case F_IEEE:
|
|
break;
|
|
|
|
case F_VAX:
|
|
case F_CRAY:
|
|
case F_IBM:
|
|
;
|
|
}
|
|
|
|
*(long PAPI *) pBuffCur->pTarget = lval[0];
|
|
*((long PAPI *) pBuffCur->pTarget+1) = lval[1];
|
|
|
|
pBuffCur->pSource += 8;
|
|
pBuffCur->pTarget += 8;
|
|
}
|
|
|
|
void NDR_Get_String( // Copy a string from the marshell buffer to the output buffer
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
short cbString;
|
|
GET_POINTER;
|
|
|
|
ALIGN(pSource, 2);
|
|
ALIGNCUR(pTarget, long);
|
|
|
|
cbString = *(short PAPI *) pBuffCur->pSource;
|
|
if (pBuffCur->fSwap)
|
|
SWAPSHORT(cbString);
|
|
|
|
pBuffCur->pSource += 2;
|
|
|
|
if (fEBCDIC) {
|
|
|
|
while (--cbString >= 0)
|
|
*pBuffCur->pTarget++ = ebcdic_to_ascii[*pBuffCur->pSource++];
|
|
}
|
|
else {
|
|
NDRcopy(pBuffCur->pTarget, pBuffCur->pSource, cbString);
|
|
|
|
pBuffCur->pTarget += cbString;
|
|
pBuffCur->pSource += cbString;
|
|
}
|
|
}
|
|
|
|
void NDR_Get_Char_Array( // Copy a character array doing byte translation
|
|
|
|
unsigned int Size
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
}
|
|
|
|
|
|
|
|
// For unmarshalling, pointers are retrieved by Get_Ptr. The current
|
|
// target offset is saved in a quque to be retrieved later. If the returned
|
|
// pointer is NIL, then no offset is retained
|
|
|
|
void NDR_Get_Ptr( // Get a pointer and save offset for later
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
if (*(void PAPI * PAPI *)(pBuffCur->pSource))
|
|
|
|
*pBuffCur->pPushLast = (void PAPI *)pBuffCur->pTarget;
|
|
else
|
|
*pBuffCur->pPushLast = 0;
|
|
|
|
pBuffCur->pPushLast++;
|
|
pBuffCur->pSource += 4;
|
|
pBuffCur->pTarget += 4;
|
|
}
|
|
|
|
int NDR_Get_Peek_Ptr( // Return TRUE if the current saved pointer is valid
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
return(!Nilp(pBuffCur->pCur));
|
|
}
|
|
|
|
void NDR_Get_Next_Arg( // Set the target pointer to the next root item
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
GET_POINTER;
|
|
|
|
// set alignment back to one suitable for walking the stack
|
|
|
|
pBuffCur->alignment = mAlignType[sizeof(int)];
|
|
|
|
pBuffCur->pTarget = pBuffCur->pTargetRoot;
|
|
pBuffCur->pCur = (char PAPI *) pBuffCur->pPushLast;
|
|
|
|
pBuffCur->pTargetRoot = 0;
|
|
|
|
}
|
|
|
|
|
|
int NDR_Get_Push_Unique( // Push the current target pointer and allocate memory
|
|
|
|
unsigned int Size
|
|
|
|
) //-----------------------------------------------------------------------//
|
|
{
|
|
void PAPI *pT;
|
|
GET_POINTER;
|
|
|
|
// first check to see if you have to pop back a level
|
|
|
|
while( (PP) pBuffCur->pCur >= pBuffCur->pPushLast ||
|
|
*(PP) pBuffCur->pCur == GET_END_LIST) {
|
|
|
|
pBuffCur->pCur = (char PAPI *)pBuffCur->pPushRet;
|
|
pBuffCur->pPushRet = (PP) (PP) pBuffCur->pCur[-1];
|
|
}
|
|
|
|
pT = *(PP)(pBuffCur->pCur);
|
|
*(PP)pBuffCur->pCur = GET_END_LIST;
|
|
|
|
if (!Nilp(pT)) {
|
|
|
|
// there exists a valid pointer in the marshell buffer
|
|
|
|
pT = *(PP)pT;
|
|
|
|
// if there is no pointer to unmarshell into, allocate one
|
|
|
|
if (Nilp(pT))
|
|
pT = (pBuffCur->pAllocator)(Size);
|
|
|
|
// if your leaving the root level, remember it for Next_Arg
|
|
|
|
if (Nilp(pBuffCur->pTargetRoot))
|
|
pBuffCur->pTargetRoot = pBuffCur->pTarget;
|
|
|
|
// push the return address
|
|
|
|
*(PP) pBuffCur->pCur = pBuffCur->pPushRet;
|
|
pBuffCur->pPushRet = (PP)pBuffCur->pCur+1;
|
|
|
|
pBuffCur->pTarget = pT;
|
|
return (1);
|
|
}
|
|
|
|
pBuffCur->pCur += 4;
|
|
return(0);
|
|
}
|