filemanager/bkupengine/src/MMCScBkupArchiveUtils.cpp
changeset 0 6a9f87576119
equal deleted inserted replaced
-1:000000000000 0:6a9f87576119
       
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0""
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: MMCScBkupArchiveUtils implementation
       
    15 *
       
    16 *
       
    17 */
       
    18 
       
    19 #include "MMCScBkupArchiveUtils.h"
       
    20 
       
    21 // System includes
       
    22 #include <s32file.h>
       
    23 #include <s32mem.h>
       
    24 
       
    25 // User includes
       
    26 #include "MMCScBkupLogger.h"
       
    27 #include "MMCScBkupDllUids.h"
       
    28 #include "MMCScBkupPhoneModelUtils.h"
       
    29 #include "CMMCScBkupArchiveFooter.h"
       
    30 #include "CMMCScBkupArchiveHeader.h"
       
    31 #include "MMMCScBkupArchiveDataInterface.h"
       
    32 #include "MMCScBkupArchiveFlags.h"
       
    33 
       
    34 // Constants
       
    35 const TInt8 KMMCScBkupArchiveFileFormatVersionMajor = 1;
       
    36 #ifdef RD_FILE_MANAGER_BACKUP
       
    37 const TInt8 KMMCScBkupArchiveFileFormatVersionMinor = 1;
       
    38 #else
       
    39 const TInt8 KMMCScBkupArchiveFileFormatVersionMinor = 0;
       
    40 #endif
       
    41 const TInt16 KMMCScBkupArchiveFileFormatVersionBuild = 1;
       
    42 const TUid KMMCScBkupArchiveFileFormatUid1 = { KMMCAppEngUID3 };
       
    43 const TUid KMMCScBkupArchiveFileFormatUid2 = { 0 };
       
    44 const TUid KMMCScBkupArchiveFileFormatUid3 = { 0x0BACCCCC }; // FIX
       
    45 
       
    46     /**
       
    47      * Fixed Header
       
    48      * ============
       
    49      * 
       
    50      * 12 bytes = 3 uids
       
    51      *  4 bytes = 1 uid crc checksum
       
    52      *
       
    53      * ARCHIVE FILE FORMAT VERSION
       
    54      * {
       
    55      *    1 byte  = version major
       
    56      *    1 byte  = version minor
       
    57      *    2 bytes = version build
       
    58      * }
       
    59      * 
       
    60      * 4 bytes = size of footer in bytes - this is always the same
       
    61      *           fixed length, hence we can write the size here. 
       
    62      *           The value can then be used to work from the back of the
       
    63      *           archive to the starting position of the footer (where
       
    64      *           most of the juicy info is).
       
    65      *
       
    66      *  4 bytes = archive flags
       
    67      *
       
    68      *  4 bytes = archive payload CRC (activated when RD_FILE_MANAGER_BACKUP)
       
    69      * 
       
    70      *  4 bytes = archive category
       
    71      * 
       
    72      *  4 bytes = archive header CRC (activated when RD_FILE_MANAGER_BACKUP)
       
    73      * 
       
    74      * KMMCScSpareByteCount bytes = spare padding
       
    75      *
       
    76      *  1 byte = phone model version string length
       
    77      *  n bytes = phone model version string
       
    78      *
       
    79      *
       
    80      *
       
    81      * Note that we deliberately do not use the streaming chevrons
       
    82      * as we then risk the problem of running the string through
       
    83      * a unicode compressor first.
       
    84      */
       
    85 
       
    86 
       
    87 // ========================= MEMBER FUNCTIONS ================================
       
    88 
       
    89 // ---------------------------------------------------------------------------
       
    90 // MMCScBkupArchiveUtils::ArchiveUidType()
       
    91 // 
       
    92 // 
       
    93 // ---------------------------------------------------------------------------
       
    94 void MMCScBkupArchiveUtils::ArchiveUidType(TUidType& aType)
       
    95     {
       
    96     aType = TUidType( KMMCScBkupArchiveFileFormatUid1,
       
    97                       KMMCScBkupArchiveFileFormatUid2,
       
    98                       KMMCScBkupArchiveFileFormatUid3 );
       
    99     }
       
   100 
       
   101 
       
   102 // ---------------------------------------------------------------------------
       
   103 // MMCScBkupArchiveUtils::ArchiveCheckedUid()
       
   104 // 
       
   105 // 
       
   106 // ---------------------------------------------------------------------------
       
   107 void MMCScBkupArchiveUtils::ArchiveCheckedUid(TCheckedUid& aCheckedUids)
       
   108     {
       
   109     TUidType uidType;
       
   110     ArchiveUidType( uidType );
       
   111     aCheckedUids.Set( uidType );
       
   112     }
       
   113 
       
   114 
       
   115 // ---------------------------------------------------------------------------
       
   116 // MMCScBkupArchiveUtils::PhoneModelFromArchiveLC()
       
   117 // 
       
   118 // 
       
   119 // ---------------------------------------------------------------------------
       
   120 HBufC8* MMCScBkupArchiveUtils::PhoneModelFromArchiveLC( MMMCScBkupArchiveDataInterface& aADI )
       
   121     {
       
   122     const TInt phoneModelOffset = OffsetOfModelInformation();
       
   123     //
       
   124     RReadStream stream( aADI.ADIReadStreamUncompressedLC( phoneModelOffset ) );
       
   125     HBufC8* modelInfo = PhoneModelFromArchiveLC( stream);
       
   126     CleanupStack::PopAndDestroy(); // stream
       
   127     //
       
   128     return modelInfo;  
       
   129     }
       
   130 
       
   131 
       
   132 // ---------------------------------------------------------------------------
       
   133 // MMCScBkupArchiveUtils::ReadPhoneValidityInformationL()
       
   134 // 
       
   135 // 
       
   136 // ---------------------------------------------------------------------------
       
   137 void MMCScBkupArchiveUtils::ReadPhoneValidityInformationL( RFs& aFsSession, const TDesC& aFileName, HBufC8*& aPhoneModelData, TBitFlags& aArchiveFlags, TVersion& aArchiveVersion )
       
   138     {
       
   139     __ASSERT_DEBUG( aPhoneModelData == NULL, User::Invariant() );
       
   140     //
       
   141     RFile64 file;
       
   142     TInt error = file.Open( aFsSession, aFileName, EFileShareReadersOnly | EFileStream | EFileRead );
       
   143     User::LeaveIfError( error );
       
   144     CleanupClosePushL(file);
       
   145 
       
   146     // First, read the archive flags
       
   147     aArchiveFlags = ReadArchiveFlagsL( file );
       
   148     
       
   149     // Read version
       
   150     ReadArchiveVersionL( file, aArchiveVersion );
       
   151     
       
   152     // Then, create a stream interface to the file
       
   153     const TInt phoneModelOffset = OffsetOfModelInformation();
       
   154     RFileReadStream stream( file, phoneModelOffset );
       
   155     CleanupStack::Pop( &file );
       
   156     CleanupClosePushL( stream ); // stream takes ownership of the file now
       
   157     //
       
   158     HBufC8* modelInfo = PhoneModelFromArchiveLC( stream );
       
   159     
       
   160     // Unfortunately we have to juggle the cleanup stack
       
   161     CleanupStack::Pop( modelInfo );
       
   162     CleanupStack::PopAndDestroy( &stream ); // also closes the file
       
   163     
       
   164     // Done
       
   165     aPhoneModelData = modelInfo;
       
   166     }
       
   167 
       
   168 
       
   169 // ---------------------------------------------------------------------------
       
   170 // MMCScBkupArchiveUtils::ArchiveRunTimeFileFormatVersion()
       
   171 // 
       
   172 // 
       
   173 // ---------------------------------------------------------------------------
       
   174 TVersion MMCScBkupArchiveUtils::ArchiveRunTimeFileFormatVersion()
       
   175     {
       
   176     return TVersion( KMMCScBkupArchiveFileFormatVersionMajor, 
       
   177                      KMMCScBkupArchiveFileFormatVersionMinor, 
       
   178                      KMMCScBkupArchiveFileFormatVersionBuild );
       
   179     }
       
   180 
       
   181 
       
   182 // ---------------------------------------------------------------------------
       
   183 // MMCScBkupArchiveUtils::WriteHeaderL()
       
   184 // 
       
   185 // 
       
   186 // ---------------------------------------------------------------------------
       
   187 const TMMCScBkupArchiveVector& MMCScBkupArchiveUtils::WriteHeaderL( MMMCScBkupArchiveDataInterface& aADI, 
       
   188     TBitFlags aCategory )
       
   189     {
       
   190     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - START");
       
   191     RWriteStream stream( aADI.ADIWriteStreamUncompressedLC() );
       
   192 
       
   193     // 16 bytes = uids + *uid* checksum
       
   194     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [16] write uids + checksum");
       
   195     TCheckedUid checkedUid;
       
   196     ArchiveCheckedUid( checkedUid );
       
   197     const TPtrC8 pUidAndCRC( checkedUid.Des() );
       
   198     stream.WriteL( pUidAndCRC );
       
   199     
       
   200     // 4 bytes = file format version
       
   201     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] write version");
       
   202     const TVersion version( ArchiveRunTimeFileFormatVersion() );
       
   203     stream.WriteInt8L( version.iMajor );
       
   204     stream.WriteInt8L( version.iMinor );
       
   205     stream.WriteInt16L( version.iBuild );
       
   206 
       
   207     // 4 bytes = Footer length - starts life as length of 0, and
       
   208     // is then written to again later on after the footer has
       
   209     // been exteranlised.
       
   210     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] write size of footer (starts life as 0)");
       
   211     const TInt footerLength = 0;
       
   212     stream.WriteInt32L( footerLength );
       
   213 
       
   214     // 4 bytes = Archive flags
       
   215     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] archive flags (archive starts life invalid)");
       
   216     const TUint32 defaultArchiveFlags = DefaultArchiveFlags();
       
   217     stream.WriteUint32L( defaultArchiveFlags );
       
   218 
       
   219     // 4 bytes = Initial payload CRC value, this will be updated with the final 
       
   220     // CRC once the entire archive has been prepared.
       
   221     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] archive payload CRC");
       
   222     const TUint32 initialPayloadCRC = 0;
       
   223     stream.WriteUint32L( initialPayloadCRC );
       
   224     
       
   225     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] archive category");
       
   226     stream.WriteUint32L( aCategory.iFlags );
       
   227     
       
   228     // 4 bytes = Initial header CRC value, this will be updated with the final 
       
   229     // CRC once the entire archive has been prepared.
       
   230     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 4] archive header CRC");
       
   231     const TUint32 initialHeaderCRC = 0;
       
   232     stream.WriteUint32L( initialHeaderCRC );
       
   233     
       
   234     // KMMCScSpareByteCount = padding, for future use
       
   235     __LOG1("MMCScBkupArchiveUtils::WriteHeaderL() - [%d] padding/spare data", KMMCScSpareByteCount);
       
   236     for(TInt i = 0; i < KMMCScSpareByteCount/sizeof(TInt32); i++)
       
   237         {
       
   238         stream.WriteInt32L( 0 );
       
   239         }
       
   240 
       
   241     // 1 byte = Phone model version string length
       
   242     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [ 1] phone model length");
       
   243     HBufC8* phoneModelString = MMCScBkupPhoneModelUtils::CurrentPhoneModelLC();
       
   244     stream.WriteInt8L( phoneModelString->Length() );
       
   245 
       
   246     // Then the version string itself
       
   247     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - [??] phone model string");
       
   248     stream.WriteL( *phoneModelString );
       
   249 
       
   250     // Tidy up
       
   251     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - committing stream...");
       
   252     stream.CommitL();
       
   253     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - destroying stream...");
       
   254     CleanupStack::PopAndDestroy( 2 ); // phoneModelString and stream
       
   255 
       
   256     __LOG("MMCScBkupArchiveUtils::WriteHeaderL() - END");
       
   257     return aADI.ADICurrentArchiveVectorInfo();
       
   258     }
       
   259 
       
   260 
       
   261 // ---------------------------------------------------------------------------
       
   262 // MMCScBkupArchiveUtils::ReadHeaderL()
       
   263 // 
       
   264 // 
       
   265 // ---------------------------------------------------------------------------
       
   266 const TMMCScBkupArchiveVector& MMCScBkupArchiveUtils::ReadHeaderL( MMMCScBkupArchiveDataInterface& aADI, CMMCScBkupArchiveHeader& aHeader )
       
   267     {
       
   268     __LOG("MMCScBkupArchiveUtils::ReadHeaderL() - START");
       
   269     RReadStream stream( aADI.ADIReadStreamUncompressedLC() );
       
   270 
       
   271     // 16 bytes = uids + *uid* checksum
       
   272     TBuf8<16> uidBuffer;
       
   273     stream.ReadL( uidBuffer, uidBuffer.MaxLength() );
       
   274 
       
   275     // Create a UID type objjec
       
   276     TCheckedUid checkedUid( uidBuffer );
       
   277     const TUidType uids( checkedUid.UidType()) ;
       
   278     __LOG3("MMCScBkupArchiveUtils::ReadHeaderL() - uids: 0x%08x/0x%08x/0x%08x", uids[0], uids[1], uids[2] );
       
   279     if  ( uids[0] == KNullUid && uids[1] == KNullUid && uids[2] == KNullUid )
       
   280         {
       
   281         // Apparently, TCheckedUid sets the uids to 0 when the CRC doesn't match
       
   282         // the value read from the file.
       
   283         User::Leave( KErrNotSupported );
       
   284         }
       
   285     aHeader.SetCheckedUid( checkedUid );
       
   286     
       
   287     // 4 bytes = file format version
       
   288     TVersion version;
       
   289     version.iMajor = stream.ReadInt8L();
       
   290     version.iMinor = stream.ReadInt8L();
       
   291     version.iBuild = stream.ReadInt16L();
       
   292     aHeader.SetVersion( version );
       
   293     __LOG3("MMCScBkupArchiveUtils::ReadHeaderL() - version: %3d.%3d.%6d", version.iMajor, version.iMinor, version.iBuild );
       
   294 
       
   295     // 4 bytes = Length of footer
       
   296     const TInt footerLength = stream.ReadInt32L();
       
   297     aHeader.SetFooterLength( footerLength );
       
   298     __LOG1("MMCScBkupArchiveUtils::ReadHeaderL() - footerLength: %d", footerLength);
       
   299 
       
   300     // 4 bytes = Archive flags
       
   301     const TUint32 archiveFlags = stream.ReadUint32L();
       
   302     aHeader.SetArchiveFlags( archiveFlags );
       
   303     __LOG1("MMCScBkupArchiveUtils::ReadHeaderL() - archiveFlags: %d", archiveFlags);
       
   304 
       
   305     // 4 bytes = Archive payload CRC
       
   306     const TUint32 payloadCRC = stream.ReadUint32L();
       
   307     __LOG1("MMCScBkupArchiveUtils::ReadHeaderL() - archive payload CRC: %d", payloadCRC);
       
   308 
       
   309     // 4 bytes = Archive Category
       
   310     const TUint32 archiveCategory = stream.ReadUint32L();
       
   311     __LOG1("MMCScBkupArchiveUtils::ReadHeaderL() - archiveCategory: %d", archiveCategory);
       
   312 
       
   313     // 4 bytes = Archive header CRC
       
   314     const TUint32 headerCRC = stream.ReadUint32L();
       
   315     __LOG1("MMCScBkupArchiveUtils::ReadHeaderL() - archive header CRC: %d", headerCRC);
       
   316 
       
   317     // KMMCScSpareByteCount of padding (spare) data. Skip for now
       
   318     for(TInt i = 0; i < KMMCScSpareByteCount/sizeof(TInt32); i++)
       
   319         {
       
   320         (void) stream.ReadInt32L();
       
   321         }
       
   322 
       
   323     // Then the version string itself - which is handled through a separate method:
       
   324     HBufC8* phoneModel = PhoneModelFromArchiveLC( stream );
       
   325     aHeader.SetPhoneModelIdentifierL( *phoneModel );
       
   326     CleanupStack::PopAndDestroy( phoneModel );
       
   327 
       
   328     // Clean up
       
   329     CleanupStack::PopAndDestroy(); // stream
       
   330 
       
   331     __LOG("MMCScBkupArchiveUtils::ReadHeaderL() - END");
       
   332     return aADI.ADICurrentArchiveVectorInfo();
       
   333     }
       
   334 
       
   335 
       
   336 // ---------------------------------------------------------------------------
       
   337 // MMCScBkupArchiveUtils::OffsetOfModelInformation()
       
   338 // 
       
   339 // 
       
   340 // ---------------------------------------------------------------------------
       
   341 TInt MMCScBkupArchiveUtils::OffsetOfModelInformation()
       
   342     {
       
   343     return EArchiveOffsetPhoneModelStringLength;
       
   344     }
       
   345 
       
   346 
       
   347 // ---------------------------------------------------------------------------
       
   348 // MMCScBkupArchiveUtils::PhoneModelFromArchiveLC()
       
   349 // 
       
   350 // 
       
   351 // ---------------------------------------------------------------------------
       
   352 HBufC8* MMCScBkupArchiveUtils::PhoneModelFromArchiveLC( RReadStream& aStream )
       
   353     {
       
   354     const TInt length = aStream.ReadInt8L();
       
   355     
       
   356     // Validate against preconditions
       
   357     const TInt maxLength = MMCScBkupPhoneModelUtils::MaximumPhoneModelIdentifierLength();
       
   358     if  ( length > maxLength || length < 0 )
       
   359         {
       
   360         User::Leave( KErrCorrupt );
       
   361         }
       
   362 
       
   363     // Now try to read the model identifier
       
   364     HBufC8* model = HBufC8::NewLC( length );
       
   365     TPtr8 pModel( model->Des() );
       
   366     aStream.ReadL( pModel, length );
       
   367 
       
   368     // All done
       
   369     return model;
       
   370     }
       
   371 
       
   372 
       
   373 // ---------------------------------------------------------------------------
       
   374 // MMCScBkupArchiveUtils::DefaultArchiveFlags()
       
   375 // 
       
   376 // 
       
   377 // ---------------------------------------------------------------------------
       
   378 TUint32 MMCScBkupArchiveUtils::DefaultArchiveFlags()
       
   379     {
       
   380     return EMMCScBkupArchiveFlagsDefault;
       
   381     }
       
   382 
       
   383 
       
   384 // ---------------------------------------------------------------------------
       
   385 // MMCScBkupArchiveUtils::SetArchiveContentAsValidL()
       
   386 // 
       
   387 // 
       
   388 // ---------------------------------------------------------------------------
       
   389 void MMCScBkupArchiveUtils::SetArchiveContentAsValidL( RFile64& aArchive )
       
   390     {
       
   391     TInt error = KErrNone;
       
   392     
       
   393     // Calculate the offset to the archive flags:
       
   394     const TUint archiveFlagsFileOffset = EArchiveOffsetArchiveFlags;
       
   395     
       
   396     // Flags are four bytes. Read the existing raw flag data
       
   397     TBuf8< KMMCScArchiveFlagsByteCount > flagData;
       
   398     error = aArchive.Read( static_cast<TInt64>( archiveFlagsFileOffset ), flagData );
       
   399     User::LeaveIfError( error );
       
   400     
       
   401     // Interpret the flag data as real flags
       
   402     RDesReadStream readStream( flagData );
       
   403     CleanupClosePushL( readStream );
       
   404     TUint32 archiveFlags = readStream.ReadUint32L();
       
   405     CleanupStack::PopAndDestroy( &readStream );
       
   406     
       
   407     // Twiddle the "archive is complete/valid" bits
       
   408     archiveFlags |= EMMCScBkupArchiveFlagsContentValid;
       
   409     
       
   410     // Write the flags back out the descriptor
       
   411     flagData.Zero();
       
   412     RDesWriteStream writeStream( flagData );
       
   413     CleanupClosePushL( writeStream );
       
   414     writeStream.WriteUint32L( archiveFlags );
       
   415     writeStream.CommitL();
       
   416     CleanupStack::PopAndDestroy( &writeStream );
       
   417     
       
   418     // Then write them to the file itself
       
   419     error = aArchive.Write( static_cast<TInt64>( archiveFlagsFileOffset ), flagData );
       
   420     User::LeaveIfError( error );
       
   421     }
       
   422 
       
   423 
       
   424 // ---------------------------------------------------------------------------
       
   425 // MMCScBkupArchiveUtils::SetFooterLengthL()
       
   426 // 
       
   427 // 
       
   428 // ---------------------------------------------------------------------------
       
   429 void MMCScBkupArchiveUtils::SetFooterLengthL( RFile64& aArchive, TInt aLength )
       
   430     {
       
   431     TInt error = KErrNone;
       
   432     
       
   433     // Calculate the offset to the footer length:
       
   434     const TUint archiveFooterLengthOffset = EArchiveOffsetFooterLength;
       
   435     
       
   436     // Prepare externalized representation of length
       
   437     TBuf8< KMMCScArchiveFooterLengthByteCount > footerLengthData;
       
   438     RDesWriteStream writeStream( footerLengthData );
       
   439     CleanupClosePushL( writeStream );
       
   440     writeStream.WriteInt32L( aLength );
       
   441     writeStream.CommitL();
       
   442     CleanupStack::PopAndDestroy( &writeStream );
       
   443     
       
   444     // Then write them to the file itself
       
   445     error = aArchive.Write( static_cast<TInt64>( archiveFooterLengthOffset ), footerLengthData );
       
   446     User::LeaveIfError( error );
       
   447     }
       
   448 
       
   449 // ---------------------------------------------------------------------------
       
   450 // MMCScBkupArchiveUtils::ReadBkUpCategoryInformationL()
       
   451 // 
       
   452 // 
       
   453 // ---------------------------------------------------------------------------
       
   454 TBitFlags MMCScBkupArchiveUtils::ReadBkUpCategoryInformationL( RFs& aFsSession, const TDesC& aFileName )
       
   455     {
       
   456     RFile64 file;
       
   457     TInt error = file.Open( aFsSession, aFileName, EFileShareReadersOnly | EFileStream | EFileRead );
       
   458     User::LeaveIfError( error );
       
   459     CleanupClosePushL(file);
       
   460 
       
   461     // Then, create a stream interface to the file
       
   462     RFileReadStream stream( file, EArchiveOffsetArchiveCategory );
       
   463     CleanupStack::Pop( &file );
       
   464     CleanupClosePushL( stream ); // stream takes ownership of the file now
       
   465     //
       
   466     TUint category = stream.ReadUint32L();
       
   467 
       
   468     CleanupStack::PopAndDestroy( &stream ); // also closes the file
       
   469     
       
   470     TBitFlags ret;
       
   471     ret.SetValue( category );
       
   472     
       
   473     return ret;
       
   474     }
       
   475 
       
   476 
       
   477 #ifdef RD_FILE_MANAGER_BACKUP
       
   478 // ---------------------------------------------------------------------------
       
   479 // MMCScBkupArchiveUtils::SetArchiveCrcsL()
       
   480 // 
       
   481 // 
       
   482 // ---------------------------------------------------------------------------
       
   483 void MMCScBkupArchiveUtils::SetArchiveCrcsL( RFile64& aArchive, TUint32 aCrc )
       
   484     {
       
   485     TInt error = KErrNone;
       
   486     
       
   487     // Payload crc 
       
   488     SetArchiveCrcL( aArchive, aCrc, EArchiveOffsetArchivePayloadCRC );
       
   489     
       
   490     // Calculate and write header crc also to the file
       
   491     TBuf8< KMMCScArchivePhoneModelStringLength > length;
       
   492     TUint32 modelLength;
       
   493     TUint32 headerCrc = 0;
       
   494     
       
   495     error = aArchive.Read( static_cast<TInt64>( EArchiveOffsetPhoneModelStringLength ), length );
       
   496     User::LeaveIfError(error);
       
   497     RDesReadStream readStream( length );
       
   498     CleanupClosePushL( readStream );
       
   499     modelLength = readStream.ReadUint8L();
       
   500     CleanupStack::PopAndDestroy( &readStream );
       
   501     
       
   502 	CalculateCrcFromArchive( headerCrc, aArchive, 0, EArchiveOffsetArchiveHeaderCRC);
       
   503 	CalculateCrcFromArchive( headerCrc, aArchive, EArchiveOffsetArchiveHeaderCRC + KMMCScArchiveCrcByteCount, 
       
   504 	     KMMCScSpareByteCount + KMMCScArchivePhoneModelStringLength + modelLength);
       
   505     SetArchiveCrcL( aArchive, headerCrc, EArchiveOffsetArchiveHeaderCRC );
       
   506     }
       
   507 
       
   508 
       
   509 // ---------------------------------------------------------------------------
       
   510 // MMCScBkupArchiveUtils::ValidateArchiveCrcsL()
       
   511 // 
       
   512 // 
       
   513 // ---------------------------------------------------------------------------
       
   514 TBool MMCScBkupArchiveUtils::ValidateArchiveCrcsL( RFs& aFsSession, const TDesC& aFileName )
       
   515     {
       
   516     TBool validCrc = EFalse;
       
   517 
       
   518     RFile64 file;
       
   519     TInt64 size;
       
   520     
       
   521     TInt error = file.Open( aFsSession, aFileName, EFileShareReadersOnly | EFileRead );
       
   522     
       
   523     if ( error == KErrNone && file.Size(size) == KErrNone)
       
   524         {
       
   525         TBuf8< KMMCScArchiveFlagsByteCount > headerCrc;
       
   526         TBuf8< KMMCScArchiveFlagsByteCount > payloadCrc;
       
   527         TBuf8< KMMCScArchivePhoneModelStringLength > length;
       
   528         TUint32 archivedHeaderCrc, calculatedHeaderCrc;
       
   529         TUint32 archivedPayloadCrc, calculatedPayloadCrc;
       
   530         TUint32 modelLength;
       
   531         
       
   532         // Read crcs from header
       
   533         error = file.Read( static_cast<TInt64>( EArchiveOffsetArchiveHeaderCRC ), headerCrc );
       
   534         User::LeaveIfError(error);
       
   535         error = file.Read( static_cast<TInt64>( EArchiveOffsetArchivePayloadCRC ), payloadCrc );
       
   536         User::LeaveIfError(error);
       
   537         error = file.Read( static_cast<TInt64>( EArchiveOffsetPhoneModelStringLength ), length );
       
   538         User::LeaveIfError(error);
       
   539         CleanupClosePushL( file );
       
   540 
       
   541         RDesReadStream readStream( headerCrc );
       
   542         CleanupClosePushL( readStream );
       
   543         archivedHeaderCrc = readStream.ReadUint32L();
       
   544         readStream.Close();
       
   545         readStream.Open(payloadCrc);
       
   546         archivedPayloadCrc = readStream.ReadUint32L();
       
   547         readStream.Close();
       
   548         readStream.Open(length);
       
   549         modelLength = readStream.ReadUint8L();
       
   550         CleanupStack::PopAndDestroy( &readStream );
       
   551         
       
   552         // Calculate crc from header in two parts
       
   553         calculatedHeaderCrc = 0;
       
   554     	CalculateCrcFromArchive( calculatedHeaderCrc, file, 0, EArchiveOffsetArchiveHeaderCRC);
       
   555     	CalculateCrcFromArchive( calculatedHeaderCrc, file, EArchiveOffsetArchiveHeaderCRC + KMMCScArchiveCrcByteCount, 
       
   556     	     KMMCScSpareByteCount + KMMCScArchivePhoneModelStringLength + modelLength);
       
   557 
       
   558         // Calculate crc from payload and footer
       
   559         TInt payloadSize = size - (EArchiveOffsetPhoneModelString + modelLength);
       
   560         calculatedPayloadCrc = 0;
       
   561     	CalculateCrcFromArchive( calculatedPayloadCrc, file, EArchiveOffsetPhoneModelString + modelLength, payloadSize);
       
   562 
       
   563     	if(archivedPayloadCrc == calculatedPayloadCrc && archivedHeaderCrc == calculatedHeaderCrc)
       
   564     	    {
       
   565     	    validCrc = ETrue;
       
   566     	    }
       
   567     	else
       
   568     	    {
       
   569     	    __LOG4("MMCScBkupArchiveUtils::ValidateArchiveCrcsL() - crc mismatch: %u vs. %u - %u vs. %u", 
       
   570     	        archivedPayloadCrc, calculatedPayloadCrc, archivedHeaderCrc, calculatedHeaderCrc);
       
   571     	    }
       
   572         
       
   573         CleanupStack::PopAndDestroy( &file );
       
   574         }
       
   575         
       
   576 	return validCrc;
       
   577 	}
       
   578 #endif // RD_FILE_MANAGER_BACKUP
       
   579 
       
   580 
       
   581 // ---------------------------------------------------------------------------
       
   582 // MMCScBkupArchiveUtils::ReadArchiveFlagsL()
       
   583 // 
       
   584 // 
       
   585 // ---------------------------------------------------------------------------
       
   586 TBitFlags MMCScBkupArchiveUtils::ReadArchiveFlagsL( RFile64& aArchive )
       
   587     {
       
   588     TInt error = KErrNone;
       
   589     
       
   590     // Calculate the offset to the archive flags:
       
   591     const TUint archiveFlagsFileOffset = EArchiveOffsetArchiveFlags;
       
   592     
       
   593     // Flags are four bytes. Read the existing raw flag data
       
   594     TBuf8< KMMCScArchiveFlagsByteCount > flagData;
       
   595     error = aArchive.Read( static_cast<TInt64>( archiveFlagsFileOffset ), flagData );
       
   596     User::LeaveIfError( error );
       
   597     
       
   598     // Interpret the flag data as real flags
       
   599     RDesReadStream readStream( flagData );
       
   600     CleanupClosePushL( readStream );
       
   601     TUint32 archiveFlags = readStream.ReadUint32L();
       
   602     CleanupStack::PopAndDestroy( &readStream );
       
   603 
       
   604     // Done
       
   605     TBitFlags ret;
       
   606     ret.SetValue( archiveFlags );
       
   607     return ret;
       
   608     }
       
   609 
       
   610 
       
   611 // ---------------------------------------------------------------------------
       
   612 // MMCScBkupArchiveUtils::ReadArchiveVersionL()
       
   613 // 
       
   614 // 
       
   615 // ---------------------------------------------------------------------------
       
   616 void MMCScBkupArchiveUtils::ReadArchiveVersionL( RFile64& aArchive, TVersion& aVersion )
       
   617     {
       
   618     TInt error = KErrNone;
       
   619     
       
   620     // Calculate the offset to the archive flags:
       
   621     const TUint archiveVersionFileOffset = EArchiveOffsetFileFormatVersion;
       
   622     
       
   623     // Flags are four bytes. Read the existing raw flag data
       
   624     TBuf8< KMMCScArchiveVersionByteCount > versionData;
       
   625     error = aArchive.Read( static_cast<TInt64>( archiveVersionFileOffset ), versionData );
       
   626     User::LeaveIfError( error );
       
   627     
       
   628     // Interpret the flag data as real flags
       
   629     RDesReadStream readStream( versionData );
       
   630     CleanupClosePushL( readStream );
       
   631     aVersion.iMajor = readStream.ReadInt8L();
       
   632     aVersion.iMinor = readStream.ReadInt8L();
       
   633     aVersion.iBuild = readStream.ReadInt16L();
       
   634     CleanupStack::PopAndDestroy( &readStream );
       
   635     }
       
   636 
       
   637 
       
   638 #ifdef RD_FILE_MANAGER_BACKUP
       
   639 // ---------------------------------------------------------------------------
       
   640 // MMCScBkupArchiveUtils::SetArchiveCrcL()
       
   641 // 
       
   642 // 
       
   643 // ---------------------------------------------------------------------------
       
   644 void MMCScBkupArchiveUtils::SetArchiveCrcL( RFile64& aArchive, TUint32 aCrc, TUint aOffset )
       
   645     {
       
   646     TInt error = KErrNone;
       
   647     
       
   648     // Prepare externalized representation of crc
       
   649     TBuf8< KMMCScArchiveCrcByteCount > crcData;
       
   650     RDesWriteStream writeStream( crcData );
       
   651     CleanupClosePushL( writeStream );
       
   652     writeStream.WriteInt32L( aCrc );
       
   653     writeStream.CommitL();
       
   654     CleanupStack::PopAndDestroy( &writeStream );
       
   655     
       
   656     // Then write crc to the file itself
       
   657     error = aArchive.Write( static_cast<TInt64>( aOffset ), crcData );
       
   658     User::LeaveIfError( error );
       
   659     }
       
   660 
       
   661 
       
   662 // ---------------------------------------------------------------------------
       
   663 // MMCScBkupArchiveUtils::CalculateCrcFromArchive()
       
   664 // 
       
   665 // 
       
   666 // ---------------------------------------------------------------------------
       
   667 void MMCScBkupArchiveUtils::CalculateCrcFromArchive( TUint32& aCrc, RFile64& aArchive, TUint32 aOffset, TUint32 aLength )
       
   668     {
       
   669     const TInt KBigBufSize=0x10000;
       
   670     const TInt KMediumBufSize=0x8000;
       
   671     const TInt KSmallBufSize=0x1000;
       
   672 
       
   673     // Allocate as large buffer as possible for crc validation, because 
       
   674     // need to read file content in chunks for crc calculation.
       
   675 	HBufC8* bufPtr = HBufC8::New(KBigBufSize);
       
   676 	
       
   677 	if ( bufPtr == NULL )
       
   678 		bufPtr = HBufC8::New(KMediumBufSize);
       
   679 	if ( bufPtr == NULL )
       
   680 		bufPtr = HBufC8::New(KSmallBufSize);
       
   681 	
       
   682 	if ( bufPtr != NULL)
       
   683 	    {
       
   684         TPtr8 copyBuf = bufPtr->Des();
       
   685         TInt64 pos = aOffset;
       
   686         TInt size = aLength;
       
   687         
       
   688         // Loop through archive file skipping archive crc
       
   689     	while(size)
       
   690     		{
       
   691     		TInt s;
       
   692     		
       
   693 		    s = Min( size, copyBuf.MaxSize() );
       
   694     		
       
   695     		TInt error = aArchive.Read( pos, copyBuf, s );
       
   696     		
       
   697     		if ( error == KErrNone && copyBuf.Length() != s )
       
   698     			break;
       
   699     		
       
   700     		pos += s;
       
   701     		size -= s;
       
   702     		Mem::Crc32(aCrc, copyBuf.Ptr(), copyBuf.Length());
       
   703     		}
       
   704     		
       
   705         delete bufPtr;
       
   706 	    }
       
   707     }
       
   708 #endif // RD_FILE_MANAGER_BACKUP
       
   709