--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/filemanager/bkupengine/src/MMCScBkupArchiveUtils.cpp Mon Jan 18 20:09:41 2010 +0200
@@ -0,0 +1,709 @@
+/*
+* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0""
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: MMCScBkupArchiveUtils implementation
+*
+*
+*/
+
+#include "MMCScBkupArchiveUtils.h"
+
+// System includes
+#include <s32file.h>
+#include <s32mem.h>
+
+// User includes
+#include "MMCScBkupLogger.h"
+#include "MMCScBkupDllUids.h"
+#include "MMCScBkupPhoneModelUtils.h"
+#include "CMMCScBkupArchiveFooter.h"
+#include "CMMCScBkupArchiveHeader.h"
+#include "MMMCScBkupArchiveDataInterface.h"
+#include "MMCScBkupArchiveFlags.h"
+
+// Constants
+const TInt8 KMMCScBkupArchiveFileFormatVersionMajor = 1;
+#ifdef RD_FILE_MANAGER_BACKUP
+const TInt8 KMMCScBkupArchiveFileFormatVersionMinor = 1;
+#else
+const TInt8 KMMCScBkupArchiveFileFormatVersionMinor = 0;
+#endif
+const TInt16 KMMCScBkupArchiveFileFormatVersionBuild = 1;
+const TUid KMMCScBkupArchiveFileFormatUid1 = { KMMCAppEngUID3 };
+const TUid KMMCScBkupArchiveFileFormatUid2 = { 0 };
+const TUid KMMCScBkupArchiveFileFormatUid3 = { 0x0BACCCCC }; // FIX
+
+ /**
+ * Fixed Header
+ * ============
+ *
+ * 12 bytes = 3 uids
+ * 4 bytes = 1 uid crc checksum
+ *
+ * ARCHIVE FILE FORMAT VERSION
+ * {
+ * 1 byte = version major
+ * 1 byte = version minor
+ * 2 bytes = version build
+ * }
+ *
+ * 4 bytes = size of footer in bytes - this is always the same
+ * fixed length, hence we can write the size here.
+ * The value can then be used to work from the back of the
+ * archive to the starting position of the footer (where
+ * most of the juicy info is).
+ *
+ * 4 bytes = archive flags
+ *
+ * 4 bytes = archive payload CRC (activated when RD_FILE_MANAGER_BACKUP)
+ *
+ * 4 bytes = archive category
+ *
+ * 4 bytes = archive header CRC (activated when RD_FILE_MANAGER_BACKUP)
+ *
+ * KMMCScSpareByteCount bytes = spare padding
+ *
+ * 1 byte = phone model version string length
+ * n bytes = phone model version string
+ *
+ *
+ *
+ * Note that we deliberately do not use the streaming chevrons
+ * as we then risk the problem of running the string through
+ * a unicode compressor first.
+ */
+
+
+// ========================= MEMBER FUNCTIONS ================================
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::ArchiveUidType()
+//
+//
+// ---------------------------------------------------------------------------
+void MMCScBkupArchiveUtils::ArchiveUidType(TUidType& aType)
+ {
+ aType = TUidType( KMMCScBkupArchiveFileFormatUid1,
+ KMMCScBkupArchiveFileFormatUid2,
+ KMMCScBkupArchiveFileFormatUid3 );
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::ArchiveCheckedUid()
+//
+//
+// ---------------------------------------------------------------------------
+void MMCScBkupArchiveUtils::ArchiveCheckedUid(TCheckedUid& aCheckedUids)
+ {
+ TUidType uidType;
+ ArchiveUidType( uidType );
+ aCheckedUids.Set( uidType );
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::PhoneModelFromArchiveLC()
+//
+//
+// ---------------------------------------------------------------------------
+HBufC8* MMCScBkupArchiveUtils::PhoneModelFromArchiveLC( MMMCScBkupArchiveDataInterface& aADI )
+ {
+ const TInt phoneModelOffset = OffsetOfModelInformation();
+ //
+ RReadStream stream( aADI.ADIReadStreamUncompressedLC( phoneModelOffset ) );
+ HBufC8* modelInfo = PhoneModelFromArchiveLC( stream);
+ CleanupStack::PopAndDestroy(); // stream
+ //
+ return modelInfo;
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::ReadPhoneValidityInformationL()
+//
+//
+// ---------------------------------------------------------------------------
+void MMCScBkupArchiveUtils::ReadPhoneValidityInformationL( RFs& aFsSession, const TDesC& aFileName, HBufC8*& aPhoneModelData, TBitFlags& aArchiveFlags, TVersion& aArchiveVersion )
+ {
+ __ASSERT_DEBUG( aPhoneModelData == NULL, User::Invariant() );
+ //
+ RFile64 file;
+ TInt error = file.Open( aFsSession, aFileName, EFileShareReadersOnly | EFileStream | EFileRead );
+ User::LeaveIfError( error );
+ CleanupClosePushL(file);
+
+ // First, read the archive flags
+ aArchiveFlags = ReadArchiveFlagsL( file );
+
+ // Read version
+ ReadArchiveVersionL( file, aArchiveVersion );
+
+ // Then, create a stream interface to the file
+ const TInt phoneModelOffset = OffsetOfModelInformation();
+ RFileReadStream stream( file, phoneModelOffset );
+ CleanupStack::Pop( &file );
+ CleanupClosePushL( stream ); // stream takes ownership of the file now
+ //
+ HBufC8* modelInfo = PhoneModelFromArchiveLC( stream );
+
+ // Unfortunately we have to juggle the cleanup stack
+ CleanupStack::Pop( modelInfo );
+ CleanupStack::PopAndDestroy( &stream ); // also closes the file
+
+ // Done
+ aPhoneModelData = modelInfo;
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::ArchiveRunTimeFileFormatVersion()
+//
+//
+// ---------------------------------------------------------------------------
+TVersion MMCScBkupArchiveUtils::ArchiveRunTimeFileFormatVersion()
+ {
+ return TVersion( KMMCScBkupArchiveFileFormatVersionMajor,
+ KMMCScBkupArchiveFileFormatVersionMinor,
+ KMMCScBkupArchiveFileFormatVersionBuild );
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::WriteHeaderL()
+//
+//
+// ---------------------------------------------------------------------------
+const TMMCScBkupArchiveVector& MMCScBkupArchiveUtils::WriteHeaderL( MMMCScBkupArchiveDataInterface& aADI,
+ TBitFlags aCategory )
+ {
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - START");
+ RWriteStream stream( aADI.ADIWriteStreamUncompressedLC() );
+
+ // 16 bytes = uids + *uid* checksum
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [16] write uids + checksum");
+ TCheckedUid checkedUid;
+ ArchiveCheckedUid( checkedUid );
+ const TPtrC8 pUidAndCRC( checkedUid.Des() );
+ stream.WriteL( pUidAndCRC );
+
+ // 4 bytes = file format version
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] write version");
+ const TVersion version( ArchiveRunTimeFileFormatVersion() );
+ stream.WriteInt8L( version.iMajor );
+ stream.WriteInt8L( version.iMinor );
+ stream.WriteInt16L( version.iBuild );
+
+ // 4 bytes = Footer length - starts life as length of 0, and
+ // is then written to again later on after the footer has
+ // been exteranlised.
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] write size of footer (starts life as 0)");
+ const TInt footerLength = 0;
+ stream.WriteInt32L( footerLength );
+
+ // 4 bytes = Archive flags
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] archive flags (archive starts life invalid)");
+ const TUint32 defaultArchiveFlags = DefaultArchiveFlags();
+ stream.WriteUint32L( defaultArchiveFlags );
+
+ // 4 bytes = Initial payload CRC value, this will be updated with the final
+ // CRC once the entire archive has been prepared.
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] archive payload CRC");
+ const TUint32 initialPayloadCRC = 0;
+ stream.WriteUint32L( initialPayloadCRC );
+
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] archive category");
+ stream.WriteUint32L( aCategory.iFlags );
+
+ // 4 bytes = Initial header CRC value, this will be updated with the final
+ // CRC once the entire archive has been prepared.
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] archive header CRC");
+ const TUint32 initialHeaderCRC = 0;
+ stream.WriteUint32L( initialHeaderCRC );
+
+ // KMMCScSpareByteCount = padding, for future use
+ __LOG1("MMCScBkupArchiveUtils::WriteHeaderL() - [%d] padding/spare data", KMMCScSpareByteCount);
+ for(TInt i = 0; i < KMMCScSpareByteCount/sizeof(TInt32); i++)
+ {
+ stream.WriteInt32L( 0 );
+ }
+
+ // 1 byte = Phone model version string length
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 1] phone model length");
+ HBufC8* phoneModelString = MMCScBkupPhoneModelUtils::CurrentPhoneModelLC();
+ stream.WriteInt8L( phoneModelString->Length() );
+
+ // Then the version string itself
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [??] phone model string");
+ stream.WriteL( *phoneModelString );
+
+ // Tidy up
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - committing stream...");
+ stream.CommitL();
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - destroying stream...");
+ CleanupStack::PopAndDestroy( 2 ); // phoneModelString and stream
+
+ __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - END");
+ return aADI.ADICurrentArchiveVectorInfo();
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::ReadHeaderL()
+//
+//
+// ---------------------------------------------------------------------------
+const TMMCScBkupArchiveVector& MMCScBkupArchiveUtils::ReadHeaderL( MMMCScBkupArchiveDataInterface& aADI, CMMCScBkupArchiveHeader& aHeader )
+ {
+ __LOG("MMCScBkupArchiveUtils::ReadHeaderL() - START");
+ RReadStream stream( aADI.ADIReadStreamUncompressedLC() );
+
+ // 16 bytes = uids + *uid* checksum
+ TBuf8<16> uidBuffer;
+ stream.ReadL( uidBuffer, uidBuffer.MaxLength() );
+
+ // Create a UID type objjec
+ TCheckedUid checkedUid( uidBuffer );
+ const TUidType uids( checkedUid.UidType()) ;
+ __LOG3("MMCScBkupArchiveUtils::ReadHeaderL() - uids: 0x%08x/0x%08x/0x%08x", uids[0], uids[1], uids[2] );
+ if ( uids[0] == KNullUid && uids[1] == KNullUid && uids[2] == KNullUid )
+ {
+ // Apparently, TCheckedUid sets the uids to 0 when the CRC doesn't match
+ // the value read from the file.
+ User::Leave( KErrNotSupported );
+ }
+ aHeader.SetCheckedUid( checkedUid );
+
+ // 4 bytes = file format version
+ TVersion version;
+ version.iMajor = stream.ReadInt8L();
+ version.iMinor = stream.ReadInt8L();
+ version.iBuild = stream.ReadInt16L();
+ aHeader.SetVersion( version );
+ __LOG3("MMCScBkupArchiveUtils::ReadHeaderL() - version: %3d.%3d.%6d", version.iMajor, version.iMinor, version.iBuild );
+
+ // 4 bytes = Length of footer
+ const TInt footerLength = stream.ReadInt32L();
+ aHeader.SetFooterLength( footerLength );
+ __LOG1("MMCScBkupArchiveUtils::ReadHeaderL() - footerLength: %d", footerLength);
+
+ // 4 bytes = Archive flags
+ const TUint32 archiveFlags = stream.ReadUint32L();
+ aHeader.SetArchiveFlags( archiveFlags );
+ __LOG1("MMCScBkupArchiveUtils::ReadHeaderL() - archiveFlags: %d", archiveFlags);
+
+ // 4 bytes = Archive payload CRC
+ const TUint32 payloadCRC = stream.ReadUint32L();
+ __LOG1("MMCScBkupArchiveUtils::ReadHeaderL() - archive payload CRC: %d", payloadCRC);
+
+ // 4 bytes = Archive Category
+ const TUint32 archiveCategory = stream.ReadUint32L();
+ __LOG1("MMCScBkupArchiveUtils::ReadHeaderL() - archiveCategory: %d", archiveCategory);
+
+ // 4 bytes = Archive header CRC
+ const TUint32 headerCRC = stream.ReadUint32L();
+ __LOG1("MMCScBkupArchiveUtils::ReadHeaderL() - archive header CRC: %d", headerCRC);
+
+ // KMMCScSpareByteCount of padding (spare) data. Skip for now
+ for(TInt i = 0; i < KMMCScSpareByteCount/sizeof(TInt32); i++)
+ {
+ (void) stream.ReadInt32L();
+ }
+
+ // Then the version string itself - which is handled through a separate method:
+ HBufC8* phoneModel = PhoneModelFromArchiveLC( stream );
+ aHeader.SetPhoneModelIdentifierL( *phoneModel );
+ CleanupStack::PopAndDestroy( phoneModel );
+
+ // Clean up
+ CleanupStack::PopAndDestroy(); // stream
+
+ __LOG("MMCScBkupArchiveUtils::ReadHeaderL() - END");
+ return aADI.ADICurrentArchiveVectorInfo();
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::OffsetOfModelInformation()
+//
+//
+// ---------------------------------------------------------------------------
+TInt MMCScBkupArchiveUtils::OffsetOfModelInformation()
+ {
+ return EArchiveOffsetPhoneModelStringLength;
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::PhoneModelFromArchiveLC()
+//
+//
+// ---------------------------------------------------------------------------
+HBufC8* MMCScBkupArchiveUtils::PhoneModelFromArchiveLC( RReadStream& aStream )
+ {
+ const TInt length = aStream.ReadInt8L();
+
+ // Validate against preconditions
+ const TInt maxLength = MMCScBkupPhoneModelUtils::MaximumPhoneModelIdentifierLength();
+ if ( length > maxLength || length < 0 )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ // Now try to read the model identifier
+ HBufC8* model = HBufC8::NewLC( length );
+ TPtr8 pModel( model->Des() );
+ aStream.ReadL( pModel, length );
+
+ // All done
+ return model;
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::DefaultArchiveFlags()
+//
+//
+// ---------------------------------------------------------------------------
+TUint32 MMCScBkupArchiveUtils::DefaultArchiveFlags()
+ {
+ return EMMCScBkupArchiveFlagsDefault;
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::SetArchiveContentAsValidL()
+//
+//
+// ---------------------------------------------------------------------------
+void MMCScBkupArchiveUtils::SetArchiveContentAsValidL( RFile64& aArchive )
+ {
+ TInt error = KErrNone;
+
+ // Calculate the offset to the archive flags:
+ const TUint archiveFlagsFileOffset = EArchiveOffsetArchiveFlags;
+
+ // Flags are four bytes. Read the existing raw flag data
+ TBuf8< KMMCScArchiveFlagsByteCount > flagData;
+ error = aArchive.Read( static_cast<TInt64>( archiveFlagsFileOffset ), flagData );
+ User::LeaveIfError( error );
+
+ // Interpret the flag data as real flags
+ RDesReadStream readStream( flagData );
+ CleanupClosePushL( readStream );
+ TUint32 archiveFlags = readStream.ReadUint32L();
+ CleanupStack::PopAndDestroy( &readStream );
+
+ // Twiddle the "archive is complete/valid" bits
+ archiveFlags |= EMMCScBkupArchiveFlagsContentValid;
+
+ // Write the flags back out the descriptor
+ flagData.Zero();
+ RDesWriteStream writeStream( flagData );
+ CleanupClosePushL( writeStream );
+ writeStream.WriteUint32L( archiveFlags );
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy( &writeStream );
+
+ // Then write them to the file itself
+ error = aArchive.Write( static_cast<TInt64>( archiveFlagsFileOffset ), flagData );
+ User::LeaveIfError( error );
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::SetFooterLengthL()
+//
+//
+// ---------------------------------------------------------------------------
+void MMCScBkupArchiveUtils::SetFooterLengthL( RFile64& aArchive, TInt aLength )
+ {
+ TInt error = KErrNone;
+
+ // Calculate the offset to the footer length:
+ const TUint archiveFooterLengthOffset = EArchiveOffsetFooterLength;
+
+ // Prepare externalized representation of length
+ TBuf8< KMMCScArchiveFooterLengthByteCount > footerLengthData;
+ RDesWriteStream writeStream( footerLengthData );
+ CleanupClosePushL( writeStream );
+ writeStream.WriteInt32L( aLength );
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy( &writeStream );
+
+ // Then write them to the file itself
+ error = aArchive.Write( static_cast<TInt64>( archiveFooterLengthOffset ), footerLengthData );
+ User::LeaveIfError( error );
+ }
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::ReadBkUpCategoryInformationL()
+//
+//
+// ---------------------------------------------------------------------------
+TBitFlags MMCScBkupArchiveUtils::ReadBkUpCategoryInformationL( RFs& aFsSession, const TDesC& aFileName )
+ {
+ RFile64 file;
+ TInt error = file.Open( aFsSession, aFileName, EFileShareReadersOnly | EFileStream | EFileRead );
+ User::LeaveIfError( error );
+ CleanupClosePushL(file);
+
+ // Then, create a stream interface to the file
+ RFileReadStream stream( file, EArchiveOffsetArchiveCategory );
+ CleanupStack::Pop( &file );
+ CleanupClosePushL( stream ); // stream takes ownership of the file now
+ //
+ TUint category = stream.ReadUint32L();
+
+ CleanupStack::PopAndDestroy( &stream ); // also closes the file
+
+ TBitFlags ret;
+ ret.SetValue( category );
+
+ return ret;
+ }
+
+
+#ifdef RD_FILE_MANAGER_BACKUP
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::SetArchiveCrcsL()
+//
+//
+// ---------------------------------------------------------------------------
+void MMCScBkupArchiveUtils::SetArchiveCrcsL( RFile64& aArchive, TUint32 aCrc )
+ {
+ TInt error = KErrNone;
+
+ // Payload crc
+ SetArchiveCrcL( aArchive, aCrc, EArchiveOffsetArchivePayloadCRC );
+
+ // Calculate and write header crc also to the file
+ TBuf8< KMMCScArchivePhoneModelStringLength > length;
+ TUint32 modelLength;
+ TUint32 headerCrc = 0;
+
+ error = aArchive.Read( static_cast<TInt64>( EArchiveOffsetPhoneModelStringLength ), length );
+ User::LeaveIfError(error);
+ RDesReadStream readStream( length );
+ CleanupClosePushL( readStream );
+ modelLength = readStream.ReadUint8L();
+ CleanupStack::PopAndDestroy( &readStream );
+
+ CalculateCrcFromArchive( headerCrc, aArchive, 0, EArchiveOffsetArchiveHeaderCRC);
+ CalculateCrcFromArchive( headerCrc, aArchive, EArchiveOffsetArchiveHeaderCRC + KMMCScArchiveCrcByteCount,
+ KMMCScSpareByteCount + KMMCScArchivePhoneModelStringLength + modelLength);
+ SetArchiveCrcL( aArchive, headerCrc, EArchiveOffsetArchiveHeaderCRC );
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::ValidateArchiveCrcsL()
+//
+//
+// ---------------------------------------------------------------------------
+TBool MMCScBkupArchiveUtils::ValidateArchiveCrcsL( RFs& aFsSession, const TDesC& aFileName )
+ {
+ TBool validCrc = EFalse;
+
+ RFile64 file;
+ TInt64 size;
+
+ TInt error = file.Open( aFsSession, aFileName, EFileShareReadersOnly | EFileRead );
+
+ if ( error == KErrNone && file.Size(size) == KErrNone)
+ {
+ TBuf8< KMMCScArchiveFlagsByteCount > headerCrc;
+ TBuf8< KMMCScArchiveFlagsByteCount > payloadCrc;
+ TBuf8< KMMCScArchivePhoneModelStringLength > length;
+ TUint32 archivedHeaderCrc, calculatedHeaderCrc;
+ TUint32 archivedPayloadCrc, calculatedPayloadCrc;
+ TUint32 modelLength;
+
+ // Read crcs from header
+ error = file.Read( static_cast<TInt64>( EArchiveOffsetArchiveHeaderCRC ), headerCrc );
+ User::LeaveIfError(error);
+ error = file.Read( static_cast<TInt64>( EArchiveOffsetArchivePayloadCRC ), payloadCrc );
+ User::LeaveIfError(error);
+ error = file.Read( static_cast<TInt64>( EArchiveOffsetPhoneModelStringLength ), length );
+ User::LeaveIfError(error);
+ CleanupClosePushL( file );
+
+ RDesReadStream readStream( headerCrc );
+ CleanupClosePushL( readStream );
+ archivedHeaderCrc = readStream.ReadUint32L();
+ readStream.Close();
+ readStream.Open(payloadCrc);
+ archivedPayloadCrc = readStream.ReadUint32L();
+ readStream.Close();
+ readStream.Open(length);
+ modelLength = readStream.ReadUint8L();
+ CleanupStack::PopAndDestroy( &readStream );
+
+ // Calculate crc from header in two parts
+ calculatedHeaderCrc = 0;
+ CalculateCrcFromArchive( calculatedHeaderCrc, file, 0, EArchiveOffsetArchiveHeaderCRC);
+ CalculateCrcFromArchive( calculatedHeaderCrc, file, EArchiveOffsetArchiveHeaderCRC + KMMCScArchiveCrcByteCount,
+ KMMCScSpareByteCount + KMMCScArchivePhoneModelStringLength + modelLength);
+
+ // Calculate crc from payload and footer
+ TInt payloadSize = size - (EArchiveOffsetPhoneModelString + modelLength);
+ calculatedPayloadCrc = 0;
+ CalculateCrcFromArchive( calculatedPayloadCrc, file, EArchiveOffsetPhoneModelString + modelLength, payloadSize);
+
+ if(archivedPayloadCrc == calculatedPayloadCrc && archivedHeaderCrc == calculatedHeaderCrc)
+ {
+ validCrc = ETrue;
+ }
+ else
+ {
+ __LOG4("MMCScBkupArchiveUtils::ValidateArchiveCrcsL() - crc mismatch: %u vs. %u - %u vs. %u",
+ archivedPayloadCrc, calculatedPayloadCrc, archivedHeaderCrc, calculatedHeaderCrc);
+ }
+
+ CleanupStack::PopAndDestroy( &file );
+ }
+
+ return validCrc;
+ }
+#endif // RD_FILE_MANAGER_BACKUP
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::ReadArchiveFlagsL()
+//
+//
+// ---------------------------------------------------------------------------
+TBitFlags MMCScBkupArchiveUtils::ReadArchiveFlagsL( RFile64& aArchive )
+ {
+ TInt error = KErrNone;
+
+ // Calculate the offset to the archive flags:
+ const TUint archiveFlagsFileOffset = EArchiveOffsetArchiveFlags;
+
+ // Flags are four bytes. Read the existing raw flag data
+ TBuf8< KMMCScArchiveFlagsByteCount > flagData;
+ error = aArchive.Read( static_cast<TInt64>( archiveFlagsFileOffset ), flagData );
+ User::LeaveIfError( error );
+
+ // Interpret the flag data as real flags
+ RDesReadStream readStream( flagData );
+ CleanupClosePushL( readStream );
+ TUint32 archiveFlags = readStream.ReadUint32L();
+ CleanupStack::PopAndDestroy( &readStream );
+
+ // Done
+ TBitFlags ret;
+ ret.SetValue( archiveFlags );
+ return ret;
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::ReadArchiveVersionL()
+//
+//
+// ---------------------------------------------------------------------------
+void MMCScBkupArchiveUtils::ReadArchiveVersionL( RFile64& aArchive, TVersion& aVersion )
+ {
+ TInt error = KErrNone;
+
+ // Calculate the offset to the archive flags:
+ const TUint archiveVersionFileOffset = EArchiveOffsetFileFormatVersion;
+
+ // Flags are four bytes. Read the existing raw flag data
+ TBuf8< KMMCScArchiveVersionByteCount > versionData;
+ error = aArchive.Read( static_cast<TInt64>( archiveVersionFileOffset ), versionData );
+ User::LeaveIfError( error );
+
+ // Interpret the flag data as real flags
+ RDesReadStream readStream( versionData );
+ CleanupClosePushL( readStream );
+ aVersion.iMajor = readStream.ReadInt8L();
+ aVersion.iMinor = readStream.ReadInt8L();
+ aVersion.iBuild = readStream.ReadInt16L();
+ CleanupStack::PopAndDestroy( &readStream );
+ }
+
+
+#ifdef RD_FILE_MANAGER_BACKUP
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::SetArchiveCrcL()
+//
+//
+// ---------------------------------------------------------------------------
+void MMCScBkupArchiveUtils::SetArchiveCrcL( RFile64& aArchive, TUint32 aCrc, TUint aOffset )
+ {
+ TInt error = KErrNone;
+
+ // Prepare externalized representation of crc
+ TBuf8< KMMCScArchiveCrcByteCount > crcData;
+ RDesWriteStream writeStream( crcData );
+ CleanupClosePushL( writeStream );
+ writeStream.WriteInt32L( aCrc );
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy( &writeStream );
+
+ // Then write crc to the file itself
+ error = aArchive.Write( static_cast<TInt64>( aOffset ), crcData );
+ User::LeaveIfError( error );
+ }
+
+
+// ---------------------------------------------------------------------------
+// MMCScBkupArchiveUtils::CalculateCrcFromArchive()
+//
+//
+// ---------------------------------------------------------------------------
+void MMCScBkupArchiveUtils::CalculateCrcFromArchive( TUint32& aCrc, RFile64& aArchive, TUint32 aOffset, TUint32 aLength )
+ {
+ const TInt KBigBufSize=0x10000;
+ const TInt KMediumBufSize=0x8000;
+ const TInt KSmallBufSize=0x1000;
+
+ // Allocate as large buffer as possible for crc validation, because
+ // need to read file content in chunks for crc calculation.
+ HBufC8* bufPtr = HBufC8::New(KBigBufSize);
+
+ if ( bufPtr == NULL )
+ bufPtr = HBufC8::New(KMediumBufSize);
+ if ( bufPtr == NULL )
+ bufPtr = HBufC8::New(KSmallBufSize);
+
+ if ( bufPtr != NULL)
+ {
+ TPtr8 copyBuf = bufPtr->Des();
+ TInt64 pos = aOffset;
+ TInt size = aLength;
+
+ // Loop through archive file skipping archive crc
+ while(size)
+ {
+ TInt s;
+
+ s = Min( size, copyBuf.MaxSize() );
+
+ TInt error = aArchive.Read( pos, copyBuf, s );
+
+ if ( error == KErrNone && copyBuf.Length() != s )
+ break;
+
+ pos += s;
+ size -= s;
+ Mem::Crc32(aCrc, copyBuf.Ptr(), copyBuf.Length());
+ }
+
+ delete bufPtr;
+ }
+ }
+#endif // RD_FILE_MANAGER_BACKUP
+