installationservices/swi/source/sisregistry/client/sisregistrysession.cpp
changeset 0 ba25891c3a9e
child 17 741e5bba2bd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swi/source/sisregistry/client/sisregistrysession.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,459 @@
+/*
+* Copyright (c) 2004-2009 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"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+* sisregistry - exported client registry session interface implementation
+*
+*/
+
+
+/**
+ @file 
+ @publishedPartner
+ @released
+*/
+
+#include "log.h"
+ 
+#include<s32mem.h>
+#include <hash.h>
+#include "sisregistryclientserver.h"
+#include "sisregistryfiledescription.h"
+#include "sisregistrysession.h"
+#include "sisregistrypackage.h"
+#include "arrayutils.h"
+#include "hashcontainer.h"
+#include "dessisdataprovider.h"
+#include "siscontroller.h"
+
+
+using namespace Swi;
+
+TInt StartSisRegistry()
+	{
+	const TUidType serverUid(KNullUid, KNullUid, KServerUid3);
+	RProcess server;
+	TInt err = server.Create(KSisRegistryImg, KNullDesC, serverUid);
+	if (err != KErrNone)
+		{
+		return err;
+		}
+	TRequestStatus stat;
+	server.Rendezvous(stat);
+	if (stat != KRequestPending)
+		{
+		server.Kill(0);		// abort startup
+		}
+	else
+		{
+		server.Resume();	// logon OK - start the server
+		}
+	User::WaitForRequest(stat);		// wait for start or death
+	// we can't use the 'exit reason' if the server panicked as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone
+	err = (server.ExitType() == EExitPanic) ? KErrGeneral : stat.Int();
+	server.Close();
+	return err;
+	}
+
+EXPORT_C TInt RSisRegistrySession::Connect()
+//
+// Connect to the server, attempting to start it if necessary
+//
+	{
+	TInt retry = 2;
+	for (;;) // loop forever, exit relies on internal count and unexpected errors happening
+		{
+		TInt err = CreateSession(KSisRegistryName, TVersion(1, 0, 0), 2);
+		if (err != KErrNotFound && err != KErrServerTerminated)
+			{
+			return err;
+			}
+		if (--retry==0)
+			{
+			return err;
+			}
+		err = StartSisRegistry();
+		if (err != KErrNone && err != KErrAlreadyExists)
+			{
+			return err;
+			}
+		}
+	}
+
+EXPORT_C void RSisRegistrySession::InstalledUidsL(RArray<TUid>& aUids)
+	{
+	HBufC8* buffer = SendReceiveBufferLC(EInstalledUids);
+	
+	// create a stream based on the buffer
+	RDesReadStream stream(*buffer);
+	CleanupClosePushL(stream);
+	// reassemble the array from the stream
+	InternalizeArrayL(aUids, stream);
+
+	CleanupStack::PopAndDestroy(2, buffer);
+	}
+
+EXPORT_C void RSisRegistrySession::InstalledPackagesL(RPointerArray<CSisRegistryPackage>& aPackages)
+	{
+	HBufC8* buffer = SendReceiveBufferLC(EInstalledPackages);
+
+	// create a stream based on the buffer
+	RDesReadStream stream(*buffer);
+	CleanupClosePushL(stream);
+	// reassemble the array from the stream
+	InternalizePointerArrayL(aPackages, stream);
+ 
+ 	CleanupStack::PopAndDestroy(2, buffer);
+	}
+ 
+EXPORT_C TBool RSisRegistrySession::IsInstalledL(TUid aUid)
+	{
+	TPckgC<TUid> uid(aUid);
+	TBool installed = EFalse;
+	TPckg<TBool> isInstalled(installed);
+	User::LeaveIfError(SendReceive(EUidInstalled, TIpcArgs(&uid, &isInstalled)));
+	return installed;
+	}
+
+EXPORT_C TBool RSisRegistrySession::IsInstalledL(TDesC8& aController)
+	{
+	TBool installed = EFalse;
+	TPckg<TBool> isInstalled(installed);
+	CDesDataProvider* desProvider = CDesDataProvider::NewLC(aController);
+	Sis::CController* controller = Sis::CController::NewLC(*desProvider, Sis::EAssumeType);
+  
+ 	CMessageDigest* msgDigest = controller->GenerateControllerHashLC(aController);
+ 	
+	TPtrC8 hash = msgDigest->Final();
+	CHashContainer* controllerHash = CHashContainer::NewLC(CMessageDigest::ESHA1, hash);
+	
+	CBufFlat* tempBuffer = CBufFlat::NewL(KDefaultBufferSize);
+	CleanupStack::PushL(tempBuffer);
+	
+	RBufWriteStream stream(*tempBuffer);
+	CleanupClosePushL(stream);
+	controllerHash->ExternalizeL(stream);
+	CleanupStack::PopAndDestroy(&stream);
+	
+	// Now, create an HBufC8 from the stream buf's length, and copy 
+	// the stream buffer into this descriptor
+	HBufC8* buffer = HBufC8::NewLC(tempBuffer->Size());
+	TPtr8 ptr(buffer->Des());
+	tempBuffer->Read(0, ptr, tempBuffer->Size());
+	
+	User::LeaveIfError(SendReceive(EControllerInstalled, TIpcArgs(&ptr, &isInstalled)));
+
+	CleanupStack::PopAndDestroy(6, desProvider);
+	return installed;
+	}
+
+EXPORT_C TBool RSisRegistrySession::ModifiableL(const TDesC& aFileName)
+	{
+	TBool modifiable = EFalse;
+	TPckg<TBool> isModifiable(modifiable);
+	
+	User::LeaveIfError(SendReceive(EModifiable, TIpcArgs(&aFileName, &isModifiable)));
+	return modifiable;
+	}
+
+EXPORT_C CHashContainer* RSisRegistrySession::HashL(const TDesC& aFileName)
+	{
+	HBufC8* buffer = SendReceiveBufferLC(EHash, aFileName);
+
+	RDesReadStream stream(*buffer);
+	CleanupClosePushL(stream);
+	
+	// reassemble the hash from the stream
+    CHashContainer* hash = CHashContainer::NewLC(stream);
+	CleanupStack::Pop(hash);
+	
+	CleanupStack::PopAndDestroy(2, buffer);
+		
+	return hash;
+	}
+
+EXPORT_C CSisRegistryPackage* RSisRegistrySession::SidToPackageL(TUid aSid)
+	{
+	TPckgC<TUid> sid(aSid);
+
+	HBufC8* buffer = SendReceiveBufferLC(ESidToPackage, static_cast<TPtrC8>(sid));
+	RDesReadStream stream(*buffer);
+	CleanupClosePushL(stream);
+	
+	// reassemble the array from the stream
+    CSisRegistryPackage* package = CSisRegistryPackage::NewLC(stream);
+	CleanupStack::Pop(package);
+	
+	CleanupStack::PopAndDestroy(2, buffer);
+	return package;
+	}
+
+EXPORT_C void RSisRegistrySession::SidToFileNameL(TUid aSid,TDes& aFileName)
+	{
+	TPckgC<TUid> sid(aSid);
+	
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK		
+
+	HBufC* buffer = HBufC::NewLC(KDefaultBufferSize);
+	TPtr ptr(buffer->Des());
+	
+	User::LeaveIfError(SendReceive(ESidToFileName, TIpcArgs(&sid, &ptr, -1)));
+	
+	// Get the filename
+	aFileName.Copy(*buffer);
+	CleanupStack::PopAndDestroy(buffer);
+#else
+    // -1 is used to indicate no drive check.
+	HBufC8* buffer = SendReceiveBufferLC(ESidToFileName, static_cast<TPtrC8>(sid), -1);
+	RDesReadStream stream(*buffer);
+	stream.PushL();
+
+	// Reassemble the CSisRegistryFileDescription from the stream
+	CSisRegistryFileDescription* fileDesc = CSisRegistryFileDescription::NewLC(stream);
+
+	aFileName.Copy(fileDesc->Target());
+
+	CleanupStack::PopAndDestroy(fileDesc);
+	CleanupStack::PopAndDestroy(&stream);	
+	CleanupStack::PopAndDestroy(buffer);	
+ #endif
+	}
+
+EXPORT_C void RSisRegistrySession::SidToFileNameL(TUid aSid,TDes& aFileName, TDriveUnit aDrive)
+	{
+	TPckgC<TUid> sid(aSid);
+	
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK		
+
+	HBufC* buffer = HBufC::NewLC(KDefaultBufferSize);
+	TPtr ptr(buffer->Des());
+	
+	User::LeaveIfError(SendReceive(ESidToFileName, TIpcArgs(&sid, &ptr, aDrive)));
+	
+	// Get the filename
+	aFileName.Copy(*buffer);
+	CleanupStack::PopAndDestroy(buffer);
+#else	
+	HBufC8* buffer = SendReceiveBufferLC(ESidToFileName, static_cast<TPtrC8>(sid), aDrive);
+
+	RDesReadStream stream(*buffer);
+	stream.PushL();
+
+	// Reassemble the CSisRegistryFileDescription from the stream
+	CSisRegistryFileDescription* fileDesc = CSisRegistryFileDescription::NewLC(stream);
+
+	// Get the filename
+	aFileName.Copy(fileDesc->Target());
+
+	CleanupStack::PopAndDestroy(fileDesc);
+	CleanupStack::PopAndDestroy(&stream);	
+	CleanupStack::PopAndDestroy(buffer);	
+#endif
+	}
+
+
+EXPORT_C TBool RSisRegistrySession::IsSidPresentL(TUid aSid)
+/**
+	Queries whether the supplied SID is associated with
+	any package on the device.
+	
+	@param	aSid			The executable's SID.
+	@return					Whether that SID is present in any registered
+							package.
+ */
+	{
+	TPckgC<TUid> sid(aSid);
+	TPckgBuf<TBool> present;
+	
+	TInt r = SendReceive(EIsSidPresent, TIpcArgs(&sid, &present));
+	User::LeaveIfError(r);
+	
+	return present();
+	}
+	
+EXPORT_C void RSisRegistrySession::RemovablePackagesL(RPointerArray<CSisRegistryPackage>& aPackages)
+	{
+	HBufC8* buffer = SendReceiveBufferLC(ERemovablePackages);
+	
+	// create a stream based on the buffer
+	RDesReadStream stream(*buffer);
+	CleanupClosePushL(stream);
+	// reassemble the array from the stream
+	InternalizePointerArrayL(aPackages, stream);
+	CleanupStack::PopAndDestroy(2, buffer);
+	}
+	
+EXPORT_C void RSisRegistrySession::RecoverL()
+	{
+	User::LeaveIfError(SendReceive(EInitRecovery));	
+	}
+
+HBufC8* RSisRegistrySession::SendReceiveBufferLC(TInt aMessage) 
+	{
+	HBufC8* output = HBufC8::NewLC(KDefaultBufferSize);
+	
+	TPtr8 pOutput(output->Des());
+	
+	TInt result = SendReceive(aMessage, TIpcArgs(&pOutput));
+	
+	if (result == KErrOverflow)
+		{
+		TInt sizeNeeded;
+		TPckg<TInt> sizeNeededPackage(sizeNeeded);
+		sizeNeededPackage.Copy(*output);
+		
+		// Re-allocate buffer after reclaiming memory
+		CleanupStack::PopAndDestroy(output);
+		output = HBufC8::NewLC(sizeNeeded);
+
+		TPtr8 pResizedOutput(output->Des());
+		
+		result=SendReceive(aMessage, TIpcArgs(&pResizedOutput));
+		}
+	User::LeaveIfError(result);
+	return output;
+	}
+	
+HBufC8* RSisRegistrySession::SendReceiveBufferLC(TInt aMessage, const TDesC& aInputDescriptor) 
+	{
+	HBufC8* output = HBufC8::NewLC(KDefaultBufferSize);
+	
+	TPtr8 pOutput(output->Des());
+	
+	TInt result = SendReceive(aMessage, TIpcArgs(&aInputDescriptor, &pOutput));
+	
+	if (result == KErrOverflow)
+		{
+		TInt sizeNeeded = 0;
+		TPckg<TInt> sizeNeededPackage(sizeNeeded);
+		sizeNeededPackage.Copy(*output);
+		
+		// Re-allocate buffer
+		CleanupStack::PopAndDestroy(output);
+		output = HBufC8::NewLC(sizeNeeded);
+
+		TPtr8 pResizedOutput(output->Des());
+		
+		result=SendReceive(aMessage, TIpcArgs(&aInputDescriptor, &pResizedOutput));
+		}
+	User::LeaveIfError(result);
+	return output;
+	}
+	
+HBufC8* RSisRegistrySession::SendReceiveBufferLC(TInt aMessage, TPtrC8 aInputBuffer) 
+	{
+	HBufC8* output = HBufC8::NewLC(KDefaultBufferSize);
+	
+	TPtr8 pOutput(output->Des());
+	
+	TInt result=SendReceive(aMessage, TIpcArgs(&aInputBuffer, &pOutput));
+	
+	if (result == KErrOverflow)
+		{
+		TInt sizeNeeded;
+ 		TPckg<TInt> sizeNeededPackage(sizeNeeded);
+		sizeNeededPackage.Copy(*output);
+		
+		// Re-allocate buffer
+		CleanupStack::PopAndDestroy(output);
+		output = HBufC8::NewLC(sizeNeeded);
+
+		TPtr8 pResizedOutput(output->Des());
+		
+		result=SendReceive(aMessage, TIpcArgs(&aInputBuffer, &pResizedOutput));
+		}
+	User::LeaveIfError(result);
+	return output;
+	}
+	
+EXPORT_C void RSisRegistrySession::RetrieveLogFileL(RPointerArray<CLogEntry>& aLogEntry)
+ 	{
+ 	HBufC8* buffer = SendReceiveBufferLC(EloggingFile);
+  
+ 	RDesReadStream stream(*buffer);
+ 	CleanupClosePushL(stream);
+ 	TInt err;
+ 	if(buffer->Length() != 0)
+ 		{
+ 		do
+	 		{
+	 		CLogEntry* log = NULL;
+	 		TRAP(err,log = CLogEntry::NewL(stream));
+	 		if(err ==KErrEof)
+	 			{
+				// coverity[memory_leak]
+	 			break;
+	 			}
+	 		else if(err != KErrNone)
+				{
+				User::Leave(err);	
+				}
+	 		CleanupStack::PushL(log);
+	 		aLogEntry.AppendL(log);
+	 		CleanupStack::Pop(log);
+	 		}
+	 	while(err == KErrNone);
+ 		}
+ 	 	
+ 	CleanupStack::PopAndDestroy(2,buffer);	//buffer,stream
+ 	}
+ 
+HBufC8* RSisRegistrySession::SendReceiveBufferLC(TInt aMessage, TPtrC8 aInputBuffer, TInt aThirdArgument) 
+	{
+	HBufC8* output = HBufC8::NewLC(KDefaultBufferSize);
+
+	TPtr8 pOutput(output->Des());
+
+	TInt result=SendReceive(aMessage, TIpcArgs(&aInputBuffer, &pOutput, aThirdArgument));
+
+	if (result == KErrOverflow)
+		{
+		TInt sizeNeeded;
+		TPckg<TInt> sizeNeededPackage(sizeNeeded);
+		sizeNeededPackage.Copy(*output);
+
+		// Re-allocate buffer
+		CleanupStack::PopAndDestroy(output);
+		output = HBufC8::NewLC(sizeNeeded);
+
+		TPtr8 pResizedOutput(output->Des());
+
+		result=SendReceive(aMessage, TIpcArgs(&aInputBuffer, &pResizedOutput, aThirdArgument));
+		}
+	User::LeaveIfError(result);
+	return output;
+	}
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+EXPORT_C TBool RSisRegistrySession::IsFileRegisteredL(const TDesC& aFileName)
+	{
+	TBool registered = EFalse;
+	TPckg<TBool> registeredPckg(registered);
+	
+	User::LeaveIfError(SendReceive(EIsFileRegistered, TIpcArgs(&aFileName, &registeredPckg)));
+	return registered;	
+	}
+	
+EXPORT_C Usif::TComponentId RSisRegistrySession::GetComponentIdForUidL(const TUid& aUid)
+	{
+	Usif::TComponentId componentId(0);
+	TPckg<Usif::TComponentId> componentIdPckg(componentId);
+	
+	User::LeaveIfError(SendReceive(EComponentIdForUid, TIpcArgs(aUid.iUid, &componentIdPckg)));
+	return componentId;		
+	}
+
+#endif //SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+