diff -r 000000000000 -r 95b198f216e5 omadrm/drmengine/server/src/DRMRightsClient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omadrm/drmengine/server/src/DRMRightsClient.cpp Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,1612 @@ +/* +* Copyright (c) 2003 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: Client side class implementation +* +*/ + + +// INCLUDE FILES +#include +#include +#include "DRMRightsClient.h" +#include "DRMEngineClientServer.h" +#include "DRMPermission.h" +#include "DRMAsset.h" +#include "drmlog.h" + +#ifdef __DRM_FULL +#include "RDRMHelper.h" +#endif + +// EXTERNAL DATA STRUCTURES +// EXTERNAL FUNCTION PROTOTYPES +// CONSTANTS +// MACROS + +// LOCAL CONSTANTS AND MACROS +_LIT( KServerFileName, "rightsserver.exe" ); + + +_LIT( KRightsServerStarterSemaphore, "RightsServerStarterSemaphore" ); + + +// Maximum number of message slots that we use +LOCAL_C const TInt KMaxMessageSlots = 4; + +// Try start the server only once. If it doesn't work, it doesn't work. +LOCAL_C const TUint8 KStartupCount = 1; + +// MODULE DATA STRUCTURES +struct TDRMFileDeletion + { + TDRMFileDeletion() : iName( KNullDesC ) {}; + ~TDRMFileDeletion() + { + if ( iName.Length() ) + { + iFs.Delete( iName ); + } + + iFs.Close(); + } + + RFs iFs; + TFileName iName; + }; + +template< class T > struct RDRMArrayReset + { + RDRMArrayReset( T& aItem ) : iItem( aItem ), + iCleanup( ResetAndDestroy, ( TAny* )this ) {}; + ~RDRMArrayReset() { }; + void PushL() + { + CleanupStack::PushL( iCleanup ); + }; + + static void ResetAndDestroy( TAny* aSelf ) + { + ( ( RDRMArrayReset< T >* )( aSelf ) )->iItem.ResetAndDestroy(); + ( ( RDRMArrayReset< T >* )( aSelf ) )->iItem.Close(); + }; + + private: + RDRMArrayReset(); // prohibit + + private: + T& iItem; + TCleanupItem iCleanup; + + }; + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::RDRMRightsClient +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +EXPORT_C RDRMRightsClient::RDRMRightsClient() : + iPtr( NULL ) + { + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::~RDRMRightsClient +// Destructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C RDRMRightsClient::~RDRMRightsClient() + { + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::Connect +// Opens connection to the server. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::Connect() + { + TInt ret = KErrNone; + TUint8 count = 0; + + const TVersion requiredVersion( + DRMEngine::KServerMajorVersion, + DRMEngine::KServerMinorVersion, + DRMEngine::KServerBuildVersion ); + + FOREVER + { + DRMLOG( _L( "RDRMRightsClient::Connect(): Create a new session" ) ); + ret = CreateSession( DRMEngine::KServerName, + requiredVersion, + KMaxMessageSlots ); + + if ( ret == KErrNotFound && count < KStartupCount ) + { + ret = StartServer(); + if ( ret ) + { + break; + } + + ++count; + } + else + { + break; + } + } + +#ifdef __DRM_FULL + // startup code, if it starts it starts if not it will be tried again. + RDRMHelper helper; + TInt ignore = helper.Connect(); // Start HelperServer + helper.Close(); +#endif + + DRMLOG2( _L( "RDRMRightsClient::Connect(): Result: %d" ), ret ); + + return ret; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::Close +// Closes the connection to the server. +// ----------------------------------------------------------------------------- +// +EXPORT_C void RDRMRightsClient::Close() + { + DRMLOG( _L( "RDRMRightsClient::Close()" ) ); + RHandleBase::Close(); + } + +EXPORT_C TInt RDRMRightsClient::StartServer() + { + DRMLOG( _L( "RDRMRightsClient::StartServer()" ) ); + + RSemaphore semaphore; + RSemaphore semaphore2; + TFindServer server( DRMEngine::KServerName ); + TFullName name; + RProcess process; + TInt error = KErrNone; + + // "local" semaphore + error = semaphore2.CreateGlobal( KRightsServerStarterSemaphore, // name + 1 , // count + EOwnerThread ); // owner + + if ( error == KErrAlreadyExists ) + { + error = semaphore2.OpenGlobal( KRightsServerStarterSemaphore ); + } + + + // Semaphore not created or opened, don't need to close + if( error ) + { + return error; + } + + // Server updated semaphore + error = semaphore.CreateGlobal( DRMEngine::KDRMSemaphore, // name + 0 , // count + EOwnerThread ); // owner + + if ( error == KErrAlreadyExists ) + { + error = semaphore.OpenGlobal( DRMEngine::KDRMSemaphore ); + } + + // Semaphore not created or opened, don't need to close + if( error ) + { + semaphore2.Close(); + return error; + } + + // Wait until server has done all its things. + semaphore2.Wait(); + + // Check if the server is already running. + error = server.Next( name ); + + if ( !error ) + { + // Yep, it's already running. + error = KErrNone; + } + else + { + error = process.Create( KServerFileName, + KNullDesC ); + + if ( !error ) + { + User::After( 1000 ); + + process.Resume(); + process.Close(); + + // Wait here for the server process startup to complete + // server will signal the global semaphore + semaphore.Wait(); + } + } + + // Close both semaphores and signal the "local" one. + semaphore.Close(); + semaphore2.Signal(); + semaphore2.Close(); + + DRMLOG2( _L( "RDRMRightsClient::StartServer(): %d" ), error ); + return error; + + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::AddRecord +// Add a new entry to the rights database. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::AddRecord( const TDesC8& aCEK, // Content encryption key + // The rights object which is to be added + const CDRMPermission& aRightsObject, + const TDesC8& aCID, // Content-ID + TDRMUniqueID& aID ) // Unique ID, out-parameter + { + DRMLOG( _L( "RDRMRightsClient::AddRecord" ) ); + TInt error = KErrArgument; + + // Check the parameters. + if ( aCEK.Length() ) + { + + HBufC8* rightsData = NULL; + TRAP( error, rightsData = aRightsObject.ExportL() ); + TInt size = aRightsObject.Size(); + + if ( rightsData && size > 0 ) + { + // For C/S communications. + TPtr8 rightsObject( NULL, 0 ); + TPtr8 uid( reinterpret_cast< TUint8* >( &aID ), + 0, + sizeof( TDRMUniqueID ) ); + + rightsObject.Set( const_cast< TUint8* >( rightsData->Ptr() ), + size, + size ); + + + // Send the message. + error = SendReceive( DRMEngine::EAddRecord, + TIpcArgs( &aCID, &rightsObject, &aCEK, &uid ) ); + + delete rightsData; + rightsData = NULL; + } + } + + DRMLOG2( _L( "RDRMRightsClient::AddRecord: %d" ), error ); + return error; + } + + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::AddProtectedRecord +// Add a protected entry to the rights database. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::AddProtectedRecord( + const TDesC8& aProtectedCek, + TBool aDomainRecord, + const CDRMPermission& aRightsObject, + const TDesC8& aCID, + TDRMUniqueID& aID ) // Unique ID, out-parameter + { + DRMLOG( _L( "RDRMRightsClient::AddProtectedRecord" ) ); + + TInt error = KErrNone; + TInt message = DRMEngine::EAddProtectedRecord; + HBufC8* rightsData = NULL; + TInt size = aRightsObject.Size(); + TPtr8 rightsObject( NULL, 0 ); + TPtr8 uid( reinterpret_cast< TUint8* >( &aID ), 0, + sizeof( TDRMUniqueID ) ); + TPtr8 key( NULL, 0 ); + + TRAP( error, rightsData = aRightsObject.ExportL() ); + if ( !error ) + { + rightsObject.Set( const_cast< TUint8* >( rightsData->Ptr() ), size, + size ); + + if ( aDomainRecord ) + { + message = DRMEngine::EAddDomainRecord; + } + error = SendReceive( message, TIpcArgs( &aCID, &rightsObject, &aProtectedCek, &uid ) ); + + delete rightsData; + rightsData = NULL; + } + DRMLOG2( _L( "RDRMRightsClient::AddProtectedRecord: %d" ), error ); + return error; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetDBEntriesL +// Get a file name from the server. The file contains the rights objects, +// which are then converted to RPointerArray. +// ----------------------------------------------------------------------------- +// +EXPORT_C void RDRMRightsClient::GetDBEntriesL( const TDesC8& aId, + RPointerArray< CDRMPermission >& aRightsList ) + { + DRMLOG( _L( "RDRMRightsClient::GetDBEntries" ) ); + if( aId.Length() ) + { + // Temporary file name from the server. + TDRMFileDeletion item; + + // Make sure that the array is empty. + aRightsList.ResetAndDestroy(); + + // For file operations. Destructor of TDRMFileDeletion + // deletes the file & closes the session. + User::LeaveIfError( item.iFs.Connect() ); + + User::LeaveIfError( SendReceive( DRMEngine::EGetEntryList, + TIpcArgs( &item.iName, &aId ) ) ); + + // Convert the file to a list. + FileToListL( item.iFs, item.iName, aRightsList ); + + DRMLOG( _L( "RDRMRightsClient::GetDBEntries ok" ) ); + + return; + } + + // Invalid parameter. + User::Leave( KErrArgument ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetDbEntryL +// Get a single RO from the server. +// ----------------------------------------------------------------------------- +// +EXPORT_C CDRMPermission* RDRMRightsClient::GetDbEntryL( const TDesC8& aContentID, + const TDRMUniqueID& aUniqueID ) + { + DRMLOG( _L( "RDRMRightsClient::GetDbEntryL" ) ); + + CDRMPermission* permission = NULL; + TInt size = 0; + TPckg package( size ); + TPtrC8 uid( reinterpret_cast< TUint8* >( const_cast< TDRMUniqueID* >( + &aUniqueID ) ), sizeof( TDRMUniqueID ) ); + + User::LeaveIfError( SendReceive( DRMEngine::EGetDbEntry, + TIpcArgs( &package, NULL, &uid, &aContentID ) ) ); + HBufC8* rightsData = HBufC8::NewMaxLC( size ); + TPtr8 objectPkg( const_cast< TUint8* >( rightsData->Ptr() ), size, + size ); + User::LeaveIfError( SendReceive( DRMEngine::EGetPreparedData, + TIpcArgs( &objectPkg) ) ); + + permission = CDRMPermission::NewLC(); + permission->ImportL( rightsData->Des() ); + CleanupStack::Pop(); // permission + CleanupStack::PopAndDestroy(); // Rights data + + DRMLOG( _L( "RDRMRightsClient::GetDbEntryL ok" ) ); + return permission; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::DeleteDbEntry +// Deletes all rights objects associated with the given UID. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::DeleteDbEntry( const TDesC8& aContentID ) + { + DRMLOG( _L( "RDRMRightsClient::DeleteDbEntry with CID" ) ); + + TInt error = KErrArgument; + + // Check the parameter. + if ( aContentID.Length() ) + { + return SendReceive( DRMEngine::EDeleteWithCID, + TIpcArgs( NULL, NULL, &aContentID ) ); + } + + return error; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::DeleteDbEntry +// Delete a single rights object identified by given parameters. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::DeleteDbEntry( const TDesC8& aContentID, + const TDRMUniqueID& aUniqueID ) + { + DRMLOG( _L( "RDRMRightsClient::DeleteDbEntry with CID & UID" ) ); + + if ( aContentID.Length() ) + { + // Something to do. + // Put aUniqueID inside a descriptor. + // Works even if its typedef is changed. + TPtrC8 uid( reinterpret_cast< TUint8* >( + const_cast< TDRMUniqueID* >( &aUniqueID ) ), + sizeof( TDRMUniqueID ) ); + + return SendReceive( DRMEngine::EDeleteRO, + TIpcArgs( &uid, NULL, NULL, &aContentID ) ); + } + + return KErrArgument; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::ExportContentIDList +// Overloaded method: requests all content IDs to be put to a file. +// Assumes that the given descriptor represents a buffer large enough to +// contain the file name. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::ExportContentIDList( TDes& aFileName ) + { + DRMLOG( _L( "RDRMRightsClient::ExportContentIDLis" ) ); + + return SendReceive( DRMEngine::EExportCIDs, + TIpcArgs( &aFileName ) ); + + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::ExportContentIDList +// Overloaded method: requests all content IDs to be put to a file, +// and then converts the file into RPointerArray. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::ExportContentIDList( RPointerArray< HBufC8 >& aCIDList ) + { + DRMLOG( _L( "RDRMRightsClient::ExportContentIDList to array" ) ); + TFileName name; + aCIDList.ResetAndDestroy(); + + TInt error = ExportContentIDList( name ); + if ( !error ) + { + RFs fs; + error = fs.Connect(); + if ( !error ) + { + TRAP( error, URIFileToArrayL( fs, name, aCIDList ) ); + if ( error ) + { + aCIDList.ResetAndDestroy(); + } + + fs.Delete( name ); + fs.Close(); + } + } + + DRMLOG2( _L( "RDRMRightsClient::ExportContentIDList: %d" ), error ); + + return error; + } + + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetDecryptionKey +// Fetches the decryption key from the server. +// Uses TR mechanisms. Uses asynchronous C/S call. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::GetDecryptionKey( const TInt aIntent, + const TDesC8& aContentID, + TDes8& aKey ) + { + DRMLOG( _L( "RDRMRightsClient::GetDecryptionKey" ) ); + // Make this internally asynchronous. + TRequestStatus status; + + SendReceive( DRMEngine::EGetKey, + TIpcArgs( aIntent, const_cast(&aContentID), &aKey ), + status ); + + User::WaitForRequest( status ); + + DRMLOG2( _L( "RDRMRightsClient::GetDecryptionKey: %d" ), status.Int() ); + + return status.Int(); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::CheckRights +// Checks if appropriate rights exist for a certain content ID. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::CheckRights( + const TInt aIntent, + const TDesC8& aContentID, + TUint32& aRejection ) + { + TInt error = KErrNone; + TInt size = 0; + + TPckg package( size ); + TPckg package2( aRejection ); + + DRMLOG( _L( "RDRMRightsClient::CheckRights" ) ); + error = SendReceive( DRMEngine::ECheckRights, TIpcArgs( aIntent, + &aContentID, &package, &package2 ) ); + + DRMLOG2( _L( "RDRMRightsClient::CheckRights: %d" ), error ); + + return error; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetActiveRightsL +// Checks if appropriate rights exist for a certain content ID and returns them. +// Returns NULL if no rights are available +// ----------------------------------------------------------------------------- +// +EXPORT_C CDRMPermission* RDRMRightsClient::GetActiveRightsL( + const TInt aIntent, + const TDesC8& aContentID, + TUint32& aRejection ) + { + TInt r; + TInt size = 0; + TPckg package( size ); + TPckg package2( aRejection ); + CDRMPermission* permission = NULL; + HBufC8* buffer = NULL; + + DRMLOG( _L( "RDRMRightsClient::GetActiveRightsL" ) ); + r = SendReceive( DRMEngine::ECheckRights, TIpcArgs( aIntent, &aContentID, + &package, &package2 ) ); + + // Get rights. Return NULL if no rights are available, otherwise leave + // for all other errors. + if ( r == KErrNone ) + { + buffer = HBufC8::NewMaxLC( size ); + TPtr8 objectPkg( const_cast< TUint8* >( buffer->Ptr() ), size, size ); + User::LeaveIfError( SendReceive( DRMEngine::EGetPreparedData, + TIpcArgs( &objectPkg) ) ); + permission = CDRMPermission::NewLC(); + permission->ImportL( buffer->Des() ); + CleanupStack::Pop(); // permission + CleanupStack::PopAndDestroy(); // buffer + } + else if ( r != KErrCANoRights && r != KErrCANoPermission && + r != KErrCAPendingRights ) + { + User::Leave( r ); + } + + DRMLOG( _L( "RDRMRightsClient::GetActiveRightsL: done" ) ); + return permission; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::Count +// Returns the amount of unique content IDs in the database. +// If an error occurs, a negative value is returned (Symbian OS / DRM 3 specific +// error code). +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::Count() + { + DRMLOG( _L( "RDRMRightsClient::Count" ) ); + + TInt count = 0; + TInt error = KErrNone; + + TPtr8 ptr( reinterpret_cast< TUint8* >( &count ), + 0, + sizeof( TInt ) ); + + error = SendReceive( DRMEngine::ECount, + TIpcArgs( &ptr ) ); + + if ( !error ) + { + error = count; + } + + DRMLOG2( _L( "RDRMRightsClient::Count: %d" ), error ); + + return error; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::DeleteAll +// Empties the database. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::DeleteAll() + { + DRMLOG( _L( "RDRMRightsClient::DeleteAll" ) ); + + TInt error = SendReceive( DRMEngine::EDeleteAll, TIpcArgs( NULL ) ); + + DRMLOG2( _L( "RDRMRightsClient::DeleteAll: %d" ), error ); + + return error; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::Consume() +// Consume the right with specific intent and contentID +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::Consume( const TInt aIntent, + const TDesC8& aContentID ) + { + TInt error = KErrNone; + DRMLOG( _L( "RDRMRightsClient::Consume" ) ); + + error = SendReceive( DRMEngine::EConsume, + TIpcArgs( aIntent, &aContentID ) ); + + DRMLOG2( _L( "RDRMRightsClient::Consume: %d" ), error ); + return error; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::CheckConsume() +// Check if Consume is possibke +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::CheckConsume( const TInt aIntent, + const TDesC8& aContentID ) + { + TInt error = KErrNone; + DRMLOG( _L( "RDRMRightsClient::CheckConsume" ) ); + + error = SendReceive( DRMEngine::ECheckConsume, + TIpcArgs( aIntent, &aContentID ) ); + + DRMLOG2( _L( "RDRMRightsClient::CheckConsume: %d" ), error ); + return error; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::CalculatePadding +// Calculate the padding from a data block and a certain content ID. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::CalculatePadding( + const TDesC8& aLastTwoDataBlocks) + { + DRMLOG( _L( "RDRMRightsClient::CalculatePadding" ) ); + + return SendReceive( DRMEngine::ECalculatePadding, + TIpcArgs ( &aLastTwoDataBlocks) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient:: +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::ForwardLockURI( HBufC8*& aURI ) + { + DRMLOG( _L( "RDRMRightsClient::ForwardLockURI" ) ); + TBuf8< DRMEngine::KMaxOmaV1CIDLength > buf; + TInt error = SendReceive( DRMEngine::EGetFLUri, + TIpcArgs( &buf ) ); + + if ( error ) + { + aURI = NULL; + return error; + } + + aURI = buf.Alloc(); + + if ( aURI ) + { + return KErrNone; + } + + return KErrNoMemory; + } + + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::AddDomainRO +// Add domain rights object xml representation to the rdb +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::AddDomainRO( const TDesC8& aRoId, + const TDesC8& aXmlData ) + { + DRMLOG( _L( "RDRMRightsClient::AddDomainRO" ) ); + TInt error = KErrArgument; + + // Check the parameters. + if ( aRoId.Length() && aXmlData.Length() ) + { + // Send the message. + error = SendReceive( DRMEngine::EAddDomainRO, + TIpcArgs( &aRoId, &aXmlData) ); + } + + DRMLOG2( _L( "RDRMRightsClient::AddDomainRO: %d" ), error ); + return error; + }; + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetDomainROL +// Get domain rights object xml representation from the rdb +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* RDRMRightsClient::GetDomainROL( const TDesC8& aRoId ) + { + DRMLOG( _L( "RDRMRightsClient::GetDomainROL" ) ); + + // Check the parameter. + if ( aRoId.Length() ) + { + TInt size = 0; + TPckg package( size ); + + // Call the server. Throw an exception in case of an error. + User::LeaveIfError( + SendReceive( DRMEngine::EGetDomainRO, + TIpcArgs( &package, &aRoId ) ) ); + + HBufC8* roData = HBufC8::NewMaxLC( size ); + + // Package 'object' into TPtr8. + TPtr8 objectPkg( const_cast< TUint8* >( roData->Ptr() ), + size, + size ); + + User::LeaveIfError( + SendReceive( DRMEngine::EGetPreparedData, + TIpcArgs( &objectPkg) ) ); + CleanupStack::Pop( roData ); // roData + return roData; + } + + User::Leave( KErrArgument ); + + // Never reached. + return NULL; + }; + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetDomainROL +// Get domain rights object xml representation from the rdb +// ----------------------------------------------------------------------------- +// +EXPORT_C void RDRMRightsClient::GetDomainRosForCidL( + const TDesC8& aContentId, + RPointerArray& aRoList) + { + TInt size = 0; + TPckg pkg(size); + HBufC8* buffer = NULL; + HBufC8* ro = NULL; + TInt roSize; + TInt offset; + + + DRMLOG(_L("RDRMRightsClient::GetDomainRoForCidL")); + User::LeaveIfError(SendReceive(DRMEngine::EGetDomainRoForCid, + TIpcArgs(&aContentId, &pkg))); + if (size > 0) + { + buffer = HBufC8::NewMaxLC(size); + TPtr8 ptr( const_cast< TUint8* >( buffer->Ptr() ), + size, + size ); + User::LeaveIfError(SendReceive(DRMEngine::EGetPreparedData, + TIpcArgs(&ptr))); + offset = 0; + while (offset < size) + { + Mem::Copy( &roSize, ptr.Ptr()+offset, sizeof(TInt) ); + offset += sizeof (TInt); + ro = ptr.Mid(offset, roSize).AllocL(); + aRoList.Append(ro); + offset += roSize; + } + CleanupStack::PopAndDestroy(); + } + }; + +// ----------------------------------------------------------------------------- +// RDRMRightsClient:: +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::Encrypt( const TDesC8& aIv, + TPtr8& aData, + TBool aAddPadding ) + { + return SendReceive( DRMEngine::EEncrypt, + TIpcArgs( &aIv, &aData, aAddPadding ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient:: +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::Decrypt( const TDesC8& aIv, + TPtr8& aData, + TBool aRemovePadding ) + { + return SendReceive( DRMEngine::EDecrypt, + TIpcArgs( &aIv, &aData, aRemovePadding ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient:: +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::InitializeKey( const TDesC8& aContentId ) + { + return SendReceive( DRMEngine::EInitializeKey, + TIpcArgs( &aContentId ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient:: +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::InitializeGroupKey( const TDesC8& aGroupId, + const TDesC8& aGroupKey, + TEncryptionMethod aMethod ) + { + return SendReceive( DRMEngine::EInitializeGroupKey, + TIpcArgs( &aGroupId, &aGroupKey, aMethod ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::DeleteDomainRO +// Delete domain rights object xml representation from the rdb +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::DeleteDomainRO( const TDesC8& aRoId ) + { + DRMLOG( _L( "RDRMRightsClient::DeleteDomainRO" ) ); + + // Check the parameter. + if ( aRoId.Length() ) + { + return SendReceive( DRMEngine::EDeleteDomainRO, + TIpcArgs( &aRoId ) ); + } + + return KErrArgument; + }; + + +// ----------------------------------------------------------------------------- +// RDRMRightsClient:: +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::IsInCache( const TDesC8& aID, + const TTime& aTime, + TBool& aInCache ) + { + DRMLOG( _L( "RDRMRightsClient::IsInCache" ) ); + TPckgC< TTime > timePckg( aTime ); + TPckg< TBool > inCache( aInCache ); + + return SendReceive( DRMEngine::EIsInCache, + TIpcArgs( &aID, &timePckg, &inCache ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient:: +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::IsInCache( const TDesC8& aID, + TBool& aInCache ) + { + DRMLOG( _L( "RDRMRightsClient::IsInCache" ) ); + + TPckg< TBool > inCache( aInCache ); + + return SendReceive( DRMEngine::EIsInCache, + TIpcArgs( &aID, NULL, &inCache ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient:: +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::AddToCache( const TDesC8& aID, + const TTime& aTime ) + { + DRMLOG( _L( "RDRMRightsClient::AddToCache" ) ); + + TPckgC< TTime > timePckg( aTime ); + + return SendReceive( DRMEngine::EAddToCache, + TIpcArgs( &aID, &timePckg ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient:: +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::AddToCache( const TDesC8& aID ) + { + DRMLOG( _L( "RDRMRightsClient::AddToCache" ) ); + + return SendReceive( DRMEngine::EAddToCache, + TIpcArgs( &aID, NULL ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::DeleteExpiredPermissions +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void RDRMRightsClient::DeleteExpiredPermissions( TRequestStatus& aStatus ) + { + DRMLOG( _L( "RDRMRightsClient::DeleteExpiredPermissions" ) ); + + SendReceive( DRMEngine::EDeleteExpired, aStatus ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::SetEstimatedArrival +// sets the estimated RO arrival time to the given delta +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::SetEstimatedArrival( const TDesC8& aContentID, + TTimeIntervalSeconds aDeltaSeconds ) + { + DRMLOG( _L( "RDRMRightsClient::SetEstimatedArrival" ) ); + TInt error = KErrNone; + + TPckg< TTimeIntervalSeconds > delta( aDeltaSeconds ); + + error = SendReceive( DRMEngine::ESetEstimatedArrival, + TIpcArgs( &aContentID, &delta ) ); + + return error; + }; + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetEstimatedArrival +// sets the amount of time in which the RO should arrive in +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::GetEstimatedArrival( const TDesC8& aContentID, + TTimeIntervalSeconds& aDeltaSeconds ) + { + DRMLOG( _L( "RDRMRightsClient::SetEstimatedArrival" ) ); + TInt error = KErrNone; + + TPckg< TTimeIntervalSeconds > delta( aDeltaSeconds ); + + error = SendReceive( DRMEngine::EGetEstimatedArrival, + TIpcArgs( &aContentID, &delta ) ); + + return error; + }; + + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::SetName +// sets the name. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::SetName( const TDesC8& aContentID, + const TDesC& aName ) + { + DRMLOG( _L( "RDRMRightsClient::SetName" ) ); + return SendReceive( DRMEngine::ESetName, + TIpcArgs( &aContentID, &aName ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetName +// Gets the name. Two-phase operation. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::GetName( const TDesC8& aContentID, + HBufC*& aName ) + { + DRMLOG( _L( "RDRMRightsClient::GetName" ) ); + TPckgBuf< TInt > size( 0 ); + + TInt error = SendReceive( DRMEngine::EGetName, + TIpcArgs( &aContentID, &size ) ); + if ( !error ) + { + if ( !size() ) + { + aName = HBufC::New( 1 ); + if ( !aName ) + { + error = KErrNoMemory; + } + } + else + { + aName = HBufC::New( size() ); + if ( aName ) + { + TPtr data( aName->Des() ); + + error = SendReceive( DRMEngine::EGetWideData, + TIpcArgs( &data ) ); + + if ( error ) + { + delete aName; aName = NULL; + } + } + else + { + error = KErrNoMemory; + } + } + } + + return error; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::Cancel +// ----------------------------------------------------------------------------- +// +EXPORT_C void RDRMRightsClient::Cancel() + { + DRMLOG( _L(" RDRMRightsClient::Cancel" ) ); + SendReceive( DRMEngine::ECancel ); + } + + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetUdtData +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::GetUdtData( TDes8& aUdtData ) + { + DRMLOG( _L( "RDRMRightsClient::GetUdtData" ) ); + + TInt error = SendReceive( DRMEngine::EGetUdtData, + TIpcArgs( &aUdtData ) ); + + return error; + }; + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::InitializeUdt +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::InitiateUdt( const TDesC8& aKey ) + { + DRMLOG( _L( "RDRMRightsClient::InitiateUdt" ) ); + + TInt error = SendReceive( DRMEngine::EInitiateUdt, + TIpcArgs( &aKey ) ); + return error; + }; + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::InitOrphanedContentIdList +// ----------------------------------------------------------------------------- +// +EXPORT_C void RDRMRightsClient::InitOrphanedContentIdList( TBool aPerformScan, + TRequestStatus& aStatus ) + { + DRMLOG( _L( "RDRMRightsClient::ExportOrphanedContentIdList" ) ); + + SendReceive( DRMEngine::EInitOrphanedList, + TIpcArgs( aPerformScan ), aStatus ); + + DRMLOG( _L( "RDRMRightsClient::ExportOrphanedContentIdList done" ) ); + }; + + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::ExportOrphanedContentIdList +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::ExportOrphanedContentIdList( TDes& aFileName ) + { + DRMLOG( _L( "RDRMRightsClient::ExportOrphanedContentIdList" ) ); + + return SendReceive( DRMEngine::EGetOrphanedList, + TIpcArgs( &aFileName ) ); + + }; + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::ExportOrphanedContentIdList +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::ExportOrphanedContentIdList( + RPointerArray& aContentIdList ) + { + DRMLOG( _L( "RDRMRightsClient::ExportOrphanedContentIdList to array" ) ); + TFileName name; + aContentIdList.ResetAndDestroy(); + + TInt error = ExportOrphanedContentIdList( name ); + if ( !error ) + { + RFs fs; + error = fs.Connect(); + if ( !error ) + { + TRAP( error, URIFileToArrayL( fs, name, aContentIdList ) ); + if ( error ) + { + aContentIdList.ResetAndDestroy(); + } + + fs.Delete( name ); + fs.Close(); + } + } + + DRMLOG2( _L( "RDRMRightsClient::ExportOrphanedContentIdList to array: %d" ), error ); + + return error; + }; + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::EncodeRightsIssuerField +// The encoded field is consturcted from +// - F/L prefix +// - phone serial number +// - base64encode(AES IV + AES encoded original field incl. padding) +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::EncodeRightsIssuerField( + const TDesC8& aOldValue, + HBufC8*& aNewValue ) + { + DRMLOG( _L( "RDRMRightsClient::EncodeRightsIssuerField" ) ); + + TInt error( KErrNone ); + + TInt size( aOldValue.Length() ); // original length + size += KDCFKeySize - ( size % KDCFKeySize ); // padding + size += KDCFKeySize; // IV + size += ( size + 2 ) / 3 * 4; // base64 + size += RMobilePhone::KPhoneSerialNumberSize; + size += 3; // "flk" + + aNewValue = HBufC8::New( size ); + if ( aNewValue ) + { + TPtr8 des( aNewValue->Des() ); + + des = aOldValue; + + error = SendReceive( DRMEngine::EEncodeRightsIssuerField, + TIpcArgs( &des ) ); + if ( error ) + { + delete aNewValue; + aNewValue = NULL; + } + } + else + { + error = KErrNoMemory; + } + + DRMLOG2( _L( "RDRMRightsClient::EncodeRightsIssuerField> %d" ), error ); + + return error; + } + +EXPORT_C TInt RDRMRightsClient::DecodeRightsIssuerField( + const TDesC8& aEncoded, + HBufC8*& aDecoded ) + { + DRMLOG( _L( "DRMRightsClient::DecodeRightsIssuerField" ) ); + + TInt error( KErrNone ); + + aDecoded = HBufC8::New( aEncoded.Length() ); + if ( aDecoded ) + { + TPtr8 des( aDecoded->Des() ); + + error = SendReceive( DRMEngine::EDecodeRightsIssuerField, + TIpcArgs( &aEncoded, + &des ) ); + if ( error ) + { + delete aDecoded; + aDecoded = NULL; + } + else if ( !( aDecoded->Length() ) ) + { + // The decoding process didn't change it. + *aDecoded = aEncoded; + } + } + else + { + error = KErrNoMemory; + } + + DRMLOG2( _L( "DRMRightsClient::DecodeRightsIssuerField: error %d" ), error ); + + return error; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::SetAuthenticationSeed +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::SetAuthenticationSeed( const TDesC8& aContentID, + const TDesC8& aSeed ) + { + DRMLOG( _L( "RDRMRightsClient::SetAuthenticationSeed" ) ); + return SendReceive( DRMEngine::ESetAuthenticationSeed, + TIpcArgs( &aContentID, &aSeed ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetAuthenticationSeed +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::GetAuthenticationSeed( const TDesC8& aContentID, + TDes8& aSeed ) + { + DRMLOG( _L( "RDRMRightsClient::GetAuthenticationSeed" ) ); + return SendReceive( DRMEngine::EGetAuthenticationSeed, + TIpcArgs( &aContentID, &aSeed ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::FileToListL +// Converts the given file into an array. +// ----------------------------------------------------------------------------- +// +void RDRMRightsClient::FileToListL( RFs& aFs, + const TDesC& aFileName, + RPointerArray< CDRMPermission >& aList ) + { + DRMLOG( _L( "RDRMRightsClient::FileToListL" ) ); + TInt error = KErrNone; + + // Temporary storage. + CDRMPermission* tmpObject; + + // To access the file data. + RFileReadStream fileStream; + + // How many objects there is in the file. + TInt size = 0; + + // Temporary counter. + TInt count = 0; + + + // Open the file. + User::LeaveIfError( fileStream.Open( aFs, aFileName, EFileRead | EFileStream ) ); + CleanupClosePushL( fileStream ); + + size = fileStream.ReadInt32L(); + + while( count < size ) + { + // Allocate a new RO. + tmpObject = CDRMPermission::NewL(); + + // Read the object. + TRAP( error, tmpObject->InternalizeL( fileStream ) ); + + if ( !error ) + { + // Add the object into the list. + error = aList.Append( tmpObject ); + } + + if ( error ) + { + delete tmpObject; + User::Leave( error ); + } + + // Now tmpObject is under responsibility of aList. + ++count; + } + + // All done. + CleanupStack::PopAndDestroy(); // fileStream + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::URIFileToArrayL +// Converts the given file into an array. +// ----------------------------------------------------------------------------- +// +void RDRMRightsClient::URIFileToArrayL( RFs& aFs, + const TDesC& aFile, + RPointerArray< HBufC8 >& aList ) + { + DRMLOG( _L( "RDRMRightsClient::URIFileToArrayL" ) ); + RFileReadStream stream; + TUint16 size = 0; + TPtr8 data( NULL, 0, 0 ); + + User::LeaveIfError( stream.Open( aFs, aFile, EFileRead | EFileStream ) ); + CleanupClosePushL( stream ); + + size = stream.ReadUint16L(); + while( size > 0 ) + { + HBufC8* tmp = HBufC8::NewLC( size ); + data.Set( tmp->Des() ); + stream.ReadL( data, size ); + User::LeaveIfError( aList.Append( tmp ) ); + CleanupStack::Pop(); // tmp + size = stream.ReadUint16L(); + } + + // All read, return. + + CleanupStack::PopAndDestroy(); // stream + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::VerifyMacL +// Verifies the MAC. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::VerifyMacL(const TDesC8& aSignedInfoElement, + const TDesC8& aMacValue ) const + { + DRMLOG( _L( "RDRMRightsClient::VerifyMacL" ) ); + + TInt error = SendReceive( DRMEngine::EVerifyMac, + TIpcArgs( &aSignedInfoElement, &aMacValue) ); + return error; + } + + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetSupportedIndividualsL +// retrieves the supported individuals list +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::GetSupportedIndividualsL( + RPointerArray& aIndividuals) const + { + DRMLOG( _L( "RDRMRightsClient::GetSupportedIndividualsL" ) ); + TPckgBuf< TInt > size( 0 ); + TInt error = SendReceive( DRMEngine::EGetSupportedIndividuals, + TIpcArgs( &size) ); + HBufC8* dataBuf = NULL; + HBufC8* individual = NULL; + TInt indivSize; + TInt offset; + + if ( !error ) + { + if ( !size() ) + { + return KErrNone; + } + else + { + dataBuf = HBufC8::NewLC( size() ); + if ( dataBuf ) + { + TPtr8 data( dataBuf->Des() ); + + error = SendReceive( DRMEngine::EGetPreparedData, + TIpcArgs( &data ) ); + + if ( !error ) + { + offset = 0; + while (offset < size()) + { + Mem::Copy( &indivSize, data.Ptr()+offset, sizeof(TInt) ); + offset += sizeof (TInt); + individual = data.Mid(offset, indivSize).AllocLC(); + aIndividuals.AppendL(individual); + CleanupStack::Pop(); // individual + offset += indivSize; + } + } + } + CleanupStack::PopAndDestroy(); + } + } + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::StopWatching +// ----------------------------------------------------------------------------- +// +EXPORT_C void RDRMRightsClient::StopWatching() const + { + SendReceive( DRMEngine::EStopWatching ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::UnwrapMacAndRek +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt RDRMRightsClient::UnwrapMacAndRek( const TDesC8& aMacAndRek, + TKeyTransportScheme aTransportScheme, + const TDesC8& aRightsIssuerId, + const TDesC8& aDomainId ) const + { + HBufC8* data = NULL; + TPtr8 dataPtr( NULL, 0 ); + TInt err = KErrNone; + + data = HBufC8::New( 1 + aMacAndRek.Size() ); + + if ( data ) + { + dataPtr.Set( data->Des() ); + dataPtr.SetLength( 1 ); + dataPtr[0] = aTransportScheme; + dataPtr.Append( aMacAndRek ); + + if( aDomainId.Length() ) + { + err = SendReceive( DRMEngine::EUnwrapDomainMacAndRek, TIpcArgs( &dataPtr, + &aRightsIssuerId, + &aDomainId ) ); + } + else + { + err = SendReceive( DRMEngine::EUnwrapDeviceMacAndRek, TIpcArgs( &dataPtr, + &aRightsIssuerId, + NULL ) ); + } + delete data; + data = NULL; + } + else + { + err = KErrNoMemory; + } + + return err; + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetRandomDataL +// ----------------------------------------------------------------------------- +// +EXPORT_C void RDRMRightsClient::GetRandomDataL( TDes8& aRandomData ) const + { + if( !aRandomData.Length() ) + { + User::Leave(KErrArgument); + } + User::LeaveIfError( SendReceive( DRMEngine::EGetRandomData, TIpcArgs( &aRandomData ) ) ); + } + +// ----------------------------------------------------------------------------- +// RDRMRightsClient::GetMeteringData() +// ----------------------------------------------------------------------------- +// +#ifndef RD_DRM_METERING +EXPORT_C HBufC8* RDRMRightsClient::GetMeteringDataL( const TDesC8& /*aRiId*/ ) + { + return NULL; + } +#else +EXPORT_C HBufC8* RDRMRightsClient::GetMeteringDataL( const TDesC8& aRiId ) + { + TInt error = KErrNone; + HBufC8* meteringData = NULL; + + if ( aRiId.Length() ) + { + TInt size = 0; + TPckg package( size ); + + error = SendReceive( DRMEngine::EGetMeteringData, + TIpcArgs( &package, &aRiId ) ); + + if ( error == KErrNotFound ) + { + return NULL; + } + + User::LeaveIfError( error ); + + meteringData = HBufC8::NewMaxLC( size ); + + // Package 'object' into TPtr8. + TPtr8 objectPkg( const_cast< TUint8* >( meteringData->Ptr() ), + size, + size ); + + User::LeaveIfError( SendReceive( DRMEngine::EGetPreparedData, + TIpcArgs( &objectPkg) ) ); + + CleanupStack::Pop(); // meteringData + return meteringData; + } + + User::Leave( KErrArgument ); + return NULL; + } +#endif //RD_DRM_METERING + + // ----------------------------------------------------------------------------- +// RDRMRightsClient::DeleteMeteringDataL +// ----------------------------------------------------------------------------- +// +#ifndef RD_DRM_METERING +EXPORT_C TInt RDRMRightsClient::DeleteMeteringDataL( const TDesC8& /*aRiId*/ ) + { + return KErrNotSupported; + } +#else +EXPORT_C TInt RDRMRightsClient::DeleteMeteringDataL( const TDesC8& aRiId ) + { + if ( aRiId.Length() ) + { + User::LeaveIfError( SendReceive( DRMEngine::EDeleteMeteringData, + TIpcArgs( &aRiId ) ) ); + return KErrNone; + } + else + { + return KErrArgument; + } + } +#endif + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + + +// End of File