profilesservices/FileList/Src/CFLDDRMImplementation.cpp
changeset 68 13e71d907dc3
child 67 940cad2b4a51
equal deleted inserted replaced
40:6465d5bb863a 68:13e71d907dc3
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Implementation of the CFLDDRMImplementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // CLASS HEADER
       
    21 #include    "CFLDDRMImplementation.h"
       
    22 
       
    23 // INTERNAL INCLUDES
       
    24 #include    "CFLDRingingTonePlayer.h" // KFLDResourceFileName
       
    25 
       
    26 // EXTERNAL INCLUDES
       
    27 #include    <DRMCommon.h>
       
    28 #include    <DRMHelper.h>
       
    29 #include    <filelist.rsg>
       
    30 #include    <MProfilesLocalFeatures.h>
       
    31 #include    <MProfileUtilitySingleton.h>
       
    32 
       
    33 #ifdef RD_DRM_COMMON_INTERFACE_FOR_OMA_AND_WMDRM
       
    34 #include	<drmutility.h>
       
    35 #include	<drmagents.h>
       
    36 #endif
       
    37 
       
    38 // CONSTANTS
       
    39 namespace
       
    40 	{
       
    41 	_LIT( KFLDROMDriveLetter, "Z:" );
       
    42 	}
       
    43 
       
    44 // ============================ MEMBER FUNCTIONS ===============================
       
    45 
       
    46 // -----------------------------------------------------------------------------
       
    47 // CFLDDRMImplementation::ConstructL
       
    48 // Symbian 2nd phase constructor can leave.
       
    49 // -----------------------------------------------------------------------------
       
    50 //
       
    51 void CFLDDRMImplementation::ConstructL()
       
    52     {
       
    53     iProfilesFeatures = &( ProfileUtilityInstanceL().ProfilesLocalFeatures() );
       
    54 	iDRMCommon = DRMCommon::NewL();
       
    55 	User::LeaveIfError( iDRMCommon->Connect() );
       
    56     iDRMHelper = CDRMHelper::NewL( *CCoeEnv::Static() );
       
    57     }
       
    58 
       
    59 // Destructor
       
    60 CFLDDRMImplementation::~CFLDDRMImplementation()
       
    61     {
       
    62    	delete iDRMHelper;
       
    63 	
       
    64     if( iDRMCommon )
       
    65     	{
       
    66 		iDRMCommon->Disconnect(); // ignore possible error
       
    67 		delete iDRMCommon;
       
    68 		}
       
    69     ReleaseProfileUtility();
       
    70     }
       
    71 
       
    72 // -----------------------------------------------------------------------------
       
    73 // CFLDDRMImplementation::SetAutomatedType
       
    74 // (other items were commented in a header).
       
    75 // -----------------------------------------------------------------------------
       
    76 //
       
    77 void CFLDDRMImplementation::SetAutomatedType(
       
    78  CDRMHelper::TDRMHelperAutomatedType aAutomatedType )
       
    79 	{
       
    80 	iAutomatedType = aAutomatedType;
       
    81 	}
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CFLDDRMImplementation::IsFileValidL
       
    85 // (other items were commented in a header).
       
    86 // -----------------------------------------------------------------------------
       
    87 //
       
    88 TBool CFLDDRMImplementation::IsFileValidL(
       
    89     const TDesC& aFileName, TIntention aIntention )
       
    90 	{
       
    91     // If the destructor is empty, return that it's valid
       
    92     if( aFileName.Compare( KNullDesC ) == 0 )
       
    93         {
       
    94         return ETrue;
       
    95         }
       
    96 
       
    97  	// Tone files on ROM are always valid
       
    98    	if( ( aFileName.Left( KFLDROMDriveLetter().Length() ).CompareF(
       
    99           KFLDROMDriveLetter ) == 0 ) )
       
   100         {
       
   101         return ETrue;
       
   102         }
       
   103 
       
   104 	// Check if file is WMDRM protected
       
   105    	TBool prot( EFalse );
       
   106    	TRAPD( err, prot = IsFileWMDRMProtectedL( aFileName ) );
       
   107    	if( err != KErrNone )
       
   108    		{
       
   109    		ShowErrorNoteL( R_FLD_QTN_FILE_FORMAT_ERROR );
       
   110         return EFalse;
       
   111    		}
       
   112    	if( prot )
       
   113    		{
       
   114         ShowErrorNoteL( R_FLD_QTN_PROFILES_INFO_TONE_DRM_PROTECTED );
       
   115 		return EFalse;
       
   116    		}
       
   117 
       
   118    	ContentAccess::TVirtualPathPtr path( aFileName,
       
   119    						ContentAccess::KDefaultContentObject );
       
   120    	CData* data = CData::NewLC( path, EContentShareReadWrite );
       
   121    	TInt isProtected;
       
   122    	TInt error = data->GetAttribute( EIsProtected, isProtected );
       
   123    	CleanupStack::PopAndDestroy(); // data
       
   124 
       
   125     if( error != DRMCommon::EOk )
       
   126         {
       
   127         // DRM Helper class knows at least rights db corrupted error message.
       
   128         // Leaves on system-wide error code.
       
   129         iDRMHelper->HandleErrorL( error, aFileName );
       
   130         return EFalse;
       
   131         }
       
   132 
       
   133 	// Obtain information whether the file can be set as automated content
       
   134 	TBool canSetAutomated( EFalse );
       
   135     TInt canSetAutomatedErr( iDRMHelper->CanSetAutomated( aFileName, canSetAutomated ) );
       
   136 
       
   137 	if( !isProtected && canSetAutomated )
       
   138 		{
       
   139 		// The file in question is not DRM protected.
       
   140         // Return ETrue if file is also Ok unprotected, otherwise EFalse.
       
   141         return IsFileValidUnprotectedL( aFileName, aIntention );
       
   142 		}
       
   143 	
       
   144 	// Operator requirement: Check restrictions if file is mp4 audio
       
   145 	TBuf<KMaxDataTypeLength> dataType( DataTypeL( aFileName ).Des() );
       
   146     if( iProfilesFeatures->IsBlockedProtectedType( dataType ) )
       
   147         {
       
   148         ShowErrorNoteL( R_FLD_QTN_PROFILES_INFO_TONE_DRM_PROTECTED );
       
   149         return EFalse;
       
   150         }
       
   151 	
       
   152 	if ( canSetAutomatedErr == DRMCommon::ERightsExpired ||
       
   153 		canSetAutomatedErr == DRMCommon::ENoRights )
       
   154 		{
       
   155 		// Rights are expired, future rights or missing
       
   156 		iDRMHelper->HandleErrorL( canSetAutomatedErr, aFileName );
       
   157 		return EFalse;
       
   158 		}
       
   159 
       
   160     // Operator requirement: Check DRM v2 tones
       
   161 	if( !canSetAutomated )
       
   162         {
       
   163 		// This is DRM v2 file OR count based v1 tone
       
   164 	     ShowErrorNoteL( aIntention == EPlay ?
       
   165 				R_FLD_QTN_DRM_PREV_RIGHTS_USE : R_FLD_QTN_DRM_PREV_RIGHTS_SET);
       
   166 		return EFalse;
       
   167         }
       
   168             
       
   169 	TInt32 infoBits( 0x00000000 );
       
   170 
       
   171 	// Find out rights information	            
       
   172 	if( !CFLDDRMImplementation::GetFileInfoL(
       
   173 	 aFileName, infoBits ) )
       
   174 		{
       
   175 		// Corrupted file or "No rights" situation
       
   176 		return EFalse;
       
   177 		}
       
   178 
       
   179 	// Operator requirement: Check CFM protection
       
   180 	if ( infoBits & ENoRingingTone )
       
   181 		{
       
   182 		// This is CFM protected file, ringingtone is set to "no"
       
   183 		ShowErrorNoteL( aIntention == EPlay ?
       
   184 			R_FLD_QTN_DRM_PREV_RIGHTS_USE : R_FLD_QTN_DRM_PREV_RIGHTS_SET);
       
   185 		return EFalse;
       
   186 		}
       
   187       
       
   188     if( aIntention == ESelect )
       
   189     	{
       
   190 		// Rights are good to go, and intention is selection
       
   191     	// call SetAutomatedPassive to show 'activation query' 
       
   192 		iDRMHelper->SetAutomatedType( iAutomatedType );
       
   193     	error = iDRMHelper->SetAutomatedPassive( aFileName );
       
   194     	if( error != KErrCancel )
       
   195     		{
       
   196 	       	// User accepted dialog
       
   197         	User::LeaveIfError( error );
       
   198         	// New way, does not require DRM capability
       
   199         	data = CData::NewLC( path, EContentShareReadWrite );
       
   200         	error = data->ExecuteIntent( ContentAccess::EPlay );
       
   201         	// Wrongly requires DRM after all. According to Risto Vilkman
       
   202         	// from DRM, KErrAccessDenied can be ignored, since if
       
   203         	// CanSetAutomated says the tone is OK, it's OK.
       
   204         	if ( error != KErrNone && error != KErrAccessDenied )
       
   205         		{
       
   206         		User::Leave( error );
       
   207         		}
       
   208         	CleanupStack::PopAndDestroy(); // data
       
   209         	}
       
   210         else
       
   211         	{
       
   212         	// User canceled dialog
       
   213         	return EFalse;
       
   214         	}
       
   215 		}
       
   216         
       
   217     return ETrue;
       
   218 	}
       
   219 
       
   220 // -----------------------------------------------------------------------------
       
   221 // CFLDDRMImplementation::GetFileInfo
       
   222 // (other items were commented in a header).
       
   223 // -----------------------------------------------------------------------------
       
   224 //
       
   225 TBool CFLDDRMImplementation::GetFileInfoL(
       
   226  const TDesC& aFileName, TInt32& aInfoBits ) const
       
   227 	{
       
   228 	DRMCommon::TContentProtection contentProtection; // ignored
       
   229 	HBufC8* mimeType = NULL; // ignored
       
   230 	TUint dataLength( 0 ); // ignored
       
   231 	HBufC8* contentURI( NULL );
       
   232 	   
       
   233 	// Obtain content URI
       
   234     TInt error = iDRMCommon->GetFileInfo(
       
   235 		aFileName, contentProtection, mimeType, contentURI, dataLength );
       
   236     delete mimeType;
       
   237 
       
   238     if( error != DRMCommon::EOk )
       
   239     	{
       
   240     	delete contentURI;
       
   241         // Handle possible corrupt file situation
       
   242         iDRMHelper->HandleErrorL( error, aFileName );
       
   243         return EFalse;
       
   244     	}
       
   245 
       
   246 	// Obtain rights object
       
   247 	CDRMRights* rights = NULL;
       
   248     error = iDRMCommon->GetActiveRights( *contentURI, DRMCommon::EPlay, rights );
       
   249     delete contentURI;
       
   250 
       
   251 	if( error == DRMCommon::ENoRights )
       
   252 		{
       
   253 		delete rights;
       
   254 		// There is no rights for given file
       
   255 		// Should never arrive here, ENoRights is handled
       
   256 		// already in IsFileValidL()
       
   257    	   	iDRMHelper->HandleErrorL( error, aFileName );
       
   258         return EFalse;
       
   259 		}
       
   260 	 
       
   261 	// Obtain infobits ( needed only for CFM case )		
       
   262    aInfoBits = rights->GetPermission().iInfoBits;
       
   263    delete rights;
       
   264    return ETrue;
       
   265    }
       
   266 
       
   267 
       
   268 // -----------------------------------------------------------------------------
       
   269 //
       
   270 // Functions related to WMDRM protection check
       
   271 //
       
   272 // -----------------------------------------------------------------------------
       
   273 
       
   274 #ifndef RD_DRM_COMMON_INTERFACE_FOR_OMA_AND_WMDRM
       
   275 
       
   276 // Some magic constants
       
   277 static const TInt KMinContentLength( 16 );
       
   278 //_LIT8( KContentProtectionType, "DRM" );
       
   279 _LIT8( KASFHeaderObject, "75B22630668E11CFA6D900AA0062CE6C" );
       
   280 _LIT8( KWrmHeader, "W\0R\0M\0H\0E\0A\0D\0E\0R\0" );
       
   281 
       
   282 // -----------------------------------------------------------------------------
       
   283 // FormatGUID
       
   284 // -----------------------------------------------------------------------------
       
   285 //
       
   286 LOCAL_C void FormatGUID( TDes8& aGUID )
       
   287     {
       
   288     TBuf8<16> copyGUID( aGUID );
       
   289     TInt i;
       
   290     for( i = 0; i < 4; i++ )
       
   291         {
       
   292         copyGUID[i] = aGUID[3-i];
       
   293         }
       
   294     for( i = 4; i < 6; i++ )
       
   295         {
       
   296         copyGUID[i] = aGUID[9 - i];
       
   297         }
       
   298     for( i = 6; i < 8; i++ )
       
   299         {
       
   300         copyGUID[i] = aGUID[13 - i];
       
   301         }
       
   302     for( i = 8; i < 16 ; i++ )
       
   303         {
       
   304         copyGUID[i] = aGUID[i];
       
   305         }
       
   306     aGUID.Delete( 0, 32 );
       
   307     for( i = 0; i <16; i++ )
       
   308         {
       
   309         aGUID.AppendNumFixedWidthUC( copyGUID[i], EHex, 2 );
       
   310         }
       
   311     }
       
   312 
       
   313 // -----------------------------------------------------------------------------
       
   314 // ConvertToInt64
       
   315 // -----------------------------------------------------------------------------
       
   316 //
       
   317 LOCAL_C TInt64 ConvertToInt64( TDesC8& aDes )
       
   318     {
       
   319     TInt64 num = 0;
       
   320     TInt i;
       
   321     for( i = 7 ; i >= 0; i-- )
       
   322         {
       
   323         num <<= 8;
       
   324         num |= aDes[i];
       
   325         }
       
   326     return num;
       
   327     }
       
   328 
       
   329 
       
   330 // -----------------------------------------------------------------------------
       
   331 // IsProtectedWmDrmL
       
   332 // returns ETrue, if file is protected WMDRM file
       
   333 //         EFalse if file is not protected WMDRM file
       
   334 // Leaves with KErrUnderflow if file has too little data to decide
       
   335 //         whether WmDrm or not
       
   336 //         may also leave with other system wide error code
       
   337 // -----------------------------------------------------------------------------
       
   338 //
       
   339 LOCAL_C TBool IsProtectedWmDrmL( RFile& aFileHandle )
       
   340     {
       
   341     TInt r( KErrNone );
       
   342     HBufC8* buffer( NULL );
       
   343     TInt pos( 0 );
       
   344     RFile file;
       
   345     TBuf8< 32 > header;
       
   346 
       
   347     TInt64 headerSize( 0 );
       
   348     TBool isProtectedWmDrm( EFalse );
       
   349     TPtr8 headerPtr( NULL, 0 );
       
   350 
       
   351     // Leave if given handle is invalid
       
   352     if( !aFileHandle.SubSessionHandle() )
       
   353         {
       
   354         User::Leave( KErrBadHandle );
       
   355         }
       
   356 
       
   357     User::LeaveIfError( file.Duplicate( aFileHandle ) );
       
   358     CleanupClosePushL( file );
       
   359 
       
   360     User::LeaveIfError( file.Seek( ESeekStart, pos ) );
       
   361 
       
   362     // Check if the file is an ASF file
       
   363     // : Check on runtime wether WM DRM is supporeted or not
       
   364 
       
   365     User::LeaveIfError( file.Read( 0, header, KMinContentLength ) );
       
   366     if( header.Length() < KMinContentLength )
       
   367         {
       
   368         User::Leave( KErrUnderflow );
       
   369         }
       
   370 
       
   371     FormatGUID( header );
       
   372 
       
   373     if( header == KASFHeaderObject )
       
   374         {
       
   375         // It's ASF, check still whether it's WM DRM protected or not
       
   376         file.Read( header,8 );
       
   377         headerSize = ConvertToInt64( header );
       
   378         if( headerSize <= 30 )
       
   379             {
       
   380             User::Leave( KErrUnderflow );
       
   381             }
       
   382         if ( headerSize > ( ( KMaxTInt32 / 2 ) - 1 ) )
       
   383             {
       
   384             User::Leave( KErrOverflow );
       
   385             }
       
   386         buffer = HBufC8::NewLC( headerSize );
       
   387 
       
   388         headerPtr.Set( buffer->Des() );
       
   389         User::LeaveIfError( file.Read( headerPtr, headerSize - 24 ) );
       
   390 
       
   391         r = headerPtr.Find( KWrmHeader );
       
   392         if ( KErrNotFound != r )
       
   393             {
       
   394             isProtectedWmDrm = ETrue;
       
   395             }
       
   396         CleanupStack::PopAndDestroy( buffer ); // buffer
       
   397         }
       
   398         CleanupStack::PopAndDestroy(); // file
       
   399 
       
   400     return isProtectedWmDrm;
       
   401     }
       
   402 
       
   403 #endif // RD_DRM_COMMON_INTERFACE_FOR_OMA_AND_WMDRM
       
   404 
       
   405 // -----------------------------------------------------------------------------
       
   406 // CFLDDRMImplementation::IsFileWMDRMProtectedL
       
   407 // -----------------------------------------------------------------------------
       
   408 //
       
   409 TBool CFLDDRMImplementation::IsFileWMDRMProtectedL( const TDesC& aFileName ) const
       
   410 	{
       
   411 	TBool res = EFalse;
       
   412 	RFs& fsSession( CCoeEnv::Static()->FsSession() );
       
   413 	RFile hFile;
       
   414 
       
   415 	TInt err = hFile.Open( fsSession, aFileName, 
       
   416 						EFileRead | EFileStream | EFileShareReadersOnly );
       
   417 	if( err == KErrInUse )
       
   418 		{
       
   419 		err = hFile.Open( fsSession, aFileName, 
       
   420 						EFileRead | EFileStream | EFileShareAny );
       
   421 		}
       
   422 	if( err != KErrNone )
       
   423 		{
       
   424 		User::Leave( err );
       
   425 		}
       
   426 	CleanupClosePushL( hFile );
       
   427 
       
   428 #ifdef RD_DRM_COMMON_INTERFACE_FOR_OMA_AND_WMDRM
       
   429 	TPtrC agent( KNullDesC );
       
   430 	DRM::CDrmUtility* drmUtil( DRM::CDrmUtility::NewLC() );
       
   431 	drmUtil->GetAgentL( hFile, agent );
       
   432 	if( agent.Compare( DRM::KDrmWMAgentName ) == 0 )
       
   433 		{
       
   434 		res = ETrue;
       
   435 		}
       
   436 	CleanupStack::PopAndDestroy( drmUtil );
       
   437 #else
       
   438 	res = IsProtectedWmDrmL( hFile );
       
   439 #endif
       
   440 
       
   441 	CleanupStack::PopAndDestroy( &hFile );
       
   442 	return res;
       
   443 	}
       
   444 
       
   445 // -----------------------------------------------------------------------------
       
   446 //
       
   447 // End of Functions related to WMDRM protection check
       
   448 //
       
   449 // -----------------------------------------------------------------------------
       
   450 
       
   451 //  End of File