diff -r 000000000000 -r 95b198f216e5 omadrm/drmengine/drmbackup/src/DRMBackup.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omadrm/drmengine/drmbackup/src/DRMBackup.cpp Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,779 @@ +/* +* 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: Implementation of the Active Backup in DRM +* +*/ + + +// INCLUDE FILES +#include + +#include + +#ifdef RD_MULTIPLE_DRIVE +#include +#endif + +#include "DRMBackup.h" +#include "DRMLog.h" +#include "RoapStorageClient.h" +#include "DRMRightsDB.h" +#include "drmbackupinterface.h" +/* +#include "flogger.h" + + +_LIT( KLogDir, "drm"); +_LIT( KLogName, "backup.log"); +*/ + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +const TInt KDoBackup = 0x00000001; +const TInt KRightsFileOpen = 0x00000002; +const TInt KContextFileOpen = 0x00000004; +const TInt KRightsSizeRead = 0x00000008; +const TInt KContextSizeRead = 0x00000010; + +// MACROS + +// LOCAL CONSTANTS AND MACROS +#ifdef RD_MULTIPLE_DRIVE +// Backup Directory +_LIT( KBackupDir, "%c:\\private\\101F51F2\\backup\\" ); +#endif + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES +LOCAL_C void CleanupData( TAny* aPtr ); + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CleanupData +// Used to catch errors and delete the file if it's needed +// ----------------------------------------------------------------------------- +// +LOCAL_C void CleanupData( TAny* aPtr ) + { + CDRMBackup* backup = reinterpret_cast( aPtr ); + + backup->PerformCleanup(); + } + + +// ============================ MEMBER FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// CDRMBackup::CDRMBackup +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CDRMBackup::CDRMBackup( CDRMRightsDB* aRightsDatabase, + RFs& aFileServer ) : + iFileServer( aFileServer ), + iDRMRightsDB( aRightsDatabase ), + iRightsFileSize( 0 ), + iContextFileSize( 0 ), + iPosition( 0 ), + iReadData( 0 ), + iStatus( 0 ) + { + }; + +// ----------------------------------------------------------------------------- +// CDRMBackup::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CDRMBackup::ConstructL() + { + TInt error = KErrNone; + +#ifndef RD_MULTIPLE_DRIVE + + // Create the backup directory if needed + error = iFileServer.MkDirAll( KBackupDirectory ); + +#else //RD_MULTIPLE_DRIVE + + TInt driveNumber( -1 ); + TChar driveLetter; + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); + iFileServer.DriveToChar( driveNumber, driveLetter ); + + TFileName backupDir; + backupDir.Format( KBackupDir, (TUint)driveLetter ); + + // Create the backup directory if needed + error = iFileServer.MkDirAll( backupDir ); + +#endif + + if( error != KErrAlreadyExists ) + { + User::LeaveIfError( error ); + } + +#ifndef RD_MULTIPLE_DRIVE + + iRightsFileName.Copy( KBackupDirectory ); + +#else //RD_MULTIPLE_DRIVE + + iRightsFileName.Copy( backupDir ); + +#endif + + iRightsFileName.Append( KRightsDbBackupFile ); + iSizeBuffer.SetLength( 4 ); + }; + +// ----------------------------------------------------------------------------- +// CDRMBackup::NewLC +// Two-phased constructor +// ----------------------------------------------------------------------------- +// +CDRMBackup* CDRMBackup::NewLC( CDRMRightsDB* aRightsDatabase, + RFs& aFileServer ) + { + CDRMBackup* self = new(ELeave) CDRMBackup( aRightsDatabase, + aFileServer ); + CleanupStack::PushL( self ); + self->ConstructL(); + + return self; + }; + +// ----------------------------------------------------------------------------- +// CDRMBackup::NewL +// Two-phased constructor +// ----------------------------------------------------------------------------- +// +CDRMBackup* CDRMBackup::NewL( CDRMRightsDB* aRightsDatabase, + RFs& aFileServer ) + { + CDRMBackup* self = NewLC( aRightsDatabase, + aFileServer ); + CleanupStack::Pop(); + + return self; + }; + +// --------------------------------------------------------- +// CDRMBackup::~CDRMBackup +// Destructor +// --------------------------------------------------------- +// +CDRMBackup::~CDRMBackup() + { + }; + + +// --------------------------------------------------------- +// CDRMBackup::AllSnapshotsSuppliedL +// --------------------------------------------------------- +// +void CDRMBackup::AllSnapshotsSuppliedL() + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("AllSnapshotsSuppliedL\n\r")); + return; + }; + +// --------------------------------------------------------- +// CDRMBackup::ReceiveSnapshotDataL +// --------------------------------------------------------- +// +void CDRMBackup::ReceiveSnapshotDataL(TDriveNumber /* aDrive */, + TDesC8& /* aBuffer */, + TBool /* aLastSection */) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RecieveSnapshotdataL\n\r")); + User::Leave( KErrNotSupported ); + }; + +// --------------------------------------------------------- +// CDRMBackup::GetExpectedDataSize +// --------------------------------------------------------- +// +TUint CDRMBackup::GetExpectedDataSize(TDriveNumber /* aDrive */) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("GetExpectedDataSize\n\r")); + return 0; + }; + +// --------------------------------------------------------- +// CDRMBackup::GetSnapshotDataL +// --------------------------------------------------------- +// +void CDRMBackup::GetSnapshotDataL(TDriveNumber /* aDrive */, + TPtr8& /* aBuffer */, + TBool& /* aFinished */) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("GetSnapShopDataL\n\r")); + User::Leave( KErrNotSupported ); + }; + +// --------------------------------------------------------- +// CDRMBackup::InitialiseGetBackupDataL +// --------------------------------------------------------- +// +void CDRMBackup::InitialiseGetBackupDataL(TDriveNumber aDrive) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("Init backup data\n\r")); + // Clean up existing data: + PerformCleanup(); + +#ifndef RD_MULTIPLE_DRIVE + + // Only do a backup when backing up drive C + if( aDrive == EDriveC ) + +#else //RD_MULTIPLE_DRIVE + + TInt driveNumber( -1 ); + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); + + // Only do a backup when backing up system drive + if( aDrive == driveNumber ) + +#endif + { + iStatus |= KDoBackup; + } + else + { + iStatus &= ~KDoBackup; + return; + } + + // Add the cleanup item to the cleanup stack + TCleanupItem resetAndDestroy( CleanupData, reinterpret_cast(this) ); + CleanupStack::PushL( resetAndDestroy ); + + // This function needs to write the two files required to be backed up. + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("Init: create rights file\n\r")); + // create the rights database backup file + CreateRightsBackupFileL(); + + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("Init: create context file\n\r")); + // create the context database backup file + CreateContextBackupFileL(); + + // If everything went properly, pop + CleanupStack::Pop(); + }; + +// --------------------------------------------------------- +// CDRMBackup::GetBackupDataSectionL +// --------------------------------------------------------- +// +void CDRMBackup::GetBackupDataSectionL(TPtr8& aBuffer, TBool& aFinished) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("GetBackupDataSectionL\n\r")); + TInt seekAmount = 0; + + // if we are not supposed to do anything, just return + if( !(iStatus & KDoBackup ) ) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("GetBackupDataSectionL: no Do Backup\n\r")); + aFinished = ETrue; + return; + } + + // Make sure that the buffer is empty and starts from the beginning + aBuffer.SetLength(0); + + // Add the cleanup item to the cleanup stack + TCleanupItem resetAndDestroy( CleanupData, reinterpret_cast(this) ); + CleanupStack::PushL( resetAndDestroy ); + + if( iPosition < iRightsFileSize ) + { + // Find the right position + iRightsBackupFile.Seek( ESeekStart,iPosition ); + + // Read data + User::LeaveIfError( iRightsBackupFile.Read( aBuffer ) ); + + iPosition += aBuffer.Length(); + + if( iPosition == iRightsFileSize ) + { + aFinished = ETrue; + } + else + { + aFinished = EFalse; + } + + } + else if( iPosition < iRightsFileSize + iContextFileSize ) + { + // Find the right position + seekAmount = iPosition-iRightsFileSize; + iContextBackupFile.Seek( ESeekStart, seekAmount ); + + // Read data + User::LeaveIfError( iContextBackupFile.Read( aBuffer ) ); + + iPosition += aBuffer.Length(); + + if( iPosition-iRightsFileSize == iContextFileSize ) + { + aFinished = ETrue; + } + else + { + aFinished = EFalse; + } + } + else + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("GetBackupDataSectionL - Error\n\r")); + User::Leave( KErrGeneral ); + } + + // if we are finished, we can clean up the stuff otherwise not + if( aFinished ) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("GetBackupDataSectionL - Finished\n\r")); + CleanupStack::PopAndDestroy(); + } + else + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("GetBackupDataSectionL - Continues\n\r")); + CleanupStack::Pop(); + } + }; + +// --------------------------------------------------------- +// CDRMBackup::InitialiseRestoreBaseDataL +// --------------------------------------------------------- +// +void CDRMBackup::InitialiseRestoreBaseDataL(TDriveNumber aDrive) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("InitializeRestoreBaseDataL\n\r")); + + // Clean up existing data: + PerformCleanup(); + +#ifndef RD_MULTIPLE_DRIVE + + // Only do a restore when restoring drive C + if( aDrive == EDriveC ) + +#else //RD_MULTIPLE_DRIVE + + TInt driveNumber( -1 ); + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); + + // Only do a restore when restoring drive C + if( aDrive == driveNumber ) + +#endif + { + iStatus |= KDoBackup; + } + else + { + iStatus &= ~KDoBackup; + } + }; + +// --------------------------------------------------------- +// CDRMBackup::RestoreBaseDataSectionL +// Create the files where the restore is performed from +// --------------------------------------------------------- +// +void CDRMBackup::RestoreBaseDataSectionL(TDesC8& aBuffer, TBool aFinished) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL\n\r")); + + TInt seekAmount = 0; + Roap::RRoapStorageClient client; + TFileName tempFileName; + TPtrC8 buffer( aBuffer ); + + if( !(iStatus & KDoBackup ) ) + { + return; + } + + // Add the cleanup item to the cleanup stack + TCleanupItem resetAndDestroy( CleanupData, reinterpret_cast(this) ); + CleanupStack::PushL( resetAndDestroy ); + + // Read the size of the first file, even if it comes in one byte chunks + if( iPosition == 0 && iReadData < 4 && !( iStatus & KRightsSizeRead ) ) + { + if( iReadData + buffer.Length() >= 4 ) + { + Mem::Copy( const_cast( iSizeBuffer.Ptr() ) + iReadData, + buffer.Ptr(), 4-iReadData ); + RMemReadStream stream( iSizeBuffer.Ptr(), 4 ); + CleanupClosePushL( stream ); + iRightsFileSize = stream.ReadInt32L(); + CleanupStack::PopAndDestroy(); + + // Remove the 'used' data from the beginning of the data block + buffer.Set( buffer.Mid( 4-iReadData ) ); + + iStatus |= KRightsSizeRead; + + iReadData = 0; + } + else + { + if( aFinished ) + { + CleanupStack::PopAndDestroy(); + return; + } + // copy the data to the temp buffer + Mem::Copy( const_cast( iSizeBuffer.Ptr() ) + iReadData, + buffer.Ptr(), buffer.Length() ); + iReadData += buffer.Length(); + CleanupStack::Pop(); + return; + } + } + + // Read the size of the 2nd file when it's needed: + if( iPosition == iRightsFileSize && iReadData < 4 && !(iStatus & KContextSizeRead) ) + { + if( iReadData + buffer.Length() >= 4 ) + { + Mem::Copy( const_cast( iSizeBuffer.Ptr() ) + iReadData, + buffer.Ptr(), 4-iReadData ); + RMemReadStream stream( iSizeBuffer.Ptr(), 4 ); + CleanupClosePushL( stream ); + iContextFileSize = stream.ReadInt32L(); + CleanupStack::PopAndDestroy(); + + // Remove the 'used' data from the beginning of the data block + buffer.Set( buffer.Mid( 4-iReadData ) ); + + iStatus |= KContextSizeRead; + iReadData = 0; + + } + else + { + if( aFinished ) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL : buggy file(1)\n\r")); + CleanupStack::PopAndDestroy(); + return; + } + // copy the data to the temp buffer + Mem::Copy( const_cast( iSizeBuffer.Ptr()) + iReadData, + buffer.Ptr(), buffer.Length() ); + iReadData += buffer.Length(); + CleanupStack::Pop(); + return; + } + } + + // Restore the two files: + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL : before restore\n\r")); + + if( iPosition < iRightsFileSize ) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL : restore starts\n\r")); + if( !( iStatus & KRightsFileOpen ) ) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL : replace the file\n\r")); + User::LeaveIfError( iRightsBackupFile.Replace( iFileServer, + iRightsFileName, + EFileRead|EFileWrite ) ); + iStatus |= KRightsFileOpen; + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL : write startn\r")); + iRightsBackupFile.Write( iSizeBuffer, 4 ); + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL : write end\n\r")); + iPosition += 4; + } + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL : before seek\n\r")); + // Find the right position + User::LeaveIfError( iRightsBackupFile.Seek( ESeekStart,iPosition ) ); + + + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL : after seek\n\r")); + // Read data + User::LeaveIfError( iRightsBackupFile.Write( buffer ) ); + + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL : after write\n\r")); + iPosition += buffer.Length(); + } + else if( iPosition < iRightsFileSize + iContextFileSize ) + { + + // Open the file if it's not open + if( !( iStatus & KContextFileOpen ) ) + { + User::LeaveIfError( iContextBackupFile.Replace( iFileServer, + iContextFileName, + EFileRead|EFileWrite ) ); + iStatus |= KContextFileOpen; + iContextBackupFile.Write( iSizeBuffer, 4 ); + iPosition += 4; + } + + // Find the right position + seekAmount = iPosition-iRightsFileSize; + iContextBackupFile.Seek( ESeekStart, seekAmount ); + + // Read data + User::LeaveIfError( iContextBackupFile.Write( buffer ) ); + + iPosition += buffer.Length(); + } + else + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreBaseDataSectionL : error\n\r")); + User::Leave( KErrGeneral ); + } + + CleanupStack::Pop(); + }; + +// --------------------------------------------------------- +// CDRMBackup::InitialiseRestoreIncrementDataL +// --------------------------------------------------------- +// +void CDRMBackup::InitialiseRestoreIncrementDataL(TDriveNumber /* aDrive */) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("init incremental restore\n\r")); + User::Leave( KErrNotSupported ); + }; + +// --------------------------------------------------------- +// CDRMBackup::RestoreIncrementDataSectionL +// --------------------------------------------------------- +// +void CDRMBackup::RestoreIncrementDataSectionL(TDesC8& /* aBuffer */, TBool /* aFinished */) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("restore incremenetal\n\r")); + User::Leave( KErrNotSupported ); + }; + +// --------------------------------------------------------- +// CDRMBackup::RestoreComplete +// This function performs the actual restoring +// --------------------------------------------------------- +// +void CDRMBackup::RestoreComplete(TDriveNumber aDrive) + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreComplete\n\r")); + TInt error = KErrNone; + TBool doUdt = EFalse; + +#ifndef RD_MULTIPLE_DRIVE + + // Only do a backup when backing up drive C + if( aDrive != EDriveC ) + +#else //RD_MULTIPLE_DRIVE + + TInt driveNumber( -1 ); + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); + + // Only do a backup when backing up drive C + if( aDrive != driveNumber ) + +#endif + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreComplete : not Drive C\n\r")); + return; + } + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("PerformRightsMergeL\n\r")); + + + + // Merge the rights + TRAP( error, PerformRightsMergeL() ); + if( error ) + { + if( error == KErrPermissionDenied ) + { + doUdt = ETrue; + } + // Log some error + error = KErrNone; + } + + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("PerformContextMergeL\n\r")); + + // Merge the Contexts + TRAP( error, PerformContextMergeL() ); + if( error ) + { + // Log some error + error = KErrNone; + } + + PerformCleanup( doUdt ); + }; + +// --------------------------------------------------------- +// CDRMBackup::TerminateMultiStageOperation +// --------------------------------------------------------- +// +void CDRMBackup::TerminateMultiStageOperation() + { + PerformCleanup(); + }; + +// --------------------------------------------------------- +// CDRMBackup::GetDataChecksum +// --------------------------------------------------------- +// +TUint CDRMBackup::GetDataChecksum(TDriveNumber /* aDrive */) + { + return 0; + }; + +// --------------------------------------------------------- +// CDRMBackup::CreateRightsBackupFileL +// --------------------------------------------------------- +// +void CDRMBackup::CreateRightsBackupFileL() + { + // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("Create backup file\n\r")); + + // Open the file and get the filename + User::LeaveIfError( iRightsBackupFile.Replace( iFileServer, + iRightsFileName, + EFileRead|EFileWrite ) ); + iStatus |= KRightsFileOpen; + + iDRMRightsDB->BackupContentToFileL( iRightsBackupFile, KNullDesC8 ); + + User::LeaveIfError( iRightsBackupFile.Size( iRightsFileSize ) ); + }; + +// --------------------------------------------------------- +// CDRMBackup::CreateContextBackupFileL +// --------------------------------------------------------- +// +void CDRMBackup::CreateContextBackupFileL() + { + //Roap::RRoapStorageClient client; + + // Open the file and get the filename +/* User::LeaveIfError( iContextBackupFile.Replace( iFileServer, + iContextFileName, + EFileRead|EFileWrite ) ); + + iStatus |= KContextFileOpen; +*/ + // Connect to the roap storage server + //User::LeaveIfError( client.Connect() ); + //CleanupClosePushL( client ); + + //client.BackupContentToFileL( iContextBackupFile, KNullDesC8 ); + }; + +// --------------------------------------------------------- +// CDRMBackup::PerformRightsMergeL +// --------------------------------------------------------- +// +void CDRMBackup::PerformRightsMergeL() + { + if( iStatus & KRightsFileOpen ) + { + iDRMRightsDB->RestoreContentFromFileL( iRightsBackupFile, KNullDesC8, + KDRMNormalBackup ); + } + else + { + User::Leave(KErrNotReady); + } + }; + +// --------------------------------------------------------- +// CDRMBackup::PerformContextMergeL +// --------------------------------------------------------- +// +void CDRMBackup::PerformContextMergeL() + { + //Roap::RRoapStorageClient client; + + // Connect to the roap storage server + //User::LeaveIfError( client.Connect() ); + //CleanupClosePushL( client ); + + //client.RestoreContentFromFileL( iContextBackupFile, KNullDesC8 ); + + //CleanupStack::PopAndDestroy();// client + }; + +// --------------------------------------------------------- +// CDRMBackup::PerformCleanup +// --------------------------------------------------------- +// +void CDRMBackup::PerformCleanup( TBool aUdt ) + { + iRightsFileSize = 0; + iContextFileSize = 0; + + if( iStatus & KRightsFileOpen ) + { + if( !aUdt ) + { + iRightsBackupFile.SetSize(0); + } + + iRightsBackupFile.Close(); + + if( !aUdt ) + { + iFileServer.Delete( iRightsFileName ); + } + } + + if( iStatus & KContextFileOpen ) + { + if( !aUdt ) + { + iContextBackupFile.SetSize(0); + } + + iContextBackupFile.Close(); + + if( !aUdt ) + { + iFileServer.Delete( iContextFileName ); + } + } + + iPosition = 0; + Mem::FillZ(const_cast(iSizeBuffer.Ptr()), 4); + iReadData = 0; + iStatus = 0; + return; + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + + +// End of File