diff -r b7fa36b488f8 -r cd54903d48da profilesapplication/Profiles/ProfileAiwProvider/src/CProfileAiwProvider.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/profilesapplication/Profiles/ProfileAiwProvider/src/CProfileAiwProvider.cpp Wed Sep 01 12:30:29 2010 +0100 @@ -0,0 +1,873 @@ +/* +* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Profile Aiw service provider. +* +*/ + + +// CLASS HEADER +#include "CProfileAiwProvider.h" + +// INTERNAL INCLUDES +#include "CProfileEngineHandler.h" +#include "CPapPopupList.h" + +// EXTERNAL INCLUDES +#include // For CAiwMenuPane +#include // For KAiwCmdAssign +#include // For MAiwNotifyCallback +#include // For TResourceReader +#include // For resource texts +#include +#include // CCoeEnv +#include // RConeResourceLoader +#include +#include // For CAknInformationNote +#include // For CAknSingleGraphicPopupMenuStyleListBox +#include +#include +#include +#include +#include +#include +#include // For PROFILES_MAX_NAME_LENGTH +#include // For EikFileUtils +#include +#include +#include +#include + +#ifdef RD_DRM_COMMON_INTERFACE_FOR_OMA_AND_WMDRM +#include +#include +#endif + + +// CONSTANTS +namespace + { + _LIT( KProfileAiwProviderResourceFileName, "z:ProfileAiwProviderResource.rsc" ); + // Allowed MIME types + _LIT( KAudioCommonMimeType, "audio/*"); + _LIT( KAudioRngMimeType, "application/vnd.nokia.ringing-tone" ); +#ifdef RD_VIDEO_AS_RINGING_TONE + _LIT( KVideoCommonMimeType, "video/*"); + _LIT( KRMVideoMimeType, "application/vnd.rn-realmedia" ); + _LIT( KRMVideoMimeType2, "application/x-pn-realmedia" ); + _LIT( KSDPVideoMimeType, "application/sdp" ); +#endif + // Granularities + const TInt KArrayGranularity( 3 ); + // List item format + _LIT( KProfileAIWProviderIconAndTab, "1\t"); + // Maximum profile name length + const TInt KProfileAiwProviderMaxNameLength( PROFILES_MAX_NAME_LENGTH ); + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CProfileAiwProvider* CProfileAiwProvider::NewL() + { + CProfileAiwProvider* self = new(ELeave) CProfileAiwProvider; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::CProfileAiwProvider +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +CProfileAiwProvider::CProfileAiwProvider() + { + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CProfileAiwProvider::ConstructL() + { + FeatureManager::InitializeLibL(); + TParse* fp = new(ELeave) TParse(); + fp->Set(KProfileAiwProviderResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL); + TFileName resourceFileName( fp->FullName() ); + delete fp; + + // Get language of resource file + BaflUtils::NearestLanguageFile( CCoeEnv::Static()->FsSession(), resourceFileName ); + iResourceOffset = CCoeEnv::Static()->AddResourceFileL( resourceFileName ); + iProfileToneHandler = CProfileToneHandler::NewL(); + // Move this to PopulateListBox() + //iEngineHandler = CProfileEngineHandler::NewL(); + + TResourceReader reader; + CCoeEnv::Static()->CreateResourceReaderLC( reader, + R_PROFILEAIWPROVIDER_MENU ); + // load strings from resource + iWMAErrorText = StringLoader::LoadL( + R_PROFILEAIWPROVIDER_TEXT_NOT_ALLOWED ); + iMP4ErrorText = StringLoader::LoadL( + R_PROFILEAIWPROVIDER_INFO_TONE_DRM_PROTECTED ); + iUnprotectedErrorText = StringLoader::LoadL( + R_PROFILEAIWPROVIDER_INFO_TONE_NO_DRM ); + iNotSupportedErrorText = StringLoader::LoadL( + R_PROFILEAIWPROVIDER_INFO_MIME_TYPE_NOT_SUPPORTED ); + iPopupTitle = StringLoader::LoadL( + R_PROFILEAIWPROVIDER_QUERY_SELECT_PROFILES ); + iChangedProfilesText = StringLoader::LoadL( + R_PROFILEAIWPROVIDER_CONFIRM_RINGTONE_CHANGED ); + iCopiedAndChangedText = StringLoader::LoadL( + R_PROFILEAIWPROVIDER_CONFIRM_RINGTONE_COPIED ); + + // Read the maximum limit for the size of a tone file: + CRepository* cenrep = CRepository::NewL( KCRUidProfileEngine ); + CleanupStack::PushL( cenrep ); + User::LeaveIfError( cenrep->Get( KProEngRingingToneMaxSize, iMaxSize ) ); + CleanupStack::PopAndDestroy( cenrep ); + iSizeErrorText = StringLoader::LoadL( + R_PROFILEAIWPROVIDER_TONE_MAXSIZE_ERROR, iMaxSize ); + + CleanupStack::PopAndDestroy(); // reader + } + +// Destructor +CProfileAiwProvider::~CProfileAiwProvider() + { + delete iIndexToIdArray; + delete iWMAErrorText; + delete iMP4ErrorText; + delete iUnprotectedErrorText; + delete iNotSupportedErrorText; + delete iPopupTitle; + delete iChangedProfilesText; + delete iSizeErrorText; + delete iCopiedAndChangedText; + + delete iProfileToneHandler; + delete iEngineHandler; + CCoeEnv::Static()->DeleteResourceFile( iResourceOffset ); + FeatureManager::UnInitializeLib(); + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::InitialiseL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CProfileAiwProvider::InitialiseL( MAiwNotifyCallback& /*aFrameworkCallback*/, + const RCriteriaArray& /*aInterest*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::HandleServiceCmdL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CProfileAiwProvider::HandleServiceCmdL( const TInt& aCmdId, + const CAiwGenericParamList& aInParamList, + CAiwGenericParamList& /*aOutParamList*/, + TUint aCmdOptions, + const MAiwNotifyCallback* aCallback ) + { + // Cope with the design problems of AIW framework + iConstNotifyCallback = const_cast (aCallback); + + if( aCmdOptions & KAiwOptCancel ) + { + if( iPopup ) + { + iPopup->CancelPopup(); + iPopup = NULL; + } + return; + } + + if( aCmdId == KAiwCmdAssign ) + { + // Retrieve filename and file MIME type from AIW param list + TPtrC fileName = + GetAiwParamAsDescriptor(aInParamList, EGenericParamFile); + + TPtrC mimeTypeString = + GetAiwParamAsDescriptor(aInParamList, EGenericParamMIMEType); + + // Leave, if there were not given all the required parameters + if ((fileName == KNullDesC) || (mimeTypeString == KNullDesC)) + { + return; + } + + if( !CheckMimeTypeL( mimeTypeString ) ) + { + // Not supported format + ShowErrorNoteL( *iNotSupportedErrorText ); + } + else if( IsFileWMDRMProtectedL( fileName ) ) + { + ShowErrorNoteL( *iMP4ErrorText ); + } + else if( !IsToneFileSizeOkL( fileName ) ) + { + // Too big file + ShowErrorNoteL( *iSizeErrorText ); + } + else + { + LaunchL( *iPopupTitle, fileName ); + } + } + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::PerformProfileChangeL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CProfileAiwProvider::PerformProfileChangeL( + const TDesC& aFileName, const TBool& aChangeAllProfiles ) const + { + TInt count( iSelectionArray->Count() ); + TInt err( KErrNone ); + TInt r( KErrNone ); + + // Check location of the tone and copy if needed + TFileName target; + TBool remote = CopyIfRemoteL( aFileName, target ); + + if( aChangeAllProfiles ) + { + if( remote ) + { + TRAP( r, err = iProfileToneHandler->SetToneForAllProfilesL( + EProfileRingingToneSetting, target ) ); + } + else + { + TRAP( r, err = iProfileToneHandler->SetToneForAllProfilesL( + EProfileRingingToneSetting, aFileName ) ); + } + } + else + { + TInt profileId( 0 ); + for( TInt index(0); index < count; index++ ) + { + profileId = iIndexToIdArray->At( iSelectionArray->At( index ) ); + + if( remote ) + { + // The first time set the tone, use SetProfileToneL to check the file + if ( index == 0 ) + { + + TRAP( r, err = iProfileToneHandler->SetProfileToneL( + profileId, EProfileRingingToneSetting, target ) ); + } + // the file has been checked at first time, use SetProfileToneL to + // avoid repeat check. + else + { + TRAP( r, err = iProfileToneHandler->SetProfileToneNotCheckL( + profileId, EProfileRingingToneSetting, target ) ); + } + } + else + { + // The first time set the tone, use SetProfileToneL to check the file + if ( index == 0 ) + { + TRAP( r, err = iProfileToneHandler->SetProfileToneL( profileId, + EProfileRingingToneSetting, aFileName ) ); + } + // the file has been checked at first time, use SetProfileToneL to + // avoid repeat check. + else + { + TRAP( r, err = iProfileToneHandler->SetProfileToneNotCheckL( + profileId, EProfileRingingToneSetting, aFileName ) ); + } + + } + + // KErrNotFound is checked for the unlikely case in which the user + // has first popped up the list of profiles and then switched to + // Profiles App and deleted a profile or more, and finally completed + // this "assigned to ringing tone" operation + if( r == KErrNotFound ) + { + r = KErrNone; + } + // The case r == KErrAccessDenied needn't be checked since only + // those profiles that are modifiable are included in the list in + // PopulateListBoxL() below + if( r != KErrNone || err != KErrNone ) + { + // no use to go on with other profiles if the tone can not be + // assigned as an alert tone: + break; + } + } + } + + if( r == KErrPermissionDenied ) + { + // Unprotected DRM tone case + ShowErrorNoteL( *iUnprotectedErrorText ); + } + else if( r == KErrArgument ) + { + // WMA case + ShowErrorNoteL( *iWMAErrorText ); + } + else if( r != KErrNone ) + { + User::Leave( r ); + } + + if ( err == KErrArgument ) + { + // MP4 case + ShowErrorNoteL( *iMP4ErrorText ); + } + + if( ( err == KErrNone ) && ( r == KErrNone ) && ( count > 0 ) ) + { + CAknConfirmationNote* note = new( ELeave ) CAknConfirmationNote( EFalse ); + if( remote ) + { + note->ExecuteLD( iCopiedAndChangedText->Des() ); + } + else + { + note->ExecuteLD( iChangedProfilesText->Des() ); + } + } + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::LaunchL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CProfileAiwProvider::LaunchL( const TDesC& aPopupTitle, + const TDesC& aFileName ) + { + // create listbox + // list item string format: "0\tLabel" where 0 is an index to icon array + CEikFormattedCellListBox* listBox = + new ( ELeave ) CAknSingleGraphicPopupMenuStyleListBox; + CleanupStack::PushL( listBox ); + + // create popup + CPapPopupList* popup = CPapPopupList::NewL( listBox, + R_AVKON_SOFTKEYS_OK_CANCEL__UNMARK ); + CleanupStack::PushL( popup ); + popup->SetTitleL( aPopupTitle ); + +#ifdef RD_SCALABLE_UI_V2 + if( AknLayoutUtils::PenEnabled() ) + { + listBox->ConstructL( popup, EAknListBoxStylusMultiselectionList ); + } + else + { + listBox->ConstructL( popup, EAknListBoxMultiselectionList ); + } +#else + listBox->ConstructL( popup, EAknListBoxMultiselectionList ); +#endif + + listBox->CreateScrollBarFrameL(ETrue); + listBox->ScrollBarFrame()-> + SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto ); + + popup->SetIconsL(); + + // create model + CDesCArrayFlat* items = new (ELeave)CDesCArrayFlat( KArrayGranularity ); + + // populate model + CleanupStack::PushL(items); + CProfileAiwProvider::PopulateListBoxL( items ); + CleanupStack::Pop(items); + + CTextListBoxModel* model = listBox->Model(); + model->SetItemTextArray(items); + + // set all items as selected + TInt count( listBox->Model()->NumberOfItems() ); + for( TInt index( 0 ); index < count; index++ ) + { + listBox->View()->SelectItemL( index ); + } + + TBool changeAllProfiles( EFalse ); + + // launch popup + iPopup = popup; + TInt res = popup->ExecuteLD(); + // No leaving functions allowed between executeLD and CleanupStack::Pop(). + CleanupStack::Pop( popup ); + iPopup = NULL; + + if( res ) + { + iSelectionArray = listBox->View()->SelectionIndexes(); + if( count == iSelectionArray->Count() ) + { + // User has selected to change all profiles + changeAllProfiles = ETrue; + } + CProfileAiwProvider::PerformProfileChangeL( aFileName, changeAllProfiles ); + } + CleanupStack::PopAndDestroy(); // listBox + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::PopulateListBoxL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CProfileAiwProvider::PopulateListBoxL( CDesCArrayFlat* aItems ) + { + // iEngineHandler must be instantiated each time to make sure + // profile list is up to date + delete iEngineHandler; + iEngineHandler = NULL; + iEngineHandler = CProfileEngineHandler::NewL(); + + MProfilesNamesArray* array = iEngineHandler->IdArray(); + MProfileEngineExtended* engine = iEngineHandler->Engine(); + + // Create the mapping array so that the IDs can be mapped to Profile IDs + // after the selection has been made + // Delete it first in case we're called several times (in the same instance) + delete iIndexToIdArray; + iIndexToIdArray = NULL; + iIndexToIdArray = new ( ELeave ) CArrayFixFlat( array->MdcaCount() ); + + // Add items + TInt count( array->MdcaCount() ); + TBuf name; // + 3 for icon and tab characters + for( TInt index( 0 ); index < count; index++ ) + { + const MProfileName* profileName = array->ProfileName( index ); + if( !profileName ) + { + continue; + } + + TInt profileId( profileName->Id() ); + // Only the profiles which modifiable flag of ringing tone item is + // enabled should be included in the list. In Off-line profile case also + // VoIP and WLAN must be supported (otherwise there wouldn't be need for + // ringing tone in Off-line profile) + if( ( profileId != EProfileOffLineId ) || + ( FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) && + FeatureManager::FeatureSupported( KFeatureIdProtocolWlan ) ) ) + { + MProfileExtended* profile( engine->ProfileLC( profileId ) ); + TUint32 modFlags( profile->ModifiableFlags() ); + CleanupStack::PopAndDestroy(); // profile + // Only the profiles which ringing tone item is modifiable should + // be included in the list + if( modFlags & EProfileFlagRingingTone ) + { + name.Copy( KProfileAIWProviderIconAndTab ); + TBuf< KProfileAiwProviderMaxNameLength > + tmpName( array->MdcaPoint( index ) ); + AknTextUtils::ReplaceCharacters( tmpName, + KAknReplaceListControlChars, + TChar( ' ' ) ); + name.Append( tmpName ); + aItems->AppendL( name ); + iIndexToIdArray->AppendL( profileId ); + } + } + } + iIndexToIdArray->Compress(); + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::InitializeMenuPaneL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CProfileAiwProvider::InitializeMenuPaneL( CAiwMenuPane& aMenuPane, + TInt aIndex, + TInt /*aCascadeId*/, + const CAiwGenericParamList& aInParamList ) + { + TResourceReader reader; + CCoeEnv::Static()->CreateResourceReaderLC( reader, + R_PROFILEAIWPROVIDER_MENU ); + + // Retrieve filename and file MIME type from AIW param list + TPtrC mimeTypeString = CProfileAiwProvider::GetAiwParamAsDescriptor + (aInParamList, EGenericParamMIMEType); + + if( CProfileAiwProvider::CheckMimeTypeL( mimeTypeString ) ) + { + // Only add menuitem if MIME type is valid + aMenuPane.AddMenuItemsL( reader, KAiwCmdAssign, aIndex ); + } + + CleanupStack::PopAndDestroy(); // reader + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::HandleMenuCmdL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CProfileAiwProvider::HandleMenuCmdL( TInt aMenuCmdId, + const CAiwGenericParamList& aInParamList, + CAiwGenericParamList& aOutParamList, + TUint aCmdOptions, + const MAiwNotifyCallback* aCallback ) + { + // Route to HandleServiceCmdL + HandleServiceCmdL(aMenuCmdId, aInParamList, + aOutParamList, aCmdOptions, aCallback); + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::GetAiwParamAsDescriptor +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TPtrC CProfileAiwProvider::GetAiwParamAsDescriptor( + const CAiwGenericParamList& aParamList, + TGenericParamId aParamType) + { + TInt index = 0; + const TAiwGenericParam* genericParam = NULL; + genericParam = aParamList.FindFirst( + index, + aParamType, + EVariantTypeDesC); + + if (index >= 0 && genericParam) + { + // Get the data + return genericParam->Value().AsDes(); + } + else + { + return KNullDesC(); + } + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::CheckMimeTypeL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CProfileAiwProvider::CheckMimeTypeL(const TDesC& aMimeTypeString) + { + if( ( aMimeTypeString.MatchF( KAudioCommonMimeType ) == 0 ) || + ( aMimeTypeString.CompareF( KAudioRngMimeType ) == 0 ) ) + { + iIsVideo = EFalse; + return ETrue; + } + +#ifdef RD_VIDEO_AS_RINGING_TONE + if( aMimeTypeString.MatchF( KVideoCommonMimeType ) == 0 || + aMimeTypeString.CompareF( KRMVideoMimeType ) == 0 || + aMimeTypeString.CompareF( KRMVideoMimeType2 ) == 0 || + aMimeTypeString.CompareF( KSDPVideoMimeType ) == 0 ) + { + iIsVideo = ETrue; + return ETrue; + } +#endif + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::IsToneFileSizeOkL +// ----------------------------------------------------------------------------- +// +TBool CProfileAiwProvider::IsToneFileSizeOkL( const TDesC& aFile ) + { + if( !iMaxSize ) + { // no limit set -> every tone will be ok (what comes to size): + return ETrue; + } + + // Get file size + TInt size = 0; + TBool result( ETrue ); + + TEntry entry; + if ( CCoeEnv::Static()->FsSession().Entry( aFile, entry ) == KErrNone ) + { + size = entry.iSize; + } + + // Check. NOTE: now if file size couldn't be determined, check fails. + if ( size > (iMaxSize*KKilo) ) + { + result = EFalse; + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::ShowErrorNoteL +// ----------------------------------------------------------------------------- +// +void CProfileAiwProvider::ShowErrorNoteL( const TDesC& aErrorText ) const + { + CAknInformationNote* note = new( ELeave ) CAknInformationNote( EFalse ); + note->ExecuteLD( aErrorText ); + } + + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::CopyIfRemoteL +// ----------------------------------------------------------------------------- +// +TBool CProfileAiwProvider::CopyIfRemoteL( const TDesC& aFileName, TFileName& aTarget ) const + { + TBool remote( EFalse ); + TParsePtrC parsedName( aFileName ); + RFs& fsSession( CCoeEnv::Static()->FsSession() ); + TDriveUnit driveUnit( parsedName.Drive() ); + TUint driveStatus( 0 ); + + DriveInfo::GetDriveStatus( fsSession, driveUnit, driveStatus ); + remote = ( ( driveStatus & DriveInfo::EDriveRemote ) == DriveInfo::EDriveRemote ); + + if( remote ) + { + // If the tone is on a remote drive, it must be copied + aTarget.Insert( 0, parsedName.NameAndExt() ); + if( iIsVideo ) + { + aTarget.Insert( 0, PathInfo::VideosPath() ); + } + else + { + aTarget.Insert( 0, PathInfo::SoundsPath() ); + } + aTarget.Insert( 0, PathInfo::PhoneMemoryRootPath() ); + User::LeaveIfError( EikFileUtils::CopyFile( aFileName, aTarget ) ); + } + + return remote; + } + + +// ----------------------------------------------------------------------------- +// +// Functions related to WMDRM protection check +// +// ----------------------------------------------------------------------------- + +#ifndef RD_DRM_COMMON_INTERFACE_FOR_OMA_AND_WMDRM + +// Some magic constants +static const TInt KMinContentLength( 16 ); +//_LIT8( KContentProtectionType, "DRM" ); +_LIT8( KASFHeaderObject, "75B22630668E11CFA6D900AA0062CE6C" ); +_LIT8( KWrmHeader, "W\0R\0M\0H\0E\0A\0D\0E\0R\0" ); + + +// ----------------------------------------------------------------------------- +// FormatGUID +// ----------------------------------------------------------------------------- +// +LOCAL_C void FormatGUID( TDes8& aGUID ) + { + TBuf8<16> copyGUID( aGUID ); + TInt i; + 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; + for( i = 7 ; i >= 0; i-- ) + { + num <<= 8; + num |= aDes[i]; + } + return num; + } + + +// ----------------------------------------------------------------------------- +// IsProtectedWmDrmL +// returns ETrue, if file is protected WMDRM file +// EFalse if file is not protected WMDRM file +// Leaves with KErrUnderflow if file has too little data to decide +// whether WmDrm or not +// may also leave with other system wide error code +// ----------------------------------------------------------------------------- +// +LOCAL_C TBool IsProtectedWmDrmL( RFile& aFileHandle ) + { + TInt r( KErrNone ); + HBufC8* buffer( NULL ); + TInt pos( 0 ); + RFile file; + TBuf8< 32 > header; + + TInt64 headerSize( 0 ); + TBool isProtectedWmDrm( EFalse ); + TPtr8 headerPtr( NULL, 0 ); + + // Leave if given handle is invalid + if( !aFileHandle.SubSessionHandle() ) + { + User::Leave( KErrBadHandle ); + } + + User::LeaveIfError( file.Duplicate( aFileHandle ) ); + CleanupClosePushL( file ); + + User::LeaveIfError( file.Seek( ESeekStart, pos ) ); + + // Check if the file is an ASF file + // : Check on runtime wether WM DRM is supporeted or not + + User::LeaveIfError( file.Read( 0, header, KMinContentLength ) ); + if( header.Length() < KMinContentLength ) + { + User::Leave( KErrUnderflow ); + } + + FormatGUID( header ); + + if( header == KASFHeaderObject ) + { + // It's ASF, check still whether it's WM DRM protected or not + file.Read( header,8 ); + headerSize = ConvertToInt64( header ); + if( headerSize <= 30 ) + { + User::Leave( KErrUnderflow ); + } + if ( headerSize > ( ( KMaxTInt32 / 2 ) - 1 ) ) + { + User::Leave( KErrOverflow ); + } + buffer = HBufC8::NewLC( headerSize ); + + headerPtr.Set( buffer->Des() ); + User::LeaveIfError( file.Read( headerPtr, headerSize - 24 ) ); + + r = headerPtr.Find( KWrmHeader ); + if ( KErrNotFound != r ) + { + isProtectedWmDrm = ETrue; + } + CleanupStack::PopAndDestroy( buffer ); // buffer + } + CleanupStack::PopAndDestroy(); // file + + return isProtectedWmDrm; + } + +#endif // RD_DRM_COMMON_INTERFACE_FOR_OMA_AND_WMDRM + +// ----------------------------------------------------------------------------- +// CProfileAiwProvider::IsFileWMDRMProtectedL +// ----------------------------------------------------------------------------- +// +TBool CProfileAiwProvider::IsFileWMDRMProtectedL( const TDesC& aFileName ) const + { + TBool res = EFalse; + RFs& fsSession( CCoeEnv::Static()->FsSession() ); + RFile hFile; + + TInt err = hFile.Open( fsSession, aFileName, + EFileRead | EFileStream | EFileShareReadersOnly ); + if( err == KErrInUse ) + { + err = hFile.Open( fsSession, aFileName, + EFileRead | EFileStream | EFileShareAny ); + } + if( err != KErrNone ) + { + User::Leave( err ); + } + CleanupClosePushL( hFile ); + +#ifdef RD_DRM_COMMON_INTERFACE_FOR_OMA_AND_WMDRM + TPtrC agent( KNullDesC ); + DRM::CDrmUtility* drmUtil( DRM::CDrmUtility::NewLC() ); + drmUtil->GetAgentL( hFile, agent ); + if( agent.Compare( DRM::KDrmWMAgentName ) == 0 ) + { + res = ETrue; + } + CleanupStack::PopAndDestroy( drmUtil ); +#else + res = IsProtectedWmDrmL( hFile ); +#endif + + CleanupStack::PopAndDestroy( &hFile ); + return res; + } + + +// ----------------------------------------------------------------------------- +// +// End of Functions related to WMDRM protection check +// +// ----------------------------------------------------------------------------- + + +// End of File