254 lines
7.2 KiB
C++
254 lines
7.2 KiB
C++
//
|
|
// The developer of the original code and/or files is Tripwire, Inc.
|
|
// Portions created by Tripwire, Inc. are copyright (C) 2000-2017 Tripwire,
|
|
// Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights
|
|
// reserved.
|
|
//
|
|
// This program is free software. The contents of this file are subject
|
|
// to the terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 2 of the License, or (at your
|
|
// option) any later version. You may redistribute it and/or modify it
|
|
// only in compliance with the GNU General Public License.
|
|
//
|
|
// This program is distributed in the hope that it will be useful.
|
|
// However, this program is distributed AS-IS WITHOUT ANY
|
|
// WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS
|
|
// FOR A PARTICULAR PURPOSE. Please see the GNU General Public License
|
|
// for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
// USA.
|
|
//
|
|
// Nothing in the GNU General Public License or any other license to use
|
|
// the code or files shall permit you to use Tripwire's trademarks,
|
|
// service marks, or other intellectual property without Tripwire's
|
|
// prior written consent.
|
|
//
|
|
// If you have any questions, please contact Tripwire, Inc. at either
|
|
// info@tripwire.org or www.tripwire.org.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// fileheader.cpp
|
|
|
|
#include "stdcore.h"
|
|
#include "fileheader.h"
|
|
#include "serializer.h"
|
|
#include "ntmbs.h"
|
|
|
|
// A magic number to put at top of file headers
|
|
// I changed this magic number in 2.1 since we now support versioning in the file header.
|
|
// (the old magic number was 0x00202039)
|
|
// I generated the random number using the random.org web site.
|
|
const uint32 FILE_HEADER_MAGIC_NUMBER = 0x78f9beb3;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// class cFileHeaderID
|
|
|
|
cFileHeaderID::~cFileHeaderID()
|
|
{
|
|
}
|
|
|
|
void cFileHeaderID::operator=( const TCHAR* pszId )
|
|
{
|
|
// RAD:10/1/99 -- Not Needed
|
|
// TODO:BAM -- I'm pretty sure that there's a bug hiding here...
|
|
//size_t len = _tcslen(id);
|
|
//if (len >= 256)
|
|
//{
|
|
// ASSERT(false);
|
|
// mIDLen = 0;
|
|
// return;
|
|
//}
|
|
|
|
size_t N = ::strlen( pszId );
|
|
if ( !(N < cFileHeaderID::MAXBYTES) )
|
|
throw eCharacter( TSS_GetString( cCore, core::STR_ERR_OVERFLOW ) );
|
|
|
|
mIDLen = static_cast<int16>( N ); // know len is less than MAXBYTES
|
|
::memcpy( mID, pszId, N * sizeof(char) );
|
|
}
|
|
|
|
void cFileHeaderID::operator=( const cFileHeaderID& rhs )
|
|
{
|
|
ASSERT( rhs.mIDLen < cFileHeaderID::MAXBYTES );
|
|
mIDLen = rhs.mIDLen;
|
|
memcpy(mID, rhs.mID, mIDLen * sizeof(char));
|
|
}
|
|
|
|
int cFileHeaderID::operator==( const cFileHeaderID& rhs ) const
|
|
{
|
|
return
|
|
( mIDLen == rhs.mIDLen ) &&
|
|
( ::memcmp( mID, rhs.mID, mIDLen * sizeof(char) ) == 0 );
|
|
}
|
|
|
|
void cFileHeaderID::Read(iSerializer* pSerializer, int32 /*version*/ ) // throw (eSerializer, eArchive)
|
|
{
|
|
int16 len;
|
|
pSerializer->ReadInt16( len );
|
|
if ( (len < 0) || (len >= cFileHeaderID::MAXBYTES ))
|
|
{
|
|
// this is invalid!
|
|
throw eSerializerInputStreamFmt( _T("File Header ID invalid") );
|
|
}
|
|
pSerializer->ReadBlob(mID, len * sizeof(char));
|
|
mIDLen = len;
|
|
}
|
|
|
|
void cFileHeaderID::Write(iSerializer* pSerializer) const // throw (eSerializer, eArchive)
|
|
{
|
|
ASSERT( mIDLen >= 0 && mIDLen < cFileHeaderID::MAXBYTES );
|
|
|
|
pSerializer->WriteInt16( mIDLen );
|
|
pSerializer->WriteBlob( mID, mIDLen * sizeof(char) );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// class cFileHeader
|
|
|
|
cFileHeader::cFileHeader()
|
|
: mVersion(0)
|
|
{
|
|
#ifdef DEBUG
|
|
mEncoding = LAST_ENCODING; // set to invalid value so we can assert on write
|
|
#else
|
|
mEncoding = NO_ENCODING;
|
|
#endif
|
|
}
|
|
|
|
cFileHeader::cFileHeader(const cFileHeader& rhs)
|
|
: iSerializable(),
|
|
mID(rhs.mID),
|
|
mVersion(rhs.mVersion),
|
|
mEncoding(rhs.mEncoding)
|
|
{
|
|
if (rhs.mBaggage.Length() > 0)
|
|
{
|
|
mBaggage.MapArchive(0, rhs.mBaggage.Length());
|
|
rhs.mBaggage.MapArchive(0, rhs.mBaggage.Length());
|
|
|
|
::memcpy(
|
|
mBaggage.GetMap(),
|
|
rhs.mBaggage.GetMap(),
|
|
static_cast<size_t>( rhs.mBaggage.Length() ) );
|
|
|
|
mBaggage.MapArchive(0, 0);
|
|
rhs.mBaggage.MapArchive(0, 0);
|
|
}
|
|
}
|
|
|
|
cFileHeader::~cFileHeader()
|
|
{
|
|
}
|
|
|
|
void cFileHeader::SetID(const cFileHeaderID& id)
|
|
{
|
|
mID = id;
|
|
}
|
|
|
|
void cFileHeader::SetVersion(uint32 v)
|
|
{
|
|
mVersion = v;
|
|
}
|
|
|
|
void cFileHeader::SetEncoding(Encoding e)
|
|
{
|
|
mEncoding = e;
|
|
}
|
|
|
|
void cFileHeader::Read(iSerializer* pSerializer, int32 /*version*/) // throw (eSerializer, eArchive)
|
|
{
|
|
int16 e;
|
|
int32 len;
|
|
int32 magicNumber;
|
|
int32 version;
|
|
|
|
cDebug d("cFileHeader::Read");
|
|
|
|
pSerializer->ReadInt32(magicNumber);
|
|
if ((unsigned int)magicNumber != FILE_HEADER_MAGIC_NUMBER)
|
|
{
|
|
d.TraceDebug("Bad magic number");
|
|
throw eSerializerInputStreamFmt(pSerializer->GetFileName() );
|
|
}
|
|
|
|
// Note this version refers to the format of this data structure in the
|
|
// file image. mVersion refers to the version of data that accompanies
|
|
// this cFileHeader, for example the database or report format.
|
|
pSerializer->ReadInt32(version);
|
|
if (version > 1)
|
|
{
|
|
// don't understand the version
|
|
d.TraceDebug("Bad version");
|
|
throw eSerializerInputStreamFmt(pSerializer->GetFileName() );
|
|
}
|
|
|
|
mID.Read(pSerializer);
|
|
|
|
pSerializer->ReadInt32(version);
|
|
mVersion = version;
|
|
|
|
pSerializer->ReadInt16(e);
|
|
mEncoding = (Encoding)e;
|
|
|
|
pSerializer->ReadInt32(len);
|
|
|
|
if (len < 0 || len > 0xffff)
|
|
throw eSerializerInputStreamFmt(pSerializer->GetFileName() );
|
|
|
|
mBaggage.MapArchive(0, len);
|
|
|
|
if (len > 0)
|
|
{
|
|
mBaggage.MapArchive(0, len);
|
|
pSerializer->ReadBlob(mBaggage.GetMap(), len);
|
|
}
|
|
|
|
mBaggage.Seek(len, cBidirArchive::BEGINNING);
|
|
mBaggage.Truncate();
|
|
mBaggage.Seek(0, cBidirArchive::BEGINNING);
|
|
}
|
|
|
|
void cFileHeader::Write(iSerializer* pSerializer) const // throw (eSerializer, eArchive)
|
|
{
|
|
#ifdef DEBUG
|
|
// check that we set some values
|
|
cFileHeaderID id;
|
|
ASSERT(mID != id);
|
|
ASSERT(mEncoding != LAST_ENCODING);
|
|
#endif
|
|
|
|
// we need to have our own versioning since we are not
|
|
// a iTypedSerializable object.
|
|
pSerializer->WriteInt32(FILE_HEADER_MAGIC_NUMBER);
|
|
|
|
// Note this version refers to the format of this data structure in the
|
|
// file image. mVersion refers to the version of data that accompanies
|
|
// this cFileHeader, for example the database or report format.
|
|
pSerializer->WriteInt32(1); // version
|
|
|
|
mID.Write(pSerializer);
|
|
|
|
pSerializer->WriteInt32(mVersion);
|
|
|
|
pSerializer->WriteInt16( static_cast<int16>(mEncoding) );
|
|
|
|
int32 len = static_cast<int32>( mBaggage.Length() );
|
|
|
|
ASSERT(len >= 0);
|
|
ASSERT(len <= 0xFFFF);
|
|
|
|
if ( len < 0 || len > 0xFFFF )
|
|
throw eSerializerOutputStreamFmt();
|
|
|
|
pSerializer->WriteInt32(len);
|
|
if (len > 0)
|
|
{
|
|
mBaggage.MapArchive(0, len);
|
|
pSerializer->WriteBlob(mBaggage.GetMap(), len);
|
|
}
|
|
}
|
|
|