applicationmanagement/server/src/AMDeploymentComponentData.cpp
changeset 0 3ce708148e4d
child 57 6757f1e2efd2
equal deleted inserted replaced
-1:000000000000 0:3ce708148e4d
       
     1 /*
       
     2  * Copyright (c) 2000 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 applicationmanagement components
       
    15  *
       
    16  */
       
    17 
       
    18 #include "amdeploymentcomponentdata.h"
       
    19 
       
    20 #include <bautils.h>
       
    21 #include <sisdataprovider.h>
       
    22 
       
    23 #include <DRMLicenseManager.h>
       
    24 #include "debug.h"
       
    25 #include <pathinfo.h>
       
    26 #include <zipfilemember.h>
       
    27 
       
    28 _LIT8( KSisxMimeType, "x-epoc/x-sisx-app" );
       
    29 _LIT( KTempDir, "piptemp\\" );
       
    30 _LIT8( KPipMimeType, "application/x-pip" );
       
    31 _LIT8( KDrmMessageMimeType, "application/vnd.oma.drm.message" );
       
    32 _LIT8( KDrmContentMimeType, "application/vnd.oma.drm.content" );
       
    33 _LIT8( KSisMimeType, "application/vnd.symbian.install");
       
    34 
       
    35 using namespace NApplicationManagement;
       
    36 
       
    37 /**
       
    38  *  Data class to Data access
       
    39  */
       
    40 CDeploymentComponentData::CDeploymentComponentData()
       
    41     {
       
    42     }
       
    43 
       
    44 CDeploymentComponentData::CDeploymentComponentData(TType aType,
       
    45         const TDesC8 &aDataFile) :
       
    46     iDataFileName(aDataFile), iType(aType)
       
    47     {
       
    48 
       
    49     }
       
    50 
       
    51 void CDeploymentComponentData::ConstructL(const TDesC8 &aData,
       
    52         const TDesC8 &aMime)
       
    53     {
       
    54     SetDataL(aData, aMime);
       
    55     }
       
    56 
       
    57 CDeploymentComponentData &CDeploymentComponentData::operator=(
       
    58         const CDeploymentComponentData &aData )
       
    59     {
       
    60     if( &aData != this )
       
    61         {
       
    62         SetDataL( aData.Data(), aData.MimeType() );
       
    63         iType = aData.iType;
       
    64         iDataFileName = aData.iDataFileName;
       
    65         }
       
    66     return *this;
       
    67     }
       
    68 
       
    69 void CDeploymentComponentData::ConstructLoadL(RReadStream &aStream)
       
    70     {
       
    71     TUint32 len(aStream.ReadUint32L() );
       
    72     aStream.ReadL(iDataFileName, len);
       
    73 
       
    74     len = aStream.ReadUint32L();
       
    75     aStream.ReadL(iMimeType, len);
       
    76     }
       
    77 
       
    78 CDeploymentComponentData* CDeploymentComponentData::NewL(TType aType,
       
    79         const TDesC8 &aData, const TDesC8 &aMime, const TDesC8 &aDataFile)
       
    80     {
       
    81     CDeploymentComponentData *self = CDeploymentComponentData::NewLC(aType,
       
    82             aData, aMime, aDataFile);
       
    83     CleanupStack::Pop();
       
    84     return self;
       
    85     }
       
    86 
       
    87 CDeploymentComponentData* CDeploymentComponentData::NewLC(TType aType,
       
    88         const TDesC8 &aData, const TDesC8 &aMime, const TDesC8 &aDataFile)
       
    89     {
       
    90     CDeploymentComponentData *self = new ( ELeave ) CDeploymentComponentData( aType, aDataFile);
       
    91     CleanupStack::PushL(self) ;
       
    92     self->ConstructL(aData, aMime);
       
    93     return self;
       
    94     }
       
    95 
       
    96 CDeploymentComponentData* CDeploymentComponentData::LoadL(
       
    97         RReadStream &aBuffer)
       
    98     {
       
    99     CDeploymentComponentData *self =
       
   100             CDeploymentComponentData::LoadLC(aBuffer);
       
   101     CleanupStack::Pop();
       
   102     return self;
       
   103     }
       
   104 
       
   105 CDeploymentComponentData* CDeploymentComponentData::LoadLC(
       
   106         RReadStream &aBuffer)
       
   107     {
       
   108     CDeploymentComponentData *self = new ( ELeave ) CDeploymentComponentData();
       
   109     CleanupStack::PushL(self) ;
       
   110     self->ConstructLoadL(aBuffer);
       
   111     return self;
       
   112     }
       
   113 
       
   114 CDeploymentComponentData::~CDeploymentComponentData()
       
   115     {
       
   116     RDEBUG8_3("CDeploymentComponentData::~CDeploymentComponentData 0x%X - 0x%X", reinterpret_cast<TUint>(this),
       
   117             reinterpret_cast<TUint>(this)+sizeof( CDeploymentComponentData ) );
       
   118 
       
   119     delete iData;
       
   120     iData = NULL;
       
   121     }
       
   122 
       
   123 TInt CDeploymentComponentData::DataLengthL() const
       
   124     {
       
   125     TInt ret( 0);
       
   126     if (iData == NULL)
       
   127         {
       
   128         if (iDataFileName.Length() > 0)
       
   129             {
       
   130             RFs fs;
       
   131             User::LeaveIfError(fs.Connect() );
       
   132             CleanupClosePushL(fs); // 1
       
   133             TEntry entry;
       
   134             TFileName fileName;
       
   135             fileName.Copy(iDataFileName);
       
   136             User::LeaveIfError(fs.Entry(fileName, entry) );
       
   137             ret = entry.iSize;
       
   138             CleanupStack::PopAndDestroy( &fs);
       
   139             }
       
   140         }
       
   141     else
       
   142         {
       
   143         ret = iData->Length();
       
   144         }
       
   145     return ret;
       
   146     }
       
   147 
       
   148 const TDesC8 &CDeploymentComponentData::Data() const
       
   149     {
       
   150     if (iData == NULL)
       
   151         {
       
   152         TRAPD( err, LoadDataL() )
       
   153         ;
       
   154         if (err != KErrNone)
       
   155             {
       
   156             return KNullDesC8();
       
   157             }
       
   158         }
       
   159     if (iData != NULL)
       
   160         {
       
   161         return *iData;
       
   162         }
       
   163     else
       
   164         {
       
   165         return KNullDesC8();
       
   166         }
       
   167     }
       
   168 
       
   169 void CDeploymentComponentData::LoadDataL() const
       
   170     {
       
   171 
       
   172     if (iDataFileName.Length() > 0)
       
   173         {
       
   174         RFs fs;
       
   175         User::LeaveIfError(fs.Connect() );
       
   176         CleanupClosePushL(fs); // 1
       
   177         RFile file;
       
   178         TFileName fileName;
       
   179         fileName.Copy(iDataFileName);
       
   180         TInt err(file.Open(fs, fileName, EFileRead) );
       
   181         if (err == KErrNone)
       
   182             {
       
   183             CleanupClosePushL(file); // 2
       
   184             TInt fsize;
       
   185             User::LeaveIfError(file.Size(fsize) );
       
   186             iData = HBufC8::NewL(fsize);
       
   187             TPtr8 ptr(iData->Des() );
       
   188             User::LeaveIfError(file.Read(ptr) );
       
   189             CleanupStack::PopAndDestroy( &file);
       
   190             }
       
   191         else
       
   192             {
       
   193             RDEBUG_3( "ERROR Leaving CDeploymentComponentData::Data - SEVERE Could not open data file '%S': %d!",
       
   194                     &fileName, err );
       
   195             User::Leave(KErrNotFound) ;
       
   196             }
       
   197         CleanupStack::PopAndDestroy( &fs);
       
   198         }
       
   199     else
       
   200         {
       
   201         RDEBUG( "ERROR Leaving CDeploymentComponentData::LoadDataL() - No file to load!" );
       
   202         User::Leave(KErrNotFound) ;
       
   203         }
       
   204     }
       
   205 
       
   206 TUid CDeploymentComponentData::SetDataL(const TDesC8& aMimeType)
       
   207     {
       
   208     RDEBUG8_2("CDeploymentComponentData::SetDataL() aMimeType: (%S)", &aMimeType);
       
   209 
       
   210     TUid ret(TUid::Null());
       
   211     iMimeType = aMimeType.Left(KMaxMimeLength);
       
   212 
       
   213     if (IsSISInstallFile(aMimeType) )
       
   214         {
       
   215         RFs fs;
       
   216         User::LeaveIfError(fs.Connect() );
       
   217         CleanupClosePushL(fs);
       
   218         ret = ResolveUidL(fs);
       
   219         CleanupStack::PopAndDestroy( &fs);
       
   220         }
       
   221     RDEBUG8_2("CDeploymentComponentData::SetDataL() UID: (0x%x)", ret.iUid);
       
   222     return ret;
       
   223     }
       
   224 
       
   225 TUid CDeploymentComponentData::SetDataL(const TFileName &aData,
       
   226         const TDesC8& aMimeType)
       
   227     {
       
   228     RDEBUG_2("CDeploymentComponentData::SetDataL() TFileName: (%S)", &aData);
       
   229 
       
   230     TUid ret(TUid::Null());
       
   231     iMimeType = aMimeType.Left(KMaxMimeLength) ;
       
   232     RFs fs;
       
   233     User::LeaveIfError(fs.Connect() );
       
   234     CleanupClosePushL(fs);
       
   235     CFileMan *fm = CFileMan::NewL(fs);
       
   236     CleanupStack::PushL(fm);
       
   237     TFileName fn;
       
   238     fn.Copy(iDataFileName);
       
   239     User::LeaveIfError(fm->Copy(aData, fn) );
       
   240 
       
   241     if (IsSISInstallFile(aMimeType) )
       
   242         {
       
   243         ret = ResolveUidL(fs);
       
   244         }
       
   245 
       
   246     CleanupStack::PopAndDestroy(fm);
       
   247     CleanupStack::PopAndDestroy( &fs);
       
   248     RDEBUG_2("CDeploymentComponentData::SetDataL() (%d)", ret.iUid);
       
   249 
       
   250     return ret;
       
   251     }
       
   252 
       
   253 TUid CDeploymentComponentData::SetDataL(const TDesC8 &aData,
       
   254         const TDesC8 &aMimeType)
       
   255     {
       
   256     TUid ret(TUid::Null());
       
   257     if (iData)
       
   258         {
       
   259         delete iData;
       
   260         iData = NULL;
       
   261         }
       
   262     iData = aData.AllocL();
       
   263     ret = SetDataL(aMimeType);
       
   264     return ret;
       
   265     }
       
   266 
       
   267 TBool CDeploymentComponentData::IsSISInstallFile(const TDesC8 &aMimeType)
       
   268     {
       
   269     TBool isSIS(EFalse);
       
   270 
       
   271     if (aMimeType == KSisxMimeType || aMimeType == KPipMimeType || aMimeType
       
   272             == KDrmMessageMimeType || aMimeType == KDrmContentMimeType || aMimeType == KSisMimeType)
       
   273         {
       
   274         isSIS = ETrue;
       
   275         }
       
   276 
       
   277     return isSIS;
       
   278     }
       
   279 
       
   280 TUid CDeploymentComponentData::ResolveUidL(RFs& aFs)
       
   281     {
       
   282     RDEBUG("CDeploymentComponentData::ResolveUidL()");
       
   283 
       
   284     TUid ret(TUid::Null() );
       
   285     HBufC* buf = HBufC::NewLC(KMaxFileName);
       
   286     TPtr16 ptr = buf->Des();
       
   287     ptr.Copy(iDataFileName);
       
   288 
       
   289     // if PIP/DRM package, we need to use license manager to extract the sis file
       
   290     if (iMimeType == KPipMimeType || iMimeType == KDrmMessageMimeType
       
   291             || iMimeType == KDrmContentMimeType)
       
   292         {
       
   293         RDEBUG8_2("	-> mime: %S", &iMimeType );
       
   294 
       
   295         RFile originalFile;
       
   296         RFile decryptedFile;
       
   297         TFileName decryptedTempFileName;
       
   298 
       
   299         RDEBUG_2("	-> opening original file: %S", &ptr );
       
   300         // leave if can not open the original file
       
   301         User::LeaveIfError(originalFile.Open(aFs, ptr, EFileWrite) );
       
   302         RDEBUG("	-> done");
       
   303 
       
   304         // First construct the temp path
       
   305         User::LeaveIfError(aFs.PrivatePath(decryptedTempFileName) );
       
   306         // set drive letter into the path
       
   307         decryptedTempFileName.Insert( 0, TParsePtrC( PathInfo::PhoneMemoryRootPath() ).Drive() );
       
   308         // append "piptemp\\"	
       
   309         decryptedTempFileName.Append(KTempDir);
       
   310         // create the folder
       
   311         aFs.MkDir(decryptedTempFileName);
       
   312 
       
   313         // Use license manager to extract files from the pip package
       
   314         CDRMLicenseManager* licenseMgr = CDRMLicenseManager::NewL();
       
   315         CleanupStack::PushL(licenseMgr);
       
   316         // decryp from the original file into the temp file   
       
   317         RDEBUG_2("	-> extracting SIS file into: %S", &decryptedTempFileName);
       
   318         User::LeaveIfError(licenseMgr->ExtractSISFileL(originalFile,
       
   319                 decryptedTempFileName) );
       
   320         RDEBUG("	-> done");
       
   321 
       
   322         // Get the sis file name 
       
   323         decryptedTempFileName.Append( *(licenseMgr->GetSISMemberL()->Name() ));
       
   324         // open temporary handle to it.
       
   325         RDEBUG_2("	-> opening decrypted file: %S", &decryptedTempFileName );
       
   326         User::LeaveIfError(decryptedFile.Open(aFs, decryptedTempFileName,
       
   327                 EFileShareAny) );
       
   328         RDEBUG("	-> done");
       
   329         // parse the uid from the file
       
   330         ret = ParseUidFromSisFileL(decryptedFile);
       
   331 
       
   332         // no use anymore for the decrypted file
       
   333         decryptedFile.Close();
       
   334         // delete the temp file
       
   335         TInt err = aFs.Delete(decryptedTempFileName);
       
   336         if (err != KErrNone)
       
   337             {
       
   338             RDEBUG_2("**** ERROR, unable to delete temporary file: %S", &decryptedTempFileName );
       
   339             }
       
   340 
       
   341         CleanupStack::PopAndDestroy(licenseMgr);
       
   342         decryptedFile.Close();
       
   343         originalFile.Close();
       
   344         }
       
   345     else
       
   346         if (iMimeType == KSisxMimeType || iMimeType == KSisMimeType )
       
   347             {
       
   348             RDEBUG("	-> mime: x-epoc/x-sisx-app");
       
   349             RFile originalFile;
       
   350             RDEBUG_2("	-> opening file: %S", &ptr );
       
   351             User::LeaveIfError(originalFile.Open(aFs, ptr, EFileRead) );
       
   352             RDEBUG("	-> opened ok");
       
   353             ret = ParseUidFromSisFileL(originalFile);
       
   354             originalFile.Close();
       
   355             }
       
   356 
       
   357         else
       
   358             {
       
   359             RDEBUG8_2( "**** ERROR - CDeploymentComponentData::ResolveUidL( ) - cannot get uid from mime type: %S", &iMimeType );
       
   360             }
       
   361 
       
   362     CleanupStack::PopAndDestroy(buf);
       
   363     return ret;
       
   364     }
       
   365 
       
   366 void CDeploymentComponentData::SerializedFormL(RWriteStream &aBuffer) const
       
   367     {
       
   368     aBuffer.WriteUint32L(iDataFileName.Length() );
       
   369     aBuffer.WriteL(iDataFileName);
       
   370 
       
   371     aBuffer.WriteUint32L(iMimeType.Length() );
       
   372     aBuffer.WriteL(iMimeType);
       
   373 
       
   374     }
       
   375 
       
   376 void CDeploymentComponentData::DestroyL(RFs &aFs) const
       
   377     {
       
   378     TFileName fn;
       
   379     fn.Copy(iDataFileName);
       
   380     aFs.Delete(fn) ;
       
   381     }
       
   382 
       
   383 const TDesC8 &CDeploymentComponentData::DataFileName() const
       
   384     {
       
   385     return iDataFileName;
       
   386     }
       
   387 
       
   388 void CDeploymentComponentData::PersistL(RFs &aFs)
       
   389     {
       
   390     if (iData)
       
   391         {
       
   392         RFile file;
       
   393         TFileName aFile;
       
   394         aFile.Copy(iDataFileName) ;
       
   395         RDEBUG_3( "CDeploymentComponentData::PersistL() - Saving '%S', dataLenght %d", &aFile, (iData ? iData->Length() : 0) );
       
   396         User::LeaveIfError(file.Replace(aFs, aFile, EFileWrite) );
       
   397         CleanupClosePushL(file) ;
       
   398 
       
   399         file.Write( *iData) ;
       
   400         file.Flush();
       
   401         delete iData;
       
   402         iData = NULL;
       
   403         CleanupStack::PopAndDestroy( &file) ; // file
       
   404         }
       
   405     else
       
   406         {
       
   407         RDEBUG( "CDeploymentComponentData::PersistL() - Already persisted" );
       
   408         }
       
   409     RDEBUG( "CDeploymentComponentData::PersistL() - Done" );
       
   410     }
       
   411 
       
   412 TInt CDeploymentComponentData::SerializedFormLength() const
       
   413     {
       
   414     return iDataFileName.Length() + (2 * 4) + iMimeType.Length();
       
   415     }
       
   416 
       
   417 void CDeploymentComponentData::SetDataFileNameL(const TDesC8 &aNewFileName)
       
   418     {
       
   419     if (aNewFileName.Length() > 0)
       
   420         {
       
   421         RFs fs;
       
   422         User::LeaveIfError(fs.Connect() );
       
   423         CleanupClosePushL(fs);
       
   424         TFileName newfile;
       
   425         newfile.Copy(aNewFileName);
       
   426         TFileName oldfile;
       
   427         oldfile.Copy(iDataFileName);
       
   428         User::LeaveIfError(BaflUtils::RenameFile(fs, oldfile, newfile) );
       
   429         CleanupStack::PopAndDestroy( &fs);
       
   430         iDataFileName = aNewFileName;
       
   431         }
       
   432     else
       
   433         {
       
   434         RDEBUG( "CDeploymentComponentData::SetDataFileNameL - ERROR Cannot set empty filename!" );
       
   435         User::Leave(KErrArgument);
       
   436         }
       
   437     }
       
   438 void CDeploymentComponentData::SetMimeTypeL(const TDesC8 &aMimeType)
       
   439 {
       
   440 	iMimeType = aMimeType.Left(KMaxMimeLength) ;
       
   441 }
       
   442 void CDeploymentComponentData::ResetData(RFs &aFs)
       
   443     {
       
   444     TRAP_IGNORE(DestroyL( aFs ));
       
   445     iDataFileName = KNullDesC8();
       
   446     delete iData;
       
   447     iData = NULL;
       
   448     }
       
   449 
       
   450 TUid CDeploymentComponentData::ParseUidFromSisFileL(RFile& aHandleToFile)
       
   451     {
       
   452     RDEBUG("CDeploymentComponentData::ParseUidFromSisFileL");
       
   453 
       
   454     TUid appUid;
       
   455     TInt uidLen = sizeof(TInt32);
       
   456     TInt seekLen = sizeof(TInt32) + sizeof(TInt32);
       
   457     User::LeaveIfError(aHandleToFile.Seek(ESeekStart, seekLen));
       
   458     TPckg<TInt32> uid1(appUid.iUid);
       
   459     User::LeaveIfError(aHandleToFile.Read(uid1, uidLen));
       
   460 
       
   461     if (uid1.Length() != uidLen)
       
   462         {
       
   463         RDEBUG("**** ERROR - uid length inconsistency - underflow");
       
   464         User::Leave(KErrUnderflow);
       
   465         }
       
   466 
       
   467     RDEBUG_2("	-> returning SIS UID: %d", appUid.iUid );
       
   468     return appUid;
       
   469     }
       
   470 
       
   471 //  End of File