omadrm/drmlicensemanager/src/DRMLicenseManager.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2004-2009 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 license manager functionality used in the
       
    15 *                install process
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <e32std.h>
       
    22 #include <e32base.h>
       
    23 #include <apmstd.h>
       
    24 #include <e32math.h>
       
    25 #include <f32file.h>
       
    26 #include <s32buf.h>
       
    27 #include <s32crypt.h>
       
    28 #include <utf.h>
       
    29 #include <DrmRights.h>
       
    30 #include <DrmCommon.h>
       
    31 #include <Oma1DcfCreator.h>
       
    32 #include <SysUtil.h>     // Disk space checking
       
    33 
       
    34 #include "ZipFile.h"
       
    35 #include "ZipFileMemberIterator.h"
       
    36 #include "DRMLicenseManager.h"
       
    37 
       
    38 // LOCAL CONSTANTS AND MACROS
       
    39 _LIT(KDefinitionFileName, "datafiles.def");
       
    40 _LIT(KSISSuffix, ".sis");
       
    41 _LIT(KSISXSuffix, ".sisx");
       
    42 _LIT8(KDefaultMIMEType, "application/binary");
       
    43 _LIT8( KIssuer , "Rights-Issuer" );
       
    44 
       
    45 const TInt KSISBufferSize = 512;
       
    46 const TInt KMaxTypeLength = 11 + 2; // Length of "application" + CR + LF
       
    47 const TInt KMaxFileDescriptionLength = KMaxPath + KMaxPath + KMaxDataTypeLength;
       
    48 
       
    49 
       
    50 // ============================ LOCAL FUNCTIONS ================================
       
    51 // -----------------------------------------------------------------------------
       
    52 // DriveOfPathL
       
    53 // -----------------------------------------------------------------------------
       
    54 LOCAL_C inline TInt DriveOfPathL(
       
    55     RFs& aFs,
       
    56     const TDesC aPathName,
       
    57     TInt aFallbackDrive = KDefaultDrive )
       
    58     {
       
    59     // find drive for destination for free space check
       
    60     TInt driveNumber( KDefaultDrive );
       
    61     TParsePtrC pptr( aPathName );
       
    62     TInt err( KErrNone );
       
    63     if ( pptr.DrivePresent() )
       
    64         {
       
    65         err = RFs::CharToDrive( pptr.Drive()[ 0 ], driveNumber );
       
    66         User::LeaveIfError( err );
       
    67         }
       
    68     else if ( aFallbackDrive != KDefaultDrive )
       
    69         {
       
    70         driveNumber = aFallbackDrive;
       
    71         }
       
    72     else
       
    73         {
       
    74         HBufC* sessionPath( HBufC::NewLC( KMaxPath ) );
       
    75         TPtr pathPtr( sessionPath->Des() );
       
    76         User::LeaveIfError( aFs.SessionPath( pathPtr ) );
       
    77 
       
    78         TParsePtrC sPPtr( pathPtr );
       
    79         if ( sPPtr.DrivePresent() )
       
    80             {
       
    81             err = RFs::CharToDrive( sPPtr.Drive()[ 0 ], driveNumber );
       
    82             User::LeaveIfError( err );
       
    83             }
       
    84         else
       
    85             {
       
    86             driveNumber = RFs::GetSystemDrive();
       
    87             }
       
    88         CleanupStack::PopAndDestroy( sessionPath );
       
    89         }
       
    90     return driveNumber;
       
    91     }
       
    92 
       
    93 // -----------------------------------------------------------------------------
       
    94 // CheckNeededFreeSpaceL
       
    95 // -----------------------------------------------------------------------------
       
    96 LOCAL_C void CheckNeededFreeSpaceL(
       
    97     RFs& aFs,
       
    98     CZipFile*& aZipFile,
       
    99     RPointerArray< TDRMDataFile >& aDataFiles,
       
   100     const TDesC& aDestination,
       
   101     TInt& aError )
       
   102     {
       
   103     static const TInt KExtraSpaceForDcf( 1024 );
       
   104     CArrayFixFlat< TInt >* arrayOfNeededSpaces( NULL );
       
   105     // Get target drive for relative files
       
   106     TInt driveForRelativePath( DriveOfPathL( aFs, aDestination ) );
       
   107 
       
   108     arrayOfNeededSpaces = new ( ELeave ) CArrayFixFlat< TInt >( KMaxDrives );
       
   109     CleanupStack::PushL(  arrayOfNeededSpaces );
       
   110 
       
   111     arrayOfNeededSpaces->SetReserveL( KMaxDrives );
       
   112     for ( TInt j( 0 ); j < KMaxDrives; ++j )
       
   113         {
       
   114         arrayOfNeededSpaces->AppendL(0);
       
   115         }
       
   116 
       
   117     for ( TInt i = 0; i < aDataFiles.Count() && aError == KErrNone; i++ )
       
   118         {
       
   119         TDRMDataFile* dataFile(
       
   120             static_cast< TDRMDataFile* >( aDataFiles[ i ] ) );
       
   121         CZipFileMember* member(
       
   122             aZipFile->CaseInsensitiveMemberL( dataFile->iSourceName ) );
       
   123         if ( member )
       
   124             {
       
   125             CleanupStack::PushL( member );
       
   126             TInt driveNumber( DriveOfPathL(
       
   127                     aFs, dataFile->iTargetName, driveForRelativePath ) );
       
   128             ( *arrayOfNeededSpaces )[ driveNumber ] +=
       
   129                 member->UncompressedSize() + KExtraSpaceForDcf;
       
   130             CleanupStack::PopAndDestroy( member );
       
   131             }
       
   132         else
       
   133             {
       
   134             aError = CDRMLicenseManager::EPIPInvalid;
       
   135             }
       
   136         }
       
   137 
       
   138     for ( TInt j( 0 ); j < KMaxDrives; ++j )
       
   139         {
       
   140         TUint element( ( *arrayOfNeededSpaces )[ j ] );
       
   141         if ( element && // no need to check if no space required
       
   142             SysUtil::DiskSpaceBelowCriticalLevelL( &aFs, element, j) )
       
   143             {
       
   144             User::Leave( KErrDiskFull );
       
   145             }
       
   146         }
       
   147     CleanupStack::PopAndDestroy( arrayOfNeededSpaces );
       
   148     }
       
   149 
       
   150 // ============================ MEMBER FUNCTIONS ===============================
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // CDRMLicenseManager::CDRMLicenseManager
       
   154 // C++ default constructor can NOT contain any code, that
       
   155 // might leave.
       
   156 // -----------------------------------------------------------------------------
       
   157 //
       
   158 CDRMLicenseManager::CDRMLicenseManager():
       
   159     iFs(NULL), iRights(NULL), iRightsIssuer(NULL)
       
   160     {
       
   161     }
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // CDRMLicenseManager::ConstructL
       
   165 // Symbian 2nd phase constructor can leave.
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 void CDRMLicenseManager::ConstructL()
       
   169     {
       
   170     iFs = new RFs();
       
   171     User::LeaveIfNull(iFs);
       
   172     User::LeaveIfError(iFs->Connect());
       
   173     }
       
   174 
       
   175 // -----------------------------------------------------------------------------
       
   176 // CDRMLicenseManager::NewL
       
   177 // Two-phased constructor.
       
   178 // -----------------------------------------------------------------------------
       
   179 //
       
   180 EXPORT_C CDRMLicenseManager* CDRMLicenseManager::NewL()
       
   181     {
       
   182     CDRMLicenseManager* self = new( ELeave ) CDRMLicenseManager;
       
   183 
       
   184     CleanupStack::PushL(self);
       
   185     self->ConstructL();
       
   186     CleanupStack::Pop( self );
       
   187 
       
   188     return self;
       
   189     }
       
   190 
       
   191 
       
   192 // Destructor
       
   193 EXPORT_C CDRMLicenseManager::~CDRMLicenseManager()
       
   194     {
       
   195     iFs->Close();
       
   196     delete iFs;
       
   197 
       
   198     iDataFiles.ResetAndDestroy();
       
   199 
       
   200     if (iZipFile)
       
   201         {
       
   202         iZipFile->Close();
       
   203         delete iZipFile;
       
   204         }
       
   205 
       
   206     if (iRights)
       
   207         {
       
   208         delete iRights;
       
   209         }
       
   210 
       
   211     if (iRightsIssuer)
       
   212         {
       
   213         delete iRightsIssuer;
       
   214         }
       
   215     }
       
   216 
       
   217 LOCAL_C TBool GetRightsIssuerL(const TFileName aFileName, HBufC8*& aRightsIssuerURL)
       
   218     {
       
   219     TInt err(KErrNotFound);
       
   220 
       
   221     HBufC8* name = HBufC8::NewLC(16);
       
   222     TPtr8 headerName( name->Des() );
       
   223     headerName.Copy( KIssuer );
       
   224 
       
   225     DRMCommon* c = DRMCommon::NewL();
       
   226     CleanupStack::PushL(c);
       
   227     err = c->GetFileHeader(aFileName, headerName, aRightsIssuerURL);
       
   228     CleanupStack::PopAndDestroy(c);
       
   229     CleanupStack::PopAndDestroy(name);
       
   230 
       
   231     if(err == DRMCommon::EOk && aRightsIssuerURL)
       
   232         {
       
   233         return ETrue;
       
   234         }
       
   235 
       
   236     return EFalse;
       
   237     }
       
   238 
       
   239 LOCAL_C TBool GetRightsIssuerL(RFile aFileName, HBufC8*& aRightsIssuerURL)
       
   240     {
       
   241     TInt err(KErrNotFound);
       
   242 
       
   243     HBufC8* name = HBufC8::NewLC(16);
       
   244     TPtr8 headerName( name->Des() );
       
   245     headerName.Copy( KIssuer );
       
   246 
       
   247     DRMCommon* c = DRMCommon::NewL();
       
   248     CleanupStack::PushL(c);
       
   249     err = c->GetFileHeader(aFileName, headerName, aRightsIssuerURL);
       
   250     CleanupStack::PopAndDestroy(c);
       
   251     CleanupStack::PopAndDestroy(name);
       
   252 
       
   253     if(err == DRMCommon::EOk && aRightsIssuerURL)
       
   254         {
       
   255         return ETrue;
       
   256         }
       
   257 
       
   258     return EFalse;
       
   259     }
       
   260 
       
   261 // -----------------------------------------------------------------------------
       
   262 // CDRMLicenseManager::ProcessL
       
   263 // Read the PIP definition file and encrypt each referenced data file
       
   264 // -----------------------------------------------------------------------------
       
   265 //
       
   266 EXPORT_C TInt CDRMLicenseManager::ProcessL(
       
   267     const TDesC& aZIPFile,
       
   268     const TDesC& aDestination)
       
   269     {
       
   270     TInt r = KErrNone;
       
   271     DRMCommon* drm = NULL;
       
   272     RPointerArray<CDRMRights>* rights = NULL;
       
   273 
       
   274     // Clean up
       
   275     if (iZipFile)
       
   276         {
       
   277         iZipFile->Close();
       
   278         delete iZipFile;
       
   279         iZipFile = NULL;
       
   280         }
       
   281 
       
   282     if (iRights)
       
   283         {
       
   284         delete iRights;
       
   285         iRights = NULL;
       
   286         }
       
   287 
       
   288     if (iRightsIssuer)
       
   289         {
       
   290         delete iRightsIssuer;
       
   291         iRightsIssuer = NULL;
       
   292         }
       
   293 
       
   294     GetRightsIssuerL(aZIPFile, iRightsIssuer);
       
   295 
       
   296     iDataFiles.ResetAndDestroy();
       
   297 
       
   298     // Get rights object for the PIP file
       
   299     iZipFile = CZipFile::NewL(*iFs, aZIPFile);
       
   300     drm = DRMCommon::NewL();
       
   301     CleanupStack::PushL(drm);
       
   302     r = drm->GetDetailedFileRights(aZIPFile, rights);
       
   303 
       
   304     // Read the definition file
       
   305     if (r == KErrNone)
       
   306         {
       
   307         iRights = (*rights)[0];
       
   308         rights->Remove(0);
       
   309         rights->ResetAndDestroy();
       
   310         delete rights;
       
   311         r = ReadDefinitionFileL();
       
   312         }
       
   313 
       
   314     // Process data files
       
   315     if (r == KErrNone)
       
   316         {
       
   317         r = ProcessDataFilesL(aDestination);
       
   318         }
       
   319 
       
   320     CleanupStack::PopAndDestroy(drm);
       
   321 
       
   322     return r;
       
   323     }
       
   324 
       
   325 // -----------------------------------------------------------------------------
       
   326 // CDRMLicenseManager::ProcessL
       
   327 // Read the PIP definition file and encrypt each referenced data file
       
   328 // -----------------------------------------------------------------------------
       
   329 //
       
   330 EXPORT_C TInt CDRMLicenseManager::ProcessL(
       
   331     RFile& aZIPFile,
       
   332     const TDesC& aDestination)
       
   333     {
       
   334     TInt r = KErrNone;
       
   335     DRMCommon* drm = NULL;
       
   336     RPointerArray<CDRMRights>* rights = NULL;
       
   337 
       
   338     // Clean up
       
   339     if (iZipFile)
       
   340         {
       
   341         iZipFile->Close();
       
   342         delete iZipFile;
       
   343         iZipFile = NULL;
       
   344         }
       
   345 
       
   346     if (iRights)
       
   347         {
       
   348         delete iRights;
       
   349         iRights = NULL;
       
   350         }
       
   351 
       
   352     if (iRightsIssuer)
       
   353         {
       
   354         delete iRightsIssuer;
       
   355         iRightsIssuer = NULL;
       
   356         }
       
   357 
       
   358     GetRightsIssuerL(aZIPFile, iRightsIssuer);
       
   359 
       
   360     iDataFiles.ResetAndDestroy();
       
   361 
       
   362     // Get rights object for the PIP file
       
   363     iZipFile = CZipFile::NewL(*iFs, aZIPFile);
       
   364     drm = DRMCommon::NewL();
       
   365     CleanupStack::PushL(drm);
       
   366     r = drm->GetDetailedFileRights(aZIPFile, rights);
       
   367 
       
   368     // Read the definition file
       
   369     if (r == KErrNone)
       
   370         {
       
   371         iRights = (*rights)[0];
       
   372         rights->Remove(0);
       
   373         rights->ResetAndDestroy();
       
   374         delete rights;
       
   375         r = ReadDefinitionFileL();
       
   376         }
       
   377 
       
   378     // Process data files
       
   379     if (r == KErrNone)
       
   380         {
       
   381         r = ProcessDataFilesL(aDestination);
       
   382         }
       
   383 
       
   384     CleanupStack::PopAndDestroy(drm);
       
   385 
       
   386     return r;
       
   387     }
       
   388 
       
   389 // -----------------------------------------------------------------------------
       
   390 // CDRMLicenseManager::ExtractSISFileL
       
   391 // Find the SIS member of the ZIP file and write it to the target destination.
       
   392 // -----------------------------------------------------------------------------
       
   393 //
       
   394 EXPORT_C TInt CDRMLicenseManager::ExtractSISFileL(
       
   395     const TDesC& aZIPFile,
       
   396     const TDesC& aDestination)
       
   397     {
       
   398     CZipFileMember* sisFile = NULL;
       
   399     TInt r = KErrNone;
       
   400 
       
   401     if (iZipFile)
       
   402         {
       
   403         iZipFile->Close();
       
   404         delete iZipFile;
       
   405         iZipFile = NULL;
       
   406         }
       
   407 
       
   408     if (iRightsIssuer)
       
   409         {
       
   410         delete iRightsIssuer;
       
   411         iRightsIssuer = NULL;
       
   412         }
       
   413 
       
   414     GetRightsIssuerL(aZIPFile, iRightsIssuer);
       
   415 
       
   416     iZipFile = CZipFile::NewL(*iFs, aZIPFile);
       
   417 
       
   418     __UHEAP_MARK;
       
   419     sisFile = GetSISMemberL();
       
   420 
       
   421     if (sisFile)
       
   422         {
       
   423         WriteSISMemberL(sisFile, aDestination);
       
   424         delete sisFile;
       
   425         }
       
   426     else
       
   427         {
       
   428         r = ESISNotFound;
       
   429         }
       
   430     __UHEAP_MARKEND;
       
   431 
       
   432     return r;
       
   433     }
       
   434 
       
   435 // -----------------------------------------------------------------------------
       
   436 // CDRMLicenseManager::ExtractSISFileL
       
   437 // Find the SIS member of the ZIP file and write it to the target destination.
       
   438 // -----------------------------------------------------------------------------
       
   439 //
       
   440 EXPORT_C TInt CDRMLicenseManager::ExtractSISFileL(
       
   441     RFile& aZIPFile,
       
   442     const TDesC& aDestination)
       
   443     {
       
   444     CZipFileMember* sisFile = NULL;
       
   445     TInt r = KErrNone;
       
   446 
       
   447     if (iZipFile)
       
   448         {
       
   449         iZipFile->Close();
       
   450         delete iZipFile;
       
   451         iZipFile = NULL;
       
   452         }
       
   453 
       
   454     if (iRightsIssuer)
       
   455         {
       
   456         delete iRightsIssuer;
       
   457         iRightsIssuer = NULL;
       
   458         }
       
   459 
       
   460     GetRightsIssuerL(aZIPFile, iRightsIssuer);
       
   461 
       
   462     iZipFile = CZipFile::NewL(*iFs, aZIPFile);
       
   463 
       
   464     __UHEAP_MARK;
       
   465     sisFile = GetSISMemberL();
       
   466 
       
   467     if (sisFile)
       
   468         {
       
   469         WriteSISMemberL(sisFile, aDestination);
       
   470         delete sisFile;
       
   471         }
       
   472     else
       
   473         {
       
   474         r = ESISNotFound;
       
   475         }
       
   476     __UHEAP_MARKEND;
       
   477 
       
   478     return r;
       
   479     }
       
   480 
       
   481 // -----------------------------------------------------------------------------
       
   482 // CDRMLicenseManager::GetSISMemberL
       
   483 // Finds the SIS member in the ZIP file by looking for the .sis file ending.
       
   484 // -----------------------------------------------------------------------------
       
   485 //
       
   486 EXPORT_C CZipFileMember* CDRMLicenseManager::GetSISMemberL(void)
       
   487     {
       
   488     CZipFileMemberIterator* members = NULL;
       
   489     CZipFileMember* sisFile = NULL;
       
   490     CZipFileMember* member = NULL;
       
   491 
       
   492     members = iZipFile->GetMembersL();
       
   493     CleanupStack::PushL(members);
       
   494     
       
   495     member = members->NextL();
       
   496     
       
   497     while (member && !sisFile)
       
   498         {
       
   499         if (member->Name()->Right(4).CompareF(KSISSuffix) == 0)
       
   500             {
       
   501             sisFile = member;
       
   502             }
       
   503         else if (member->Name()->Right(5).CompareF(KSISXSuffix) == 0)
       
   504             {
       
   505             sisFile = member;
       
   506             }
       
   507         else
       
   508             {
       
   509             delete member;
       
   510             member = NULL;
       
   511             member = members->NextL();
       
   512             }
       
   513         }
       
   514     
       
   515     CleanupStack::PopAndDestroy(members);
       
   516 
       
   517     if(!sisFile)
       
   518         {
       
   519         User::Leave(KErrNotFound);
       
   520         }
       
   521     
       
   522     return sisFile;
       
   523     }
       
   524 
       
   525 // -----------------------------------------------------------------------------
       
   526 // CDRMLicenseManager::WriteSISMemberL
       
   527 // Write a SIS member to disk.
       
   528 // -----------------------------------------------------------------------------
       
   529 //
       
   530 void CDRMLicenseManager::WriteSISMemberL(
       
   531     CZipFileMember* aSisMember,
       
   532     const TDesC& aDestination)
       
   533     {
       
   534     RZipFileMemberReaderStream* input = NULL;
       
   535     RFileWriteStream output;
       
   536     TBuf8<KSISBufferSize> buffer;
       
   537 
       
   538     // Check free space and leave if not enough space available
       
   539     if ( SysUtil::DiskSpaceBelowCriticalLevelL(
       
   540             iFs,
       
   541             aSisMember->UncompressedSize(),
       
   542             DriveOfPathL( *iFs, aDestination ) ) )
       
   543         {
       
   544         User::Leave( KErrDiskFull );
       
   545         }
       
   546 
       
   547     iZipFile->GetInputStreamL(aSisMember, input);
       
   548     CleanupStack::PushL(input);
       
   549 
       
   550     iFs->SetSessionPath(aDestination);
       
   551     User::LeaveIfError(output.Replace(*iFs, *aSisMember->Name(), EFileWrite));
       
   552     output.PushL();
       
   553     do
       
   554         {
       
   555         input->Read(buffer, KSISBufferSize);
       
   556         if (buffer.Size() > 0)
       
   557             {
       
   558             output.WriteL(buffer);
       
   559             }
       
   560         }
       
   561     while (buffer.Size() > 0);
       
   562     output.Close();
       
   563 
       
   564     CleanupStack::PopAndDestroy(&output);
       
   565     CleanupStack::PopAndDestroy(input);
       
   566     }
       
   567 
       
   568 // -----------------------------------------------------------------------------
       
   569 // CDRMLicenseManager::ReadDefinitionFileL
       
   570 // Read the PIP type and definition lines from the definition file.
       
   571 // -----------------------------------------------------------------------------
       
   572 //
       
   573 TInt CDRMLicenseManager::ReadDefinitionFileL(void)
       
   574     {
       
   575     CZipFileMember* definitionFile = NULL;
       
   576     RZipFileMemberReaderStream* input = NULL;
       
   577     TBuf8<KMaxTypeLength> type;
       
   578     TInt r = KErrNone;
       
   579 
       
   580     TRAP(r, definitionFile =
       
   581         iZipFile->CaseInsensitiveMemberL(KDefinitionFileName));
       
   582 
       
   583     if (r == KErrNone && definitionFile)
       
   584         {
       
   585         CleanupStack::PushL(definitionFile);
       
   586         iZipFile->GetInputStreamL(definitionFile, input);
       
   587         ReadLine(input, type);
       
   588         while (r == KErrNone)
       
   589             {
       
   590             r = ReadFileDescription(input);
       
   591             }
       
   592         delete input;
       
   593         CleanupStack::PopAndDestroy(definitionFile);
       
   594         }
       
   595     else
       
   596         {
       
   597         r = EPIPInvalid;
       
   598         }
       
   599 
       
   600     if (r == KErrEof)
       
   601         {
       
   602         r = KErrNone;
       
   603         }
       
   604 
       
   605     return r;
       
   606     }
       
   607 
       
   608 // -----------------------------------------------------------------------------
       
   609 // CDRMLicenseManager::ReadFileDescription
       
   610 // Read the name, type and target name of a data file.
       
   611 // -----------------------------------------------------------------------------
       
   612 //
       
   613 TInt CDRMLicenseManager::ReadFileDescription(
       
   614     RZipFileMemberReaderStream* aStream)
       
   615     {
       
   616     TBuf8<KMaxFileDescriptionLength> description;
       
   617     TInt r = KErrNone;
       
   618     TDRMDataFile* dataFile = NULL;
       
   619 
       
   620     ReadLine(aStream, description);
       
   621     description.TrimAll();
       
   622     if (description.Length() > 0)
       
   623         {
       
   624         TLex8 lex(description);
       
   625 
       
   626         dataFile = new TDRMDataFile();
       
   627         if( !dataFile )
       
   628             {
       
   629             return KErrNoMemory;
       
   630             }
       
   631 
       
   632         // Get the original file name
       
   633         lex.SkipSpaceAndMark();
       
   634         lex.SkipCharacters();
       
   635         CnvUtfConverter::ConvertToUnicodeFromUtf8(
       
   636             dataFile->iSourceName, lex.MarkedToken());
       
   637 
       
   638         // Get the MIME type. If not present, "application/binary" is used
       
   639         // and the target file name is the source file name
       
   640         lex.SkipSpaceAndMark();
       
   641         lex.SkipCharacters();
       
   642         if (lex.TokenLength() > 0)
       
   643             {
       
   644             dataFile->iMimeType = lex.MarkedToken();
       
   645 
       
   646             // Get the target file name. If not present, the target file name
       
   647             // will be the original file name, stored in the install directory.
       
   648             lex.SkipSpaceAndMark();
       
   649             lex.SkipCharacters();
       
   650             if (lex.TokenLength() > 0)
       
   651                 {
       
   652                 CnvUtfConverter::ConvertToUnicodeFromUtf8(
       
   653                     dataFile->iTargetName, lex.MarkedToken());
       
   654                 }
       
   655             else
       
   656                 {
       
   657                 dataFile->iTargetName = dataFile->iSourceName;
       
   658                 }
       
   659             }
       
   660         else
       
   661             {
       
   662             dataFile->iMimeType = KDefaultMIMEType;
       
   663             dataFile->iTargetName = dataFile->iSourceName;
       
   664             }
       
   665 
       
   666         iDataFiles.Append(dataFile);
       
   667         }
       
   668     else
       
   669         {
       
   670         r = KErrEof;
       
   671         }
       
   672     return r;
       
   673     }
       
   674 
       
   675 // -----------------------------------------------------------------------------
       
   676 // CDRMLicenseManager::ReadLine
       
   677 // Read one line ending with 0x0d or until the input buffer is full.
       
   678 // -----------------------------------------------------------------------------
       
   679 //
       
   680 void CDRMLicenseManager::ReadLine(
       
   681     RZipFileMemberReaderStream* aStream,
       
   682     TDes8& aLine)
       
   683     {
       
   684     TBuf8<1> c;
       
   685     TInt n = 0;
       
   686     TBool done = EFalse;
       
   687 
       
   688     while (!done)
       
   689         {
       
   690         if (aLine.Length() < aLine.MaxLength())
       
   691             {
       
   692             aStream->Read(c, 1);
       
   693             if (c.Length() > 0 && c[0] != 0x0d)
       
   694                 {
       
   695                 aLine.Append(c);
       
   696                 n++;
       
   697                 if (n == aLine.MaxLength() + 1)
       
   698                     {
       
   699                     done = ETrue;
       
   700                     }
       
   701                 }
       
   702             else
       
   703                 {
       
   704                 done = ETrue;
       
   705                 }
       
   706             }
       
   707         else
       
   708             {
       
   709             done = ETrue;
       
   710             }
       
   711         }
       
   712 
       
   713     if (c.Length() > 0 && c[0] == 0x0d)
       
   714         {
       
   715         aStream->Read(c, 1);
       
   716         }
       
   717     }
       
   718 
       
   719 // -----------------------------------------------------------------------------
       
   720 // CDRMLicenseManager::ProcessDataFilesL
       
   721 // Get all data files from the ZIP file and encrypt them.
       
   722 // -----------------------------------------------------------------------------
       
   723 //
       
   724 TInt CDRMLicenseManager::ProcessDataFilesL(
       
   725     const TDesC& aDestination)
       
   726     {
       
   727     TDRMDataFile* dataFile( NULL );
       
   728     CZipFileMember* member( NULL );
       
   729     TInt r( KErrNone );
       
   730 
       
   731     // check if there is enough free space for the process
       
   732     CheckNeededFreeSpaceL( *iFs, iZipFile, iDataFiles, aDestination, r );
       
   733 
       
   734     for ( TInt i = 0; i < iDataFiles.Count() && r == KErrNone; i++ )
       
   735         {
       
   736         dataFile = static_cast< TDRMDataFile* >( iDataFiles[ i ] );
       
   737         member = iZipFile->CaseInsensitiveMemberL( dataFile->iSourceName );
       
   738         if ( member )
       
   739             {
       
   740             CleanupStack::PushL(member);
       
   741             EncryptDataFileL(dataFile, aDestination, member);
       
   742             CleanupStack::PopAndDestroy(member);
       
   743             }
       
   744         else
       
   745             {
       
   746             r = EPIPInvalid;
       
   747             }
       
   748         }
       
   749 
       
   750     return r;
       
   751     }
       
   752 
       
   753 // -----------------------------------------------------------------------------
       
   754 // CDRMLicenseManager::EncryptDataFileL
       
   755 // Encrypt a single data file, reusing the outer PIP's RO. For application
       
   756 // protection, the file is encrypted again.
       
   757 // -----------------------------------------------------------------------------
       
   758 //
       
   759 void CDRMLicenseManager::EncryptDataFileL(
       
   760     TDRMDataFile* aDataFile,
       
   761     const TDesC& aDestination,
       
   762     CZipFileMember* aZipMember)
       
   763     {
       
   764     RZipFileMemberReaderStream* input = NULL;
       
   765     RFileWriteStream output;
       
   766     TBuf8<KSISBufferSize> buffer;
       
   767     COma1DcfCreator* drm = NULL;
       
   768     TFileName outputFile;
       
   769     DRMCommon* common = NULL;
       
   770 
       
   771     drm = COma1DcfCreator::NewL();
       
   772     CleanupStack::PushL(drm);
       
   773 
       
   774     iZipFile->GetInputStreamL(aZipMember, input);
       
   775     CleanupStack::PushL(input);
       
   776 
       
   777     // Set the path so we can use relative paths
       
   778     iFs->SetSessionPath(aDestination);
       
   779 
       
   780     output.PushL();
       
   781     // Create the output file stream
       
   782     User::LeaveIfError(output.Replace(*iFs, aDataFile->iTargetName,
       
   783         EFileWrite));
       
   784 
       
   785     // Encrypt
       
   786     drm->EncryptInitializeL(output, aDataFile->iMimeType, iRights);
       
   787     do
       
   788         {
       
   789         input->Read(buffer, KSISBufferSize);
       
   790         if (buffer.Size() > 0)
       
   791             {
       
   792             drm->EncryptUpdateL(buffer);
       
   793             }
       
   794         }
       
   795     while (buffer.Size() > 0);
       
   796     drm->EncryptFinalizeL();
       
   797     output.Close();
       
   798     CleanupStack::PopAndDestroy( &output );
       
   799 
       
   800     // Add the rights issuer uri to the file if it exists
       
   801     if( iRightsIssuer )
       
   802         {
       
   803         common = DRMCommon::NewL();
       
   804         CleanupStack::PushL(common);
       
   805         outputFile.Append( aDataFile->iTargetName );
       
   806         common->SetFileHeader( outputFile, KIssuer,
       
   807                                iRightsIssuer->Des());
       
   808         CleanupStack::PopAndDestroy(common);
       
   809         }
       
   810     CleanupStack::PopAndDestroy(input);
       
   811     CleanupStack::PopAndDestroy(drm);
       
   812     }
       
   813 
       
   814