<?xml version="1.0" encoding="utf-8"?>+ −
<!-- Copyright (c) 2007-2010 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: + −
-->+ −
<!DOCTYPE concept+ −
PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">+ −
<concept id="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052" xml:lang="en"><title>Migrating+ −
to V2 client-server APIs</title><shortdesc>Describes how to modify client-server implementations to use the+ −
new Version 2 client-server APIs instead of the deprecated Version 1 APIs.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>+ −
<p>The new APIs have been introduced as part of the effort to provide a more+ −
secure interface for client-server communications, and form an essential component+ −
of Platform Security in Symbian platform. </p>+ −
<ul>+ −
<li id="GUID-C53A38E9-A821-577A-930A-F478954FF806"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-35D3BD7A-8C16-50C3-80AD-2422E3B92AAB">General points</xref> </p> </li>+ −
<li id="GUID-FD82A424-BDB5-5DE7-8904-C579C7683CA1"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-0FA5EC5C-8F7B-5E95-BE28-CD0DB6BDCBEE">The Version 1 client-server APIs</xref> </p> </li>+ −
<li id="GUID-63746CDF-E64B-5BA0-A133-8DFD0FA9FCF5"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-8BDFF94E-80E6-5CAF-8CC0-04D7F74FAF43">The Version 2 client-server APIs</xref> </p> </li>+ −
<li id="GUID-87719C35-00EB-51BE-8D01-6955535C6B4A"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-C5A1C9BA-7637-53EB-9898-A58336F87389">Changes to the client interface</xref> </p> </li>+ −
<li id="GUID-CFDDD4B4-DD54-5F9C-B60D-D361EA621670"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-450BE510-C3C9-5988-853B-1A03A84F0875">Changes to the server interface</xref> </p> </li>+ −
<li id="GUID-30E36FBF-25EA-5347-810E-D2C85F853CCD"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-07F7FFA6-D421-54E2-90F7-69F002702C46">Using RMessagePtr2</xref> </p> </li>+ −
<li id="GUID-A2E1CEF3-BD6F-594D-B4DC-098FBABBC6F4"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-1ABF5DC6-A957-5623-93AB-CD7631A36A33">Migration quick reference</xref> </p> </li>+ −
</ul>+ −
<section id="GUID-35D3BD7A-8C16-50C3-80AD-2422E3B92AAB"><title>General points</title> <p>The+ −
user library, EUSER.DLL, makes both the Version 1 and Version 2 client-server+ −
APIs available. However, it is possible to 'hide' the Version 1 APIs during+ −
compilation by defining the C pre-processor macro <codeph>__HIDE_IPC_V1__</codeph>. </p> <p>For+ −
example, by adding the following line to a component's MMP file: </p> <codeblock id="GUID-048E20E3-1E8C-5F08-9E40-CE0A43849AD5" xml:space="preserve">macro __HIDE_IPC_V1__</codeblock> <p>This+ −
can also be done globally for all components in Symbian platform by defining+ −
the macro in the platform's HRH file: </p> <codeblock id="GUID-30C6F786-CB13-5962-80E5-5ACBB5879B8C" xml:space="preserve">#define __HIDE_IPC_V1__</codeblock> <p>In+ −
addition, the EUSER header files define the macro <codeph>__IPC_V2_PRESENT__</codeph>,+ −
which allows source code that still needs to compile with older Symbian platform+ −
releases, to detect the presence of the new APIs, and use conditional compilation+ −
as appropriate. </p> </section>+ −
<section id="GUID-0FA5EC5C-8F7B-5E95-BE28-CD0DB6BDCBEE"><title>The Version+ −
1 client-server APIs</title> <p>The following classes and functions are defined+ −
as constituting the Version 1 client-server APIs: </p> <codeblock id="GUID-339D79DC-B401-5F09-B5A2-3D3EE10B3D63" xml:space="preserve">class CSharableSession+ −
class CSession+ −
class CServer+ −
class RMessagePtr+ −
class RMessage+ −
class RServer+ −
+ −
RSessionBase::Share(TAttachMode aAttachMode=EExplicitAttach)+ −
RSessionBase::Attach()+ −
RSessionBase::Send(TInt aFunction,TAny* aPtr)+ −
RSessionBase::SendReceive(TInt aFunction,TAny* aPtr,TRequestStatus& aStatus) + −
RSessionBase::SendReceive(TInt aFunction,TAny* aPtr)+ −
+ −
RSubSessionBase::CreateSubSession(RSessionBase&,TInt aFunction,const TAny* aPtr)+ −
RSubSessionBase::Send(TInt aFunction,const TAny* aPtr)+ −
RSubSessionBase::SendReceive(TInt aFunction,const TAny* aPtr,TRequestStatus&)+ −
RSubSessionBase::SendReceive(TInt aFunction,const TAny* aPtr)+ −
+ −
RThread::GetDesLength(const TAny* aPtr)+ −
RThread::GetDesMaxLength(const TAny* aPtr)+ −
RThread::ReadL(const TAny* aPtr,TDes8& aDes,TInt anOffset)+ −
RThread::ReadL(const TAny* aPtr,TDes16 &aDes,TInt anOffset)+ −
RThread::WriteL(const TAny* aPtr,const TDesC8& aDes,TInt anOffset)+ −
RThread::WriteL(const TAny* aPtr,const TDesC16& aDes,TInt anOffset)</codeblock> <p>The+ −
following functions are considered part of the client-server Version 1 APIs,+ −
when the target thread is in another process. Note that these APIs are <i>not</i> hidden+ −
by the <codeph>__HIDE_IPC_V1__</codeph> macro. </p> <codeblock id="GUID-BDAF69BC-F736-5E2F-9E7C-37B9AAC75A0E" xml:space="preserve">RThread::RequestComplete(TRequestStatus*& aStatus,TInt aReason)+ −
RThread::Kill(TInt aReason)+ −
RThread::Terminate(TInt aReason)+ −
RThread::Panic(const TDesC& aCategory,TInt aReason)+ −
</codeblock> </section>+ −
<section id="GUID-8BDFF94E-80E6-5CAF-8CC0-04D7F74FAF43"><title>The Version+ −
2 client-server APIs</title> <p>The following classes and functions are defined+ −
as constituting the Version 2 client-server APIs. </p> <codeblock id="GUID-E2EDBA7A-5668-52F4-BCF1-18F53A2DD1E9" xml:space="preserve">class CSession2+ −
class CServer2+ −
class RMessagePtr2+ −
class RMessage2+ −
class RServer2+ −
class TIpcArgs+ −
+ −
RSessionBase::Send(TInt aFunction,const TIpcArgs& aArgs)+ −
RSessionBase::SendReceive(TInt aFunction,const TIpcArgs& aArgs, TRequestStatus&)+ −
RSessionBase::SendReceive(TInt aFunction, const TIpcArgs& aArgs)+ −
RSessionBase::ShareAuto()+ −
+ −
RSubSessionBase::CreateSubSession(RSessionBase&,TInt aFunction,const TIpcArgs&)+ −
RSubSessionBase::Send(TInt aFunction,const TIpcArgs& aArgs)+ −
RSubSessionBase::SendReceive(TInt aFunction,const TIpcArgs& aArgs, TRequestStatus&)+ −
RSubSessionBase::SendReceive(TInt aFunction,const TIpcArgs& aArgs)</codeblock> </section>+ −
<section id="GUID-C5A1C9BA-7637-53EB-9898-A58336F87389"><title>Changes to+ −
the client interface</title> <p>The client interface to a server consists+ −
of a class derived either from <codeph>RSessionBase</codeph> or <codeph>RSubSessionBase</codeph>.+ −
This section lists the changes required to the use of these classes. </p> <ul>+ −
<li id="GUID-65CF4ED6-3133-5452-800C-F1EDA040B7C2"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-F5FB0FB3-6868-5B26-99A5-62082BFA87FD">RSessionBase::Share()</xref> </p> </li>+ −
<li id="GUID-93211175-EBE0-5C2E-9F67-3BFF6E50E5DD"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-68B92D5D-7786-51CD-9A3D-7C835FD64496">RSessionBase::Attach()</xref> </p> </li>+ −
<li id="GUID-596E1B2A-E1FF-553B-A257-A4091DD15F1A"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-8AF1B8B3-F598-5318-B9F9-5C74EEE8FCC9">RSessionBase::Send() & RSessionBase::SendReceive()</xref> </p> </li>+ −
<li id="GUID-E88F13D3-C4C9-5624-A90B-2CC3EA841D5D"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-449D6257-772B-5E08-8E4B-40C11EAF8FBA">RSubSessionBase::CreateSubSession()</xref> </p> </li>+ −
<li id="GUID-B28619D3-BDE6-5434-AB33-3016BA200633"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-858A58D1-A539-55FB-855E-50B997BA9A41">RSubSessionBase::Send() & RSubSessionBase::SendReceive()</xref> </p> </li>+ −
</ul> <p id="GUID-F5FB0FB3-6868-5B26-99A5-62082BFA87FD"><b>RSessionBase::Share()</b> </p> <table id="GUID-175135E8-8583-53E4-8829-88738EEFA357">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 functions: </p> </entry>+ −
<entry><codeblock id="GUID-3A5C2CAB-646B-5C1F-BA30-9808202B61E5" xml:space="preserve">Share()+ −
Share(EExplicitAttach)+ −
Share(EAutoAttach)</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><codeblock id="GUID-D946029A-A553-5BB3-B868-5348D06CF11E" xml:space="preserve">ShareAuto()</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>In Version 1, the two different share modes existed for historical+ −
reasons. All sessions created with new Version 2 servers behave like the Version+ −
1 <i>auto attach</i> sessions; there is no <i>explicit attach</i> sharing+ −
mode. The new <codeph>ShareAuto()</codeph> function should be used to replace+ −
all occurrences of <codeph>Share()</codeph>. </p> <p id="GUID-68B92D5D-7786-51CD-9A3D-7C835FD64496"><b>RSessionBase::Attach()</b> </p> <table id="GUID-43575561-41F7-5F61-ADF2-06892D06941B">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 function: </p> </entry>+ −
<entry><codeblock id="GUID-4E94517B-AAD4-5A7C-8B67-19E2DABF99BF" xml:space="preserve">Attach()</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><p>NONE </p> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>There is no explicit attach mode in the Version 2 API, (see <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-F5FB0FB3-6868-5B26-99A5-62082BFA87FD">RSessionBase::Share()</xref>).+ −
This means that all occurrences of <codeph>Attach()</codeph> must be removed+ −
from your code when migrating. </p> <p id="GUID-8AF1B8B3-F598-5318-B9F9-5C74EEE8FCC9"><b>RSessionBase::Send() &+ −
RSessionBase::SendReceive()</b> </p> <table id="GUID-BA09FDB1-4DF3-5D73-B314-1333E479FF35">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 functions: </p> </entry>+ −
<entry><codeblock id="GUID-7117993F-8620-598F-818B-769B91A94E02" xml:space="preserve">Send(TInt aFunction,TAny* aPtr)+ −
SendReceive(TInt aFunction,TAny* aPtr,TRequestStatus& aStatus)+ −
SendReceive(TInt aFunction,TAny* aPtr)</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 functions: </p> </entry>+ −
<entry><codeblock id="GUID-0A9B8E34-708E-531F-B6C3-2AD2EF9A831B" xml:space="preserve">Send(TInt aFunction,const TIpcArgs& aArgs)+ −
SendReceive(TInt aFunction,const TIpcArgs& aArgs, TRequestStatus& aStatus)+ −
SendReceive(TInt aFunction, const TIpcArgs& aArgs)</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>These are functions for sending request messages to a server.+ −
Each of these messages can take up to <codeph>KMaxMessageArguments</codeph> arbitrary+ −
arguments (i.e. 4 arguments), and it is the packaging of these arguments which+ −
has been changed in the Version 2 APIs. </p> <p>The Version 1 APIs take a <codeph>TAny*</codeph>,+ −
which points to a C array containing a <codeph>KMaxMessageArguments</codeph> number+ −
of 32-bit quantities, usually <codeph>TAny</codeph> * or <codeph>TInt</codeph> types.+ −
This is an example Version 1 client function: </p> <codeblock id="GUID-5FF9D271-11EC-5144-A3ED-8D0B65DD43E1" xml:space="preserve">TInt RMySession::Write(TDes8C& aDes, TInt aLength, TInt aMode)+ −
{+ −
TAny* args[KMaxMessageArguments];+ −
args[0]=&aDes;+ −
args[1]=(TAny*)aLength;+ −
args[2]=(TAny*)aMode;+ −
return SendReceive(ERequestWrite, &args[0]);+ −
}</codeblock> <p>The Version 2 APIs package all of the arguments into+ −
a <codeph>TIpcArgs</codeph> object. This has templated constructors that take+ −
between 0 and 4 objects. The above example would be implemented like this+ −
using the Version 2 APIs: </p> <codeblock id="GUID-3AD69C4D-B00D-5384-9455-4529235ADC0B" xml:space="preserve">TInt RMySession::Write(TDes8& aDes, TInt aLength, TInt aMode)+ −
{+ −
TIpcArgs args(&aDes, aLength, aMode);+ −
return SendReceive(ERequestWrite, args);+ −
}</codeblock> <p>This could also be written in a shorter way: </p> <codeblock id="GUID-9F904E6F-C2BE-57C9-B287-F25D4C743B54" xml:space="preserve">TInt RMySession::Write(TDes8C& aDes, TInt aLength, TInt aMode)+ −
{+ −
return SendReceive(ERequestWrite, TIpcArgs(&aDes, aLength, aMode) );+ −
}</codeblock> <p>The <codeph>TIpcArgs</codeph> object stores additional+ −
type information for each argument, and this is used to validate a server's+ −
usage of the arguments with the various <codeph>RMessagePtr2::Read()</codeph> and <codeph>RMessagePtr2::Write()</codeph> functions. </p> <p>If+ −
you need to explicitly send an empty or unused argument to a server, then+ −
use the <codeph>ENothing</codeph> enumeration. For example: </p> <codeblock id="GUID-1AFAE8D7-6EF1-531C-9605-249952DD3414" xml:space="preserve">TIpcArgs args(arg1, TIpcArgs::ENothing, arg3);</codeblock> <p>The+ −
second argument will have an undefined value when the server receives the+ −
message. </p> <p id="GUID-449D6257-772B-5E08-8E4B-40C11EAF8FBA"><b>RSubSessionBase::CreateSubSession()</b> </p> <table id="GUID-D11D839A-A6DC-56F6-A375-715C3C20DB58">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 function: </p> </entry>+ −
<entry><codeblock id="GUID-C10014FE-A269-55B4-8D7C-AFA726A7468D" xml:space="preserve">CreateSubSession(RSessionBase& aSession,TInt aFunction,const TAny* aPtr)</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><codeblock id="GUID-4EDF33FA-B99D-5089-AB2E-F6DD29814FA7" xml:space="preserve">CreateSubSession(RSessionBase, TInt aFunction, const TIpcArgs& aArgs)</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>The message arguments supplied to this function use a <codeph>TIpcArgs</codeph> object+ −
in Version 2. This is for the same reason as described in <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-8AF1B8B3-F598-5318-B9F9-5C74EEE8FCC9">RSessionBase::Send() & RSessionBase::SendReceive()</xref>. </p> <p id="GUID-858A58D1-A539-55FB-855E-50B997BA9A41"><b>RSubSessionBase::Send()+ −
& RSubSessionBase::SendReceive()</b> </p> <table id="GUID-3357BA2C-42CF-5590-94EE-0AC5C46C463B">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 functions: </p> </entry>+ −
<entry><codeblock id="GUID-4CCEAB86-160A-50DD-B2AD-63BAD6E865C7" xml:space="preserve">Send(TInt aFunction,const TAny* aPtr)+ −
SendReceive(TInt aFunction,const TAny* aPtr,TRequestStatus&)+ −
SendReceive(TInt aFunction,const TAny* aPtr)</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 functions: </p> </entry>+ −
<entry><codeblock id="GUID-0E7FE44C-19E2-5F5C-98A7-04F9F7129C70" xml:space="preserve">Send(TInt aFunction,const TIpcArgs& aArgs)+ −
SendReceive(TInt aFunction,const TIpcArgs& aArgs, TRequestStatus&)+ −
SendReceive(TInt aFunction,const TIpcArgs& aArgs)</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>The message arguments supplied to this function use a <codeph>TIpcArgs</codeph> object+ −
in Version 2. This is for the same reason as described in <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-8AF1B8B3-F598-5318-B9F9-5C74EEE8FCC9">RSessionBase::Send() & RSessionBase::SendReceive()</xref>. </p> </section>+ −
<section id="GUID-450BE510-C3C9-5988-853B-1A03A84F0875"><title>Changes to+ −
the server interface</title> <p>This section details the changes required+ −
to migrate a server implementation to the Version 2 APIs. These APIs have,+ −
in nearly all cases, been implemented using the same class names as in Version+ −
1, but with the addition of the suffix '2'. For example, <codeph>CServer2</codeph> implements+ −
the Version 2 APIs corresponding to the Version 1 functionality provided by <codeph>CServer</codeph>. </p> <ul>+ −
<li id="GUID-F2E4AB18-F24A-5EEF-B5CC-F8FBF947DE4E"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-43CF1E50-8E60-5633-97B7-B030D1DEC182">CServer</xref> </p> </li>+ −
<li id="GUID-7A262AF7-DBBD-5765-8179-F72E288304B2"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-B05AFD51-FF98-5972-9F40-107D8F8FEA5A">CServer::NewSessionL()</xref> </p> </li>+ −
<li id="GUID-1E1E1D8C-5BA5-5116-99B0-41453000DEE5"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-77592C37-AF3E-59DE-981E-AF23B442163B">CSharableSession</xref> </p> </li>+ −
<li id="GUID-C02F715E-6DF6-5AB0-A607-D740F32ADCEF"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-1616B87E-A4C3-509B-AF79-D4A964032BF1">CSharableSession::CreateL()</xref> </p> </li>+ −
<li id="GUID-3D09C142-DCF5-5FC6-99CC-A54D2FBECFBF"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-868E4703-DD82-5145-809D-91908237266C">CSharableSession::ResourceCountMarkEnd()</xref> </p> </li>+ −
<li id="GUID-38A6E9AB-4804-5852-907D-264F0CDA6D0B"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-54BF8797-7AE5-57E0-B5FD-C36C45D8CFFB">CSharableSession::RMessage()</xref> </p> </li>+ −
<li id="GUID-69440B22-6333-5783-A129-AFFFF7639068"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-F62D83DD-2A1C-5745-9813-E6646FF167BB">CSession</xref> </p> </li>+ −
<li id="GUID-12DC701E-E313-5CFA-9113-077423AE1CFE"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-F0C1B0F6-BF72-5A52-84D1-E7E748D3E1A5">CSession::CSession()</xref> </p> </li>+ −
<li id="GUID-D1DE193D-A5E7-5A80-B317-2E657008B174"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-F2BB351E-73DA-522A-96ED-361F2EB1A379">RMessage</xref> </p> </li>+ −
<li id="GUID-606187D7-226C-5919-86D9-7881540D30D6"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-B0431DFE-C0E5-5767-A299-564EC502B01E">RMessage::Client()</xref> </p> </li>+ −
<li id="GUID-06E2F69F-ABEE-5AB8-9751-45E285C3B494"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-4EEFEF47-D875-5C16-8836-98DD03C0A91D">RMessage::MessagePtr()</xref> </p> </li>+ −
<li id="GUID-73BB6C0D-FEE3-5C9A-B2E6-7BFCD2C59C1B"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-8754F52F-371C-546B-9290-B5369E915318">RMessage::descriptor access methods</xref> </p> </li>+ −
<li id="GUID-CE72E73D-4BA9-566B-ABA0-6FC52F1E17EC"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-49869449-4440-5D20-97ED-32C14C5D1DAF">RMessagePtr</xref> </p> </li>+ −
<li id="GUID-F91895A2-E211-56AF-9DA8-372D312E5E1B"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-A94A9960-319C-51B5-B693-2538D3985004">RThread</xref> </p> </li>+ −
<li id="GUID-4C8AF2A5-72D9-5367-9A7E-3721CC94401F"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-9DA5C542-44B6-5277-837D-1D9150F43B10">RThread::RequestComplete()</xref> </p> </li>+ −
</ul> <p id="GUID-43CF1E50-8E60-5633-97B7-B030D1DEC182"><b>CServer</b> </p> <table id="GUID-BD8385C6-AEAA-5379-87F3-F3B3A9CA5397">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 class: </p> </entry>+ −
<entry><codeblock id="GUID-48ECE79F-22EA-5DE5-A52F-1F6689969E3C" xml:space="preserve">CServer</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 class: </p> </entry>+ −
<entry><codeblock id="GUID-F213E0FA-2708-5365-92F5-551D0A3B15FB" xml:space="preserve">CServer2</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>Simply replace <codeph>CServer</codeph> with <codeph>CServer2</codeph>. </p> <p id="GUID-B05AFD51-FF98-5972-9F40-107D8F8FEA5A"><b>CServer::NewSessionL()</b> </p> <table id="GUID-1755D610-F3C5-50A8-9CE4-BE357883373B">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 function: </p> </entry>+ −
<entry><codeblock id="GUID-0E800CBB-6A25-5338-940C-93FD1D5EAB12" xml:space="preserve">CSharableSession* CServer::NewSessionL(const TVersion& aVersion) const</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><codeblock id="GUID-515A05BB-AB3C-5231-B32A-C8812A55B414" xml:space="preserve">CSession2* CServer2::NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>In Version 1, <codeph>CServer::NewSessionL()</codeph> is implemented+ −
by a class derived from <codeph>CServer</codeph>. In Version 2, your derived+ −
class uses <codeph>CServer2</codeph> as the base class. </p> <p>The <codeph>RMessage2</codeph> argument+ −
in Version 2 is the 'connect' message from the client. It has been added to+ −
allow implementations to check identity and security information about the+ −
new client. </p> <p>This message argument can be ignored when migrating code+ −
from the Version 1 APIs. </p> <p id="GUID-77592C37-AF3E-59DE-981E-AF23B442163B"><b>CSharableSession</b> </p> <table id="GUID-3FE15D11-51FA-5B24-B153-47EF5B20C925">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 class: </p> </entry>+ −
<entry><codeblock id="GUID-067FF488-35CE-585F-94FE-BF350B0DA2E1" xml:space="preserve">CSharableSession</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 class: </p> </entry>+ −
<entry><codeblock id="GUID-241A9E7D-2FC5-5202-A9F1-FC17D5CA8F38" xml:space="preserve">CSession2</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>Simply replace <codeph>CSharableSession</codeph> with <codeph>CSession2</codeph>. </p> <p id="GUID-1616B87E-A4C3-509B-AF79-D4A964032BF1"><b>CSharableSession::CreateL()</b> </p> <table id="GUID-7805C54A-7534-5C20-BE26-09575363F9C2">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 function: </p> </entry>+ −
<entry><codeblock id="GUID-D484349C-7B49-5DFE-8B0E-92AD511CC615" xml:space="preserve">void CSharableSession::CreateL(const CServer& aServer)</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><codeblock id="GUID-7B9C9D6D-A20C-571A-A533-3A4359067B84" xml:space="preserve">void CSession2::CreateL()</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>In Version 1, <codeph>CSharableSession::CreateL()</codeph> can+ −
be re-implemented by a class derived from <codeph>CSharableSession</codeph>.+ −
In Version 2, your derived class uses <codeph>CSession2</codeph> as the base+ −
class. </p> <p>The Version 2 <codeph>CreateL()</codeph> function has no arguments.+ −
If a derived session object overrides this function, then it will need modifying. </p> <p id="GUID-868E4703-DD82-5145-809D-91908237266C"><b>CSharableSession::ResourceCountMarkEnd()</b> </p> <table id="GUID-0E84FAD2-8007-5EA6-BCBB-659E67B0E94D">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 function: </p> </entry>+ −
<entry><codeblock id="GUID-52CC1805-86C8-5B3F-8AC2-D53020B93DDF" xml:space="preserve">void CSharableSession::ResourceCountMarkEnd()</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><codeblock id="GUID-037656C1-A71D-52BA-80BE-9647B12D2E6E" xml:space="preserve">void CSession2::ResourceCountMarkEnd(const RMessage2& aMessage)</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>In Version 2, the function requires a reference to the client+ −
message that requested the resource check. This message is used to panic the+ −
client if the check fails. </p> <p id="GUID-54BF8797-7AE5-57E0-B5FD-C36C45D8CFFB"><b>CSharableSession::RMessage()</b> </p> <table id="GUID-342A2BD3-8446-5437-B785-47BD8071B307">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 function: </p> </entry>+ −
<entry><codeblock id="GUID-86D3741D-F30E-5A9A-A211-5A1C008B70B2" xml:space="preserve">const RMessage& CSharableSession::Message() const</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><p>No equivalent function. </p> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>In Version 1. this function returns a reference to the last message+ −
delivered to the server. It is usually used by a session implementation to+ −
mean <i>the current message being processed by the session</i>. </p> <p>This+ −
function is not available in Version 2. When a session needs to manipulate+ −
a message delivered to it, it should use the <codeph>RMessage2</codeph> argument+ −
passed to <codeph>ServiceL()</codeph>, instead. Achieving this may require+ −
passing this reference as an argument between function calls, or if that is+ −
complex, then storing a reference to the message in the session object. </p> <p id="GUID-F62D83DD-2A1C-5745-9813-E6646FF167BB"><b>CSession</b> </p> <table id="GUID-DB57B8A0-66D6-59CF-8DF6-15DBF0EDE488">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 class: </p> </entry>+ −
<entry><codeblock id="GUID-44314564-FEE3-57B5-8878-A989125074EB" xml:space="preserve">CSession</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 class: </p> </entry>+ −
<entry><codeblock id="GUID-18D7BC87-81E7-54D0-A4E0-E4BDAB172FD8" xml:space="preserve">CSession2</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>Replace <codeph>CSession</codeph> with <codeph>CSession2</codeph>. </p> <p>The+ −
changes applicable to <codeph>CSharableSession</codeph> derived classes also+ −
apply to <codeph>CSession</codeph> derived classes. See: </p> <ul>+ −
<li id="GUID-5C5C37DF-5D39-571C-8998-43A3ECB48DA2"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-1616B87E-A4C3-509B-AF79-D4A964032BF1">CSharableSession::CreateL()</xref> </p> </li>+ −
<li id="GUID-F40EFC23-D7A3-5814-8660-DEE9E9CE7762"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-868E4703-DD82-5145-809D-91908237266C">CSharableSession::ResourceCountMarkEnd()</xref> </p> </li>+ −
<li id="GUID-74ED0DB9-10A1-5616-9CFE-3FE2A37F1905"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-54BF8797-7AE5-57E0-B5FD-C36C45D8CFFB">CSharableSession::RMessage()</xref> </p> </li>+ −
</ul> <p>In addition, if you use the following <codeph>CSession</codeph> functions,+ −
then you will need to change your code to use the equivalent functions in+ −
the <codeph>RMessage2</codeph> and/or <codeph>RMessagePtr2</codeph> classes.+ −
See <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-07F7FFA6-D421-54E2-90F7-69F002702C46">Using+ −
RMessagePtr2</xref>. </p> <codeblock id="GUID-97AE07E6-AA05-59D2-9F6E-4D063C40BAD2" xml:space="preserve">void ReadL(const TAny* aPtr,TDes8& aDes) const;+ −
void ReadL(const TAny* aPtr,TDes8& aDes,TInt anOffset) const;+ −
void ReadL(const TAny* aPtr,TDes16& aDes) const;+ −
void ReadL(const TAny* aPtr,TDes16& aDes,TInt anOffset) const;+ −
void WriteL(const TAny* aPtr,const TDesC8& aDes) const;+ −
void WriteL(const TAny* aPtr,const TDesC8& aDes,TInt anOffset) const;+ −
void WriteL(const TAny* aPtr,const TDesC16& aDes) const;+ −
void WriteL(const TAny* aPtr,const TDesC16& aDes,TInt anOffset) const;+ −
void Panic(const TDesC& aCategory,TInt aReason) const;+ −
void Kill(TInt aReason) const;+ −
void Terminate(TInt aReason) const;</codeblock> <p id="GUID-F0C1B0F6-BF72-5A52-84D1-E7E748D3E1A5"><b>CSession::CSession()</b> </p> <table id="GUID-8EE0CBE3-B5C4-54A4-9027-0DD37C00EDBD">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 function: </p> </entry>+ −
<entry><codeblock id="GUID-E445EA4B-C26A-5F19-BD11-8C420C005C9E" xml:space="preserve">CSession::CSession(RThread aClient)</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><p>No equivalent constructor. </p> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>The Version 1 <codeph>CSession</codeph> object stores a handle+ −
for the client thread. This should no longer be required after moving over+ −
to Version 2, and indeed, a constructor taking a thread handle as an argument+ −
is not supplied. </p> <p id="GUID-F2BB351E-73DA-522A-96ED-361F2EB1A379"><b>RMessage</b> </p> <table id="GUID-AE303124-F8E6-5814-ABF3-86CE010AEB0D">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 class: </p> </entry>+ −
<entry><codeblock id="GUID-97B0E175-06DD-56D5-B72D-F248AA327E28" xml:space="preserve">RMessage</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 class: </p> </entry>+ −
<entry><codeblock id="GUID-F4DEABFB-9B23-5CA1-B8B4-2A83FA36F787" xml:space="preserve">RMessage2</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>Replace <codeph>RMessage</codeph> with <codeph>RMessage2</codeph>. </p> <p>Note+ −
that <codeph>RMessage2</codeph> derives from <codeph>RMessagePtr2</codeph> and+ −
that most of the functions that were members of the Version 1 class <codeph>RMessage</codeph> are+ −
now implemented in the Version 2 class <codeph>RMessagePtr2</codeph>. </p> <p id="GUID-B0431DFE-C0E5-5767-A299-564EC502B01E"><b>RMessage::Client()</b> </p> <table id="GUID-D8B43D00-689F-5A63-B2D8-89D74E2D5ACE">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 function: </p> </entry>+ −
<entry><codeblock id="GUID-2E080CC6-801E-5E91-9146-BE08338C7F2E" xml:space="preserve">const RThread& RMessage::Client() const</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><codeblock id="GUID-6FC3BD1F-11BC-5309-AFE3-EC3043B162E6" xml:space="preserve">TInt RMessage2::Client(RThread& aClient, TOwnerType aOwnerType=EOwnerProcess) const</codeblock> <p>(Note that the function is implemented by the <codeph>RMessagePtr2</codeph> base+ −
class.) </p> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>In Version 1, the kernel maintains a handle to the client thread+ −
which can be extracted from a message by calling <codeph>RMessage::Client()</codeph>. </p> <p>In+ −
Version 2, this special handle is not present; instead, a function is provided+ −
that explicitly opens a handle on the client thread. This should be treated+ −
just like any other thread handle, i.e. <codeph>Close()</codeph> should be+ −
called on the handle when it is no longer needed. </p> <p>Here's an example+ −
of its usage: </p> <codeblock id="GUID-60EB6ACF-4A2D-5EEA-9008-265DDEF3E332" xml:space="preserve">void CMySession::ServiceL(const RMessage2& aMessage)+ −
{+ −
...+ −
RThread clientThread;+ −
// Open a handle on the client thread. Leaving if there is an error.+ −
User::LeaveIfError(aMessage.Client(clientThread));+ −
// Do something with the handle. (Print its ID in this example)+ −
RDebug::Print(_L("Client Thread ID = %n"),clientThread.Id());+ −
// Close handle+ −
clientThread.Close();+ −
...+ −
}</codeblock> <p> <b>You need to carefully examine all uses of RMessage::Client(),+ −
as most servers should not need to use this function after migrating to the+ −
Version 2 APIs. This is because the use of thread handles in a Version 1 server+ −
is likely to involve those functions that have been removed from the Version+ −
2 APIs.</b> See <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-A94A9960-319C-51B5-B693-2538D3985004">RThread</xref> for+ −
more information. </p> <p id="GUID-4EEFEF47-D875-5C16-8836-98DD03C0A91D"><b>RMessage::MessagePtr()</b> </p> <table id="GUID-C4466017-A740-505D-BFF2-90CCE1014878">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 function: </p> </entry>+ −
<entry><codeblock id="GUID-D771DA22-E50F-532E-AE35-16FCFD1194B9" xml:space="preserve">const RMessagePtr RMessage::MessagePtr() const</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><p>No equivalent function. </p> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p> <codeph>RMessage2</codeph> derives from <codeph>RMessagePtr2</codeph>,+ −
therefore an <codeph>RMessagePtr2</codeph> can be simply constructed or assigned+ −
directly from an <codeph>RMessage2</codeph>. There is no need for an explicit+ −
method of construction as was the case in the Version 1 APIs. </p> <p id="GUID-8754F52F-371C-546B-9290-B5369E915318"><b>RMessage::descriptor access+ −
methods</b> </p> <table id="GUID-E584453B-6BC7-56C1-9FDB-E531A3BC0A8C">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 functions: </p> </entry>+ −
<entry><codeblock id="GUID-9C3A91D8-FABE-5D70-91F0-0103FAD39E63" xml:space="preserve">void RMessage::ReadL(const TAny* aPtr,TDes8& aDes) const;+ −
void RMessage::ReadL(const TAny* aPtr,TDes8& aDes,TInt anOffset) const;+ −
void RMessage::ReadL(const TAny* aPtr,TDes16& aDes) const;+ −
void RMessage::ReadL(const TAny* aPtr,TDes16& aDes,TInt anOffset) const;+ −
void RMessage::WriteL(const TAny* aPtr,const TDesC8& aDes) const;+ −
void RMessage::WriteL(const TAny* aPtr,const TDesC8& aDes,TInt anOffset) const;+ −
void RMessage::WriteL(const TAny* aPtr,const TDesC16& aDes) const;+ −
void RMessage::WriteL(const TAny* aPtr,const TDesC16& aDes,TInt anOffset) const;</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 functions: </p> </entry>+ −
<entry><p>These functions are replaced by functions that take a message argument+ −
index instead of a <codeph>TAny*</codeph>. See <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-07F7FFA6-D421-54E2-90F7-69F002702C46">Using+ −
RMessagePtr2</xref>. </p> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p id="GUID-49869449-4440-5D20-97ED-32C14C5D1DAF"><b>RMessagePtr</b> </p> <table id="GUID-D7F81784-48AD-5896-8DFF-F71CCE379E1D">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 class: </p> </entry>+ −
<entry><codeblock id="GUID-BF9BEDE9-DB54-5CEB-B66E-4ACA8D97AA92" xml:space="preserve">RMessagePtr</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 class: </p> </entry>+ −
<entry><codeblock id="GUID-AD8BAE63-C125-5912-8B97-FAEE0F41CB58" xml:space="preserve">RMessagePtr2</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>Replace <codeph>RMessagePtr</codeph> with <codeph>RMessagePtr2</codeph>. </p> <p>See <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-07F7FFA6-D421-54E2-90F7-69F002702C46">Using+ −
RMessagePtr2</xref>. </p> <p id="GUID-A94A9960-319C-51B5-B693-2538D3985004"><b>RThread</b> </p> <p>Calls+ −
to the following functions need to be changed to use the equivalent functions+ −
in a <codeph>RMessage2</codeph> /<codeph>RMessagePtr2</codeph> class. See <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-07F7FFA6-D421-54E2-90F7-69F002702C46">Using+ −
RMessagePtr2</xref>. </p> <codeblock id="GUID-589B9378-3AF1-5AFF-99A1-ADF44D7AB575" xml:space="preserve">TInt RThread::GetDesLength(const TAny* aPtr) const+ −
TInt RThread::GetDesMaxLength(const TAny* aPtr)+ −
void RThread::ReadL(const TAny* aPtr,TDes8& aDes,TInt anOffset) const+ −
void RThread::ReadL(const TAny* aPtr,TDes16 &aDes,TInt anOffset) const+ −
void RThread::WriteL(const TAny* aPtr,const TDesC8& aDes,TInt anOffset) const+ −
void RThread::WriteL(const TAny* aPtr,const TDesC16& aDes,TInt anOffset) const+ −
void RThread::Kill(TInt aReason)+ −
void RThread::Terminate(TInt aReason)+ −
void RThread::Panic(const TDesC& aCategory,TInt aReason)</codeblock> <p id="GUID-9DA5C542-44B6-5277-837D-1D9150F43B10"><b>RThread::RequestComplete()</b> </p> <table id="GUID-CB602E73-0C6F-51DC-88BB-CC2D334008DD">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p>Version 1 function: </p> </entry>+ −
<entry><codeblock id="GUID-0338C808-E3B3-567E-95AE-EA577E286A7B" xml:space="preserve">void RThread::RequestComplete(TRequestStatus*& aStatus,TInt aReason) const</codeblock> </entry>+ −
</row>+ −
<row>+ −
<entry><p>Version 2 function: </p> </entry>+ −
<entry><codeblock id="GUID-6201C836-1533-5252-B68A-2AEE7CFA59D9" xml:space="preserve">void RMessagePtr2::Complete(TInt aReason) const</codeblock> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> <p>With the Version 2 APIs, the only way of signalling a client's+ −
request status in a different process is by completing a message sent by the+ −
client to the session. This means that a call to <codeph>RThread::RequestComplete()</codeph> should+ −
be replaced by a call to <codeph>RMessagePtr2::Complete()</codeph>. This requires+ −
some minor changes to the internal architecture of the server. </p> <p>An+ −
example of a call to <codeph>RThread::RequestComplete()</codeph> is where+ −
a server implements a kind of notification service, where a client asks to+ −
be signalled when some event or change of state occurs. </p> <p><b>A+ −
version 1 server implementation</b> </p> <p>In a Version 1 server implementation,+ −
the notification scheme is often implemented with code similar to this: </p> <p>Client+ −
function: </p> <codeblock id="GUID-97208CAC-12F1-5871-A7FE-C9CD465B2C5E" xml:space="preserve">TInt RMySession::NotifyChanges(TRequestStatus& aStatus)+ −
{+ −
TAny* args[KMaxMessageArguments];+ −
args[0]=&aStatus;+ −
return SendReceive(ERequestNotifyChanges, &args[0]);+ −
}</codeblock> <p>The server processes the request like this: </p> <codeblock id="GUID-34777BB5-E58B-5EA2-BF62-6CF96CBECA94" xml:space="preserve">void CMySession::ServiceL(const RMessage& aMessage)+ −
{+ −
...+ −
// Get arguments needed to signal client+ −
RThread clientThread = aMessage.Client();+ −
TRequestStatus* clientStatus = (TRequestStatus*)aMessage.Ptr0();+ −
// Make notify object+ −
TMyNotifyChanges notifyObject(clientThread,clientStatus);+ −
// Add notify object to list of all requests+ −
TInt result=AddNotification(notifyObject);+ −
// Complete request message+ −
aMessage.Complete(result);+ −
...+ −
}</codeblock> <p>When the event happens, clients are notified: </p> <codeblock id="GUID-E45B2795-EA7D-51EF-8892-0516E0BF53DB" xml:space="preserve">void CMySession::SignalNotifications(TInt aResult)+ −
{+ −
TMyNotifyChanges* notifyObject;+ −
while(notifyObject=RemoveNotifyObject())+ −
{+ −
// Complete each NotifyChanges object+ −
RThread clientThread = notifyObject->ClientThread();+ −
TRequestStatus* clientStatus = notifyObject->ClientStatus();+ −
clientThread.RequestComplete(clientStatus,aResult);+ −
}+ −
}</codeblock> <p><b>A+ −
version 2 server implementation</b> </p> <p>In a Version 2 server implementation,+ −
the notification scheme could be implemented using the Version 2 APIs like+ −
this: </p> <p>Client function: </p> <codeblock id="GUID-0FC0A82A-1C12-5455-BD31-1439C1BC89E2" xml:space="preserve">void RMySession::NotifyChanges(TRequestStatus& aStatus)+ −
{+ −
TIpcArgs args(); // No arguments+ −
// Use asynchronous SendReceive for request+ −
SendReceive(ERequestNotifyChanges, args, aStatus);+ −
// void return type because errors will be signalled through aStatus+ −
}</codeblock> <p>The server processes the request like this: </p> <codeblock id="GUID-A27E21CB-C83E-5FA5-B06C-C7326B219314" xml:space="preserve">void CMySession::ServiceL(const RMessage2& aMessage)+ −
{+ −
...+ −
RMessagePtr2 messagePtr = aMessage;+ −
// Make notify object+ −
TMyNotifyChanges notifyObject(messagePtr);+ −
// Add notify object to list of all requests+ −
TInt result=AddNotification(notifyObject);+ −
// Complete request message (only if error)+ −
if(result!=KErrNone)+ −
{+ −
aMessage.Complete(result);+ −
}+ −
...+ −
}</codeblock> <p>When the event happens, clients will be notified: </p> <codeblock id="GUID-3CFBE6E0-226F-5893-BB8B-978D739A2379" xml:space="preserve">void CMySession::SignalNotifications(TInt aResult)+ −
{+ −
TMyNotifyChanges* notifyObject;+ −
while(notifyObject=RemoveNotifyObject())+ −
{+ −
// Complete each NotifyChanges object+ −
RMessagePtr2 messagePtr = notifyObject->MessagePtr();+ −
messagePtr.Complete(aResult)+ −
}+ −
}</codeblock> </section>+ −
<section id="GUID-07F7FFA6-D421-54E2-90F7-69F002702C46"><title>Using RMessagePtr2</title> <p>In+ −
Version 2, a server's interaction with its clients is channelled through <codeph>RMessagePtr2</codeph>,+ −
from which <codeph>RMessage2</codeph> is derived. An <codeph>RMessagePtr2</codeph> object+ −
acts as a handle to the message that the client has sent. The details of the+ −
original message are maintained within the kernel so that it can enforce correct+ −
use of the <codeph>RMessagePtr2</codeph> functions. </p> <p>The <codeph>RThread</codeph> and <codeph>RSession</codeph> functions+ −
for accessing descriptors, panicking the client and completing requests are+ −
not available in Version 2. Instead, this functionality is provided by <codeph>RMessagePtr2</codeph>.+ −
Because of this, server implementations may need to have a reference to the+ −
message available in many places. This may be done by passing such references+ −
as arguments between functions or by storing a reference in the session object+ −
processing the request. </p> <ul>+ −
<li id="GUID-522FC7B3-A4BA-5507-9BD3-05CBAE0DDED8"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-5D18833F-55D6-50C1-94DB-569F5CA30ECB">Descriptor access functions</xref> </p> </li>+ −
<li id="GUID-D78F8B64-0E73-56EC-A40D-FC7E8FB1D722"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-4BCF7E62-3ACA-535C-B201-84E570F95DE1">RMessagePtr2::Complete()</xref> </p> </li>+ −
<li id="GUID-5DFDDBFB-41AE-5EBC-943A-528C1C42312F"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-460A24B8-6BA3-5059-BE3B-FF9287ACF965">RMessagePtr2::Kill()</xref> </p> </li>+ −
<li id="GUID-A21E615F-A19C-5673-A7A0-372309AC944F"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-FD417FCA-8EC2-568F-A848-1F5712828E7D">RMessagePtr2::Terminate()</xref> </p> </li>+ −
<li id="GUID-CC7E6514-B7C0-507D-902C-2FE3F8EE1D36"><p> <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-3005E91E-1930-5092-B89D-60772D5BD9CA">RMessagePtr2::Panic()</xref> </p> </li>+ −
</ul> <p id="GUID-5D18833F-55D6-50C1-94DB-569F5CA30ECB"><b>Descriptor access functions</b> </p> <codeblock id="GUID-959C66E7-9219-54F7-A104-374CCF8B9D5A" xml:space="preserve">TInt RMessagePtr2::GetDesLength(TInt aParam) const;+ −
TInt RMessagePtr2::GetDesMaxLength(TInt aParam) const;+ −
void RMessagePtr2::ReadL(TInt aParam,TDes8& aDes,TInt aOffset=0) const;+ −
void RMessagePtr2::ReadL(TInt aParam,TDes16 &aDes,TInt aOffset=0) const;+ −
void RMessagePtr2::WriteL(TInt aParam,const TDesC8& aDes,TInt aOffset=0) const;+ −
void RMessagePtr2::WriteL(TInt aParam,const TDesC16& aDes,TInt aOffset=0) const;+ −
TInt RMessagePtr2::Read(TInt aParam,TDes8& aDes,TInt aOffset=0) const;+ −
TInt RMessagePtr2::Read(TInt aParam,TDes16 &aDes,TInt aOffset=0) const;+ −
TInt RMessagePtr2::Write(TInt aParam,const TDesC8& aDes,TInt aOffset=0) const;+ −
TInt RMessagePtr2::Write(TInt aParam,const TDesC16& aDes,TInt aOffset=0) const</codeblock> <p>These+ −
are used in the same way as the equivalent <codeph>RThread</codeph> functions+ −
in the Version 1 APIs, except that instead of referring to the descriptor+ −
by an address in the client, the <codeph>aParam</codeph> argument is used.+ −
This is a value between 0 and 3 and indicates which of the four arguments+ −
in the original client message contains the pointer to the descriptor. </p> <p>For+ −
example, if a client sends a message using code like this </p> <codeblock id="GUID-CF62ABBF-824D-5E84-A39B-58068C85C38F" xml:space="preserve">TInt RMySession::Write(TDes8C& aDes, TInt aLength)+ −
{+ −
return SendReceive(ERequestWrite, TIpcArgs(&aDes, aLength) );+ −
}</codeblock> <p>then the server would access <codeph>aDes</codeph> using+ −
an <codeph>aParam</codeph> value of 0. </p> <codeblock id="GUID-B608F856-8443-58DC-BBAE-D3253E911EA5" xml:space="preserve">void CMySession::ServiceL(const RMessage2& aMessage)+ −
{+ −
...+ −
TInt length=aMessage.Int1(); // Get length from message param 1+ −
TPtr8 buffer=MyNewBufferL(length); // Make a new buffer for the data+ −
aMessage.ReadL(0,buffer); // Read data from client descriptor (param 0)+ −
...</codeblock> <p>Because <codeph>TIpcArgs</codeph> also stores type+ −
information about arguments, the kernel knows that argument 0 in the above+ −
message is an 8-bit constant descriptor. On Symbian platforms+ −
using the EKA2 kernel, this information is used to enforce correct usage of+ −
descriptor access methods; in this case, trying to write to <codeph>aDes</codeph>,+ −
or treating it as a 16-bit descriptor would fail with <codeph>KErrBadDescriptor</codeph>.+ −
(The latter case would have allowed access to data beyond the length of the+ −
8- bit descriptor. </p> <p>Note, both leaving and non-leaving versions of+ −
the <codeph>Read()</codeph> and <codeph>Write()</codeph> functions are provided.+ −
This allows the removal of some TRAP statements in code after migration to+ −
the Version 2 APIs. </p> <p id="GUID-4BCF7E62-3ACA-535C-B201-84E570F95DE1"><b>RMessagePtr2::Complete()</b> </p> <codeblock id="GUID-D0231B69-B33C-5EF5-89D3-0D332C840518" xml:space="preserve">void RMessagePtr2::Complete(TInt aReason) const;</codeblock> <p>This+ −
function signals completion of the client request, in the same way that <codeph>RMessage::Complete()</codeph> does+ −
in Version 1. After completion, the <codeph>iHandle</codeph> member is set+ −
to zero, and this means that <codeph>RMessagePtr2::Handle()</codeph> returns+ −
zero, and <codeph>RMessagePtr2::IsNull()</codeph> returns True. </p> <p>It+ −
is important to note that once a message has been completed, it cannot be+ −
used by the server, and any such attempt results in a KERN-EXEC 44 panic (Bad+ −
Message Handle). To avoid this situation, implementations may need to check <codeph>RMessagePtr2::IsNull()</codeph>,+ −
but be aware that any copies of the message made before completion will not+ −
have had their handles nulled. For this reason, it is best to avoid making+ −
copies of <codeph>RMessage2</codeph> or <codeph>RMessagePtr2</codeph> objects,+ −
this includes passing them as arguments to other functions 'by value'. Use+ −
references instead. </p> <p id="GUID-460A24B8-6BA3-5059-BE3B-FF9287ACF965"><b>RMessagePtr2::Kill()</b> </p> <codeblock id="GUID-E3A4E634-BCA5-5680-96F8-8D83429BB832" xml:space="preserve">void RMessagePtr2::Kill(TInt aReason) const;</codeblock> <p>This+ −
function is used in the same way as the equivalent <codeph>RMessage</codeph> or <codeph>RThread</codeph> functions+ −
in Version 1. Note that this function also performs the action of <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-4BCF7E62-3ACA-535C-B201-84E570F95DE1">RMessagePtr2::Complete()</xref>, so care must be taken that the message is+ −
not used again. </p> <p id="GUID-FD417FCA-8EC2-568F-A848-1F5712828E7D"><b>RMessagePtr2::Terminate()</b> </p> <codeblock id="GUID-69309A0B-36C9-5F5F-9C9B-DD0C318B35DB" xml:space="preserve">void RMessagePtr2::Terminate(TInt aReason) const;</codeblock> <p>This+ −
function is used in the same way as the equivalent <codeph>RMessage</codeph> or <codeph>RThread</codeph> functions+ −
in Version 1. Note that this function also performs the action of <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-4BCF7E62-3ACA-535C-B201-84E570F95DE1">RMessagePtr2::Complete()</xref>, so care must be taken that the message is+ −
not used again. </p> <p id="GUID-3005E91E-1930-5092-B89D-60772D5BD9CA"><b>RMessagePtr2::Panic()</b> </p> <codeblock id="GUID-F31F59D2-D286-57F6-A685-C255225B45C8" xml:space="preserve">void RMessagePtr2::Panic(const TDesC& aCategory,TInt aReason) const;</codeblock> <p>This+ −
function is used in the same way as the equivalent <codeph>RMessage</codeph> or <codeph>RThread</codeph> functions+ −
in Version 1. Note that this function also performs the action of <xref href="GUID-0A332D6E-E712-5186-8CD0-D5022FA54052.dita#GUID-0A332D6E-E712-5186-8CD0-D5022FA54052/GUID-4BCF7E62-3ACA-535C-B201-84E570F95DE1">RMessagePtr2::Complete()</xref>, so care must be taken that the message is+ −
not used again. </p> </section>+ −
<section id="GUID-1ABF5DC6-A957-5623-93AB-CD7631A36A33"><title>Migration quick+ −
reference</title> <p>This is a quick reference to show you which Version 2+ −
APIs you should use to replace the Version 1 APIs. </p> <table id="GUID-0DAF9004-8A70-5F88-899D-996CC96090CC">+ −
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>+ −
<tbody>+ −
<row>+ −
<entry><p> <b>Version 1 (where used)</b> </p> </entry>+ −
<entry><p> <b>Version 2 (replace with...)</b> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>CSharableSession</codeph> </p> </entry>+ −
<entry><p> <codeph>CSession2</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>CSession</codeph> </p> </entry>+ −
<entry><p> <codeph>CSession2</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>CServer</codeph> </p> </entry>+ −
<entry><p> <codeph>CServer2</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RMessagePtr</codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RMessage</codeph> </p> </entry>+ −
<entry><p> <codeph>RMessage2</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RServer</codeph> </p> </entry>+ −
<entry><p> <codeph>RServer2</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RThread::GetDesLength(const TAny* aPtr)</codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2::GetDesLength(TInt aParam)</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RThread::GetDesMaxLength(const TAny* aPtr)</codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2::GetDesMaxLength(TInt aParam)</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RThread::ReadL(const TAny* aPtr,TDes8& aDes,TInt + −
anOffset)</codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2::ReadL(TInt aParam,TDes8& aDes,TInt + −
aOffset=0)</codeph> </p> <p>Note: use of <codeph>RThread::ReadL()</codeph> enclosed+ −
in a TRAP statement can be replaced by the non-leaving <codeph>RMessagePtr2::Read()</codeph>. </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RThread::ReadL(const TAny* aPtr,TDes16& aDes,TInt + −
anOffset) </codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2::ReadL(TInt aParam,TDes16& aDes,TInt + −
aOffset=0)</codeph> </p> <p>Note: use of <codeph>RThread::ReadL()</codeph> enclosed+ −
in a TRAP statement can be replaced by the non-leaving <codeph>RMessagePtr2::Read()</codeph>. </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RThread::WriteL(const TAny* aPtr,const TDesC8& + −
aDes,TInt anOffset) </codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2::WriteL(TInt aParam,const TDesC8& + −
aDes,TInt aOffset=0)</codeph> </p> <p>Note: use of <codeph>RThread::WriteL()</codeph> enclosed+ −
in a TRAP statement can be replaced by the non-leaving <codeph>RMessagePtr2::Write()</codeph>. </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RThread::WriteL(const TAny* aPtr,const TDesC16& + −
aDes,TInt anOffset)</codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2::WriteL(TInt aParam,const TDesC16& + −
aDes,TInt aOffset=0)</codeph> </p> <p>Note: use of <codeph>RThread::WriteL()</codeph> enclosed+ −
in a TRAP statement can be replaced by the non-leaving <codeph>RMessagePtr2::Write()</codeph>. </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RThread::RequestComplete(TRequestStatus*& aStatus,TInt+ −
aReason)</codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2::Complete(TInt aReason)</codeph> </p> <p>Note:+ −
the only way of signalling the client thread is by completing a message which+ −
the client sent to the session. </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RThread::Kill(TInt aReason)</codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2::Kill(TInt aReason)</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RThread::Terminate(TInt aReason)</codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2::Terminate(TInt aReason)</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RThread::Panic(const TDesC& aCategory,TInt + −
aReason)</codeph> </p> </entry>+ −
<entry><p> <codeph>RMessagePtr2::Panic(const TDesC& aCategory,TInt + −
aReason)</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RSessionBase::Share()</codeph> </p> <p>or </p> <p> <codeph>RSessionBase::Share(EExplicitAttach)</codeph> </p> <p>or </p> <p> <codeph>RSessionBase::Share(EAutoAttach)</codeph> </p> </entry>+ −
<entry><p> <codeph>RSessionBase::ShareAuto()</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RSessionBase::Attach()</codeph> </p> </entry>+ −
<entry><p>Not required in Version 2. </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RSessionBase::Send(TInt aFunction,TAny* aPtr)</codeph> </p> </entry>+ −
<entry><p> <codeph>RSessionBase::Send(TInt aFunction,const TIpcArgs& + −
aArgs)</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RSessionBase::SendReceive(TInt aFunction,TAny* + −
aPtr,TRequestStatus& aStatus)</codeph> </p> </entry>+ −
<entry><p> <codeph>RSessionBase::SendReceive(TInt aFunction,const + −
TIpcArgs& aArgs, TRequestStatus& aStatus)</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RSessionBase::SendReceive(TInt aFunction,TAny* aPtr)</codeph> </p> </entry>+ −
<entry><p> <codeph>RSessionBase::SendReceive(TInt aFunction, const + −
TIpcArgs& aArgs)</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RSubSessionBase::CreateSubSession(RSessionBase& + −
aSession,TInt aFunction,const TAny* aPtr)</codeph> </p> </entry>+ −
<entry><p> <codeph>RSubSessionBase::CreateSubSession(RSessionBase, TInt + −
aFunction, const TIpcArgs& aArgs);</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RSubSessionBase::Send(TInt aFunction,const TAny* + −
aPtr)</codeph> </p> </entry>+ −
<entry><p> <codeph>RSubSessionBase::Send(TInt aFunction,const TIpcArgs&+ −
aArgs)</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RSubSessionBase::SendReceive(TInt aFunction,const TAny*+ −
aPtr,TRequestStatus&)</codeph> </p> </entry>+ −
<entry><p> <codeph>RSubSessionBase::SendReceive(TInt aFunction,const + −
TIpcArgs& aArgs, TRequestStatus&)</codeph> </p> </entry>+ −
</row>+ −
<row>+ −
<entry><p> <codeph>RSubSessionBase::SendReceive(TInt aFunction,const TAny*+ −
aPtr)</codeph> </p> </entry>+ −
<entry><p> <codeph>RSubSessionBase::SendReceive(TInt aFunction,const + −
TIpcArgs& aArgs)</codeph> </p> </entry>+ −
</row>+ −
</tbody>+ −
</tgroup>+ −
</table> </section>+ −
</conbody></concept>+ −