--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/omadrm/drmengine/server/src/DRMRightsData.cpp Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,849 @@
+/*
+* Copyright (c) 2004 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: Datatype for Rights Constraint
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <s32file.h>
+#include <s32std.h>
+#include <caf/caf.h>
+
+#include "DRMPointerArray.h"
+#include "DRMCommonData.h"
+#include "DRMPermission.h"
+#include "DRMRightsData.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+const TInt KEncryptionKeySize = 16;
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+class TPermData
+ {
+ public: // Constructor
+ TPermData( HBufC8* aParentId, const TInt aIndex, TBool aIsValid ) :
+ iParentId( aParentId ),
+ iIndex( aIndex ),
+ iIsValid( aIsValid ) { };
+
+ public: // Member variables
+ HBufC8* iParentId;
+ TInt iIndex;
+ TBool iIsValid;
+ };
+
+
+// ============================= LOCAL FUNCTIONS ===============================
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::NewLC
+// -----------------------------------------------------------------------------
+//
+CDRMRightsData* CDRMRightsData::NewLC( CDRMCommonData* aData,
+ const TDesC8& aKey,
+ const TFileName& aRightsFile,
+ RFs& aFileServer )
+ {
+ CDRMRightsData* self = new( ELeave ) CDRMRightsData( aData, aFileServer );
+ CleanupStack::PushL( self );
+ self->ConstructL( aRightsFile, aKey );
+
+ return self;
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::NewL
+// -----------------------------------------------------------------------------
+//
+CDRMRightsData* CDRMRightsData::NewL( CDRMCommonData* aData,
+ const TDesC8& aKey,
+ const TFileName& aRightsFile,
+ RFs& aFileServer )
+ {
+ CDRMRightsData* self = NewLC( aData, aKey, aRightsFile, aFileServer );
+ CleanupStack::Pop();
+
+ return self;
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::OpenLC
+// -----------------------------------------------------------------------------
+//
+CDRMRightsData* CDRMRightsData::OpenLC( const TFileName& aRightsFile,
+ RFs& aFileServer )
+ {
+ CDRMCommonData* common = CDRMCommonData::NewL();
+
+ CDRMRightsData* self = new( ELeave ) CDRMRightsData( common, aFileServer );
+ CleanupStack::PushL( self );
+ self->ConstructL( aRightsFile );
+
+ return self;
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::OpenL
+// -----------------------------------------------------------------------------
+//
+CDRMRightsData* CDRMRightsData::OpenL( const TFileName& aRightsFile,
+ RFs& aFileServer )
+ {
+ CDRMRightsData* self = OpenLC( aRightsFile, aFileServer );
+ CleanupStack::Pop();
+
+ return self;
+ };
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CDRMRightsData::~CDRMRightsData()
+ {
+ // Permanent File Store
+ if( iStore )
+ {;
+ delete iStore;
+ iStore = NULL;
+ }
+
+ // index array
+ iArray.Close();
+
+ // Common Data
+ if( iData )
+ {
+ delete iData;
+ iData = NULL;
+ }
+ };
+
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::GetCommonDataL
+// -----------------------------------------------------------------------------
+//
+const CDRMCommonData* CDRMRightsData::GetCommonDataL() const
+ {
+ return iData;
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::UpdateCommonDataL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::UpdateCommonDataL( CDRMCommonData* aData )
+ {
+ RStoreWriteStream stream;
+
+ // If not data is given, that is an error
+ if( !aData )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ // Open the stream
+ stream.ReplaceLC( *iStore, iCommonId );
+
+ // Delete the old data if it's around
+ // if the old data has been modified, write it as such
+ if( iData != aData )
+ {
+ if( iData )
+ {
+ delete iData;
+ iData = NULL;
+ }
+ iData = aData;
+ }
+
+ // Write the data to the stream
+ iData->ExternalizeL( stream );
+
+ // commit the stream
+ stream.CommitL();
+
+ // commit the store
+ iStore->CommitL();
+
+ // pop the stream
+ CleanupStack::PopAndDestroy();
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::StoreNewPermissionL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::StoreNewPermissionL( CDRMPermission& aPermission,
+ TDRMUniqueID& aStream )
+ {
+ TStreamId sid;
+ TStreamId rootId;
+ RStoreWriteStream stream;
+ RStoreWriteStream rootStream;
+
+ // Create a new stream to the store:
+ sid = stream.CreateLC( *iStore );
+
+ aPermission.iUniqueID = sid.Value();
+ aStream = sid.Value();
+
+ // Externalize the permission data
+ aPermission.ExternalizeL( stream );
+ stream.CommitL();
+
+ // add the id to the array
+ iArray.InsertInUnsignedKeyOrder( aStream );
+
+ // Get the stream id of the root
+ rootId = iStore->Root();
+
+ // Open the root stream
+ rootStream.ReplaceLC( *iStore, rootId );
+
+ // Store the changed index
+ StoreIndexL( rootStream );
+ rootStream.CommitL();
+
+ // Commit the store
+ iStore->CommitL();
+
+ CleanupStack::PopAndDestroy(); // root stream
+ CleanupStack::PopAndDestroy(); // stream
+
+ iStore->CompactL();
+ iStore->CommitL();
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::UpdatePermissionL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::UpdatePermissionL( const CDRMPermission& aPermission )
+ {
+ TStreamId sid( aPermission.iUniqueID );
+ RStoreWriteStream stream;
+ TInt index = 0;
+
+ // get the id from the array if it doesn't exist, error
+ index = iArray.FindInUnsignedKeyOrder( aPermission.iUniqueID );
+
+ if( index == KErrNotFound )
+ {
+ User::Leave( KErrCANoPermission );
+ }
+
+ // Replace the existing stream
+ stream.ReplaceLC( *iStore, sid );
+
+ // Externalize the permission data
+ aPermission.ExternalizeL( stream );
+
+ // Required by the ReplaceLC
+ stream.CommitL();
+
+ // Commit the store
+ iStore->CommitL();
+
+ CleanupStack::PopAndDestroy();
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::FetchPermissionL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::FetchPermissionL( CDRMPermission& aPermission,
+ const TDRMUniqueID& aStream ) const
+ {
+ TStreamId sid( aStream );
+ RStoreReadStream stream;
+ TInt index = 0;
+
+ // get the id from the array if it doesn't exist, error
+ index = iArray.FindInUnsignedKeyOrder( aStream );
+
+ if( index == KErrNotFound )
+ {
+ User::Leave( KErrCANoPermission );
+ }
+
+ // Open the root stream
+ stream.OpenLC( *iStore, sid );
+
+ // Read the common id
+ aPermission.InternalizeL( stream );
+
+ // Close the stream
+ CleanupStack::PopAndDestroy();
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::DeletePermissionL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::DeletePermissionL( const TDRMUniqueID& aStream )
+ {
+ TStreamId sid( aStream );
+ TStreamId rootId;
+ TInt index = 0;
+ RStoreWriteStream rootStream;
+
+ // get the id from the array if it doesn't exist, error
+ index = iArray.FindInUnsignedKeyOrder( aStream );
+
+ if( index == KErrNotFound )
+ {
+ User::Leave( KErrCANoPermission );
+ }
+
+ // Delete the stream from the store
+ iStore->DeleteL( sid );
+
+ iArray.Remove( index );
+
+
+ // Get the stream id of the root
+ rootId = iStore->Root();
+
+ // Open the root stream
+ rootStream.ReplaceLC( *iStore, rootId );
+
+ // Store the changed index
+ StoreIndexL( rootStream );
+ rootStream.CommitL();
+
+ // Commit the store
+ iStore->CommitL();
+
+ CleanupStack::PopAndDestroy(); // root stream
+
+ // Compact and commit the changes
+ iStore->CompactL();
+ iStore->CommitL();
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::FetchAllPermissionsL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::FetchAllPermissionsL( RPointerArray<CDRMPermission>&
+ aPointerArray)
+ {
+ CDRMPermission* perm = NULL;
+
+ if ( iArray.Count() == 0)
+ {
+ User::Leave( KErrCANoPermission );
+ }
+
+ for( TInt count = 0; count < iArray.Count(); count++ )
+ {
+ perm = CDRMPermission::NewLC();
+ FetchPermissionL( *perm, iArray[ count ] );
+ aPointerArray.AppendL( perm );
+ CleanupStack::Pop();
+ }
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::DeleteAllPermissionsL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::DeleteAllPermissionsL()
+ {
+ TStreamId rootId;
+ RStoreWriteStream rootStream;
+
+ // Delete all permissions from the store
+ for( TInt i = 0; i < iArray.Count(); i++ )
+ {
+ TStreamId sid( iArray[i] );
+ iStore->DeleteL( sid );
+ }
+
+ // Reset the array
+ iArray.Reset();
+
+ // Get the stream id of the root
+ rootId = iStore->Root();
+
+ // Open the root stream
+ rootStream.ReplaceLC( *iStore, rootId );
+
+ // Store the changed index
+ StoreIndexL( rootStream );
+ rootStream.CommitL();
+
+ // Commit the store
+ iStore->CommitL();
+
+ CleanupStack::PopAndDestroy(); // root stream
+
+ // Compact and Commit the store
+ iStore->CompactL();
+ iStore->CommitL();
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::DeleteExpiredPermissionsL
+// Deletes all rights objects which have been expired
+// if the given time aTime is Time::NullTTime() then
+// deletes only non time based rights
+// -----------------------------------------------------------------------------
+//
+TInt CDRMRightsData::DeleteExpiredPermissionsL( const TTime& aTime, TBool& aParents )
+ {
+ CDRMPermission* permission = NULL;
+ RStoreReadStream stream;
+ TStreamId rootId;
+ RStoreWriteStream rootStream;
+ TBool remove = EFalse;
+ TInt k = 0;
+ TBool performDelete = ETrue;
+
+ // A list for the permissions:
+ CDRMPointerArray<CDRMPermission>* permList = CDRMPointerArray<CDRMPermission>::NewLC();
+ permList->SetAutoCleanup( ETrue );
+ CDRMPointerArray<TPermData>* permDataList = CDRMPointerArray<TPermData>::NewLC();
+ permDataList->SetAutoCleanup( ETrue );
+
+ // Fill the array:
+ for( TInt j = 0 ; j < iArray.Count(); j++ )
+ {
+ TPermData* perm = NULL;
+ // Create the sid:
+ TStreamId psid( iArray[j] );
+
+ // Open the correct stream
+ stream.OpenLC( *iStore, psid );
+
+ permission = CDRMPermission::NewLC();
+
+ // Read the permission
+ permission->InternalizeL( stream );
+
+ permList->AppendL( permission );
+ CleanupStack::Pop(); // permission
+
+ // if the permission has a parent check if we found now or have found an
+ // expired one or a valid one,
+ // store info if required
+ if( permission->iParentUID )
+ {
+ if( !aParents )
+ {
+ aParents = ETrue;
+ }
+
+ for( k = 0; k < permDataList->Count(); k++ )
+ {
+ if( !(*permDataList)[k]->iParentId->Compare( *permission->iParentUID ) )
+ {
+ if( !(*permDataList)[k]->iIsValid && !permission->Expired( aTime ) )
+ {
+ (*permDataList)[k]->iParentId = permission->iParentUID;
+ (*permDataList)[k]->iIndex = j;
+ (*permDataList)[k]->iIsValid = ETrue;
+ }
+ break;
+ }
+ }
+
+ // if it's not found, add it:
+ if( k == permDataList->Count() )
+ {
+ if( !permission->Expired( aTime ) )
+ {
+ perm = new(ELeave) TPermData( permission->iParentUID, j, ETrue);
+ }
+ else
+ {
+ perm = new(ELeave) TPermData( permission->iParentUID, j, EFalse);
+ }
+ CleanupStack::PushL( perm );
+ permDataList->AppendL( perm );
+ CleanupStack::Pop(); // perm
+ }
+ }
+
+ // Close the stream
+ CleanupStack::PopAndDestroy(); // stream
+ }
+
+
+ // Delete all expired permissions from the store
+ for( TInt i = iArray.Count() - 1 ; i >= 0; i-- )
+ {
+ permission = (*permList)[i];
+
+ // Check if the permission is expired
+ // if it is, check if it has a parent and if it can be deleted
+ if( permission->Expired( aTime ) )
+ {
+ // if it has a parent go through the list and see if this can be deleted
+ // or not
+ if( permission->iParentUID )
+ {
+ performDelete = EFalse;
+ for( k = 0; k < permDataList->Count(); k++ )
+ {
+ TPermData* aData = (*permDataList)[k];
+
+ // since it's set up like this a pointer comparison is enough:
+ if( !(*permDataList)[k]->iParentId->Compare( *permission->iParentUID ) )
+ {
+ if( i != (*permDataList)[k]->iIndex )
+ {
+ performDelete = ETrue;
+ }
+ }
+ }
+ }
+
+ if( performDelete )
+ {
+ // Create the sid:
+ TStreamId sid( iArray[i] );
+
+ iStore->Delete( sid );
+
+ // remove from the array
+ iArray.Remove( i );
+
+ if( !remove )
+ {
+ remove = ETrue;
+ }
+ }
+ }
+ performDelete = ETrue;
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); // permDataList, permList
+
+ // Write the data into the the file
+ // if some of the rights have been removed
+ if( remove )
+ {
+ // Get the stream id of the root
+ rootId = iStore->Root();
+
+ // Open the root stream
+ rootStream.ReplaceLC( *iStore, rootId );
+
+ // Store the changed index
+ StoreIndexL( rootStream );
+ rootStream.CommitL();
+
+ // Commit the store
+ iStore->CommitL();
+
+ CleanupStack::PopAndDestroy(); // root stream
+
+ // Compact and Commit the store
+ iStore->CompactL();
+ iStore->CommitL();
+ }
+
+ return iArray.Count();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::StoreKeyL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::StoreKeyL()
+ {
+ RStoreWriteStream stream;
+ TUint32 size = 0;
+
+ stream.OpenLC( *iStore, iKeyId );
+
+ if( iKeyExists )
+ {
+ size = KEncryptionKeySize;
+ }
+
+ stream.WriteUint32L( size );
+
+ if( size )
+ {
+ stream.WriteL( iKey, KEncryptionKeySize );
+ }
+
+ stream.CommitL();
+ iStore->CommitL();
+
+ CleanupStack::PopAndDestroy();
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::GetKeyL
+// -----------------------------------------------------------------------------
+//
+HBufC8* CDRMRightsData::GetKeyL() const
+ {
+ HBufC8* key = NULL;
+
+ if( iKeyExists )
+ {
+ key = HBufC8::NewL( KEncryptionKeySize );
+ *key = iKey;
+ }
+
+ return key;
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::FetchKeyL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::FetchKeyL()
+ {
+ RStoreReadStream stream;
+ TUint32 size = 0;
+
+ // Open the root stream
+ stream.OpenLC( *iStore, iKeyId );
+
+ size = stream.ReadUint32L();
+
+ if( !size )
+ {
+ iKeyExists = EFalse;
+ }
+ else
+ {
+ stream.ReadL( iKey, KEncryptionKeySize );
+ iKeyExists = ETrue;
+ }
+
+ CleanupStack::PopAndDestroy();
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::CreateAndInitializeStoreL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::CreateAndInitializeStoreL( const TFileName& aRightsStore )
+ {
+ TStreamId rootId;
+ RStoreWriteStream stream;
+ RStoreWriteStream stream2;
+ RStoreWriteStream rootStream;
+ TUint32 size = 0;
+
+ // Create and initialize the permanent file store
+ iStore = CPermanentFileStore::ReplaceL( iFileServer, aRightsStore,
+ EFileRead|EFileWrite );
+ iStore->SetTypeL( KPermanentFileStoreLayoutUid );
+ iStore->CommitL();
+
+ // Create the root stream:
+ rootId = rootStream.CreateLC( *iStore );
+ rootStream.CommitL();
+ iStore->SetRootL( rootId );
+ iStore->CommitL();
+
+ // Create the common data
+ iCommonId = stream.CreateLC( *iStore );
+ iData->ExternalizeL( stream );
+ stream.CommitL();
+ iStore->CommitL();
+
+ CleanupStack::PopAndDestroy(); // stream
+
+ // Create the key
+ iKeyId = stream2.CreateLC( *iStore );
+
+ // if the key exists set the key size accordingly
+ if( iKeyExists )
+ {
+ size = KEncryptionKeySize;
+ }
+ stream2.WriteUint32L( size );
+
+ if( size )
+ {
+ stream2.WriteL( iKey, KEncryptionKeySize );
+ }
+ stream2.CommitL();
+ iStore->CommitL();
+
+ CleanupStack::PopAndDestroy(); // stream2
+ CleanupStack::PopAndDestroy(); // rootStream
+
+ // Create the index now that we have all the data
+ rootId = iStore->Root();
+
+ rootStream.ReplaceLC(*iStore, rootId);
+ StoreIndexL( rootStream );
+ rootStream.CommitL();
+ iStore->CommitL();
+
+ // Commit the changes to the store as well
+ CleanupStack::PopAndDestroy(); // rootStream
+ };
+
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::StoreIndexL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::StoreIndexL( RWriteStream& aStream ) const
+ {
+ // Write the common id to the stream
+ iCommonId.ExternalizeL( aStream );
+
+ // Write the key id to the stream
+ iKeyId.ExternalizeL( aStream );
+
+ // Write the array size and possibly the array to the stream
+ aStream.WriteInt32L( iArray.Count() );
+
+ for( TInt count = 0; count < iArray.Count(); count++ )
+ {
+ aStream.WriteUint32L( iArray[ count ] );
+ }
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::FetchIndexL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::FetchIndexL()
+ {
+ TStreamId rootId;
+ RStoreReadStream stream;
+ TInt count = 0;
+ TDRMUniqueID id;
+
+ // Get the stream id of the root
+ rootId = iStore->Root();
+
+ // Open the root stream
+ stream.OpenLC( *iStore, rootId );
+
+ // Do the actual reading, reading also the key id and the common id
+
+ // Read the common id
+ iCommonId.InternalizeL( stream );
+
+ // Read the key id
+ iKeyId.InternalizeL( stream );
+
+ // read the count of the array:
+ iArray.Reset();
+
+ count = stream.ReadInt32L();
+
+ for( ; count > 0; count-- )
+ {
+ id = stream.ReadUint32L();
+ iArray.InsertInUnsignedKeyOrder( id );
+ }
+
+ // Close the stream
+ CleanupStack::PopAndDestroy();
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMRightsData::FetchCommonDataL
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::FetchCommonDataL()
+ {
+ RStoreReadStream stream;
+
+ // Open the root stream
+ stream.OpenLC( *iStore, iCommonId );
+
+ iData->InternalizeL( stream );
+
+ CleanupStack::PopAndDestroy();
+ };
+
+
+// -----------------------------------------------------------------------------
+// Default Constructor - First phase.
+// Can be used by itself to generate an empty object
+// -----------------------------------------------------------------------------
+//
+CDRMRightsData::CDRMRightsData( CDRMCommonData* aData, RFs& aFileServer ) :
+ iFileServer( aFileServer ), iData( aData )
+ {
+ };
+
+// -----------------------------------------------------------------------------
+// 2nd phase Constructor
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::ConstructL( const TFileName& aRightsStore )
+ {
+ // Open the file store
+ iStore = CPermanentFileStore::OpenL( iFileServer, aRightsStore, EFileRead|EFileWrite );
+
+ // Get the index
+ FetchIndexL();
+
+ // Get the common data
+ FetchCommonDataL();
+
+ // Get the key
+ FetchKeyL();
+ };
+
+// -----------------------------------------------------------------------------
+// 2nd phase Constructor
+// -----------------------------------------------------------------------------
+//
+void CDRMRightsData::ConstructL( const TFileName& aRightsStore,
+ const TDesC8& aKey )
+ {
+
+ // Check if the key is given or a null desc
+ if( aKey.Length() )
+ {
+ iKey = aKey;
+ iKeyExists = ETrue;
+ }
+ else
+ {
+ iKeyExists = EFalse;
+ }
+
+ // Creates the required stores and indexes
+ CreateAndInitializeStoreL( aRightsStore );
+ };
+
+
+// End of File