libraries/qr3/src/sandbox.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // sandbox.cpp
       
     2 // 
       
     3 // Copyright (c) 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 #include <e32base.h>
       
    13 #include "sandbox.h"
       
    14 #include <APMREC.H>
       
    15 #include <fshell/memoryaccess.h>
       
    16 
       
    17 enum TMsg
       
    18 	{
       
    19 	EGetRecog,
       
    20 	EGetRecog2,
       
    21 	ECloseServer,
       
    22 	EGetVTablePtr,
       
    23 	EMaxArgs,
       
    24 	};
       
    25 
       
    26 #ifndef SERVER
       
    27 
       
    28 
       
    29 class RSandboxSession : public RSessionBase
       
    30 	{
       
    31 public:
       
    32 	TInt Connect(const TDesC& aServerName)
       
    33 		{
       
    34 		return CreateSession(aServerName, TVersion(0,0,0));
       
    35 		}
       
    36 
       
    37 	TInt GetRecogniserInfo(TUid aImplementationUid, RArray<TDataType>& aMimeTypes)
       
    38 		{
       
    39 		TInt size = SendReceive(EGetRecog, TIpcArgs(aImplementationUid.iUid));
       
    40 		if (size < 0) return size;
       
    41 		TInt err = aMimeTypes.Reserve(size/sizeof(TDataType));
       
    42 		if (err) return err;
       
    43 		RBuf8 buf;
       
    44 		err = buf.Create(size);
       
    45 		if (err) return err;
       
    46 		err = SendReceive(EGetRecog2, TIpcArgs(&buf));
       
    47 		if (err) { buf.Close(); return err; }
       
    48 
       
    49 		const TDataType* ptr = (const TDataType*)buf.Ptr();
       
    50 		for (TInt i = 0; i < size/sizeof(TDataType); i++)
       
    51 			{
       
    52 			err = aMimeTypes.Append(ptr[i]);
       
    53 			if (err) break;
       
    54 			}
       
    55 		buf.Close();
       
    56 		return err;
       
    57 		}
       
    58 
       
    59 	TInt GetVTablePtrFromEcomUid(TUid aUid, TAny*& vtablePtr)
       
    60 		{
       
    61 		TPckgBuf<TAny*> pkg(NULL);
       
    62 		TInt err = SendReceive(EGetVTablePtr, TIpcArgs(aUid.iUid, &pkg));
       
    63 		if (err) return err;
       
    64 		vtablePtr = pkg();
       
    65 		return KErrNone;
       
    66 		}
       
    67 
       
    68 	void Byebye()
       
    69 		{
       
    70 		SendReceive(ECloseServer);
       
    71 		}
       
    72 	};
       
    73 
       
    74 #define GETSESSIONL(process, session)										\
       
    75 	RProcess process;														\
       
    76 	User::LeaveIfError(process.Create(_L("QR3Sandbox.exe"), KNullDesC));	\
       
    77 	TRequestStatus stat;													\
       
    78 	process.Rendezvous(stat);												\
       
    79 	process.Resume();														\
       
    80 	User::WaitForRequest(stat);												\
       
    81 																			\
       
    82 	RSandboxSession session;												\
       
    83 	User::LeaveIfError(session.Connect(sandbox.FullName()));
       
    84 
       
    85 
       
    86 void Sandbox::GetRecogniserInfoL(TUid aImplementationUid, RArray<TDataType>& aMimeTypes)
       
    87 	{
       
    88 	GETSESSIONL(sandbox, sess);
       
    89 
       
    90 	User::LeaveIfError(sess.GetRecogniserInfo(aImplementationUid, aMimeTypes));
       
    91 
       
    92 	sess.Byebye();
       
    93 	sandbox.Close();
       
    94 	}
       
    95 
       
    96 void Sandbox::GetDllNameFromEcomUidL(RMemoryAccess& aMemAccess, TUid aUid, TFileName& aFileName)
       
    97 	{
       
    98 	// Try and instanciate object and figure out what DLL it belongs to by looking up its vtable pointer
       
    99 	// We do the instanciation in a separate process so as to avoid worrying about cleanup or side-effects of instanciation
       
   100 
       
   101 	GETSESSIONL(sandbox, sess);
       
   102 
       
   103 	TAny* vtablePtr = NULL;
       
   104 	TInt err = sess.GetVTablePtrFromEcomUid(aUid, vtablePtr);
       
   105 
       
   106 	TFullName8 dllName;
       
   107 	if (!err)
       
   108 		{
       
   109 		err = aMemAccess.FindAddressInCodeSegments(dllName, vtablePtr);
       
   110 		}
       
   111 	sess.Byebye(); // We have to call FindAddressInCodeSegments before sandbox exits, because when it does the code segment will most likely be unloaded!
       
   112 	sandbox.Close();
       
   113 	User::LeaveIfError(err);
       
   114 	
       
   115 	aFileName.Copy(dllName);
       
   116 	}
       
   117 
       
   118 
       
   119 #else
       
   120 
       
   121 #include <e32property.h>
       
   122 #include <ecom/ecom.h>
       
   123 
       
   124 void GoL();
       
   125 
       
   126 class CSandboxSession : public CSession2
       
   127 	{
       
   128 	void ServiceL(const RMessage2 &aMessage);
       
   129 	RBuf8 iBuf;
       
   130 	};
       
   131 
       
   132 class CSandboxServer : public CServer2
       
   133 	{
       
   134 public:
       
   135 	CSandboxServer() : CServer2(0,ESharableSessions) {}
       
   136 
       
   137 protected:
       
   138 	CSession2* NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const
       
   139 		{
       
   140 		return new(ELeave) CSandboxSession();
       
   141 		}
       
   142 	};
       
   143 
       
   144 
       
   145 TInt E32Main()
       
   146 	{
       
   147 	User::SetJustInTime(EFalse); // Don't want to debug problems in the sandbox
       
   148 
       
   149 	CTrapCleanup* cleanup=CTrapCleanup::New();
       
   150 	TRAPD(err, GoL());
       
   151 	return err;
       
   152 	}
       
   153 
       
   154 void GoL()
       
   155 	{
       
   156 	CActiveScheduler* s=new(ELeave) CActiveScheduler;
       
   157 	CActiveScheduler::Install(s);
       
   158 	CSandboxServer* server = new(ELeave) CSandboxServer();
       
   159 	// Scope the TFullName
       
   160 		{
       
   161 		TFullName serverName = RProcess().FullName();
       
   162 		server->StartL(serverName);
       
   163 		}
       
   164 	RProcess::Rendezvous(KErrNone);
       
   165 	CActiveScheduler::Start();
       
   166 	}
       
   167 
       
   168 void CSandboxSession::ServiceL(const RMessage2 &aMessage)
       
   169 	{
       
   170 	if (aMessage.Function() >= EMaxArgs)
       
   171 		{
       
   172 		aMessage.Complete(KErrArgument);
       
   173 		return;
       
   174 		}
       
   175 
       
   176 	if (aMessage.Function() == EGetRecog2)
       
   177 		{
       
   178 		aMessage.WriteL(0, iBuf);
       
   179 		iBuf.Close();
       
   180 		aMessage.Complete(KErrNone);
       
   181 		}
       
   182 	else if (aMessage.Function() == EGetRecog)
       
   183 		{
       
   184 		if (iBuf.MaxLength() == 0)
       
   185 			{
       
   186 			iBuf.ReAllocL(1024); // Must be > sizeof(TDataType) otherwise the reallocating logic below is flawed
       
   187 			}
       
   188 		TUid uid = TUid::Uid(aMessage.Int0());
       
   189 		TUid destructorKey;
       
   190 		CApaDataRecognizerType* rec = static_cast<CApaDataRecognizerType*>(REComSession::CreateImplementationL(uid, destructorKey));
       
   191 		TInt count = rec->MimeTypesCount();
       
   192 		for (TInt j = 0; j < count; j++)
       
   193 			{
       
   194 			TDataType type = rec->SupportedDataTypeL(j);
       
   195 			TPckg<TDataType> buf(type);
       
   196 			if (iBuf.Length() + buf.Length() >= iBuf.MaxLength())
       
   197 				{
       
   198 				iBuf.ReAllocL(iBuf.MaxLength() * 2);
       
   199 				}
       
   200 			iBuf.Append(buf);
       
   201 			}
       
   202 
       
   203 		aMessage.Complete(iBuf.Size());
       
   204 		}
       
   205 	else if (aMessage.Function() == ECloseServer)
       
   206 		{
       
   207 		aMessage.Complete(KErrNone);
       
   208 		CActiveScheduler::Stop();
       
   209 		}
       
   210 	else if (aMessage.Function() == EGetVTablePtr)
       
   211 		{
       
   212 		TUid destructorKey;
       
   213 		TAny* obj = NULL;
       
   214 		obj = REComSession::CreateImplementationL(TUid::Uid(aMessage.Int0()), destructorKey);
       
   215 		TAny* vtablePtr = *((TAny**)obj);	
       
   216 		TPckg<TAny*> res(vtablePtr);
       
   217 		aMessage.WriteL(1, res);
       
   218 		aMessage.Complete(KErrNone);
       
   219 		}
       
   220 	else
       
   221 		{
       
   222 		ASSERT(0);
       
   223 		}
       
   224 	}
       
   225 
       
   226 #endif