diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,243 @@ + + + + + +Environment +SlotsUp to 16 separate pieces of information can be passed to a process +on creation using Environment Slots. These include handles and binary data. +

Handles and binary data can be passed to a process at process creation +time using environment slots. This topic describes this concept, and explains +how to use the process APIs for environment slots.

+ +
Overview

Handles +and binary data, in the form of descriptors or integer values, can be passed +to a process at process creation time, using what are called environment slots.

Up +to 16 separate pieces of information can be passed to a process on creation. +For this purpose, a process has 16 environment slots that can contain the +information passed to it by the launching process.

Slot 0 is reserved +and is never available for general purpose information passing.

The +parent (launching) process can only pass information to the child (created) +process after the child process has been created. However, it should be done +before the child process is resumed; it is an error to try and set environment +data in a child process that has been resumed.

A child process can +only extract the information from its environment slots once. Extracting information +from a slot causes that information to be deleted from the slot.

It +is a matter of convention between the parent and child process as to the meaning +to be applied to a slot, and the type of data that it is to contain.

+
The APIs

To +pass, a handle, a client server subsession, or binary data to a child process, +the parent process calls RProcess::SetParameter(), where +the RProcess object represents the newly created child +process. There are five overloaded variants of SetParameter() used +for passing:

+ + + +

handle:

+TInt RProcess::SetParameter(TInt aSlot, RHandleBase aHandle); +
+ +

client server subsession:

+TInt RProcess::SetParameter(TInt aSlot, const RSubSessionBase& aSession); +
+ +

8-bit descriptor:

+TInt RProcess::SetParameter(TInt aSlot, const TDesC8& aDes); +
+ +

16-bit descriptor:

+TInt RProcess::SetParameter(TInt aSlot, const TDesC16& aDes); +
+ +

integer:

+TInt RProcess::SetParameter(TInt aSlot, TInt aData); +
+ + +

To extract, a handle, or a client server subsession, a child process +can use the Open() function called on the relevant RHandleBase derived +type:

TInt RSemaphore ::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +TInt RBusLogicalChannel::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +TInt RMsgQueueBase::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +TInt RMutex::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +TInt RChunk::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +TInt RSessionBase::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +

To extract descriptor data, or integer data, a child process +can use the User class functions:

static TInt User::ParameterLength(TInt aSlot); +static TInt User::GetTIntParameter(TInt aSlot, TInt& aData); +static TInt User::GetDesParameter(TInt aSlot, TDes8& aDes); +static TInt User::GetDesParameter(TInt aSlot, TDes16& aDes); + +Environment slots + +
+
Passing a +file handle and a subsession

File server session handles and file +handles can both be passed to a child process.

The child process adopts +the file handle, and must not be closed by the parent. To use a file handle, +the session handle must also be passed.

For security reasons, +when sharing a file handle, the parent process should create a separate file +server session for the specific purpose of sharing the file handle. If the +parent process has other files open with this file server session, the child +process can gain access to those files by iterating through all the possible +values for the file handle and attempting to Adopt() each +one. For the same reason, the child process should only use this session for +sharing the file; it should not access other files through this session.

The +following two code fragments show code in the parent process and corresponding +code in the child process.

//Code in the parent (launching) process + + RProcess p; + p.Create(KProcName, KNullDesC); //create “child” process + + RFile file; + RFs session; + session.Connect(); //connect to file server + session.ShareProtected(); + file.Create(iSession, KFileName, EFileStreamText|EFileWrite|EFileShareAny); + file.Write(0, KTestData); + + p.SetParameter(5, session); //session handle passed in slot 5 + p.SetParameter(6, file); //file handle passed in slot 6 + Session.Close(); + p.Resume(); +

KProcName is the full path name of the +executable associated with the child process, and KFilename is +the file name.

//Code in the child (launched) process + + RFs session; + session.Open(5); //obtain session handle from slot 5 + + RFile file; + TInt handle; + ret = User::GetTIntParameter(8, handle);//get file handle from slot 8 + file.Adopt(session, handle); //adopt the handle + TBuf8<100> rbuf; //use the file + ret = file.Read(0, rbuf); + file.Close(); + session.Close(); +
+
Passing a +general handle, derived from RHandleBase

