wmdrm/wmdrmengine/asf/src/asf.cpp
changeset 0 95b198f216e5
child 25 50c53e893c3f
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2006 - 2007 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 asf file handler class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <e32base.h>
       
    22 #include <f32file.h>
       
    23 #include <utf.h>
       
    24 #include <caf/caf.h>
       
    25 #include "asf.h"
       
    26 
       
    27 #define _LOGGING_FILE L"asf.txt"
       
    28 
       
    29 #include "logfn.h"
       
    30 
       
    31 // LOCAL CONSTANTS AND MACROS
       
    32 
       
    33 #define M4CC(a) ((a[0] << 24) + (a[1] << 16) + (a[2] << 8) + a[3])
       
    34 
       
    35 _LIT8 (KASFHeaderObject, "75B22630668E11CFA6D900AA0062CE6C");
       
    36 _LIT8 (KASFFilePropertiesObject, "8CABDCA1A94711CF8EE400C00C205365");
       
    37 _LIT8 (KASFContentDescriptionObject, "75B22633668E11CFA6D900AA0062CE6C");
       
    38 _LIT8 (KASFExtendedContentDescriptionObject, "D2D0A440E30711D297F000A0C95EA850");
       
    39 _LIT8 (KASFContentEncryptionObject, "2211B3FBBD2311D2B4B700A0C955FC6E");
       
    40 _LIT8 (KASFExtendedContentEncryptionObject, "298AE61426224C17B935DAE07EE9289C");
       
    41 _LIT8 (KASFDigitalSignatureObject, "2211B3FCBD2311D2B4B700A0C955FC6E");
       
    42 
       
    43 _LIT(KWMAlbumTitle,           "WM/AlbumTitle\0");
       
    44 _LIT(KWMPicture,              "WM/Picture\0");
       
    45 _LIT(KWMText,                 "WM/Text\0");
       
    46 _LIT(KWMComposer,             "WM/Composer\0");
       
    47 _LIT(KWMGenre,                "WM/Genre\0");
       
    48 _LIT(KWMYear,                 "WM/Year\0");
       
    49 _LIT(KWMYear1,                "WM/OriginalReleaseYear\0");
       
    50 _LIT(KWMOriginalArtist,       "WM/OriginalArtist\0");
       
    51 _LIT(KWMTrackNumber,          "WM/TrackNumber\0");
       
    52 _LIT(KWMUniqueFileIdentifier, "WM/UniqueFileIdentifier\0");
       
    53 _LIT(KWMAudioFileURL,         "WM/AudioFileURL\0");
       
    54 _LIT(KWMSharedUserRating,     "WM/SharedUserRating\0");
       
    55 _LIT(KWMDate,                 "WM/OriginalReleaseTime\0");
       
    56 
       
    57 _LIT8(KWrmHeader, "W\0R\0M\0H\0E\0A\0D\0E\0R\0");
       
    58 
       
    59 _LIT(KAsfMimeType, "application/vnd.drm.asf");
       
    60 _LIT(KWmaMimeType, "audio/x-ms-wma");
       
    61 _LIT(KWmvMimeType, "video/x-ms-wmv");
       
    62 
       
    63 _LIT(KAsfExtension, ".asf");
       
    64 _LIT(KWmaExtension, ".wma");
       
    65 _LIT(KWmvExtension, ".wmv");
       
    66 
       
    67 #define SET_PTR16(ptr, descriptor, offset, length) \
       
    68     ptr.Set( reinterpret_cast<const TUint16*>( (descriptor).Ptr() + (offset) ), length );
       
    69 
       
    70 /*
       
    71 * 16 B Obj GUID
       
    72 * 8  B Obj Size
       
    73 * xx B Obj Data
       
    74 */
       
    75 const TInt KObjectID( 16 );
       
    76 const TInt KObjectSize( 8 );
       
    77 
       
    78 // ============================= LOCAL FUNCTIONS ===============================
       
    79 
       
    80 LOCAL_C TUint32 ReadUint64FromBlockL( const TDesC8& aBlock, TInt aOffset );
       
    81 LOCAL_C TUint32 ReadUint32FromBlockL( const TDesC8& aBlock, TInt aOffset );
       
    82 LOCAL_C TUint16 ReadUint16FromBlockL( const TDesC8& aBlock, TInt aOffset );
       
    83 
       
    84 LOCAL_C HBufC16* HBuf16FromBlockL(
       
    85     const TDesC8& aBlock,
       
    86     TInt aOffset,
       
    87     TInt aLength );
       
    88 
       
    89 LOCAL_C TUint32 ReadUint64FromBlockL( const TDesC8& aBlock, TInt aOffset )
       
    90     {
       
    91     if ( aBlock.Length() <= ( aOffset + 3 ) )
       
    92         {
       
    93         User::Leave( KErrArgument );
       
    94         }
       
    95     return ( aBlock[aOffset + 3] << 24 ) +
       
    96            ( aBlock[aOffset + 2] << 16 ) +
       
    97            ( aBlock[aOffset + 1] << 8 ) +
       
    98              aBlock[aOffset];
       
    99     }
       
   100 
       
   101 LOCAL_C TUint32 ReadUint32FromBlockL( const TDesC8& aBlock, TInt aOffset )
       
   102     {
       
   103     if ( aBlock.Length() <= ( aOffset + 3 ) )
       
   104         {
       
   105         User::Leave( KErrArgument );
       
   106         }
       
   107     return ( aBlock[aOffset + 3] << 24 ) +
       
   108            ( aBlock[aOffset + 2] << 16 ) +
       
   109            ( aBlock[aOffset + 1] << 8 ) +
       
   110              aBlock[aOffset];
       
   111     }
       
   112 
       
   113 LOCAL_C TUint16 ReadUint16FromBlockL( const TDesC8& aBlock, TInt aOffset )
       
   114     {
       
   115     if ( aBlock.Length() <= ( aOffset + 1 ) )
       
   116         {
       
   117         User::Leave( KErrArgument );
       
   118         }
       
   119     return ( aBlock[aOffset + 1] << 8 ) + 
       
   120              aBlock[aOffset];
       
   121     }
       
   122 
       
   123 LOCAL_C HBufC16* HBuf16FromBlockL(
       
   124     const TDesC8& aBlock,
       
   125     TInt aOffset,
       
   126     TInt aLength )
       
   127     {
       
   128     if ( aBlock.Length() < ( aOffset + aLength ) )
       
   129         {
       
   130         User::Leave( KErrArgument );
       
   131         }
       
   132     HBufC16* buffer( HBufC16::NewL( aLength / 2 + 1 ) );
       
   133     TPtr ptr( buffer->Des() );
       
   134     
       
   135     for ( TInt i( 0 ) ; i < aLength; i+=2 )
       
   136         {
       
   137         ptr.Append( aBlock[aOffset + i] );
       
   138 	    }
       
   139 	
       
   140 	return buffer;
       
   141     }
       
   142 
       
   143 // ============================ MEMBER FUNCTIONS ===============================
       
   144 
       
   145 // -----------------------------------------------------------------------------
       
   146 // CAsf::CAsf
       
   147 // C++ default constructor can NOT contain any code, that
       
   148 // might leave.
       
   149 // -----------------------------------------------------------------------------
       
   150 //
       
   151 CAsf::CAsf():
       
   152     iTitle( NULL ),
       
   153     iAuthor( NULL ),
       
   154     iCopyright( NULL ),
       
   155     iDescription( NULL ),
       
   156     iRating( NULL ),
       
   157     iAlbumTitle( NULL ),
       
   158     iPicture( NULL ),
       
   159     iText( NULL ),
       
   160     iComposer( NULL ),
       
   161     iGenre( NULL ),
       
   162     iOriginalArtist( NULL ),
       
   163     iTrackNumber( NULL ),
       
   164     iUniqueFileID( NULL ),
       
   165     iAudioFileUrl( NULL ),
       
   166     iSharedUserRating( NULL ),
       
   167     iDate( NULL ),
       
   168     iYear( NULL ),
       
   169     iIsDrmProtected( EFalse ),
       
   170     iIsValidated( EFalse ),
       
   171     iHeaderData( NULL ),
       
   172     iSecretData( NULL ),
       
   173     iProtectionType( NULL ),
       
   174     iKeyId( NULL ),
       
   175     iLicenseUrl( NULL ),
       
   176     iExtendedContentEncryptionObject( NULL ),
       
   177     iContentDescriptionObjectExists( EFalse ),
       
   178     iFilePropertiesObjectExists( EFalse ),
       
   179     iExtendedContentDescriptionObjectExists( EFalse ),
       
   180     iExtendedContentEncryptionObjectExists( EFalse ),
       
   181     iContentEncryptionObjectExists( EFalse ),
       
   182     iMimeType( KAsfMimeType )
       
   183     {
       
   184     LOGFN( "CAsf::CAsf" );
       
   185     }
       
   186 
       
   187 // -----------------------------------------------------------------------------
       
   188 // CAsf::ConstructL
       
   189 // Symbian 2nd phase constructor can leave.
       
   190 // -----------------------------------------------------------------------------
       
   191 //
       
   192 void CAsf::ConstructL( const TDesC& aFileName )
       
   193     {
       
   194     TInt r = KErrNone;
       
   195 
       
   196     LOGFN( "CAsf::ConstructL" );
       
   197     LOG( aFileName );
       
   198     User::LeaveIfError( iFs.Connect() );
       
   199     r = iFile.Open( iFs, aFileName, EFileStream | EFileRead | EFileShareReadersOrWriters );
       
   200     if( r == KErrInUse )
       
   201         {
       
   202         r = iFile.Open( iFs, aFileName, EFileStream | EFileRead | EFileShareAny);
       
   203         if ( r == KErrInUse )
       
   204             {
       
   205             r = iFile.Open( iFs, aFileName, EFileStream | EFileRead |
       
   206                 EFileShareReadersOnly);
       
   207             }
       
   208         }
       
   209     User::LeaveIfError( r );
       
   210     InitializeL();
       
   211     }
       
   212 
       
   213 // -----------------------------------------------------------------------------
       
   214 // CAsf::ConstructL
       
   215 // Symbian 2nd phase constructor can leave.
       
   216 // -----------------------------------------------------------------------------
       
   217 //
       
   218 void CAsf::ConstructL( const RFile& aFile )
       
   219     {
       
   220     LOGFN( "CAsf::ConstructL (2)" );
       
   221     iFile.Duplicate( aFile );
       
   222     iFile.Size( iLength );
       
   223     InitializeL();
       
   224     }
       
   225 
       
   226 // -----------------------------------------------------------------------------
       
   227 // CAsf::InitializeL
       
   228 //
       
   229 // -----------------------------------------------------------------------------
       
   230 //
       
   231 void CAsf::InitializeL()
       
   232     {
       
   233     TFileName name;
       
   234 
       
   235     LOGFN( "CAsf::InitializeL" );
       
   236     iFile.FullName( name );
       
   237     if ( name.Right( 4 ).CompareF( KWmaExtension ) == 0 )
       
   238         {
       
   239         iMimeType.Set( KWmaMimeType );
       
   240         }
       
   241     else if ( name.Right( 4 ).CompareF( KWmvExtension ) == 0 ||
       
   242         name.Right( 4 ).CompareF( KAsfExtension ) == 0 )
       
   243         {
       
   244         iMimeType.Set( KWmvMimeType );
       
   245         }
       
   246 
       
   247     ValidateL();
       
   248     }
       
   249 
       
   250 // -----------------------------------------------------------------------------
       
   251 // CAsf::NewL
       
   252 // Two-phased constructor.
       
   253 // -----------------------------------------------------------------------------
       
   254 //
       
   255 EXPORT_C CAsf* CAsf::NewL( const RFile& aFile )
       
   256     {
       
   257     LOGFN( "CAsf::NewL" );
       
   258     CAsf* self = new (ELeave) CAsf;
       
   259     CleanupStack::PushL( self );
       
   260     self->ConstructL( aFile );
       
   261     CleanupStack::Pop( self );
       
   262     return self;
       
   263     }
       
   264 
       
   265 // -----------------------------------------------------------------------------
       
   266 // CAsf::NewL
       
   267 // Two-phased constructor.
       
   268 // -----------------------------------------------------------------------------
       
   269 //
       
   270 EXPORT_C CAsf* CAsf::NewL( const TDesC& aFileName )
       
   271     {
       
   272     LOGFN( "CAsf::NewL (2)" );
       
   273     CAsf* self = new (ELeave) CAsf;
       
   274     CleanupStack::PushL( self );
       
   275     self->ConstructL( aFileName );
       
   276     CleanupStack::Pop( self );
       
   277     return self;
       
   278     }
       
   279 
       
   280 // -----------------------------------------------------------------------------
       
   281 // CAsf::~CAsf
       
   282 // Destructor
       
   283 // -----------------------------------------------------------------------------
       
   284 //
       
   285 
       
   286 EXPORT_C CAsf::~CAsf()
       
   287     {
       
   288     LOGFN( "CAsf::~CAsf" );
       
   289     if ( iFile.SubSessionHandle() != KNullHandle )
       
   290         {
       
   291         iFile.Close();
       
   292         }
       
   293     if ( iFs.Handle() != KNullHandle )
       
   294         {
       
   295         iFs.Close();
       
   296         }
       
   297 
       
   298     delete iHeaderData;
       
   299     delete iSecretData;
       
   300     delete iProtectionType;
       
   301     delete iKeyId;
       
   302     delete iLicenseUrl;
       
   303     delete iExtendedContentEncryptionObject;
       
   304     delete iDigitalSignatureObject;
       
   305     delete iSignedData;
       
   306 
       
   307     // Content description Object
       
   308     delete iTitle;
       
   309     delete iAuthor;
       
   310     delete iCopyright;
       
   311     delete iDescription;
       
   312     delete iRating;
       
   313 
       
   314     // Extended Content description Object
       
   315     delete iAlbumTitle;
       
   316     delete iPicture;
       
   317     delete iText;
       
   318     delete iComposer;
       
   319     delete iGenre;
       
   320     delete iYear;
       
   321     delete iOriginalArtist;
       
   322     delete iTrackNumber;
       
   323     delete iUniqueFileID;
       
   324     delete iAudioFileUrl;
       
   325     delete iSharedUserRating;
       
   326     delete iDate;
       
   327     }
       
   328 
       
   329 // -----------------------------------------------------------------------------
       
   330 // CAsf::
       
   331 //
       
   332 // -----------------------------------------------------------------------------
       
   333 //
       
   334 EXPORT_C TBool CAsf::IsProtected( const TDesC8& aAsfHeader )
       
   335     {
       
   336     LOGFN( "CAsf::IsProtected" );
       
   337     if ( aAsfHeader.Find( KWrmHeader ) == KErrNotFound )
       
   338         {
       
   339         return EFalse;
       
   340         }
       
   341     else
       
   342         {
       
   343         return ETrue;
       
   344         }
       
   345     }
       
   346 
       
   347 
       
   348 // -----------------------------------------------------------------------------
       
   349 // CAsf::ValidateL
       
   350 //
       
   351 // -----------------------------------------------------------------------------
       
   352 //
       
   353 void CAsf::ValidateL()
       
   354     {
       
   355     // ASF_Header_Object GUID 128 bits.
       
   356     TBuf8<32> header;
       
   357 
       
   358     LOGFN( "CAsf::ValidateL" );
       
   359     iFile.Read( 0, header, KObjectID );
       
   360     if ( header.Length() < KObjectID )
       
   361         {
       
   362         User::Leave( KErrOverflow );
       
   363         }
       
   364     FormatGUID( header );
       
   365     if ( header !=  KASFHeaderObject )
       
   366         {
       
   367         User::Leave( KErrArgument );
       
   368         }
       
   369     
       
   370     // read header object size.
       
   371     iFile.Read( header, KObjectSize );
       
   372     iHeaderSize = ReadUint64FromBlockL( header, 0 );
       
   373     if ( iHeaderSize <= 30 || iHeaderSize > KMaxTInt / 2 - 1 )
       
   374         {
       
   375         User::Leave( KErrOverflow );
       
   376         }
       
   377 
       
   378     // read header object
       
   379     // 2~31 = 2 GB, size of header would not be greater than this,
       
   380     // also, HBufC does not have a NewL with TInt64 as arguement.
       
   381     iHeaderData = HBufC8::NewL( iHeaderSize );
       
   382     TPtr8 headerPtr = iHeaderData->Des();
       
   383     iFile.Read( headerPtr, iHeaderSize - ( KObjectID + KObjectSize ) );
       
   384 
       
   385     iNbrOfObjects = ReadUint32FromBlockL( *iHeaderData, 0 );
       
   386     if ( iNbrOfObjects <= 0 )
       
   387         {
       
   388         User::Leave( KErrArgument );
       
   389         }
       
   390 
       
   391     TInt objOffset( 6 );
       
   392     if ( iHeaderData->Length() < ( objOffset + KObjectID ) )
       
   393         {
       
   394         User::Leave( KErrArgument );
       
   395         }
       
   396     //Read next object GUID
       
   397     TBuf8<32> objGUID = iHeaderData->Mid( objOffset, KObjectID );
       
   398     FormatGUID( objGUID );
       
   399     TBool loop( ETrue );
       
   400 
       
   401     //Loop until all needed headers are handled or top level header is finished
       
   402     while ( loop )
       
   403         {
       
   404         //Read current object size
       
   405         TUint32 objSize( ReadUint64FromBlockL( *iHeaderData, objOffset + KObjectID ) );
       
   406         if ( objSize < 24 )
       
   407             {
       
   408             User::Leave( KErrArgument );
       
   409             }
       
   410         
       
   411         if ( !iContentDescriptionObjectExists && objGUID == 
       
   412              KASFContentDescriptionObject )
       
   413             {
       
   414             iContentDescriptionObjectExists = ETrue;
       
   415             iContentDescriptionOffset = objOffset;
       
   416             ParseContentDescriptionObjectL();
       
   417             }
       
   418         else if ( !iFilePropertiesObjectExists && objGUID == 
       
   419              KASFFilePropertiesObject )
       
   420             {
       
   421             iFilePropertiesObjectExists = ETrue; // must exist
       
   422             iFilePropertiesOffset = objOffset;
       
   423             iFilePropertiesEndOffset = iFilePropertiesOffset + objSize;
       
   424             }
       
   425         else if ( !iExtendedContentDescriptionObjectExists && objGUID ==
       
   426              KASFExtendedContentDescriptionObject )
       
   427             {
       
   428             iExtendedContentDescriptionObjectExists = ETrue;
       
   429             iExtendedContentDescriptionOffset = objOffset;
       
   430             ParseExtendedContentDescriptionObjectL();
       
   431             }
       
   432         else if ( !iExtendedContentEncryptionObjectExists && objGUID ==
       
   433              KASFExtendedContentEncryptionObject )
       
   434             {
       
   435             iExtendedContentEncryptionObjectExists = ETrue;
       
   436             iExtendedContentEncryptionOffset = objOffset;
       
   437             iIsDrmProtected = ETrue;
       
   438             TInt eCEODataOffset( objOffset + KObjectID + KObjectSize + 4 );
       
   439             TInt eCEODataLength( objSize - ( KObjectID + KObjectSize + 4 ) );
       
   440             if ( iHeaderData->Length() < eCEODataOffset + eCEODataLength ||
       
   441                  eCEODataLength < 0)
       
   442                 {
       
   443                 User::Leave( KErrArgument );
       
   444                 }
       
   445             iExtendedContentEncryptionObject = iHeaderData->Mid( eCEODataOffset,
       
   446                                                                  eCEODataLength ).AllocL();
       
   447             }
       
   448         else if ( !iContentEncryptionObjectExists && objGUID ==
       
   449              KASFContentEncryptionObject )
       
   450             {
       
   451             iContentEncryptionObjectExists = ETrue;
       
   452             iContentEncryptionOffset = objOffset;
       
   453             iIsDrmProtected = ETrue;
       
   454             ParseContentEncryptionObjectL();
       
   455             }
       
   456         else if ( !iDigitalSignatureObjectExists && objGUID ==
       
   457              KASFDigitalSignatureObject )
       
   458             {
       
   459             iDigitalSignatureObjectExists = ETrue;
       
   460             iDigitalSignatureOffset = objOffset;
       
   461             
       
   462             TInt dSODataOffset( objOffset + KObjectID + KObjectSize + 8 );
       
   463             TInt dSODataLength( objSize - ( KObjectID + KObjectSize + 8 ) );
       
   464             if ( iHeaderData->Length() < dSODataOffset + dSODataLength ||
       
   465                  dSODataLength < 0 )
       
   466                 {
       
   467                 User::Leave( KErrArgument );
       
   468                 }
       
   469             iDigitalSignatureObject = iHeaderData->Mid( dSODataOffset,
       
   470                                                         dSODataLength ).AllocL();
       
   471             
       
   472             if ( iHeaderData->Length() < iFilePropertiesEndOffset + ( iDigitalSignatureOffset - iFilePropertiesEndOffset ) ||
       
   473                  iDigitalSignatureOffset - iFilePropertiesEndOffset < 0 ||
       
   474                  iFilePropertiesEndOffset < 0 )
       
   475                 {
       
   476                 iDigitalSignatureObjectExists = EFalse;
       
   477                 iDigitalSignatureOffset = 0;
       
   478                 delete iDigitalSignatureObject;
       
   479                 iDigitalSignatureObject = NULL;
       
   480                 }
       
   481             else
       
   482                 {
       
   483                 iSignedData = 
       
   484                     iHeaderData->Mid( iFilePropertiesEndOffset,
       
   485                                       iDigitalSignatureOffset - iFilePropertiesEndOffset ).AllocL();
       
   486                 }
       
   487             }
       
   488         
       
   489         //Move object offset to the end of the current header object  
       
   490         objOffset += objSize;
       
   491         //End loop, if top level header is finished or all needed headers are handled
       
   492         if ( objOffset >= iHeaderSize - 30 ||
       
   493             ( iContentDescriptionObjectExists &&
       
   494               iFilePropertiesObjectExists &&
       
   495               iExtendedContentDescriptionObjectExists &&
       
   496               iExtendedContentEncryptionObjectExists &&
       
   497               iDigitalSignatureObjectExists ) )
       
   498             {
       
   499             loop = EFalse;
       
   500             }
       
   501         //Loop isn't finished, read next object GUID
       
   502         else
       
   503             {
       
   504             if ( iHeaderData->Length() < ( objOffset + KObjectID ) || objOffset < 0 )
       
   505                 {
       
   506                 User::Leave( KErrArgument );
       
   507                 }
       
   508             objGUID = iHeaderData->Mid( objOffset, KObjectID );
       
   509             FormatGUID( objGUID );
       
   510             }
       
   511         }
       
   512     if ( iFilePropertiesObjectExists )
       
   513         {
       
   514         iIsValidated = ETrue;
       
   515         }
       
   516     }
       
   517 
       
   518 
       
   519 // -----------------------------------------------------------------------------
       
   520 // CAsf::FormatGUID
       
   521 // -----------------------------------------------------------------------------
       
   522 //
       
   523 void CAsf::FormatGUID( TDes8 &aGUID )
       
   524     {
       
   525     LOGFN( "CAsf::FormatGUID" );
       
   526 
       
   527     TBuf8<16> copyGUID( aGUID );
       
   528     TInt i;
       
   529     for( i = 0; i < 4; i++ )
       
   530         {
       
   531         copyGUID[i] = aGUID[3-i];
       
   532         }
       
   533     for( i = 4; i < 6; i++ )
       
   534         {
       
   535         copyGUID[i] = aGUID[9 - i];
       
   536         }
       
   537     for ( i = 6; i < 8; i++ )
       
   538         {
       
   539         copyGUID[i] = aGUID[13 - i];
       
   540         }
       
   541     for( i = 8; i < 16 ; i++ )
       
   542         {
       
   543         copyGUID[i] = aGUID[i];
       
   544         }
       
   545     aGUID.Delete( 0, 32 );
       
   546     for( i = 0; i < 16; i++ )
       
   547         {
       
   548         aGUID.AppendNumFixedWidthUC( copyGUID[i], EHex, 2 );
       
   549         }
       
   550     }
       
   551 
       
   552 // -----------------------------------------------------------------------------
       
   553 // CAsf::ParseContentDescriptionObject
       
   554 // -----------------------------------------------------------------------------
       
   555 //
       
   556 void CAsf::ParseContentDescriptionObjectL()
       
   557     {
       
   558     LOGFN( "CAsf::ParseContentDescriptionObjectL" );
       
   559     TInt offset( iContentDescriptionOffset + KObjectID );
       
   560     TUint32 objSize( ReadUint64FromBlockL( *iHeaderData, offset ) );
       
   561 
       
   562     if ( iHeaderData->Length() < iContentDescriptionOffset + objSize )
       
   563         {
       
   564         User::Leave( KErrOverflow );
       
   565         }
       
   566 
       
   567     offset += KObjectSize;
       
   568     iTitleLength = ReadUint16FromBlockL( *iHeaderData, offset );
       
   569     offset += 2;
       
   570     iAuthorLength = ReadUint16FromBlockL( *iHeaderData, offset );
       
   571     offset += 2;
       
   572     iCopyrightLength = ReadUint16FromBlockL( *iHeaderData, offset );
       
   573     offset += 2;
       
   574     iDescriptionLength = ReadUint16FromBlockL( *iHeaderData, offset );
       
   575     offset += 2;
       
   576     iRatingLength = ReadUint16FromBlockL( *iHeaderData, offset );
       
   577     offset += 2;
       
   578 
       
   579     TInt length( iTitleLength + iAuthorLength + iCopyrightLength + iDescriptionLength + iRatingLength );
       
   580     if ( length > objSize - ( KObjectID + KObjectSize + 10 ) )
       
   581         {
       
   582         User::Leave( KErrOverflow );
       
   583         }
       
   584 
       
   585     iTitle = HBuf16FromBlockL( *iHeaderData, offset, iTitleLength );
       
   586     offset += iTitleLength;
       
   587     iAuthor = HBuf16FromBlockL( *iHeaderData, offset, iAuthorLength );
       
   588     offset += iAuthorLength;
       
   589     iCopyright = HBuf16FromBlockL( *iHeaderData, offset, iCopyrightLength );
       
   590     offset += iCopyrightLength;
       
   591     iDescription = HBuf16FromBlockL( *iHeaderData, offset, iDescriptionLength );
       
   592     offset += iDescriptionLength;
       
   593     iRating = HBuf16FromBlockL( *iHeaderData, offset, iRatingLength );
       
   594     offset += iRatingLength;
       
   595     }
       
   596 
       
   597 // -----------------------------------------------------------------------------
       
   598 // CAsf::ParseContentEncryptionObject
       
   599 // -----------------------------------------------------------------------------
       
   600 //
       
   601 void CAsf::ParseContentEncryptionObjectL()
       
   602     {
       
   603     LOGFN( "CAsf::ParseContentEncryptionObject" );
       
   604     TInt offset( iContentEncryptionOffset + KObjectID );
       
   605     TUint32 objSize( ReadUint64FromBlockL( *iHeaderData, offset ) );
       
   606 
       
   607     if ( iHeaderData->Length() < iContentEncryptionOffset + objSize ) 
       
   608         {
       
   609         User::Leave( KErrOverflow );
       
   610         }
       
   611 
       
   612     offset += KObjectSize;
       
   613     TInt len( ReadUint32FromBlockL( *iHeaderData, offset ) );
       
   614     offset += 4;
       
   615     if ( iHeaderData->Length() < ( offset + len ) )
       
   616         {
       
   617         User::Leave( KErrArgument );
       
   618         }
       
   619     iSecretData = iHeaderData->Mid( offset, len ).AllocL();
       
   620     offset += len;
       
   621 
       
   622     len = ReadUint32FromBlockL( *iHeaderData, offset );
       
   623     offset += 4;
       
   624     if ( iHeaderData->Length() < ( offset + len ) )
       
   625         {
       
   626         User::Leave( KErrArgument );
       
   627         }
       
   628     iProtectionType = iHeaderData->Mid( offset, len ).AllocL();
       
   629     offset += len;
       
   630 
       
   631     len = ReadUint32FromBlockL( *iHeaderData, offset );
       
   632     offset += 4;
       
   633     if ( iHeaderData->Length() < ( offset + len ) )
       
   634         {
       
   635         User::Leave( KErrArgument );
       
   636         }
       
   637     iKeyId = iHeaderData->Mid( offset, len ).AllocL();
       
   638     offset += len;
       
   639 
       
   640     len = ReadUint32FromBlockL( *iHeaderData, offset );
       
   641     offset += 4;
       
   642     if ( iHeaderData->Length() < ( offset + len ) )
       
   643         {
       
   644         User::Leave( KErrArgument );
       
   645         }
       
   646     iLicenseUrl = iHeaderData->Mid( offset, len ).AllocL();
       
   647     }
       
   648 
       
   649 // -----------------------------------------------------------------------------
       
   650 // CAsf::ParseExtendedContentDescriptionObjectL
       
   651 // -----------------------------------------------------------------------------
       
   652 //
       
   653 void CAsf::ParseExtendedContentDescriptionObjectL()
       
   654     {
       
   655     TInt i;
       
   656     
       
   657     LOGFN( "CAsf::ParseExtendedContentDescriptionObjectL" );
       
   658     TInt offset( iExtendedContentDescriptionOffset + KObjectID );
       
   659     TUint32 objSize( ReadUint64FromBlockL( *iHeaderData, offset ) );
       
   660 
       
   661     if ( iHeaderData->Length() < iExtendedContentDescriptionOffset + objSize )
       
   662         {
       
   663         User::Leave( KErrOverflow );
       
   664         }
       
   665 
       
   666     offset += KObjectSize;
       
   667     iExtendedContentDescriptionCount = ReadUint16FromBlockL( *iHeaderData, offset );
       
   668     offset += 2;
       
   669 
       
   670     for ( i = 0 ; i < iExtendedContentDescriptionCount; i++ )
       
   671         {
       
   672         TInt nameLength( ReadUint16FromBlockL( *iHeaderData, offset ) );
       
   673         offset += 2;
       
   674         HBufC16* name16( HBuf16FromBlockL( *iHeaderData, offset, nameLength ) );
       
   675         offset += nameLength;
       
   676         CleanupStack::PushL( name16 );
       
   677         if( !name16->CompareF( KWMAlbumTitle ) )
       
   678             {
       
   679             iAlbumTitle = ReadExtendedContentObjectL( offset );
       
   680             }
       
   681         else if( !name16->CompareF( KWMPicture ) )
       
   682             {
       
   683             iPicture = ReadExtendedContentObjectL( offset );
       
   684             }
       
   685         else if( !name16->CompareF( KWMText) )
       
   686             {
       
   687             iText = ReadExtendedContentObjectL( offset );
       
   688             }
       
   689         else if( !name16->CompareF( KWMComposer ) )
       
   690             {
       
   691             iComposer = ReadExtendedContentObjectL( offset );
       
   692             }
       
   693         else if( !name16->CompareF( KWMGenre ) )
       
   694             {
       
   695             iGenre = ReadExtendedContentObjectL( offset );
       
   696             }
       
   697         else if( !name16->CompareF( KWMYear ) || !name16->CompareF( KWMYear1 ) )
       
   698             {
       
   699             if ( !iYear )
       
   700                 {
       
   701                 iYear = ReadExtendedContentObjectL( offset );
       
   702                 }
       
   703             }
       
   704         else if( !name16->CompareF( KWMOriginalArtist) )
       
   705             {
       
   706             iOriginalArtist = ReadExtendedContentObjectL( offset );
       
   707             }
       
   708         else if( !name16->CompareF( KWMTrackNumber ) )
       
   709             {
       
   710             iTrackNumber = ReadExtendedContentObjectL( offset );
       
   711             }
       
   712         else if( !name16->CompareF( KWMUniqueFileIdentifier ) )
       
   713             {
       
   714             iUniqueFileID = ReadExtendedContentObjectL( offset );
       
   715             }
       
   716         else if( !name16->CompareF( KWMAudioFileURL ) )
       
   717             {
       
   718             iAudioFileUrl = ReadExtendedContentObjectL( offset );
       
   719             }
       
   720         else if( !name16->CompareF( KWMSharedUserRating ) )
       
   721             {
       
   722             iSharedUserRating = ReadExtendedContentObjectL( offset );
       
   723             }
       
   724         else if( !name16->CompareF( KWMDate ) )
       
   725             {
       
   726             iDate = ReadExtendedContentObjectL( offset );
       
   727             }
       
   728         CleanupStack::PopAndDestroy( name16 );
       
   729 
       
   730         offset += 2; // data type
       
   731         TInt valueLength( ReadUint16FromBlockL( *iHeaderData, offset ) );
       
   732         offset += 2;
       
   733         offset += valueLength;
       
   734         }
       
   735     }
       
   736 
       
   737 // -----------------------------------------------------------------------------
       
   738 // CAsf::ReadExtendedContentObjectL
       
   739 // -----------------------------------------------------------------------------
       
   740 //
       
   741 HBufC16* CAsf::ReadExtendedContentObjectL( TInt aOffset )
       
   742     {
       
   743     HBufC16* buffer( NULL );
       
   744 
       
   745     LOGFN( "CAsf::ReadExtendedContentObjectL" );
       
   746     TInt dataTypeInt( ReadUint16FromBlockL( *iHeaderData, aOffset ) );
       
   747     if ( dataTypeInt == 0x00 )
       
   748         {
       
   749         TInt length( ReadUint16FromBlockL( *iHeaderData, aOffset + 2 ) );
       
   750         if ( length > 0 )
       
   751             {
       
   752             buffer = HBuf16FromBlockL( *iHeaderData, aOffset + 4, length - 2 );
       
   753             }
       
   754         }
       
   755     else if ( dataTypeInt == 0x02 || dataTypeInt == 0x03 )
       
   756         {
       
   757         TUint32 dword( ReadUint32FromBlockL( *iHeaderData, aOffset + 4 ) );
       
   758         buffer = HBufC::NewL( 16 );
       
   759         TPtr dataString( buffer ->Des() );
       
   760         dataString.Num( dword );
       
   761         }
       
   762     else if ( dataTypeInt == 0x05 )
       
   763         {
       
   764         TUint16 word( ReadUint16FromBlockL( *iHeaderData, aOffset + 4 ) );
       
   765         buffer = HBufC::NewL( 8 );
       
   766         TPtr dataString( buffer->Des() );
       
   767         dataString.Num( word ) ;
       
   768         }
       
   769     return buffer;
       
   770     }
       
   771 
       
   772 //  End of File