omadrm/drmlicensemanager/src/DRMLicenseManager.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omadrm/drmlicensemanager/src/DRMLicenseManager.cpp	Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,814 @@
+/*
+* Copyright (c) 2004-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:  Implementation of the license manager functionality used in the
+*                install process
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <e32base.h>
+#include <apmstd.h>
+#include <e32math.h>
+#include <f32file.h>
+#include <s32buf.h>
+#include <s32crypt.h>
+#include <utf.h>
+#include <DrmRights.h>
+#include <DrmCommon.h>
+#include <Oma1DcfCreator.h>
+#include <SysUtil.h>     // Disk space checking
+
+#include "ZipFile.h"
+#include "ZipFileMemberIterator.h"
+#include "DRMLicenseManager.h"
+
+// LOCAL CONSTANTS AND MACROS
+_LIT(KDefinitionFileName, "datafiles.def");
+_LIT(KSISSuffix, ".sis");
+_LIT(KSISXSuffix, ".sisx");
+_LIT8(KDefaultMIMEType, "application/binary");
+_LIT8( KIssuer , "Rights-Issuer" );
+
+const TInt KSISBufferSize = 512;
+const TInt KMaxTypeLength = 11 + 2; // Length of "application" + CR + LF
+const TInt KMaxFileDescriptionLength = KMaxPath + KMaxPath + KMaxDataTypeLength;
+
+
+// ============================ LOCAL FUNCTIONS ================================
+// -----------------------------------------------------------------------------
+// DriveOfPathL
+// -----------------------------------------------------------------------------
+LOCAL_C inline TInt DriveOfPathL(
+    RFs& aFs,
+    const TDesC aPathName,
+    TInt aFallbackDrive = KDefaultDrive )
+    {
+    // find drive for destination for free space check
+    TInt driveNumber( KDefaultDrive );
+    TParsePtrC pptr( aPathName );
+    TInt err( KErrNone );
+    if ( pptr.DrivePresent() )
+        {
+        err = RFs::CharToDrive( pptr.Drive()[ 0 ], driveNumber );
+        User::LeaveIfError( err );
+        }
+    else if ( aFallbackDrive != KDefaultDrive )
+        {
+        driveNumber = aFallbackDrive;
+        }
+    else
+        {
+        HBufC* sessionPath( HBufC::NewLC( KMaxPath ) );
+        TPtr pathPtr( sessionPath->Des() );
+        User::LeaveIfError( aFs.SessionPath( pathPtr ) );
+
+        TParsePtrC sPPtr( pathPtr );
+        if ( sPPtr.DrivePresent() )
+            {
+            err = RFs::CharToDrive( sPPtr.Drive()[ 0 ], driveNumber );
+            User::LeaveIfError( err );
+            }
+        else
+            {
+            driveNumber = RFs::GetSystemDrive();
+            }
+        CleanupStack::PopAndDestroy( sessionPath );
+        }
+    return driveNumber;
+    }
+
+// -----------------------------------------------------------------------------
+// CheckNeededFreeSpaceL
+// -----------------------------------------------------------------------------
+LOCAL_C void CheckNeededFreeSpaceL(
+    RFs& aFs,
+    CZipFile*& aZipFile,
+    RPointerArray< TDRMDataFile >& aDataFiles,
+    const TDesC& aDestination,
+    TInt& aError )
+    {
+    static const TInt KExtraSpaceForDcf( 1024 );
+    CArrayFixFlat< TInt >* arrayOfNeededSpaces( NULL );
+    // Get target drive for relative files
+    TInt driveForRelativePath( DriveOfPathL( aFs, aDestination ) );
+
+    arrayOfNeededSpaces = new ( ELeave ) CArrayFixFlat< TInt >( KMaxDrives );
+    CleanupStack::PushL(  arrayOfNeededSpaces );
+
+    arrayOfNeededSpaces->SetReserveL( KMaxDrives );
+    for ( TInt j( 0 ); j < KMaxDrives; ++j )
+        {
+        arrayOfNeededSpaces->AppendL(0);
+        }
+
+    for ( TInt i = 0; i < aDataFiles.Count() && aError == KErrNone; i++ )
+        {
+        TDRMDataFile* dataFile(
+            static_cast< TDRMDataFile* >( aDataFiles[ i ] ) );
+        CZipFileMember* member(
+            aZipFile->CaseInsensitiveMemberL( dataFile->iSourceName ) );
+        if ( member )
+            {
+            CleanupStack::PushL( member );
+            TInt driveNumber( DriveOfPathL(
+                    aFs, dataFile->iTargetName, driveForRelativePath ) );
+            ( *arrayOfNeededSpaces )[ driveNumber ] +=
+                member->UncompressedSize() + KExtraSpaceForDcf;
+            CleanupStack::PopAndDestroy( member );
+            }
+        else
+            {
+            aError = CDRMLicenseManager::EPIPInvalid;
+            }
+        }
+
+    for ( TInt j( 0 ); j < KMaxDrives; ++j )
+        {
+        TUint element( ( *arrayOfNeededSpaces )[ j ] );
+        if ( element && // no need to check if no space required
+            SysUtil::DiskSpaceBelowCriticalLevelL( &aFs, element, j) )
+            {
+            User::Leave( KErrDiskFull );
+            }
+        }
+    CleanupStack::PopAndDestroy( arrayOfNeededSpaces );
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::CDRMLicenseManager
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CDRMLicenseManager::CDRMLicenseManager():
+    iFs(NULL), iRights(NULL), iRightsIssuer(NULL)
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CDRMLicenseManager::ConstructL()
+    {
+    iFs = new RFs();
+    User::LeaveIfNull(iFs);
+    User::LeaveIfError(iFs->Connect());
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CDRMLicenseManager* CDRMLicenseManager::NewL()
+    {
+    CDRMLicenseManager* self = new( ELeave ) CDRMLicenseManager;
+
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+
+// Destructor
+EXPORT_C CDRMLicenseManager::~CDRMLicenseManager()
+    {
+    iFs->Close();
+    delete iFs;
+
+    iDataFiles.ResetAndDestroy();
+
+    if (iZipFile)
+        {
+        iZipFile->Close();
+        delete iZipFile;
+        }
+
+    if (iRights)
+        {
+        delete iRights;
+        }
+
+    if (iRightsIssuer)
+        {
+        delete iRightsIssuer;
+        }
+    }
+
+LOCAL_C TBool GetRightsIssuerL(const TFileName aFileName, HBufC8*& aRightsIssuerURL)
+    {
+    TInt err(KErrNotFound);
+
+    HBufC8* name = HBufC8::NewLC(16);
+    TPtr8 headerName( name->Des() );
+    headerName.Copy( KIssuer );
+
+    DRMCommon* c = DRMCommon::NewL();
+    CleanupStack::PushL(c);
+    err = c->GetFileHeader(aFileName, headerName, aRightsIssuerURL);
+    CleanupStack::PopAndDestroy(c);
+    CleanupStack::PopAndDestroy(name);
+
+    if(err == DRMCommon::EOk && aRightsIssuerURL)
+        {
+        return ETrue;
+        }
+
+    return EFalse;
+    }
+
+LOCAL_C TBool GetRightsIssuerL(RFile aFileName, HBufC8*& aRightsIssuerURL)
+    {
+    TInt err(KErrNotFound);
+
+    HBufC8* name = HBufC8::NewLC(16);
+    TPtr8 headerName( name->Des() );
+    headerName.Copy( KIssuer );
+
+    DRMCommon* c = DRMCommon::NewL();
+    CleanupStack::PushL(c);
+    err = c->GetFileHeader(aFileName, headerName, aRightsIssuerURL);
+    CleanupStack::PopAndDestroy(c);
+    CleanupStack::PopAndDestroy(name);
+
+    if(err == DRMCommon::EOk && aRightsIssuerURL)
+        {
+        return ETrue;
+        }
+
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::ProcessL
+// Read the PIP definition file and encrypt each referenced data file
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CDRMLicenseManager::ProcessL(
+    const TDesC& aZIPFile,
+    const TDesC& aDestination)
+    {
+    TInt r = KErrNone;
+    DRMCommon* drm = NULL;
+    RPointerArray<CDRMRights>* rights = NULL;
+
+    // Clean up
+    if (iZipFile)
+        {
+        iZipFile->Close();
+        delete iZipFile;
+        iZipFile = NULL;
+        }
+
+    if (iRights)
+        {
+        delete iRights;
+        iRights = NULL;
+        }
+
+    if (iRightsIssuer)
+        {
+        delete iRightsIssuer;
+        iRightsIssuer = NULL;
+        }
+
+    GetRightsIssuerL(aZIPFile, iRightsIssuer);
+
+    iDataFiles.ResetAndDestroy();
+
+    // Get rights object for the PIP file
+    iZipFile = CZipFile::NewL(*iFs, aZIPFile);
+    drm = DRMCommon::NewL();
+    CleanupStack::PushL(drm);
+    r = drm->GetDetailedFileRights(aZIPFile, rights);
+
+    // Read the definition file
+    if (r == KErrNone)
+        {
+        iRights = (*rights)[0];
+        rights->Remove(0);
+        rights->ResetAndDestroy();
+        delete rights;
+        r = ReadDefinitionFileL();
+        }
+
+    // Process data files
+    if (r == KErrNone)
+        {
+        r = ProcessDataFilesL(aDestination);
+        }
+
+    CleanupStack::PopAndDestroy(drm);
+
+    return r;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::ProcessL
+// Read the PIP definition file and encrypt each referenced data file
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CDRMLicenseManager::ProcessL(
+    RFile& aZIPFile,
+    const TDesC& aDestination)
+    {
+    TInt r = KErrNone;
+    DRMCommon* drm = NULL;
+    RPointerArray<CDRMRights>* rights = NULL;
+
+    // Clean up
+    if (iZipFile)
+        {
+        iZipFile->Close();
+        delete iZipFile;
+        iZipFile = NULL;
+        }
+
+    if (iRights)
+        {
+        delete iRights;
+        iRights = NULL;
+        }
+
+    if (iRightsIssuer)
+        {
+        delete iRightsIssuer;
+        iRightsIssuer = NULL;
+        }
+
+    GetRightsIssuerL(aZIPFile, iRightsIssuer);
+
+    iDataFiles.ResetAndDestroy();
+
+    // Get rights object for the PIP file
+    iZipFile = CZipFile::NewL(*iFs, aZIPFile);
+    drm = DRMCommon::NewL();
+    CleanupStack::PushL(drm);
+    r = drm->GetDetailedFileRights(aZIPFile, rights);
+
+    // Read the definition file
+    if (r == KErrNone)
+        {
+        iRights = (*rights)[0];
+        rights->Remove(0);
+        rights->ResetAndDestroy();
+        delete rights;
+        r = ReadDefinitionFileL();
+        }
+
+    // Process data files
+    if (r == KErrNone)
+        {
+        r = ProcessDataFilesL(aDestination);
+        }
+
+    CleanupStack::PopAndDestroy(drm);
+
+    return r;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::ExtractSISFileL
+// Find the SIS member of the ZIP file and write it to the target destination.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CDRMLicenseManager::ExtractSISFileL(
+    const TDesC& aZIPFile,
+    const TDesC& aDestination)
+    {
+    CZipFileMember* sisFile = NULL;
+    TInt r = KErrNone;
+
+    if (iZipFile)
+        {
+        iZipFile->Close();
+        delete iZipFile;
+        iZipFile = NULL;
+        }
+
+    if (iRightsIssuer)
+        {
+        delete iRightsIssuer;
+        iRightsIssuer = NULL;
+        }
+
+    GetRightsIssuerL(aZIPFile, iRightsIssuer);
+
+    iZipFile = CZipFile::NewL(*iFs, aZIPFile);
+
+    __UHEAP_MARK;
+    sisFile = GetSISMemberL();
+
+    if (sisFile)
+        {
+        WriteSISMemberL(sisFile, aDestination);
+        delete sisFile;
+        }
+    else
+        {
+        r = ESISNotFound;
+        }
+    __UHEAP_MARKEND;
+
+    return r;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::ExtractSISFileL
+// Find the SIS member of the ZIP file and write it to the target destination.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CDRMLicenseManager::ExtractSISFileL(
+    RFile& aZIPFile,
+    const TDesC& aDestination)
+    {
+    CZipFileMember* sisFile = NULL;
+    TInt r = KErrNone;
+
+    if (iZipFile)
+        {
+        iZipFile->Close();
+        delete iZipFile;
+        iZipFile = NULL;
+        }
+
+    if (iRightsIssuer)
+        {
+        delete iRightsIssuer;
+        iRightsIssuer = NULL;
+        }
+
+    GetRightsIssuerL(aZIPFile, iRightsIssuer);
+
+    iZipFile = CZipFile::NewL(*iFs, aZIPFile);
+
+    __UHEAP_MARK;
+    sisFile = GetSISMemberL();
+
+    if (sisFile)
+        {
+        WriteSISMemberL(sisFile, aDestination);
+        delete sisFile;
+        }
+    else
+        {
+        r = ESISNotFound;
+        }
+    __UHEAP_MARKEND;
+
+    return r;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::GetSISMemberL
+// Finds the SIS member in the ZIP file by looking for the .sis file ending.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CZipFileMember* CDRMLicenseManager::GetSISMemberL(void)
+    {
+    CZipFileMemberIterator* members = NULL;
+    CZipFileMember* sisFile = NULL;
+    CZipFileMember* member = NULL;
+
+    members = iZipFile->GetMembersL();
+    CleanupStack::PushL(members);
+    
+    member = members->NextL();
+    
+    while (member && !sisFile)
+        {
+        if (member->Name()->Right(4).CompareF(KSISSuffix) == 0)
+            {
+            sisFile = member;
+            }
+        else if (member->Name()->Right(5).CompareF(KSISXSuffix) == 0)
+            {
+            sisFile = member;
+            }
+        else
+            {
+            delete member;
+            member = NULL;
+            member = members->NextL();
+            }
+        }
+    
+    CleanupStack::PopAndDestroy(members);
+
+    if(!sisFile)
+        {
+        User::Leave(KErrNotFound);
+        }
+    
+    return sisFile;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::WriteSISMemberL
+// Write a SIS member to disk.
+// -----------------------------------------------------------------------------
+//
+void CDRMLicenseManager::WriteSISMemberL(
+    CZipFileMember* aSisMember,
+    const TDesC& aDestination)
+    {
+    RZipFileMemberReaderStream* input = NULL;
+    RFileWriteStream output;
+    TBuf8<KSISBufferSize> buffer;
+
+    // Check free space and leave if not enough space available
+    if ( SysUtil::DiskSpaceBelowCriticalLevelL(
+            iFs,
+            aSisMember->UncompressedSize(),
+            DriveOfPathL( *iFs, aDestination ) ) )
+        {
+        User::Leave( KErrDiskFull );
+        }
+
+    iZipFile->GetInputStreamL(aSisMember, input);
+    CleanupStack::PushL(input);
+
+    iFs->SetSessionPath(aDestination);
+    User::LeaveIfError(output.Replace(*iFs, *aSisMember->Name(), EFileWrite));
+    output.PushL();
+    do
+        {
+        input->Read(buffer, KSISBufferSize);
+        if (buffer.Size() > 0)
+            {
+            output.WriteL(buffer);
+            }
+        }
+    while (buffer.Size() > 0);
+    output.Close();
+
+    CleanupStack::PopAndDestroy(&output);
+    CleanupStack::PopAndDestroy(input);
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::ReadDefinitionFileL
+// Read the PIP type and definition lines from the definition file.
+// -----------------------------------------------------------------------------
+//
+TInt CDRMLicenseManager::ReadDefinitionFileL(void)
+    {
+    CZipFileMember* definitionFile = NULL;
+    RZipFileMemberReaderStream* input = NULL;
+    TBuf8<KMaxTypeLength> type;
+    TInt r = KErrNone;
+
+    TRAP(r, definitionFile =
+        iZipFile->CaseInsensitiveMemberL(KDefinitionFileName));
+
+    if (r == KErrNone && definitionFile)
+        {
+        CleanupStack::PushL(definitionFile);
+        iZipFile->GetInputStreamL(definitionFile, input);
+        ReadLine(input, type);
+        while (r == KErrNone)
+            {
+            r = ReadFileDescription(input);
+            }
+        delete input;
+        CleanupStack::PopAndDestroy(definitionFile);
+        }
+    else
+        {
+        r = EPIPInvalid;
+        }
+
+    if (r == KErrEof)
+        {
+        r = KErrNone;
+        }
+
+    return r;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::ReadFileDescription
+// Read the name, type and target name of a data file.
+// -----------------------------------------------------------------------------
+//
+TInt CDRMLicenseManager::ReadFileDescription(
+    RZipFileMemberReaderStream* aStream)
+    {
+    TBuf8<KMaxFileDescriptionLength> description;
+    TInt r = KErrNone;
+    TDRMDataFile* dataFile = NULL;
+
+    ReadLine(aStream, description);
+    description.TrimAll();
+    if (description.Length() > 0)
+        {
+        TLex8 lex(description);
+
+        dataFile = new TDRMDataFile();
+        if( !dataFile )
+            {
+            return KErrNoMemory;
+            }
+
+        // Get the original file name
+        lex.SkipSpaceAndMark();
+        lex.SkipCharacters();
+        CnvUtfConverter::ConvertToUnicodeFromUtf8(
+            dataFile->iSourceName, lex.MarkedToken());
+
+        // Get the MIME type. If not present, "application/binary" is used
+        // and the target file name is the source file name
+        lex.SkipSpaceAndMark();
+        lex.SkipCharacters();
+        if (lex.TokenLength() > 0)
+            {
+            dataFile->iMimeType = lex.MarkedToken();
+
+            // Get the target file name. If not present, the target file name
+            // will be the original file name, stored in the install directory.
+            lex.SkipSpaceAndMark();
+            lex.SkipCharacters();
+            if (lex.TokenLength() > 0)
+                {
+                CnvUtfConverter::ConvertToUnicodeFromUtf8(
+                    dataFile->iTargetName, lex.MarkedToken());
+                }
+            else
+                {
+                dataFile->iTargetName = dataFile->iSourceName;
+                }
+            }
+        else
+            {
+            dataFile->iMimeType = KDefaultMIMEType;
+            dataFile->iTargetName = dataFile->iSourceName;
+            }
+
+        iDataFiles.Append(dataFile);
+        }
+    else
+        {
+        r = KErrEof;
+        }
+    return r;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::ReadLine
+// Read one line ending with 0x0d or until the input buffer is full.
+// -----------------------------------------------------------------------------
+//
+void CDRMLicenseManager::ReadLine(
+    RZipFileMemberReaderStream* aStream,
+    TDes8& aLine)
+    {
+    TBuf8<1> c;
+    TInt n = 0;
+    TBool done = EFalse;
+
+    while (!done)
+        {
+        if (aLine.Length() < aLine.MaxLength())
+            {
+            aStream->Read(c, 1);
+            if (c.Length() > 0 && c[0] != 0x0d)
+                {
+                aLine.Append(c);
+                n++;
+                if (n == aLine.MaxLength() + 1)
+                    {
+                    done = ETrue;
+                    }
+                }
+            else
+                {
+                done = ETrue;
+                }
+            }
+        else
+            {
+            done = ETrue;
+            }
+        }
+
+    if (c.Length() > 0 && c[0] == 0x0d)
+        {
+        aStream->Read(c, 1);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::ProcessDataFilesL
+// Get all data files from the ZIP file and encrypt them.
+// -----------------------------------------------------------------------------
+//
+TInt CDRMLicenseManager::ProcessDataFilesL(
+    const TDesC& aDestination)
+    {
+    TDRMDataFile* dataFile( NULL );
+    CZipFileMember* member( NULL );
+    TInt r( KErrNone );
+
+    // check if there is enough free space for the process
+    CheckNeededFreeSpaceL( *iFs, iZipFile, iDataFiles, aDestination, r );
+
+    for ( TInt i = 0; i < iDataFiles.Count() && r == KErrNone; i++ )
+        {
+        dataFile = static_cast< TDRMDataFile* >( iDataFiles[ i ] );
+        member = iZipFile->CaseInsensitiveMemberL( dataFile->iSourceName );
+        if ( member )
+            {
+            CleanupStack::PushL(member);
+            EncryptDataFileL(dataFile, aDestination, member);
+            CleanupStack::PopAndDestroy(member);
+            }
+        else
+            {
+            r = EPIPInvalid;
+            }
+        }
+
+    return r;
+    }
+
+// -----------------------------------------------------------------------------
+// CDRMLicenseManager::EncryptDataFileL
+// Encrypt a single data file, reusing the outer PIP's RO. For application
+// protection, the file is encrypted again.
+// -----------------------------------------------------------------------------
+//
+void CDRMLicenseManager::EncryptDataFileL(
+    TDRMDataFile* aDataFile,
+    const TDesC& aDestination,
+    CZipFileMember* aZipMember)
+    {
+    RZipFileMemberReaderStream* input = NULL;
+    RFileWriteStream output;
+    TBuf8<KSISBufferSize> buffer;
+    COma1DcfCreator* drm = NULL;
+    TFileName outputFile;
+    DRMCommon* common = NULL;
+
+    drm = COma1DcfCreator::NewL();
+    CleanupStack::PushL(drm);
+
+    iZipFile->GetInputStreamL(aZipMember, input);
+    CleanupStack::PushL(input);
+
+    // Set the path so we can use relative paths
+    iFs->SetSessionPath(aDestination);
+
+    output.PushL();
+    // Create the output file stream
+    User::LeaveIfError(output.Replace(*iFs, aDataFile->iTargetName,
+        EFileWrite));
+
+    // Encrypt
+    drm->EncryptInitializeL(output, aDataFile->iMimeType, iRights);
+    do
+        {
+        input->Read(buffer, KSISBufferSize);
+        if (buffer.Size() > 0)
+            {
+            drm->EncryptUpdateL(buffer);
+            }
+        }
+    while (buffer.Size() > 0);
+    drm->EncryptFinalizeL();
+    output.Close();
+    CleanupStack::PopAndDestroy( &output );
+
+    // Add the rights issuer uri to the file if it exists
+    if( iRightsIssuer )
+        {
+        common = DRMCommon::NewL();
+        CleanupStack::PushL(common);
+        outputFile.Append( aDataFile->iTargetName );
+        common->SetFileHeader( outputFile, KIssuer,
+                               iRightsIssuer->Des());
+        CleanupStack::PopAndDestroy(common);
+        }
+    CleanupStack::PopAndDestroy(input);
+    CleanupStack::PopAndDestroy(drm);
+    }
+
+