General handles derived +from RHandleBase can be passed to a child process.

The +handle is duplicated when it is stored in the child process’s environment. +The parent can close the handle immediately after calling SetParameter(), +or continue to use the handle and close it later.

The following two +code fragments show code in the parent process and corresponding code in the +child process.

//Code in the parent (launching) process, +//passing handles to a mutex and a semaphore. + + RMutex mutex; + RSemaphore sem; + + RProcess p; + p.Create(KProcName, KNullDesC); + mutex.CreateGlobal(KMutexName); //create the mutex + sem.CreateGlobal(KSemName,0); //create the semaphore + p.SetParameter(3, mutex); //put mutex handle into child process env' slot 3 + p.SetParameter(4, sem); //put semaphore handle into child process env' slot 4 + mutex.Close(); + Sem.Close(); + p.Resume(); //resume the child process + //Code in the child (launched) process retrieving the handles. + + RMutex mutex; + mutex.Open(3, EOwnerThread); //get mutex handle + RSemaphore sem; + sem.Open(4, EOwnerThread); //get semaphore handle + + //use the semaphore and mutex + mutex.Close(); + sem.Close(); +
+
Passing descriptor +data

Both 8-bit and 16-bit descriptor data can be passed from a +parent to a child process.

Internally, an HBuf descriptor +is created containing the passed descriptor data, and a pointer to this descriptor +is passed in the relevant slot.

The child process retrieves the descriptor +data by calling User::GetDesParameter(). It can get the +length of the data by calling User::ParameterLength().

The +following two code fragments show code in the parent process and corresponding +code in the child process.

//Code in the parent (launching) process, passing 8 and sixteen bit data + + RProcess p; + p.Create(KProcName, KNullDesC); + p.SetParameter(2, KSixteenBitDes); + p.SetParameter(3, KEightBitDes); + p.Resume(); +

where KSixteenBitDes is a 16-descriptor, +and KEightBitDes is an 8-bit descriptor.

//Code in the child (launched) process retrieving 8 and sixteen bit data + + TInt len; + TInt ret; + + TBuf16<40> buf; + len = User::ParameterLength(2); //parameter length is the size in bytes + ret = User::GetDesParameter(2, buf); + + //buf.Length() should have the value of len/2; + + + TBuf8<40> buf8; + len = User::ParameterLength(3); + ret = User::GetDesParameter(3, buf8); + //buf.Length() should be the same as len +

Note that the descriptors, buf, and buf8 used +in the child process must have sufficiently large maximum lengths to accomodate +the data.

+
Passing an +integer

An integer can be passed from a parent to a child process.

The +following two code fragments show code in the parent process and corresponding +code in the child process.

//Code in the parent (launching) process + + RProcess p; + TInt ret; + + ret = p.Create(KProcName, KNullDesC); + p.SetParameter(12, 1234); // Using slot 12 + p.Resume(); + //Code in the child (launched) process, retrieving the integer. + + TInt val; + TInt ret; + + ret = User::GetTIntParameter(12, val); + +
+
Error handling +issues

The parent process is panicked when calling SetParameter() with +a handle if:

    +
  • the parent process is +not the creator of the child process

  • +
  • the slot number is out +of range, i.e. is not in the range 0 to 15

  • +
  • the slot is in use

  • +
  • the handle is local.

  • +

The parent process is panicked when calling SetParameter() with +a descriptor or integer if:

    +
  • the parent process is +not the creator of the child process

  • +
  • the slot number is out +of range, i.e. is not in the range 0 to 15

  • +
  • the slot is in use

  • +
  • the length of the data +is negative.

  • +

The child process is panicked if the slot number is out of range.

The +API functions that extract data from the process environment return KErrArgument if +a slot contains the incorrect data type, or the length is incorrect. They +return KErrNotFound if a slot is empty.

+
\ No newline at end of file