Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

252 lines
6.0 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: MemDeSer.cxx
//
// History: 29-Jul-94 KyleP Created
//
//
// The CMemSerStream and CDeMemSerStream have different requirements for
// handling buffer overflow conditions. In the case of the driver this
// is indicative of a corrupted stream and we would like to raise an
// exception. On the other hand in Query implementation we deal with
// streams whose sizes are precomputed in the user mode. Therefore we
// do not wish to incur any additional penalty in handling such situations.
// In debug builds this condition is asserted while in retail builds it is
// ignored. The CMemSerStream and CMemDeSerStream implementation are
// implemented using a macro HANDLE_OVERFLOW(fOverflow) which take the
// appropriate action.
//
//--------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include "serover.hxx"
#if DBGPROP
BOOLEAN IsUnicodeString(WCHAR const *pwszname, ULONG cb);
BOOLEAN IsAnsiString(CHAR const *pszname, ULONG cb);
#endif
BYTE CMemDeSerStream::GetByte()
{
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
BYTE b = *_pbCurrent;
_pbCurrent += 1;
return(b);
}
void CMemDeSerStream::SkipByte()
{
_pbCurrent += 1;
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
}
void CMemDeSerStream::GetChar( char * pc, ULONG cc )
{
BYTE *pb = _pbCurrent;
_pbCurrent += cc;
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
memcpy( pc, pb, cc );
}
void CMemDeSerStream::SkipChar( ULONG cc )
{
_pbCurrent += cc;
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
}
void CMemDeSerStream::GetWChar( WCHAR * pwc, ULONG cc )
{
WCHAR * pwcTemp = AlignWCHAR(_pbCurrent);
_pbCurrent = (BYTE *)(pwcTemp + cc);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
memcpy( pwc, pwcTemp, cc * sizeof(WCHAR) );
}
void CMemDeSerStream::SkipWChar( ULONG cc )
{
WCHAR * pwcTemp = AlignWCHAR(_pbCurrent);
_pbCurrent = (BYTE *)(pwcTemp + cc);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
}
USHORT CMemDeSerStream::GetUShort()
{
USHORT * pus = AlignUSHORT(_pbCurrent);
_pbCurrent = (BYTE *)(pus + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
return( *pus );
}
void CMemDeSerStream::SkipUShort()
{
USHORT * pus = AlignUSHORT(_pbCurrent);
_pbCurrent = (BYTE *)(pus + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
}
ULONG CMemDeSerStream::GetULong()
{
ULONG * pul = AlignULONG(_pbCurrent);
_pbCurrent = (BYTE *)(pul + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
return( *pul );
}
void CMemDeSerStream::SkipULong()
{
ULONG * pul = AlignULONG(_pbCurrent);
_pbCurrent = (BYTE *)(pul + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
}
long CMemDeSerStream::GetLong()
{
long * pl = AlignLong(_pbCurrent);
_pbCurrent = (BYTE *)(pl + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
return( *pl );
}
void CMemDeSerStream::SkipLong()
{
long * pl = AlignLong(_pbCurrent);
_pbCurrent = (BYTE *)(pl + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
}
#if defined(KERNEL) // Can not return floats in the kernel
ULONG CMemDeSerStream::GetFloat()
{
ASSERT( sizeof(ULONG) == sizeof(float) );
ULONG * pf = (ULONG *) AlignFloat(_pbCurrent);
#else
float CMemDeSerStream::GetFloat()
{
float * pf = AlignFloat(_pbCurrent);
#endif
_pbCurrent = (BYTE *)(pf + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
return( *pf );
}
void CMemDeSerStream::SkipFloat()
{
float * pf = AlignFloat(_pbCurrent);
_pbCurrent = (BYTE *)(pf + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
}
#if defined(KERNEL) // Can not return doubles in the kernel
LONGLONG CMemDeSerStream::GetDouble()
{
ASSERT( sizeof(LONGLONG) == sizeof(double) );
LONGLONG * pd = (LONGLONG *) AlignDouble(_pbCurrent);
#else
double CMemDeSerStream::GetDouble()
{
double * pd = AlignDouble(_pbCurrent);
#endif
_pbCurrent = (BYTE *)(pd + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
return( *pd );
}
void CMemDeSerStream::SkipDouble()
{
double * pd = AlignDouble(_pbCurrent);
_pbCurrent = (BYTE *)(pd + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
}
ULONG CMemDeSerStream::PeekULong()
{
ULONG * pul = AlignULONG(_pbCurrent);
HANDLE_OVERFLOW(((BYTE *)pul + sizeof(ULONG)) > _pbEnd);
return( *pul );
}
char * CMemDeSerStream::GetString()
{
ULONG * pul = AlignULONG(_pbCurrent);
_pbCurrent = (BYTE *)(pul + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
ULONG len = *pul;
CHAR *pszTemp = (CHAR *)_pbCurrent;
_pbCurrent += len;
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
char * psz = new char[len+1];
if (psz != NULL) {
memcpy(psz, pszTemp, len);
psz[len] = '\0';
ASSERT(IsAnsiString(psz, len + 1));
}
return(psz);
}
WCHAR * CMemDeSerStream::GetWString()
{
ULONG * pul = AlignULONG(_pbCurrent);
_pbCurrent = (BYTE *)(pul + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
ULONG len = *pul;
WCHAR *pwszTemp = (WCHAR *)_pbCurrent;
_pbCurrent += len * sizeof(WCHAR);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
WCHAR * pwsz = new WCHAR[len + 1];
if (pwsz != NULL) {
memcpy(pwsz, pwszTemp, len * sizeof(WCHAR) );
pwsz[len] = L'\0';
ASSERT(IsUnicodeString(pwsz, (len + 1) * sizeof(WCHAR)));
}
return(pwsz);
}
void CMemDeSerStream::GetBlob( BYTE * pb, ULONG cb )
{
BYTE *pbTemp = _pbCurrent;
_pbCurrent += cb;
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
memcpy( pb, pbTemp, cb );
}
void CMemDeSerStream::SkipBlob( ULONG cb )
{
_pbCurrent += cb;
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
}
void CMemDeSerStream::GetGUID( GUID & guid )
{
GUID * pguid = (GUID *)AlignGUID(_pbCurrent);
_pbCurrent = (BYTE *)(pguid + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
guid = *pguid;
}
void CMemDeSerStream::SkipGUID()
{
GUID * pguid = (GUID *)AlignGUID(_pbCurrent);
_pbCurrent = (BYTE *)(pguid + 1);
HANDLE_OVERFLOW(_pbCurrent > _pbEnd);
}