--- 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<TInt64> 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<TInt> pkgDrive(drive);
+ TInt addedDrive;
+ TPckg<TInt> 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 <drive>\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<TUint>(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 <drive>\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<TInt>(aDrive));
+
+ //Get the list of tokens.
+ const RPointerArray <CSisRegistryToken>& 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<CSisRegistryFileDescription>& fileDescriptions = object->FileDescriptions();
+
+ _LIT(KHashPathFormat, "%c:\\sys\\hash\\%S");
+
+ for(TInt j=0; j<fileDescriptions.Count(); ++j)
+ {
+ const TDesC& targetPath = fileDescriptions[j]->Target();
+ 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<TUint>(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);
+ }