--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commondrm/drmutility/src/DrmUtility.cpp Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,505 @@
+/*
+* Copyright (c) 2006-2009 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: DRM Utility
+*
+*/
+
+
+// INCLUDE FILES
+#include <Oma2Dcf.h>
+#include <drmagents.h>
+#include <drmutility.h>
+#include <centralrepository.h>
+#include <UTF.h>
+
+#include "Oma1Dcf.h"
+
+#include "DrmUtilityInternalcrkeys.h" // Cenrep extension for OmaBased
+
+// CONSTANTS
+_LIT8( KASFHeaderObject, "75B22630668E11CFA6D900AA0062CE6C" );
+_LIT8( KWrmHeader, "W\0R\0M\0H\0E\0A\0D\0E\0R\0" );
+
+const TInt KMinContentLength( 16 );
+const TInt KOma2EncryptionFieldOffset( 8 );
+const TInt KOmaHeaderLength( 512 );
+// This constant is for OMA1 case in which a buffer of 35-40
+// bytes is needed to recognize the mime type.
+const TInt KMinContentLengthOma1Based( 40 );
+const TInt KWMHeaderObjectLength( 8 );
+const TInt KWMTopLevelHeaderObjectLength( 30 );
+const TInt KMaxWMHeaderLength( ( KMaxTInt32 / 2 ) - 1 );
+
+const TInt KCenRepDataLength( 50 );
+
+// ============================ LOCAL FUNCTIONS ================================
+
+// -----------------------------------------------------------------------------
+// FormatGUID
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void FormatGUID( TDes8 &aGUID )
+ {
+ TBuf8<16> copyGUID( aGUID );
+ TInt i( 0 );
+ for ( i = 0; i < 4; i++ )
+ {
+ copyGUID[i] = aGUID[3-i];
+ }
+ for ( i = 4; i < 6; i++ )
+ {
+ copyGUID[i] = aGUID[9 - i];
+ }
+ for ( i = 6; i < 8; i++ )
+ {
+ copyGUID[i] = aGUID[13 - i];
+ }
+ for ( i = 8; i < 16 ; i++)
+ {
+ copyGUID[i] = aGUID[i];
+ }
+ aGUID.Delete( 0, 32 );
+ for ( i = 0; i < 16; i++ )
+ {
+ aGUID.AppendNumFixedWidthUC( copyGUID[i], EHex, 2 );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ConvertToInt64
+// -----------------------------------------------------------------------------
+//
+LOCAL_C TInt64 ConvertToInt64( TDesC8& aDes )
+ {
+ TInt64 num( 0 );
+ TInt i( 0 );
+ for ( i = 7 ; i >= 0; i-- )
+ {
+ num <<= 8;
+ num |= aDes[i];
+ }
+ return num;
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// Default constructor
+// -----------------------------------------------------------------------------
+//
+DRM::CDrmUtility::CDrmUtility()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+DRM::CDrmUtility::~CDrmUtility()
+ {
+ delete iOmaBasedAgentName;
+ delete iOmaBasedMimeType;
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmUtility::NewLC
+// First phase constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C DRM::CDrmUtility* DRM::CDrmUtility::NewLC()
+ {
+ DRM::CDrmUtility* self( new( ELeave ) CDrmUtility );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmUtility::NewL
+// First phase constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C DRM::CDrmUtility* DRM::CDrmUtility::NewL()
+ {
+ DRM::CDrmUtility* self( NewLC() );
+ CleanupStack::Pop();
+ return self;
+ }
+
+void DRM::CDrmUtility::ConstructL()
+ {
+ TInt err( KErrNone );
+
+ TRAP(err, FetchOmaBasedInfoL() );
+ if( err)
+ {
+ if( iOmaBasedAgentName )
+ {
+ delete iOmaBasedAgentName;
+ }
+ iOmaBasedAgentName = NULL;
+ if( iOmaBasedMimeType )
+ {
+ delete iOmaBasedMimeType;
+ }
+ iOmaBasedMimeType = NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmUtility::FetchOmaBasedInfoL
+// -----------------------------------------------------------------------------
+//
+void DRM::CDrmUtility::FetchOmaBasedInfoL()
+ {
+ TInt err = KErrNone;
+ CRepository* repository( NULL );
+ RBuf bOmaBasedAgentName;
+ RBuf bOmaBasedMimeType;
+
+ CleanupClosePushL(bOmaBasedAgentName);
+ CleanupClosePushL(bOmaBasedMimeType);
+ bOmaBasedAgentName.CreateL( KCenRepDataLength );
+ bOmaBasedMimeType.CreateL( KCenRepDataLength );
+
+ TRAP( err, repository = CRepository::NewL( KCRUidOmaBased ) );
+ if ( !err )
+ {
+ CleanupStack::PushL( repository );
+
+ err = repository->Get( KDrmOmaBasedName, bOmaBasedAgentName );
+ if( !err )
+ {
+ iOmaBasedAgentName = bOmaBasedAgentName.AllocL();
+ }
+
+ err = repository->Get( KOmaBasedMimeType, bOmaBasedMimeType );
+ if( !err )
+ {
+ iOmaBasedMimeType = CnvUtfConverter::ConvertFromUnicodeToUtf8L( bOmaBasedMimeType );
+ }
+ CleanupStack::PopAndDestroy( repository );
+ }
+
+ CleanupStack::PopAndDestroy(2);
+
+ User::LeaveIfError( err );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDrmUtility::GetDrmInfoL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool DRM::CDrmUtility::GetDrmInfoL(
+ RFile& aFileHandle,
+ TPtrC& aAgent,
+ DRM::TDrmProtectionStatus& aProtected ) const
+ {
+ TInt r( KErrNone );
+ HBufC8* buffer( NULL );
+ TInt pos( 0 );
+ RFile file;
+ TBuf8< 32 > header;
+ TInt64 headerSize( 0 );
+ TBool isDrmFile( EFalse );
+ TPtr8 headerPtr( NULL, 0 );
+
+ aProtected = DRM::EUUnprotected;
+ aAgent.Set( KNullDesC );
+
+ CheckFileHandleL( aFileHandle );
+ User::LeaveIfError( file.Duplicate( aFileHandle ) );
+ CleanupClosePushL( file );
+
+ User::LeaveIfError( file.Seek( ESeekStart, pos ) );
+
+ // Check if the file is an ASF file
+ // To be Checked on runtime wether WM DRM is supporeted or not
+ User::LeaveIfError( file.Read( 0, header, KMinContentLength ) );
+ if ( header.Length() < KMinContentLength )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ FormatGUID( header );
+
+ if ( header == KASFHeaderObject )
+ {
+ // It's ASF, check still whether it's WM DRM protected or not
+ file.Read( header, KWMHeaderObjectLength );
+ headerSize = ConvertToInt64( header );
+ if( headerSize <= KWMTopLevelHeaderObjectLength ||
+ headerSize > KMaxWMHeaderLength )
+ {
+ User::Leave( KErrArgument );
+ }
+ buffer = HBufC8::NewLC( headerSize );
+
+ headerPtr.Set( buffer->Des() );
+ User::LeaveIfError( file.Read( headerPtr,
+ headerSize - ( KMinContentLength + KWMHeaderObjectLength ) ) );
+
+ r = headerPtr.Find( KWrmHeader );
+ if ( r == KErrNotFound )
+ {
+ aProtected = DRM::EUUnprotected;
+ }
+ else
+ {
+ isDrmFile = ETrue;
+ aProtected = DRM::EUProtected;
+ aAgent.Set( DRM::KDrmWMAgentName );
+ }
+ CleanupStack::PopAndDestroy( buffer ); // buffer
+ }
+ else
+ {
+ // Check whether it's OMA DRM protected or not
+ buffer = HBufC8::NewLC( KOmaHeaderLength );
+
+ headerPtr.Set( buffer->Des() );
+ User::LeaveIfError( file.Read( 0, headerPtr ));
+
+ if ( COma1Dcf::IsValidDcf( headerPtr ) )
+ {
+ isDrmFile = ETrue;
+ aProtected = DRM::EUProtected;
+ aAgent.Set( DRM::KDrmOmaAgentName );
+ }
+ else if ( COma2Dcf::IsValidDcf( headerPtr ) )
+ {
+ isDrmFile = ETrue;
+ _LIT8( KCommonHeadersBox, "ohdr" );
+ pos = headerPtr.Find( KCommonHeadersBox );
+
+ // If no box can be found or if there isn't enough data
+ // set protection as unknown
+ if( pos == KErrNotFound ||
+ headerPtr.Length() < pos + KOma2EncryptionFieldOffset )
+ {
+ aProtected = DRM::EUUnknown;
+ }
+ // If encryption field is 0, then content isn't protected
+ else if ( !headerPtr[pos + KOma2EncryptionFieldOffset] )
+ {
+ aProtected = DRM::EUUnprotected;
+ }
+ else
+ {
+ aProtected = DRM::EUProtected;
+ }
+ aAgent.Set( DRM::KDrmOmaAgentName );
+ }
+ else if ( (buffer->Des())[0] == 1)
+ {
+ // set the mimetype from the buffer which is in the beginning
+ // starting from byte 3 with the length specified at position 2
+ TPtrC8 mimeType( buffer->Des().Mid(3, (buffer->Des())[1]) );
+ if( !mimeType.CompareF( *iOmaBasedMimeType ) )
+ {
+ aAgent.Set( *DRM::CDrmUtility::iOmaBasedAgentName );
+ isDrmFile = ETrue;
+ }
+ }
+ CleanupStack::PopAndDestroy( buffer );
+ }
+ CleanupStack::PopAndDestroy( &file ); // file
+ return isDrmFile;
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmUtility::GetDrmInfoL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool DRM::CDrmUtility::GetDrmInfoL(
+ const TDesC8& aContent,
+ TPtrC& aAgent,
+ DRM::TDrmProtectionStatus& aProtected ) const
+ {
+ TInt r( KErrNone );
+ RFile file;
+ TPtr8 asfPtr( NULL, 0 );
+ TBuf8< 32 > asfGuidHex;
+ TBool isDrmFile( EFalse );
+
+ aProtected = DRM::EUUnprotected;
+ aAgent.Set( KNullDesC );
+
+ if ( aContent.Length() < KMinContentLength )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ // Check if the file is an ASF file
+ asfPtr.Set(
+ const_cast<TUint8*>( asfGuidHex.Ptr() ), 0, KMinContentLength * 2 );
+ asfPtr.Copy( aContent.Left( KMinContentLength ) );
+ FormatGUID( asfPtr );
+
+ if ( asfPtr == KASFHeaderObject )
+ {
+ // It's ASF, check still whether it's WM DRM protected or not
+ r = aContent.Find( KWrmHeader );
+ if ( r == KErrNotFound )
+ {
+ aProtected = DRM::EUUnprotected;
+ }
+ else
+ {
+ isDrmFile = ETrue;
+ aProtected = DRM::EUProtected;
+ aAgent.Set( DRM::KDrmWMAgentName );
+ }
+ }
+ else
+ {
+ // Check whether it's OMA DRM protected or not.
+ if ( ( aContent.Length() >= KMinContentLengthOma1Based ) &&
+ ( COma1Dcf::IsValidDcf( aContent ) ) )
+ {
+ isDrmFile = ETrue;
+ aProtected = DRM::EUProtected;
+ aAgent.Set( DRM::KDrmOmaAgentName );
+ }
+ else if ( COma2Dcf::IsValidDcf( aContent ) )
+ {
+ isDrmFile = ETrue;
+ _LIT8( KCommonHeadersBox, "ohdr" );
+ TInt pos( aContent.Find( KCommonHeadersBox ) );
+
+ // If no box can be found or if there isn't enough data
+ // set protection as unknown
+ if ( pos == KErrNotFound ||
+ aContent.Length() < pos + KOma2EncryptionFieldOffset )
+ {
+ aProtected = DRM::EUUnknown;
+ }
+ // If encryption field is 0, then content isn't protected
+ else if ( !aContent[pos + KOma2EncryptionFieldOffset] )
+ {
+ aProtected = DRM::EUUnprotected;
+ }
+ else
+ {
+ aProtected = DRM::EUProtected;
+ }
+ aAgent.Set( DRM::KDrmOmaAgentName );
+ }
+ else if ( (aContent)[0] == 1)
+ {
+ // set the mimetype from the buffer which is in the beginning
+ // starting from byte 3 with the length specified at position 2
+ TPtrC8 mimeType( aContent.Mid(3, (aContent)[1]) );
+ if( !mimeType.CompareF( *iOmaBasedMimeType ) )
+ {
+ aAgent.Set( *DRM::CDrmUtility::iOmaBasedAgentName );
+ isDrmFile = ETrue;
+ aProtected = DRM::EUProtected;
+ }
+ }
+ }
+ return isDrmFile;
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmUtility::IsProtectedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool DRM::CDrmUtility::IsProtectedL( RFile& aFileHandle ) const
+ {
+ DRM::TDrmProtectionStatus protection( DRM::EUUnknown );
+ TPtrC agent( KNullDesC );
+ TBool isDrmFile( EFalse );
+ TBool isProtected( EFalse );
+
+ isDrmFile = GetDrmInfoL( aFileHandle, agent, protection );
+
+ if ( isDrmFile && protection == DRM::EUProtected )
+ {
+ isProtected = ETrue;
+ }
+ return isProtected;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDrmUtility::IsProtectedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool DRM::CDrmUtility::IsProtectedL( const TDesC8& aContent ) const
+ {
+ DRM::TDrmProtectionStatus protection( DRM::EUUnknown );
+ TPtrC agent( KNullDesC );
+ TBool isDrmFile( EFalse );
+ TBool isProtected( EFalse );
+
+ isDrmFile = GetDrmInfoL( aContent, agent, protection );
+
+ if( isDrmFile && protection == DRM::EUProtected )
+ {
+ isProtected = ETrue;
+ }
+ return isProtected;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDrmUtility::GetAgentL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool DRM::CDrmUtility::GetAgentL(
+ RFile& aFileHandle,
+ TPtrC& aAgent ) const
+ {
+ DRM::TDrmProtectionStatus protection( DRM::EUUnknown );
+ TBool isDrmFile( EFalse );
+
+ isDrmFile = GetDrmInfoL( aFileHandle, aAgent, protection );
+
+ return isDrmFile;
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmUtility::GetAgentL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool DRM::CDrmUtility::GetAgentL(
+ const TDesC8& aContent,
+ TPtrC& aAgent ) const
+ {
+ DRM::TDrmProtectionStatus protection( DRM::EUUnknown );
+ TBool isDrmFile( EFalse );
+
+ isDrmFile = GetDrmInfoL( aContent, aAgent, protection );
+
+ return isDrmFile;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDrmUtility::CheckFileHandlerL
+// Checks whether given filehandle is valid if not leaves with KErrArgument
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void DRM::CDrmUtility::CheckFileHandleL( RFile& aFileHandle ) const
+ {
+ if ( !aFileHandle.SubSessionHandle() )
+ {
+ User::Leave( KErrBadHandle );
+ }
+ }
+
+// End of File