mirror of https://github.com/tongzx/nt5src
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
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);
|
|
}
|