installationservices/swi/source/sisregistry/server_legacy/sisregistryserversession.cpp
branchRCL_3
changeset 26 8b7f4e561641
parent 25 7333d7932ef7
child 27 e8965914fac7
--- 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);
+    }