commondrm/drmutility/src/DrmUtility.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
--- /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