diff -r 7333d7932ef7 -r 8b7f4e561641 installationservices/swi/source/sisregistry/server_legacy/sisregistryserversession.cpp --- a/installationservices/swi/source/sisregistry/server_legacy/sisregistryserversession.cpp Tue Aug 31 15:21:33 2010 +0300 +++ b/installationservices/swi/source/sisregistry/server_legacy/sisregistryserversession.cpp Wed Sep 01 12:22:02 2010 +0100 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * This component and the accompanying materials are made available * under the terms of the License "Eclipse Public License v1.0" @@ -50,7 +50,6 @@ #include "sisrevocationmanager.h" #include "siscontroller.h" #include "siscertificatechain.h" - #include "cleanuputils.h" #include "sisregistryutil.h" #include "sisinfo.h" @@ -64,7 +63,7 @@ #include "sisinstallblock.h" #include "sisregistryfiledescription.h" #include "sisregistrywritablesession.h" - +#include "securitycheckutil.h" using namespace Swi; @@ -627,54 +626,60 @@ TPckg pkgTransactionID(transactionID); aMessage.ReadL(EIpcArgument3, pkgTransactionID); - // create a integrity service object - CIntegrityServices* integrityService = CIntegrityServices::NewLC(transactionID, KIntegrityServicesPath); - Server().Cache().RemoveRegistryEntryL(*object, *integrityService); - - //If removal is for ROM upgrade type, - //After removing the existing registry entry set, - //re generate the Registry Entry Cache. - //If any of the ROM based stub doesn't have it's registry set - //in appropriate path, it will create them (.reg & . ctl) - //from the ROM based stub sis file. - if ((object->InstallType() == Sis::EInstInstallation || - object->InstallType() == Sis::EInstPartialUpgrade) && - SisRegistryUtil::RomBasedPackageL(object->Uid())) - { - Server().Cache().RegenerateCacheL(); - } - - HBufC* logName = SisRegistryUtil::BuildLogFileNameLC(); - - TDriveUnit sysDrive(RFs::GetSystemDrive()); - TBuf<128> logDir = sysDrive.Name(); - logDir.Append(KLogDir); + DeleteEntryL(*object, transactionID); - if( SisRegistryUtil::FileExistsL(iFs,*logName)) - { - TInt sizeOfFile = 0; - RFile file; - User::LeaveIfError(file.Open(iFs,logDir,EFileRead)); - CleanupClosePushL(file); - User::LeaveIfError(file.Size(sizeOfFile)); - RBuf8 text; - text.CreateL(sizeOfFile); - text.CleanupClosePushL(); - file.Read(text,sizeOfFile); - file.Close(); - integrityService->RemoveL(*logName); - User::LeaveIfError(file.Create(iFs,logDir,EFileWrite| EFileShareExclusive |EFileStream)); - User::LeaveIfError(file.Write(text,sizeOfFile)); - CleanupStack::PopAndDestroy(2,&file); - } - integrityService->AddL(*logName); - Server().Cache().AddLogEntryL(*object,ESwiLogUnInstall); - - CleanupStack::PopAndDestroy(3, object);// object, integrityService , logName - + CleanupStack::PopAndDestroy(object); aMessage.Complete(KErrNone); } +void CSisRegistrySession::DeleteEntryL(const CSisRegistryObject& aObject, TInt64 aTransactionId, TBool aRegenerateCache/*=ETrue*/) + { + // Create a integrity service object + CIntegrityServices* integrityService = CIntegrityServices::NewLC(aTransactionId, KIntegrityServicesPath); + Server().Cache().RemoveRegistryEntryL(aObject, *integrityService); + + //If removal is for ROM upgrade type, + //After removing the existing registry entry set, + //re generate the Registry Entry Cache. + //If any of the ROM based stub doesn't have it's registry set + //in appropriate path, it will create them (.reg & . ctl) + //from the ROM based stub sis file. + if ((aObject.InstallType() == Sis::EInstInstallation || + aObject.InstallType() == Sis::EInstPartialUpgrade) && + SisRegistryUtil::RomBasedPackageL(aObject.Uid()) && + aRegenerateCache) + { + Server().Cache().RegenerateCacheL(); + } + + HBufC* logName = SisRegistryUtil::BuildLogFileNameLC(); + + TDriveUnit sysDrive(RFs::GetSystemDrive()); + TBuf<128> logDir = sysDrive.Name(); + logDir.Append(KLogDir); + + if( SisRegistryUtil::FileExistsL(iFs,*logName)) + { + TInt sizeOfFile = 0; + RFile file; + User::LeaveIfError(file.Open(iFs,logDir,EFileRead)); + CleanupClosePushL(file); + User::LeaveIfError(file.Size(sizeOfFile)); + RBuf8 text; + text.CreateL(sizeOfFile); + text.CleanupClosePushL(); + file.Read(text,sizeOfFile); + file.Close(); + integrityService->RemoveL(*logName); + User::LeaveIfError(file.Create(iFs,logDir,EFileWrite| EFileShareExclusive |EFileStream)); + User::LeaveIfError(file.Write(text,sizeOfFile)); + CleanupStack::PopAndDestroy(2,&file); + } + integrityService->AddL(*logName); + Server().Cache().AddLogEntryL(aObject,ESwiLogUnInstall); + + CleanupStack::PopAndDestroy(2, integrityService);// logName,integrityService + } void CSisRegistrySession::OpenRegistryUidEntryL(const RMessage2& aMessage) { // expects a UID as an arg 0 @@ -1693,14 +1698,87 @@ void CSisRegistrySession::AddDriveL(const RMessage2& aMessage) { - TInt drive; - TPckg pkgDrive(drive); + TInt addedDrive; + TPckg pkgDrive(addedDrive); aMessage.ReadL(EIpcArgument0, pkgDrive); - DEBUG_PRINTF2(_L8("Sis Registry Server - Removable drive %d added."), drive); - + DEBUG_PRINTF2(_L8("Sis Registry Server - Removable drive %d added."), addedDrive); + + // Get the drive character. + TChar drive; + User::LeaveIfError(iFs.DriveToChar(addedDrive, drive)); + TUint driveChar(drive); + + // Retrieve drive info. + TDriveInfo driveInfo; + User::LeaveIfError(iFs.Drive(driveInfo, addedDrive)); + +#ifndef __WINSCW__ + if(driveInfo.iDriveAtt & KDriveAttLogicallyRemovable) + { +#endif + /* + In case a logically removable drive is added, + Look for the presence of the first boot marker file corresponding to it in the sisregistry private + folder in C drive. If absent, assume first boot and create the marker file. + Also added a marker file in the \sys\install directory which would be used to detect a format. + + Subsequent boots would look for the drive format marker to check if a format has occured and delete + the registry entries. + */ + + // Create first boot marker path. + _LIT(KFirstBootMarkerFilePath, "%c:%SfirstBootMarkerFileFor%c"); + + RBuf privatePath; + privatePath.CreateL(KMaxPath); + CleanupClosePushL(privatePath); + + User::LeaveIfError(iFs.PrivatePath(privatePath)); + + RBuf firstBootMarkerFilePath; + firstBootMarkerFilePath.CreateL(KMaxPath); + CleanupClosePushL(firstBootMarkerFilePath); + + TChar systemDrive = RFs::GetSystemDriveChar(); + firstBootMarkerFilePath.Format(KFirstBootMarkerFilePath, static_cast(systemDrive), &privatePath, driveChar); + + // Create drive format marker path. + _LIT(KFormatMarkerPath, "%c:\\sys\\install\\formatMarkerFile"); + + RBuf formatMarkerPath; + formatMarkerPath.CreateL(KMaxPath); + CleanupClosePushL(formatMarkerPath); + formatMarkerPath.Format(KFormatMarkerPath, driveChar); + + // The drive marker files are marked hidden and read-only. + TUint fileAttributes = KEntryAttReadOnly | KEntryAttHidden; + + if(!SisRegistryUtil::FileExistsL(iFs, firstBootMarkerFilePath)) + { + // First boot detected. Add the first boot marker file as well as the format marker on the drive. + SisRegistryUtil::CreateFileWithAttributesL(iFs, firstBootMarkerFilePath); + SisRegistryUtil::CreateFileWithAttributesL(iFs, formatMarkerPath, fileAttributes); + } + else + { + // Subsequent boot. Check for the presence of a marker file \sys\install directory. + // If absent, assume format. + if(!SisRegistryUtil::FileExistsL(iFs, formatMarkerPath)) + { + DriveFormatDetectedL(TDriveUnit(addedDrive)); + //Add missing format marker file + SisRegistryUtil::CreateFileWithAttributesL(iFs, formatMarkerPath, fileAttributes); + } + } + + CleanupStack::PopAndDestroy(3, &privatePath); +#ifndef __WINSCW__ + } +#endif + // update the drives state - Server().Cache().AddDriveAndRefreshL(drive); + Server().Cache().AddDriveAndRefreshL(addedDrive); aMessage.Complete(KErrNone); } @@ -1778,6 +1856,7 @@ { // Destroys object so we continue to next iteration. CleanupStack::PopAndDestroy(sidObject); + sidObject = NULL; } } // End for loop. @@ -2255,3 +2334,103 @@ CleanupStack::PopAndDestroy(&files); } + +void CSisRegistrySession::DriveFormatDetectedL(TDriveUnit aDrive) + { + DEBUG_PRINTF2(_L("Sis Registry Server - Drive format detected for drive %d"), static_cast(aDrive)); + + //Get the list of tokens. + const RPointerArray & tokensArray = Server().Cache().TokenList(); + + TTime currentTime; + currentTime.UniversalTime(); + TInt64 transactionId = currentTime.Int64(); + + TBool regenerateCache = EFalse; + + TInt i(0); + + while(i < tokensArray.Count()) + { + TUint installedDrives = tokensArray[i]->Drives(); + + // Look for the formatted drive in the list of installed drives. + if(installedDrives & (1 << aDrive)) + { + CSisRegistryObject* object = Server().Cache().ObjectL(*tokensArray[i]); + CleanupStack::PushL(object); + + if (!regenerateCache && + (object->InstallType() == Sis::EInstInstallation || object->InstallType() == Sis::EInstPartialUpgrade) && + SisRegistryUtil::RomBasedPackageL(object->Uid())) + { + regenerateCache = ETrue; + } + + // Retrieve all the associated files. + const RPointerArray& fileDescriptions = object->FileDescriptions(); + + _LIT(KHashPathFormat, "%c:\\sys\\hash\\%S"); + + for(TInt j=0; jTarget(); + DEBUG_PRINTF2(_L("File - %S "), &targetPath); + + // Get the drive on which the file is present. + TInt drive; + User::LeaveIfError(RFs::CharToDrive(targetPath[0], drive)); + + // If the file is a binary ( present in \sys\bin), delete the corresponding hash present in + // C:\sys\hash + + if(KErrNotFound != targetPath.FindF(KBinPath)) + { + // Retrieve the filename from the target path. + TParsePtrC parser(targetPath); + HBufC* fileName = parser.NameAndExt().AllocLC(); + + TChar systemDrive = RFs::GetSystemDriveChar(); + + // Create the hash file path. + RBuf hashFilePath; + hashFilePath.CreateL(KMaxPath); + CleanupClosePushL(hashFilePath); + hashFilePath.Format(KHashPathFormat, static_cast(systemDrive), fileName); + + // Delete hash file. + SisRegistryUtil::DeleteFile(iFs, hashFilePath); //Ignore return code. + + CleanupStack::PopAndDestroy(2, fileName); + + } + + if(aDrive == TDriveUnit(drive)) + { + // File should not exist on disk as the drive is assumed to have been formatted. + continue; + } + SisRegistryUtil::DeleteFile(iFs, targetPath); //Ignore return code. + } + + // Delete registry entry. + DeleteEntryL(*object, transactionId, EFalse); + CleanupStack::PopAndDestroy(object); + } + else + { + // Increment only in case an entry is not found. + i++; + } + } + + if(regenerateCache) + { + Server().Cache().RegenerateCacheL(); + } + + // Commit the changes. + CIntegrityServices* intServ = CIntegrityServices::NewLC(transactionId, KIntegrityServicesPath); + intServ->CommitL(); + CleanupStack::PopAndDestroy(intServ); + }