--- /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