Leaked source code of windows server 2003
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.
 
 
 
 
 
 

450 lines
14 KiB

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include "MarshalPC.h"
#include <string.h>
//*****************************************************************************
// Un/Marshaling
//*****************************************************************************
void InitXSCM(LPMYSCARDHANDLE phTmp, const BYTE *pbBuffer, WORD len)
{
phTmp->xSCM.wResLen = len;
if (FLAG2VERSION(phTmp->dwFlags) == VERSION_1_0)
phTmp->xSCM.wExpLen = 1; // Prereserves the return code
else
phTmp->xSCM.wExpLen = 0; // Return code in SW2
phTmp->xSCM.wGenLen = 0;
phTmp->xSCM.pbBuffer = (LPBYTE)pbBuffer;
}
WORD GetSCMBufferLength(LPXSCM pxSCM)
{
return pxSCM->wGenLen;
}
BYTE *GetSCMCrtPointer(LPXSCM pxSCM)
{
return pxSCM->pbBuffer;
}
//*****************************************************************************
// PARAM EXTRACTION (we care only that there is enough data received, i.e.
// we ignore pxSCM->wGenLen & pxSCM->wExpLen
SCODE XSCM2SCODE(LPXSCM pxSCM)
{
BYTE by;
if (pxSCM->wResLen == 0)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
pxSCM->wResLen -= sizeof(UINT8);
by = *(pxSCM->pbBuffer)++;
return MAKESCODE(by);
}
UINT8 XSCM2UINT8(LPXSCM pxSCM)
{
if (pxSCM->wResLen == 0)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
pxSCM->wResLen -= sizeof(UINT8);
return *((UINT8 *)pxSCM->pbBuffer)++;
}
HFILE XSCM2HFILE(LPXSCM pxSCM)
{
return (HFILE)(XSCM2UINT8(pxSCM));
}
UINT16 XSCM2UINT16(LPXSCM pxSCM, BOOL fBigEndian)
{
if (pxSCM->wResLen < sizeof(UINT16))
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
pxSCM->wResLen -= sizeof(UINT16);
if (fBigEndian)
{
UINT16 w = *((UINT16 *)pxSCM->pbBuffer)++;
w = (UINT16)(w>>8) | (UINT16)(w<<8);
return w;
}
else
return *((UNALIGNED UINT16 *)pxSCM->pbBuffer)++;
}
// Returns length in WCHAR
WCSTR XSCM2String(LPXSCM pxSCM, UINT8 *plen, BOOL fBigEndian)
{
// Get the length (addr next byte + length -> next object
WCSTR wsz;
UINT8 len, i;
len = XSCM2UINT8(pxSCM);
if (len == 0)
{
wsz = NULL;
}
else
{
if (pxSCM->wResLen < (WORD)len)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
pxSCM->wResLen -= (WORD)len;
wsz = (WCSTR)pxSCM->pbBuffer;
// In place byte switching
// if (fBigEndian)
// {
// BYTE b;
// for (i=0 ; i<(len&0xF7)-2 ; i+=2)
// {
// b = pxSCM->pbBuffer[i];
// pxSCM->pbBuffer[i] = pxSCM->pbBuffer[i + 1];
// pxSCM->pbBuffer[i+1] = b;
// }
// }
// Verify 0 terminated within len/2
for (i=0 ; i<len/2 ; i++)
{
if (wsz[i] == (WCHAR)0)
break;
}
if (i >= len/2)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
else
len = i+1;
pxSCM->pbBuffer += len;
}
if (plen)
*plen = len;
return wsz;
}
TCOUNT XSCM2ByteArray(LPXSCM pxSCM, UINT8 **ppb)
{
TCOUNT len = XSCM2UINT8(pxSCM);
if (len)
{
if (pxSCM->wResLen < (WORD)len)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
pxSCM->wResLen -= (WORD)len;
*ppb = (UINT8 *)pxSCM->pbBuffer;
pxSCM->pbBuffer += len;
}
else
*ppb = NULL;
return len;
}
//*****************************************************************************
void UINT82XSCM(LPXSCM pxSCM, UINT8 val, int type)
{
switch (type)
{
case TYPE_NOTYPE_NOCOUNT: // Goes in the header
break; // There can't be a problem
case TYPE_NOTYPE_COUNT: // Probably #param or a param type (1 byte)
if (pxSCM->wExpLen + sizeof(UINT8) > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
break;
case TYPE_TYPED: // 8 bits number passed by value (2 bytes)
if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type (8)
*((UINT8 *)pxSCM->pbBuffer)++ = 8;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
break;
}
// Add the value already !
*((UINT8 *)pxSCM->pbBuffer)++ = val;
if (type != TYPE_NOTYPE_NOCOUNT) // Header doesn't count as expanded
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
}
// proxies HFILE as an UINT8
void HFILE2XSCM(LPXSCM pxSCM, HFILE val)
{
if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type (8 -> UINT8)
*((UINT8 *)pxSCM->pbBuffer)++ = 8;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
*((UINT8 *)pxSCM->pbBuffer)++ = (UINT8)val;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
}
void UINT162XSCM(LPXSCM pxSCM, UINT16 val, BOOL fBigEndian)
{
if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT16) > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type (16)
*((UINT8 *)pxSCM->pbBuffer)++ = 16;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
if (fBigEndian)
{
*pxSCM->pbBuffer++ = (BYTE)(val>>8);
*pxSCM->pbBuffer++ = (BYTE)(val);
}
else
*((UNALIGNED UINT16 *)pxSCM->pbBuffer)++ = val;
pxSCM->wExpLen += sizeof(UINT16);
pxSCM->wGenLen += sizeof(UINT16);
}
void ByteArray2XSCM(LPXSCM pxSCM, const BYTE *pbBuffer, TCOUNT len)
{
if (pbBuffer == NULL)
{
// This is equivalent to marshal a NULL & "len as a UINT8"
NULL2XSCM(pxSCM);
UINT82XSCM(pxSCM, len, TYPE_TYPED);
}
else
{
if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + len > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type ('A')
*((UINT8 *)pxSCM->pbBuffer)++ = 'A';
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// Add the length
*((UINT8 *)pxSCM->pbBuffer)++ = len;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// Add the data already
memcpy(pxSCM->pbBuffer, pbBuffer, len);
pxSCM->pbBuffer += len;
pxSCM->wExpLen += len;
pxSCM->wGenLen += len;
}
}
void String2XSCM(LPXSCM pxSCM, WCSTR wsz, BOOL fBigEndian)
{
UINT16 len; //, i;
if (wsz == NULL)
{
// This is equivalent to marshal a NULL
NULL2XSCM(pxSCM);
}
else
{
// No overflow needs to be checked in the following assignement to len
if (wcslen(wsz) > 0x7FFE)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// compute the length (addr next byte + length -> next object
len = (wcslen(wsz) + 1) * sizeof(WCHAR);
if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + len > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type ('S')
*((UINT8 *)pxSCM->pbBuffer)++ = 'S';
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// Add the length
*((UINT8 *)pxSCM->pbBuffer)++ = (UINT8)len; // No chance the length check succeeds
// if len > 255
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// Add the data already
// Byte switching?
// if (fBigEndian)
// {
// for (i=0 ; i<len ; i+=2)
// {
// pxSCM->pbBuffer[i] = (BYTE)(wsz[i>>1]>>8);
// pxSCM->pbBuffer[i+1] = (BYTE)(wsz[i>>1]);
// }
// }
// else
memcpy(pxSCM->pbBuffer, (BYTE *)wsz, len);
pxSCM->pbBuffer += len;
pxSCM->wExpLen += len;
pxSCM->wGenLen += len;
}
}
void UINT8BYREF2XSCM(LPXSCM pxSCM, UINT8 *val)
{
if (val)
{
// In this case the card unmarshaling code will reserve 1 byte in the
// OutputBuffer and have _param[_iparam++]._pv point to it
if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + sizeof(UINT8) > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type (108)
*((UINT8 *)pxSCM->pbBuffer)++ = 108;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// Add the value already
*((UINT8 *)pxSCM->pbBuffer)++ = *val;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// As mentioned above, 1 byte will be reserved in the output buffer
pxSCM->wExpLen += sizeof(UINT8);
}
else
{
// This is equivalent to marshal a NULL
NULL2XSCM(pxSCM);
}
}
void HFILEBYREF2XSCM(LPXSCM pxSCM, HFILE *val)
{
if (val)
{
// In this case the card unmarshaling code will reserve 1 byte in the
// OutputBuffer and have _param[_iparam++]._pv point to it
if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + sizeof(UINT8) > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type (108)
*((UINT8 *)pxSCM->pbBuffer)++ = 108;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// Add the value already
*((UINT8 *)pxSCM->pbBuffer)++ = (UINT8)*val;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// As mentioned above, 1 byte will be reserved in the output buffer
pxSCM->wExpLen += sizeof(UINT8);
}
else
{
// This is equivalent to marshal a NULL
NULL2XSCM(pxSCM);
}
}
void UINT16BYREF2XSCM(LPXSCM pxSCM, UINT16 *val, BOOL fBigEndian)
{
if (val)
{
// In this case the card unmarshaling code will reserve 2 bytes in the
// OutputBuffer and have _param[_iparam++]._pv point to it
if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT16) + sizeof(UINT16) > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type (116)
*((UINT8 *)pxSCM->pbBuffer)++ = 116;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// Add the value already
if (fBigEndian)
{
*pxSCM->pbBuffer++ = (BYTE)((*val)>>8);
*pxSCM->pbBuffer++ = (BYTE)(*val);
}
else
*((UNALIGNED UINT16 *)pxSCM->pbBuffer)++ = *val;
pxSCM->wExpLen += sizeof(UINT16);
pxSCM->wGenLen += sizeof(UINT16);
// As mentioned above, 2 bytes will be reserved in the output buffer
pxSCM->wExpLen += sizeof(UINT16);
}
else
{
// This is equivalent to marshal a NULL
NULL2XSCM(pxSCM);
}
}
void ByteArrayOut2XSCM(LPXSCM pxSCM, BYTE *pb, TCOUNT len)
{
if (pb)
{
// In this case the card unmarshaling code will reserve 1+len bytes in the
// OutputBuffer and have _param[_iparam++]._pv point to the len bytes
// Note that the current buffer isn't passed in
if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + sizeof(UINT8) + len > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type ('a')
*((UINT8 *)pxSCM->pbBuffer)++ = 'a';
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// Add the length
*((UINT8 *)pxSCM->pbBuffer)++ = len;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// As mentioned above, 1+len bytes will be reserved in the output buffer
pxSCM->wExpLen += sizeof(UINT8) + len;
}
else
{
// This is equivalent to marshal a NULL & "len as a UINT8"
NULL2XSCM(pxSCM);
UINT82XSCM(pxSCM, len, TYPE_TYPED);
}
}
void StringOut2XSCM(LPXSCM pxSCM, WSTR wsz, TCOUNT len, BOOL fBigEndian)
{
if (wsz)
{
// len is a WCHAR count
if (len > 127) // This would cause overflows in String marshaling
RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
// In this case the card unmarshaling code will reserve 1+len*2 bytes in the
// OutputBuffer and have _param[_iparam++]._pv point to the len bytes
// Note that the current buffer isn't passed in
if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + sizeof(UINT8) + len*2 > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type ('s')
*((UINT8 *)pxSCM->pbBuffer)++ = 's';
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
*((UINT8 *)pxSCM->pbBuffer)++ = len*2;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
// As mentioned above, 1+len*2 bytes will be reserved in the output buffer
pxSCM->wExpLen += sizeof(UINT8) + len*2;
}
else
{
// This is equivalent to marshal a NULL & "len as a UINT8"
NULL2XSCM(pxSCM);
UINT82XSCM(pxSCM, len, TYPE_TYPED);
}
}
void NULL2XSCM(LPXSCM pxSCM)
{
if (pxSCM->wExpLen + sizeof(UINT8) > pxSCM->wResLen)
RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
// Prefix by the type (0)
*((UINT8 *)pxSCM->pbBuffer)++ = 0;
pxSCM->wExpLen += sizeof(UINT8);
pxSCM->wGenLen += sizeof(UINT8);
}