installationservices/swi/source/sislauncher/client/sislauncherclient.cpp
changeset 0 ba25891c3a9e
child 25 7333d7932ef7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swi/source/sislauncher/client/sislauncherclient.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,354 @@
+/*
+* 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: 
+* SisLauncher - client SisLaunchers interface implementation
+*
+*/
+
+
+/**
+ @file 
+ @released
+ @internalComponent
+*/
+
+#include<s32mem.h>
+ 
+#include "sislauncherclient.h"
+#include "sislauncherclientserver.h"
+#include "sisregistryfiledescription.h"
+#include "secutils.h"
+
+#include "arrayutils.h"  // from source/sisregistry/common/ 
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+#include "swtypereginfo.h"
+#endif
+
+using namespace Swi;
+
+static TInt StartSisLauncherServer()
+	{
+	const TUidType serverUid(KNullUid, KNullUid, KServerUid3);
+	RProcess server;
+	TInt err = server.Create(KSisLauncherServerImg, 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 RSisLauncherSession::Connect()
+//
+// Connect to the server, attempting to start it if necessary
+//
+	{
+	TInt retry=2;
+	for (;;)
+		{
+		TInt err = CreateSession(KSisLauncherServerName, TVersion(0, 0, 0), 1);
+		if (err != KErrNotFound && err != KErrServerTerminated)
+			{
+			return err;
+			}
+		if (--retry==0)
+			{
+			return err;
+			}
+		err = StartSisLauncherServer();
+		if (err != KErrNone && err != KErrAlreadyExists)
+			{
+			return err;
+			}
+		}
+	}
+
+EXPORT_C void RSisLauncherSession::RunExecutableL(const TDesC& aFileName, TBool aWait)
+	{
+	TPckgC<TBool> wait(aWait);
+	User::LeaveIfError(SendReceive(ERunExecutable, TIpcArgs(&aFileName, &wait)));
+	}
+
+EXPORT_C void RSisLauncherSession::StartDocumentL(RFile& aFile, TBool aWait)
+	{
+	TPckgC<TBool> wait(aWait);
+	TIpcArgs ipcArgs;
+	aFile.TransferToServer(ipcArgs, 0, 1);
+	ipcArgs.Set(2, &wait);
+	User::LeaveIfError(SendReceive(EStartDocumentByHandle, ipcArgs));
+	}
+
+EXPORT_C void RSisLauncherSession::StartByMimeL(RFile& aFile, const TDesC8& aMimeType, TBool aWait)
+	{
+	TPckgC<TBool> wait(aWait);
+	TIpcArgs ipcArgs;
+	aFile.TransferToServer(ipcArgs, 0, 1);
+	ipcArgs.Set(2, &aMimeType);
+	ipcArgs.Set(3, &wait);
+	
+	User::LeaveIfError(SendReceive(EStartByMimeByHandle, ipcArgs));
+	}
+
+EXPORT_C void RSisLauncherSession::StartDocumentL(const TDesC& aFileName, TBool aWait)
+	{
+	TPckgC<TBool> wait(aWait);
+	User::LeaveIfError(SendReceive(EStartDocument, TIpcArgs(&aFileName, &wait)));
+	}
+
+EXPORT_C void RSisLauncherSession::StartByMimeL(const TDesC& aFileName, const TDesC8& aMimeType, TBool aWait)
+	{
+	TPckgC<TBool> wait(aWait);
+	User::LeaveIfError(SendReceive(EStartByMime, TIpcArgs(&aFileName, &aMimeType, &wait)));
+	}
+
+EXPORT_C void RSisLauncherSession::ShutdownAllL()
+	{
+	User::LeaveIfError(SendReceive(EShutdownAll));
+	}
+
+EXPORT_C void RSisLauncherSession::CheckApplicationInUseL(RArray<TAppInUse>& aUidList)
+	{
+	TInt uidCount=aUidList.Count();
+	if (uidCount)
+		{
+		HBufC8* appInUseBuf=HBufC8::NewLC(uidCount * sizeof(TAppInUse));
+		TPtr8 appInUsePtr=appInUseBuf->Des();
+		TUint8* dataPtr(NULL);
+		TInt i;
+		for (i = 0 ; i < uidCount ; ++i)
+			{
+			dataPtr=reinterpret_cast<TUint8*>(&aUidList[i]);
+			appInUsePtr.Append(dataPtr, sizeof(TAppInUse));			
+			}	
+		User::LeaveIfError((SendReceive(ECheckApplicationInUse, TIpcArgs(&appInUsePtr))));
+
+		//Copy the result back to the RArray
+		dataPtr=const_cast<TUint8*>(appInUsePtr.Ptr());
+		TAppInUse* appInUseDataPtr=reinterpret_cast<TAppInUse*>(dataPtr);
+		for (i = 0; i < uidCount; ++i)
+			{
+			aUidList[i]=appInUseDataPtr[i];	
+			}				
+			
+		CleanupStack::PopAndDestroy(appInUseBuf);				
+		}
+	}
+	
+EXPORT_C void RSisLauncherSession::ShutdownL(const RArray<TUid>& aUidList, TInt aTimeout)
+	{
+	TInt uidCount=aUidList.Count();
+	if (uidCount)	
+		{
+		HBufC8* tUidBuf=HBufC8::NewLC(uidCount * sizeof(TUid));
+		TPtr8 tUidBufPtr=tUidBuf->Des();
+		const TUint8* dataPtr(NULL);
+		
+		for (TInt i=0;i<uidCount;i++)
+			{
+			dataPtr=reinterpret_cast<const TUint8*>(&aUidList[i]);
+			tUidBufPtr.Append(dataPtr, sizeof(TUid));
+			}	
+		User::LeaveIfError((SendReceive(EShutdown, TIpcArgs(&tUidBufPtr, aTimeout))));		
+		CleanupStack::PopAndDestroy(tUidBuf);							
+		}
+	}
+
+EXPORT_C void RSisLauncherSession::NotifyNewAppsL(const RPointerArray<TDesC>& aFiles)
+	{
+	if (aFiles.Count() > 0)
+		{
+		CBufFlat* tmpBuf = CBufFlat::NewL(255);
+		CleanupStack::PushL(tmpBuf);
+			
+		RBufWriteStream stream(*tmpBuf);
+		CleanupClosePushL(stream);
+
+		ExternalizePointerArrayL(aFiles, stream);
+
+		// Create an HBufC8 from the stream buf's length, and copy 
+		// the stream buffer into this descriptor
+		HBufC8* buffer = HBufC8::NewLC(tmpBuf->Size());
+		TPtr8 ptr(buffer->Des());
+		tmpBuf->Read(0, ptr, tmpBuf->Size());
+	
+		User::LeaveIfError(SendReceive(ENotifyNewApps, TIpcArgs(&ptr)));
+		CleanupStack::PopAndDestroy(3, tmpBuf);
+		}
+	}
+
+EXPORT_C void RSisLauncherSession::RunAfterEcomNotificationL(const RPointerArray<CSisRegistryFileDescription>& aFileList)
+	{
+	TInt count = aFileList.Count();
+	if (count <= 0)
+		{
+		return; 
+		}
+
+	RFs fs;
+	User::LeaveIfError(fs.Connect());
+	CleanupClosePushL(fs);
+	User::LeaveIfError(fs.ShareProtected());
+
+	for (TInt i = 0; i < count; ++i)
+		{
+		CSisRegistryFileDescription* fileDes = aFileList[i];
+
+		// open the file entry
+		TEntry entry;
+		if (fs.Entry(fileDes->Target(), entry) != KErrNone)
+			{
+			// just ignore, there's nothing we can do and we should try to process the
+			// remaining files.
+			continue;
+			}
+		
+		TIpcArgs ipcArgs;
+		TBool waitEnd = 0 != (fileDes->OperationOptions() & Sis::EInstFileRunOptionWaitEnd);
+		TPckgC<TBool> wait(waitEnd);
+		ipcArgs.Set(2, &wait);
+
+		TInt err = KErrNone;
+
+		if (entry.IsTypeValid() && SecUtils::IsExe(entry))
+			{
+			ipcArgs.Set(0,&fileDes->Target());
+			err = SendReceive(EQueueRunExecutable, ipcArgs);
+			}
+		else 
+			{
+			RFile file;
+			CleanupClosePushL(file);
+			err = file.Open(fs, fileDes->Target(), EFileShareExclusive|EFileWrite);
+
+			HBufC8* mimeType = 0;
+
+			if (err == KErrNone)
+				{
+				if (fileDes->OperationOptions() & Sis::EInstFileRunOptionByMimeType)
+					{
+					mimeType = HBufC8::NewLC(fileDes->MimeType().Length());
+					TPtr8 ptr = mimeType->Des();
+					ptr.Copy(fileDes->MimeType());
+					}
+
+				if (file.TransferToServer(ipcArgs, 0, 1) != KErrNone)
+					{
+					// best effort is to continue with remaining exes
+					}	
+				else if (mimeType != 0)
+					{
+					TPtrC8 x = mimeType->Des();
+					ipcArgs.Set(3, &x);
+					err = SendReceive(EQueueStartByMimeByHandle, ipcArgs);
+					}
+				else
+					{
+					err = SendReceive(EQueueStartDocumentByHandle, ipcArgs);
+					}
+				if (mimeType != 0)
+					{
+					CleanupStack::PopAndDestroy(mimeType);
+					}
+				}
+			CleanupStack::PopAndDestroy(&file); 
+			}
+		// best effort is to continue with other exes in the event of an error
+		// so do nothing here.
+		}
+	CleanupStack::PopAndDestroy(&fs);
+	User::LeaveIfError(SendReceive(EExecuteQueue));
+	
+	}
+
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+EXPORT_C void RSisLauncherSession::ParseSwTypeRegFileL(RFile& aFile, RPointerArray<CSoftwareTypeRegInfo>& aSwTypeRegInfoArray)
+	{
+	// Pack the file handle
+	TIpcArgs ipcArgs;
+	aFile.TransferToServer(ipcArgs, 0, 1);
+
+	// Allocate a buffer for the parsed registration info
+	TInt bufLen = 0;
+	User::LeaveIfError(aFile.Size(bufLen));
+	HBufC8* buf = HBufC8::NewLC(bufLen); // using the size of the file here is overhead but provides very simple code
+	
+	// Packe the buffer
+	TPtr8 bufPtr(buf->Des());
+	ipcArgs.Set(2, &bufPtr);
+	
+	// Send request to the server
+	User::LeaveIfError(SendReceive(EParseSwTypeRegFile, ipcArgs));
+
+	// Unpack the parsed registration info
+	RDesReadStream rs(*buf);
+	CleanupClosePushL(rs);
+	SoftwareTypeRegInfoUtils::UnserializeArrayL(rs, aSwTypeRegInfoArray);
+
+	CleanupStack::PopAndDestroy(2, buf); // rs
+	}
+
+EXPORT_C void RSisLauncherSession::RegisterSifLauncherMimeTypesL(const RPointerArray<HBufC8>& aMimeTypes)
+	{
+	RegisterSifLauncherMimeTypesImplL(aMimeTypes, ETrue);
+	}
+
+EXPORT_C void RSisLauncherSession::UnregisterSifLauncherMimeTypesL(const RPointerArray<HBufC8>& aMimeTypes)
+	{
+	RegisterSifLauncherMimeTypesImplL(aMimeTypes, EFalse);
+	}
+
+void RSisLauncherSession::RegisterSifLauncherMimeTypesImplL(const RPointerArray<HBufC8>& aMimeTypes, TBool aRegister)
+	{
+	// Calculate the size of aMimeTypes in a buffer
+	TInt bufLen = sizeof(TInt);
+	for (TInt i=0; i<aMimeTypes.Count(); ++i)
+		{
+		bufLen += sizeof(TInt) + aMimeTypes[i]->Size();
+		}
+	
+	// Externalize MIME types
+	HBufC8* buf = HBufC8::NewLC(bufLen);
+	TPtr8 bufPtr(buf->Des());
+
+	RDesWriteStream ws(bufPtr);
+	CleanupClosePushL(ws);
+	
+	ExternalizePointerArrayL(aMimeTypes, ws);
+
+	ws.CommitL();
+	CleanupStack::PopAndDestroy(&ws);
+
+	// Send MIME types to the server
+	TIpcArgs ipcArgs(&bufPtr);
+	User::LeaveIfError(SendReceive(aRegister?ERegisterSifLauncherMimeTypes:EUnregisterSifLauncherMimeTypes, ipcArgs));
+
+	CleanupStack::PopAndDestroy(buf);
+	}
+#endif