os/kernelhwsrv/kernel/eka/euser/us_ksvr.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\euser\us_ksvr.cpp
    15 // 
    16 //
    17 
    18 #include "us_std.h"
    19 #include "us_data.h"
    20 #include <e32svr.h>
    21 #include <e32uid.h>
    22 #include <e32ldr.h>	
    23 
    24 //#define __DEBUG_IMAGE__ 1
    25 #if defined(__DEBUG_IMAGE__) && defined (__EPOC32__)
    26 #define __IF_DEBUG(t) {RDebug::t;}
    27 #else
    28 #define __IF_DEBUG(t)
    29 #endif
    30 
    31 //
    32 // class RNotifier
    33 //
    34 
    35 /**
    36 Requests the extended notifier server to start the notifier identified by
    37 the specified UID.
    38 
    39 The request is synchronous; the call returns when the request is complete.
    40 
    41 The notifier may not be started immediately if a higher priority notifier is
    42 already active. In this case, the notifier is queued until it has the highest
    43 priority outstanding request for the channel(s) it operates on.
    44 
    45 @param aNotifierUid The UID identifying the notifier.
    46 @param aBuffer      Data that can be passed to the notifier; the format and meaning
    47                     of this depends on the notifier.
    48 
    49 @return KErrNone, if successful;
    50         KErrNotFound, if there is no notifier matching the specified UID;
    51         KErrAlreadyExists, if the notifier has already been started, or has
    52         an outstanding start request. It may also return with one of the other
    53         system-wide error codes, if the notifier cannot be started by
    54         the server due to low memory or it leaves from its server side
    55         call to StartL().
    56         
    57 @see CServer
    58 */
    59 EXPORT_C TInt RNotifier::StartNotifier(TUid aNotifierUid, const TDesC8& aBuffer)
    60 	{
    61 	return SendReceive(EStartNotifier, TIpcArgs(
    62 										(TInt)aNotifierUid.iUid,
    63 										&aBuffer,
    64 										(TAny*)NULL // No resonse required
    65 										));
    66 	}
    67 
    68 
    69 
    70 
    71 /**
    72 Requests the extended notifier server to start the notifier identified by
    73 the specified UID.
    74 
    75 The request is synchronous; the call returns when the request is complete.
    76 
    77 The notifier may not start immediately if a higher priority notifier is
    78 already active. In this case, the notifier is queued until it has the highest
    79 priority outstanding request for the channel(s) it operates on.
    80 This can also cause unexpected behaviour: the function can return
    81 before the notifier has been started with the added consequence that no response
    82 data is written.
    83 
    84 For this reason, this function has been deprecated. Instead, use
    85 RNotifier::StartNotifierAndGetResponse(), or if there is no need to wait for a
    86 response, use the two argument overload of RNotifier::StartNotifier().
    87 
    88 @param aNotifierUid The UID identifying the notifier.
    89 @param aBuffer      Data that can be passed to the notifier; the format and meaning
    90                     of this depends on the notifier.
    91 @param aResponse    Response data; the format
    92                     and meaning of this depends on the notifier.
    93 
    94 @return KErrNone, if successful;
    95         KErrNotFound, if there is no notifier matching the specified UID;
    96         KErrAlreadyExists, if the notifier has already been started, or has
    97         an outstanding start request. It may also return with one of the other
    98         system-wide error codes, if the notifier cannot be started by
    99         the server due to low memory or it leaves from its server side
   100         call to StartL().
   101         
   102 @see CServer
   103 
   104 @deprecated use RNotifier::StartNotifierAndGetResponse(), or if there is no
   105             need to wait for a response, use the two argument overload
   106             of RNotifier::StartNotifier()
   107 */
   108 EXPORT_C TInt RNotifier::StartNotifier(TUid aNotifierUid, const TDesC8& aBuffer, TDes8& aResponse)
   109 	{
   110 	return SendReceive(EStartNotifier, TIpcArgs(
   111 										(TInt)aNotifierUid.iUid,
   112 										&aBuffer,
   113 										&aResponse
   114 										));
   115 	}
   116 
   117 /*
   118 This function has never been implemented on any Symbian OS version.
   119 It always returns KErrNotSupported.
   120 @publishedPartner
   121 @removed
   122 */
   123 EXPORT_C TInt RNotifier::StartNotifier(TUid aNotifierDllUid,TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
   124 	{
   125 	return SendReceive(EStartNotifierFromSpecifiedDll, TIpcArgs(
   126 										(TInt)aNotifierUid.iUid,
   127 										&aBuffer,
   128 										&aResponse,
   129 										(TInt)aNotifierDllUid.iUid
   130 										));
   131 	}
   132 
   133 /**
   134 Requests the extended notifier server to cancel the notifier identified by
   135 the specified UID.
   136 
   137 The request is synchronous; the call returns when the request is complete.
   138 
   139 Any notifier that was queued pending the completion of aNotifierUid will be
   140 automatically started.
   141 
   142 @param  aNotifierUid The UID identifying the notifier.
   143 
   144 @return KErrNone, if successful;
   145         KErrNotFound, if there is no notifier matching the specified UID.
   146 */
   147 EXPORT_C TInt RNotifier::CancelNotifier(TUid aNotifierUid)
   148 	{
   149 	return SendReceive(ECancelNotifier, TIpcArgs( (TInt)aNotifierUid.iUid ));
   150 	}
   151 
   152 /**
   153 Requests the extended notifier server to update the active notifier identified by
   154 the specified UID.
   155 
   156 The request is synchronous; the call returns when the request is complete.
   157 
   158 @param aNotifierUid The UID identifying the notifier.
   159 @param aBuffer      Data that can be passed to the notifier; the format and meaning
   160                     of this depends on the notifier.
   161 @param aResponse    Reserved for future use.
   162 
   163 @return KErrNone, if successful;
   164         KErrNotFound, if there is no notifier matching the specified UID.
   165 */
   166 EXPORT_C TInt RNotifier::UpdateNotifier(TUid aNotifierUid, const TDesC8& aBuffer,TDes8& aResponse)
   167 	{
   168 	return SendReceive(EUpdateNotifier, TIpcArgs(
   169 										(TInt)aNotifierUid.iUid,
   170 										&aBuffer,
   171 										&aResponse
   172 										));
   173 	}
   174 
   175 /**
   176 Requests the extended notifier server to update the active notifier identified by
   177 the specified UID.
   178 
   179 This is an asynchronous request.It may be called multiple times for
   180 some notifier implementations; see specific notifier documentation for exact details.
   181 
   182 @param aRs          The request status. On request completion, contains:
   183                     KErrNone, if successful; otherwise, one of the other system
   184                     wide error codes.
   185 @param aNotifierUid The UID identifying the notifier.
   186 @param aBuffer      Data that can be passed to the notifier; the format and meaning
   187                     of this depends on the notifier.
   188 @param aResponse    Reserved for future use.
   189 
   190 */
   191 EXPORT_C void RNotifier::UpdateNotifierAndGetResponse(TRequestStatus& aRs, TUid aNotifierUid, const TDesC8& aBuffer, TDes8& aResponse)
   192 	{
   193 	SendReceive(EUpdateNotifierAndGetResponse, TIpcArgs(
   194 										(TInt)aNotifierUid.iUid,
   195 										&aBuffer,
   196 										&aResponse
   197 										), aRs);
   198 	}
   199 	
   200 /**
   201 Requests the extended notifier server to start the notifier identified by
   202 the specified UID.
   203 
   204 This is an asynchronous request.It may be called multiple times for
   205 some notifier implementations; see specific notifier documentation for exact details.
   206 
   207 @param aRs          The request status. On request completion, contains:
   208                     KErrNone, if successful; otherwise, one of the other system
   209                     wide error codes.
   210 @param aNotifierUid The UID identifying the notifier.
   211 @param aBuffer      Data that can be passed to the notifier; the format
   212                     and meaning of this depends on the notifier.
   213 @param aResponse    Response data; the format
   214                     and meaning of this depends on the notifier.
   215 */
   216 EXPORT_C void RNotifier::StartNotifierAndGetResponse(TRequestStatus& aRs,TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
   217 	{
   218 	SendReceive(EStartNotifierAndGetResponse, TIpcArgs(
   219 										(TInt)aNotifierUid.iUid,
   220 										&aBuffer,
   221 										&aResponse
   222 										), aRs);
   223 	}
   224 
   225 
   226 
   227 
   228 /**
   229 @publishedPartner
   230 @removed
   231 
   232 This function has never been implemented on any Symbian OS version.
   233 The request always completes with KErrNotSupported.
   234 */
   235 EXPORT_C void RNotifier::StartNotifierAndGetResponse(TRequestStatus& aRs,TUid aNotifierDllUid,TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
   236 	{
   237 	SendReceive(EStartNotifierFromSpecifiedDllAndGetResponse, TIpcArgs(
   238 										(TInt)aNotifierUid.iUid,
   239 										&aBuffer,
   240 										&aResponse,
   241 										(TInt)aNotifierDllUid.iUid
   242 										), aRs);
   243 	}
   244 
   245 
   246 
   247 
   248 /**
   249 @publishedPartner
   250 @removed
   251 
   252 This function has never been implemented on any Symbian OS version.
   253 It always returns KErrNotSupported.
   254 */
   255 EXPORT_C TInt RNotifier::UnloadNotifiers(TUid /*aNotifierUid*/)
   256 	{
   257 	return KErrNotSupported;
   258 	}
   259 
   260 
   261 
   262 
   263 /**
   264 @publishedPartner
   265 @removed
   266 
   267 This function has never been implemented on any Symbian OS version.
   268 It always returns KErrNotSupported.
   269 */
   270 EXPORT_C TInt RNotifier::LoadNotifiers(TUid /*aNotifierUid*/)
   271 	{
   272 	return KErrNotSupported;
   273 	}
   274 
   275 
   276 
   277 
   278 /**
   279 Default constructor.
   280 */		
   281 EXPORT_C RNotifier::RNotifier()
   282 	:	iButtonVal(NULL,0),
   283 		iCombinedBuffer(NULL)
   284 	{}
   285 
   286 
   287 
   288 
   289 /**
   290 Connects to the extended notifier server, creating a session with that server.
   291 Note: Notifier server is started during window server start-up sequence.
   292 
   293 The function must be called before any other function.
   294 
   295 @return KErrNone, if successful, otherwise one of the other system-wide error codes 
   296 */
   297 EXPORT_C TInt RNotifier::Connect()
   298 	{
   299 	return CreateSession(__NOTIFIER_NAME,TVersion(KNotifierMajorVersionNumber,KNotifierMinorVersionNumber,KNotifierBuildVersionNumber),-1);
   300 	}
   301 
   302 
   303 
   304 
   305 /**
   306 Launches a simple two line dialog that displays two lines of text.
   307 
   308 This is an asynchronous request that completes when the dialog exits.
   309 
   310 @param aLine1     A descriptor containing the first line of text to be displayed.
   311 @param aLine2     A descriptor containing the second line of text to be displayed.
   312 @param aBut1      A descriptor containing text to be displayed in the first button.
   313 @param aBut2      A descriptor containing text to be displayed in the (optional) second button.
   314 @param aButtonVal An integer value which is set when the dialog exits. It is set to:
   315                   0, if the first button is selected;
   316                   1, if the second button is selected.
   317 @param aStatus    The request status object. If the request completes normally, this is set to KErrNone.
   318 */
   319 EXPORT_C void RNotifier::Notify(const TDesC& aLine1,const TDesC& aLine2,const TDesC& aBut1,const TDesC& aBut2, TInt& aButtonVal, TRequestStatus& aStatus)
   320 	{
   321 	const TInt requiredLengthOfCombinedBuffer=aLine1.Length()+aLine2.Length()+aBut1.Length()+aBut2.Length();
   322 	if ((iCombinedBuffer!=NULL) && (iCombinedBuffer->Des().MaxLength()<requiredLengthOfCombinedBuffer))
   323 		{
   324 		delete iCombinedBuffer;
   325 		iCombinedBuffer=NULL;
   326 		}
   327 	if (iCombinedBuffer==NULL)
   328 		{
   329 		iCombinedBuffer=HBufC::New(requiredLengthOfCombinedBuffer);
   330 		}
   331 	if (iCombinedBuffer==NULL)
   332 		{
   333 		// report the error back via the TRequestStatus
   334 		TRequestStatus* status=&aStatus;
   335 		User::RequestComplete(status,KErrNoMemory);
   336 		}
   337 	else
   338 		{
   339 		TPtr combinedBufferForNotify(iCombinedBuffer->Des());
   340 		combinedBufferForNotify = aLine1;
   341 		combinedBufferForNotify.Append(aLine2);
   342 		combinedBufferForNotify.Append(aBut1);
   343 		combinedBufferForNotify.Append(aBut2);
   344 		iButtonVal.Set(REINTERPRET_CAST(TUint8*,&aButtonVal),sizeof(TInt),sizeof(TInt));
   345 		__ASSERT_ALWAYS(((aLine1.Length()|aLine2.Length()|aBut1.Length()|aBut2.Length())&~KMaxTUint16)==0,Panic(ENotifierTextTooLong)); // check that all of the descriptor lengths are less than or equal to KMaxTUint16
   346 		SendReceive(ENotifierNotify,TIpcArgs(&iButtonVal,iCombinedBuffer,(aLine1.Length()<<16)|aLine2.Length(),(aBut1.Length()<<16)|aBut2.Length()),aStatus);
   347 		}
   348 	}
   349 
   350 
   351 
   352 
   353 /**
   354 Not implemented by the server.
   355 */
   356 EXPORT_C void RNotifier::NotifyCancel()
   357 	{
   358 	SendReceive(ENotifierNotifyCancel,TIpcArgs()); // ignores any returned error
   359 	}
   360 
   361 
   362 
   363 
   364 /**
   365 Closes the notifier.
   366 */
   367 EXPORT_C void RNotifier::Close()
   368 	{
   369 	delete iCombinedBuffer;
   370 	iCombinedBuffer=NULL;
   371 	RSessionBase::Close();
   372 	}
   373 
   374 
   375 
   376 
   377 /**
   378 @internalAll
   379 */
   380 EXPORT_C TInt RNotifier::InfoPrint(const TDesC& aDes)
   381 	{
   382 	return SendReceive(ENotifierInfoPrint, TIpcArgs(&aDes));
   383 	}
   384 
   385 
   386 //
   387 // Class TChunkCreateInfo
   388 //
   389 
   390 /**
   391 Default constructor. 
   392 
   393 This defaults the chunk to be created to be local, to have no attributes set
   394 and to use the default clear byte.
   395 
   396 A local chunk is private to the process creating it and is not 
   397 intended for access by other user processes.
   398 */
   399 EXPORT_C TChunkCreateInfo::TChunkCreateInfo() :
   400 	// Specifing individual initialisers for members instead of using memclear
   401 	// so that Coverity doesn't complain about uninitialised local variables in
   402 	// calls to e.g., TChunkCreateInfo::SetPaging().
   403 	iVersionNumber(0),
   404 	iType(TChunkCreate::ENormal),
   405     iGlobal(EFalse),
   406     iMaxSize(0),
   407     iOwnerType(EOwnerProcess),
   408     iName(NULL),
   409     iInitialBottom(0),
   410     iInitialTop(0),
   411     iAttributes(TChunkCreate::EPagingUnspec),
   412 	iClearByte(KChunkClearByteDefault)
   413 	{
   414 	}
   415 
   416 
   417 /**	
   418 Sets the chunk to be created to have a committed region that always starts at the 
   419 bottom of the reserved region.
   420 
   421 
   422 @param aSize    The number of bytes committed to this chunk.
   423 @param aMaxSize The maximum size to which the reserved region of this chunk 
   424                 can grow.
   425 @see RChunk::CreateLocal()
   426 */
   427 EXPORT_C void TChunkCreateInfo::SetNormal(TInt aInitialSize, TInt aMaxSize)
   428 	{
   429 	iType = TChunkCreate::ENormal | TChunkCreate::EData;
   430 	iInitialBottom = 0;
   431 	iInitialTop = aInitialSize;
   432 	iMaxSize = aMaxSize;
   433 	}
   434 
   435 
   436 /**
   437 Sets the chunk to be created to be user writable and to be marked by the kernel
   438 as containing code.
   439 This can only be set on local chunks.
   440 
   441 @param aInitialSize	The number of bytes committed to this chunk.
   442 @param aMaxSize 	The maximum size to which the reserved region of this chunk
   443                 	can grow.
   444 @see RChunk::CreateLocalCode()
   445 */
   446 EXPORT_C void TChunkCreateInfo::SetCode(TInt aInitialSize, TInt aMaxSize)
   447 	{
   448 	iType = TChunkCreate::ENormal | TChunkCreate::ECode;
   449 	iInitialBottom = 0;
   450 	iInitialTop = aInitialSize;
   451 	iMaxSize = aMaxSize;
   452 	}
   453 
   454 
   455 /**	
   456 Sets the chunk to be created to have a commited region that that can be any 
   457 contiguous subset of the reserved region.
   458 
   459 @param aInitialBottom The offset of the bottom of the new committed region 
   460                       from the base of the chunk's reserved region.
   461 @param aInitialTop    The offset of the top of the new committed region from
   462                       the  base of the chunk's reserved region. 
   463 @param aMaxSize       The maximum size to which the reserved region of
   464                       this chunk can grow.
   465 @see RChunk::CreateDoubleEndedLocal()
   466 */
   467 EXPORT_C void TChunkCreateInfo::SetDoubleEnded(TInt aInitialBottom, TInt aInitialTop, TInt aMaxSize)
   468 	{
   469 	iType = TChunkCreate::EDoubleEnded | TChunkCreate::EData;
   470 	iInitialBottom = aInitialBottom;
   471 	iInitialTop = aInitialTop;
   472 	iMaxSize = aMaxSize;
   473 	}
   474 
   475 /** 
   476 Set the chunk to be created to have a committed region consisting of an 
   477 arbitrary set of MMU pages within the reserved region.
   478 
   479 @param aInitialBottom 	The offset of the bottom of the new committed region 
   480                       	from the base of the chunk's reserved region.
   481 @param aInitialTop		The offset of the top of the new committed region 
   482 						from the  base of the chunk's reserved region. 
   483 @param aMaxSize       	The maximum size to which the reserved region of
   484                       	this chunk can grow.
   485 @see RChunk::CreateDisconnectedLocal()
   486 */
   487 EXPORT_C void TChunkCreateInfo::SetDisconnected(TInt aInitialBottom, TInt aInitialTop, TInt aMaxSize)
   488 	{
   489 	iType = TChunkCreate::EDisconnected | TChunkCreate::EData;
   490 	iInitialBottom = aInitialBottom;
   491 	iInitialTop = aInitialTop;
   492 	iMaxSize = aMaxSize;
   493 	}
   494 
   495 
   496 /**	
   497 Sets the chunk to be created to be a thread heap chunk.
   498 For internal use only.
   499 
   500 @param aInitialSize	The number of bytes committed to this chunk.
   501 @param aMaxSize 	The maximum size to which the reserved region of this chunk 
   502                 	can grow.
   503 @param aName		The name to be given to the chunk to be created
   504 @internalComponent
   505 */
   506 void TChunkCreateInfo::SetThreadHeap(TInt aInitialSize, TInt aMaxSize, const TDesC& aName)
   507 	{
   508 	iType = TChunkCreate::ENormal | TChunkCreate::EData;
   509 	iInitialBottom = 0;
   510 	iInitialTop = aInitialSize;
   511 	iMaxSize = aMaxSize;
   512 	iAttributes |= TChunkCreate::ELocalNamed;
   513 	iName = &aName;
   514 	iOwnerType = EOwnerThread;
   515 	}
   516 
   517 /** 
   518 Sets the owner of the chunk to be created.
   519 @param aType	The owner of the chunk to be created.
   520 */
   521 EXPORT_C void TChunkCreateInfo::SetOwner(TOwnerType aType)
   522 	{
   523 	iOwnerType = aType;
   524 	}
   525 
   526 /** 
   527 Sets the chunk to be created to be global, i.e. it is potentially visible
   528 to all processes and is intended for access by other user processes.
   529 
   530 @param aName          A reference to a descriptor containing the name to be
   531                       assigned to the global chunk. The length of
   532                       the descriptor must be no greater than that allowed for
   533                       a TKName type.
   534 */
   535 EXPORT_C void TChunkCreateInfo::SetGlobal(const TDesC& aName)
   536 	{
   537 	iName = &aName;
   538 	iGlobal = ETrue;
   539 	}
   540 
   541 /** 
   542 Sets the byte value that all memory committed to the chunk will be cleared to.
   543 @param TUint8 aClearByte.
   544 */
   545 EXPORT_C void TChunkCreateInfo::SetClearByte(TUint8 aClearByte)
   546 	{
   547 	iClearByte = aClearByte;
   548 	}
   549 
   550 
   551 /** 
   552 Sets the data paging attributes for the chunk to be created.  Any previous calls
   553 to this method will be overridden for this TChunkCreateInfo object.
   554 
   555 @param aPaging	The data paging attributes of the chunk to be created.
   556 
   557 @prototype
   558 */
   559 EXPORT_C void TChunkCreateInfo::SetPaging(const TChunkPagingAtt aPaging)
   560 	{
   561 	__ASSERT_COMPILE(TChunkCreate::EPagingUnspec == 0);
   562 	iAttributes &= ~TChunkCreate::EPagingMask;
   563 	if (aPaging == EPaged)
   564 		iAttributes |= TChunkCreate::EPaged;
   565 	if (aPaging == EUnpaged)
   566 		iAttributes |= TChunkCreate::EUnpaged;
   567 	}
   568 
   569 /**
   570 Sets the global chunk to be created to be read only. Only the creating process
   571 will be able to write to it, not other processes.
   572 
   573 Read-Only chunks are currently only available on the Flexible Memory Model.
   574 
   575 Chunk must be global.
   576 */
   577 EXPORT_C void TChunkCreateInfo::SetReadOnly()
   578 	{
   579 	iAttributes |= TChunkCreate::EReadOnly;
   580 	}
   581 
   582 
   583 EXPORT_C void TChunkCreateInfo::SetCache(TInt aMaxSize)
   584 	{
   585 	iType = TChunkCreate::ECache | TChunkCreate::EData;
   586 	iInitialBottom = 0;
   587 	iInitialTop = 0;
   588 	iMaxSize = aMaxSize;
   589 	SetPaging(EUnpaged);
   590 	}
   591 
   592 
   593 //
   594 // class RChunk
   595 //
   596 
   597 EXPORT_C TInt RChunk::CreateLocal(TInt aSize,TInt aMaxSize,TOwnerType aType)
   598 /**
   599 Creates a local chunk.
   600 
   601 The chunk is local to the process creating it; i.e. it is private to the process 
   602 creating it and is not intended for access by other user processes.
   603 
   604 aMaxSize specifies the maximum size of the chunk and aSize specifies the number 
   605 of bytes to be committed on creation of the chunk. Both values are rounded 
   606 up to the next nearest processor page boundary value if they are not already 
   607 on a processor page boundary.
   608 
   609 The committed region always starts at the bottom of the reserved region.
   610 
   611 By default, ownership of this chunk handle is vested in the current process. 
   612 Ownership of the chunk handle can be vested in the current thread by passing 
   613 EOwnerThread as the third parameter to this function. 
   614 
   615 @param aSize    The number of bytes committed to this chunk.
   616 @param aMaxSize The maximum size to which the reserved region of this chunk 
   617                 can grow.
   618 @param aType    An enumeration whose enumerators define the ownership of this 
   619                 chunk handle. If not explicitly specified, EOwnerProcess is
   620                 taken as default.
   621 
   622 @return KErrNone if successful, otherwise another of the system-wide error 
   623         codes.
   624 
   625 @panic USER 99  if aMaxSize is negative.
   626 @panic USER 100 if aSize is negative.
   627 @panic USER 101 if aSize is greater than or equal to the supplied
   628        value of aMaxSize.
   629 */
   630 	{
   631 	TChunkCreateInfo createInfo;
   632 	createInfo.SetNormal(aSize, aMaxSize);
   633 	createInfo.SetOwner(aType);
   634 	return Create(createInfo);
   635 	}
   636 
   637 
   638 
   639 
   640 EXPORT_C TInt RChunk::CreateLocalCode(TInt aSize,TInt aMaxSize,TOwnerType aType)
   641 /**
   642 Creates a user writable chunk that is marked by the kernel as containing code.
   643 
   644 The chunk is local to the process creating it, i.e. it is private to the process 
   645 creating it and is not intended for access by other user processes.
   646 
   647 On systems using a Harvard cache, this type of chunk removes the need to flush 
   648 the instruction cache (I-Cache) on a context switch. However, the instruction 
   649 Translation Look-aside Buffer (ITLB) still needs to be flushed when switching 
   650 to or from a process with one of these chunks in its address space.  Systems with
   651 a dynamic branch predictor may also need to flush their branch target buffer when
   652 switching from one process using this type of chunk to another.
   653 
   654 @param aSize    The number of bytes committed to this chunk.
   655 @param aMaxSize The maximum size to which the reserved region of this chunk 
   656                 can grow. 
   657 @param aType    An enumeration whose enumerators define the ownership of this 
   658                 chunk handle. If not explicitly specified, EOwnerProcess is
   659                 taken as default.
   660 
   661 @return KErrNone if successful, otherwise another of the system-wide error 
   662         codes.
   663 
   664 @panic USER 99  if aMaxSize is negative.
   665 @panic USER 100 if aSize is negative.
   666 @panic USER 101 if aSize is greater than or equal to the supplied
   667        value of aMaxSize.
   668 
   669 @see UserHeap::ChunkHeap
   670 @see User::IMB_Range
   671 */
   672 	{
   673 	TChunkCreateInfo createInfo;
   674 	createInfo.SetCode(aSize, aMaxSize);
   675 	createInfo.SetOwner(aType);
   676 	return Create(createInfo);
   677 	}
   678 
   679 
   680 
   681 
   682 EXPORT_C TInt RChunk::CreateGlobal(const TDesC &aName,TInt aSize,TInt aMaxSize,TOwnerType aType)
   683 /**
   684 Creates a global chunk.
   685 
   686 The chunk is global; i.e. it is potentially visible to all processes and is
   687 intended for access by other user processes.
   688 
   689 aMaxSize specifies the maximum size of the chunk and aSize specifies the number 
   690 of bytes to be committed on creation of the chunk. Both values are rounded 
   691 up to the next nearest processor page boundary value ,if they are not already 
   692 on a processor page boundary value.
   693 
   694 The committed region always starts at the bottom of the reserved region.
   695 
   696 The descriptor aName contains the name to be assigned to this global chunk. If
   697 this name is empty, the chunk will be anonymous. Anonymous chunks cannot be
   698 accessed by other processes unless the creator explicitly passes them a handle
   699 to the chunk - this can be used to transfer large amounts of data between
   700 processes in a secure fashion.
   701 
   702 By default, ownership of this chunk handle is vested in the current process. 
   703 Ownership of the chunk handle can be vested in the current thread by passing 
   704 EOwnerThread as the third parameter to this function.
   705 
   706 @param aName    A reference to a descriptor containing the name to be assigned 
   707                 to this global chunk. The length of the descriptor must be no
   708                 greater than that allowed for a TKName type.
   709 @param aSize    The number of bytes committed to this chunk.
   710 @param aMaxSize The maximum size to which the reserved region of this chunk 
   711                 can grow. 
   712 @param aType    An enumeration whose enumerators define the ownership of this 
   713                 chunk handle. If not explicitly specified, EOwnerProcess is taken
   714                 as default.
   715 
   716 @return KErrNone if successful, otherwise another of the system error codes.
   717 
   718 @panic USER 99  if aMaxSize is negative.
   719 @panic USER 100 if aSize is negative.
   720 @panic USER 101 if aSize is greater than or equal to the supplied
   721        value of aMaxSize.
   722 */
   723 	{
   724 	TChunkCreateInfo createInfo;
   725 	createInfo.SetNormal(aSize, aMaxSize);
   726 	createInfo.SetGlobal(aName);
   727 	createInfo.SetOwner(aType);
   728 	return Create(createInfo);
   729 	}
   730 
   731 
   732 
   733 
   734 EXPORT_C TInt RChunk::CreateDoubleEndedLocal(TInt aInitialBottom, TInt aInitialTop,TInt aMaxSize,TOwnerType aType)
   735 /**
   736 Creates a local, double ended, chunk.
   737 
   738 The chunk is local to the process creating it; i.e. it is private to
   739 the process creating it and is not intended for access by other
   740 user processes.
   741 
   742 The committed region of a double ended chunk can be any contiguous subset 
   743 of the reserved region.
   744 
   745 aMaxSize specifies the maximum size of the chunk.
   746 
   747 The difference between aInitialTop and aInitialBottom gives the number of 
   748 bytes to be committed, on creation of the chunk; aInitialBottom gives the 
   749 offset of the bottom of the committed region from the base of the chunk's 
   750 reserved region; aInitialTop gives the offset of the top of the committed 
   751 region from the base of the chunk's reserved region.
   752 
   753 Both aInitialBottom and aInitialTop are rounded up to the next nearest
   754 processor page boundary value, if they are not already on
   755 a processor page boundary value.
   756 
   757 By default, ownership of this chunk handle is vested in the current process. 
   758 Ownership of the chunk handle can be vested in the current thread by passing 
   759 EOwnerThread as the third parameter to this function.
   760 
   761 Note that:
   762 
   763 1. the lowest valid address in a double ended chunk is the sum of the base of 
   764    the chunk's reserved region plus the adjusted value of aInitialBottom
   765 
   766 2. the highest valid address in a double ended chunk is the the sum of the base 
   767    of the chunk's reserved region plus the adjusted value of aInitialTop - 1.
   768 
   769 @param aInitialBottom The offset of the bottom of the new committed region 
   770                       from the base of the chunk's reserved region.
   771 @param aInitialTop    The offset of the top of the new committed region from
   772                       the  base of the chunk's reserved region. 
   773 @param aMaxSize       The maximum size to which the reserved region of
   774                       this chunk can grow.
   775 @param aType          An enumeration whose enumerators define the ownership of
   776                       this chunk handle. If not explicitly specified,
   777                       EOwnerProcess is taken as default.
   778                       
   779 @return KErrNone if successful, otherwise another of the system error codes.
   780 
   781 @panic USER 99  if aMaxSize is negative.
   782 @panic USER 120 if aInitialBottom is negative.
   783 @panic USER 121 if aInitialTop is negative.
   784 @panic USER 122 if aInitialBottom is greater than the supplied value
   785        of aInitialTop.
   786 @panic USER 123 if aInitialTop is greater than the supplied value of aMaxSize.
   787 */
   788 	{
   789 	TChunkCreateInfo createInfo;
   790 	createInfo.SetDoubleEnded(aInitialBottom, aInitialTop, aMaxSize);
   791 	createInfo.SetOwner(aType);
   792 	return Create(createInfo);
   793 	}
   794 
   795 
   796 
   797 
   798 EXPORT_C TInt RChunk::CreateDoubleEndedGlobal(const TDesC &aName,TInt aInitialBottom,TInt aInitialTop,TInt aMaxSize,TOwnerType aType)
   799 /**
   800 Creates a global, double ended, chunk.
   801 
   802 The chunk is global; i.e. it is visible to all processes and is intended
   803 for access by other user processes.
   804 
   805 The committed region of a double ended chunk can be any contiguous subset 
   806 of the reserved region.
   807 
   808 aMaxSize specifies the maximum size of the chunk.
   809 
   810 The difference between aInitialTop and aInitialBottom gives the number of 
   811 bytes to be committed, on creation of the chunk; aInitialBottom gives the 
   812 offset of the bottom of the committed region from the base of the chunk's 
   813 reserved region; aInitialTop gives the offset of the top of the committed 
   814 region from the base of the chunk's reserved region.
   815 
   816 Both aInitialBottom and aInitialTop are rounded up to the next nearest
   817 processor page boundary value, if they are not already on a processor page
   818 boundary value.
   819 
   820 The descriptor aName contains the name to be assigned to this global chunk.
   821 
   822 By default, ownership of this chunk handle is vested in the current process. 
   823 Ownership of the chunk handle can be vested in the current thread by passing 
   824 EOwnerThread as the third parameter to this function. 
   825 
   826 Note that:
   827 
   828 1. the lowest valid address in a double ended chunk is the sum of the base of 
   829    the chunk's reserved region plus the adjusted value of aInitialBottom
   830 
   831 2. the highest valid address in a double ended chunk is the the sum of the base 
   832    of the chunk's reserved region plus the adjusted value of aInitialTop - 1.
   833 
   834 @param aName          A reference to a descriptor containing the name to be
   835                       assigned to this global chunk. The length of
   836                       the descriptor must be no greater than that allowed for
   837                       a TKName type.
   838 @param aInitialBottom The offset of the bottom of the new committed region 
   839                       from the base of the chunk's reserved region.
   840 @param aInitialTop    The offset of the top of the new committed region from
   841                       the base of the chunk's reserved region. 
   842 @param aMaxSize       The maximum size to which the reserved region of
   843                       this chunk can grow. 
   844 @param aType          An enumeration whose enumerators define the ownership of
   845                       this chunk handle. If not explicitly specified,
   846                       EOwnerProcess is taken as default.
   847 
   848 @return KErrNone if successful, otherwise another of the system error codes.
   849 
   850 @panic USER 99  if aMaxSize is negative.
   851 @panic USER 120 if aInitialBottom is negative.
   852 @panic USER 121 if aInitialTop is negative.
   853 @panic USER 122 if aInitialBottom is greater than the supplied value
   854        of aInitialTop.
   855 @panic USER 123 if aInitialTop is greater than the supplied value of aMaxSize.
   856 @panic USER 163 if aName is empty.
   857 */
   858 	{
   859 	TChunkCreateInfo createInfo;
   860 	createInfo.SetDoubleEnded(aInitialBottom, aInitialTop, aMaxSize);
   861 	createInfo.SetGlobal(aName);
   862 	createInfo.SetOwner(aType);
   863 	return Create(createInfo);
   864 	}
   865 
   866 
   867 
   868 
   869 EXPORT_C TInt RChunk::CreateDisconnectedLocal(TInt aInitialBottom, TInt aInitialTop,TInt aMaxSize,TOwnerType aType)
   870 /**
   871 Creates a local, disconnected chunk.
   872 
   873 The chunk is local to the process creating it; i.e. it is private to
   874 the process creating it and is not intended for access by other
   875 user processes.
   876 
   877 A disconnected chunk has a committed region consisting of an arbitrary set
   878 of MMU pages within the reserved region, i.e. each page-sized address range
   879 within the reserved region which begins on a page boundary may be committed
   880 independently.
   881 
   882 aMaxSize specifies the maximum size of the chunk.
   883 
   884 The difference between aInitialTop and aInitialBottom gives the number of 
   885 bytes to be committed, on creation of the chunk; aInitialBottom gives the 
   886 offset of the bottom of the committed region from the base of the chunk's 
   887 reserved region; aInitialTop gives the offset of the top of the committed 
   888 region from the base of the chunk's reserved region.
   889 
   890 Both aInitialBottom and aInitialTop are rounded up to the next nearest
   891 processor page boundary value, if they are not already on
   892 a processor page boundary value.
   893 
   894 By default, ownership of this chunk handle is vested in the current process. 
   895 Ownership of the chunk handle can be vested in the current thread by passing 
   896 EOwnerThread as the third parameter to this function.
   897 
   898 @param aInitialBottom The offset of the bottom of the new committed region 
   899                       from the base of the chunk's reserved region.
   900 @param aInitialTop    The offset of the top of the new committed region from
   901                       the  base of the chunk's reserved region. 
   902 @param aMaxSize       The maximum size to which the reserved region of
   903                       this chunk can grow.
   904 @param aType          An enumeration whose enumerators define the ownership of
   905                       this chunk handle. If not explicitly specified,
   906                       EOwnerProcess is taken as default.
   907                       
   908 @return KErrNone if successful, otherwise another of the system error codes.
   909 
   910 @panic USER 99  if aMaxSize is negative.
   911 @panic USER 120 if aInitialBottom is negative.
   912 @panic USER 121 if aInitialTop is negative.
   913 @panic USER 122 if aInitialBottom is greater than the supplied value
   914        of aInitialTop.
   915 @panic USER 123 if aInitialTop is greater than the supplied value of aMaxSize.
   916 */
   917 	{
   918 	TChunkCreateInfo createInfo;
   919 	createInfo.SetDisconnected(aInitialBottom, aInitialTop, aMaxSize);
   920 	createInfo.SetOwner(aType);
   921 	return Create(createInfo);
   922 	}
   923 
   924 
   925 
   926 
   927 EXPORT_C TInt RChunk::CreateDisconnectedGlobal(const TDesC &aName,TInt aInitialBottom,TInt aInitialTop,TInt aMaxSize,TOwnerType aType)
   928 /**
   929 Creates a global, disconnected, chunk.
   930 
   931 The chunk is global; i.e. it is visible to all processes and is intended
   932 for access by other user processes.
   933 
   934 A disconnected chunk has a committed region consisting of an arbitrary set
   935 of MMU pages within the reserved region, i.e. each page-sized address range
   936 within the reserved region which begins on a page boundary may be committed
   937 independently.
   938 
   939 aMaxSize specifies the maximum size of the chunk.
   940 
   941 The difference between aInitialTop and aInitialBottom gives the number of 
   942 bytes to be committed, on creation of the chunk; aInitialBottom gives the 
   943 offset of the bottom of the committed region from the base of the chunk's 
   944 reserved region; aInitialTop gives the offset of the top of the committed 
   945 region from the base of the chunk's reserved region.
   946 
   947 Both aInitialBottom and aInitialTop are rounded up to the next nearest
   948 processor page boundary value, if they are not already on a processor page
   949 boundary value.
   950 
   951 The descriptor aName contains the name to be assigned to this global chunk.
   952 
   953 By default, ownership of this chunk handle is vested in the current process. 
   954 Ownership of the chunk handle can be vested in the current thread by passing 
   955 EOwnerThread as the third parameter to this function. 
   956 
   957 @param aName          A reference to a descriptor containing the name to be
   958                       assigned to this global chunk. The length of
   959                       the descriptor must be no greater than that allowed for
   960                       a TKName type.
   961 @param aInitialBottom The offset of the bottom of the new committed region 
   962                       from the base of the chunk's reserved region.
   963 @param aInitialTop    The offset of the top of the new committed region from
   964                       the base of the chunk's reserved region. 
   965 @param aMaxSize       The maximum size to which the reserved region of
   966                       this chunk can grow. 
   967 @param aType          An enumeration whose enumerators define the ownership of
   968                       this chunk handle. If not explicitly specified,
   969                       EOwnerProcess is taken as default.
   970 
   971 @return KErrNone if successful, otherwise another of the system error codes.
   972 
   973 @panic USER 99  if aMaxSize is negative.
   974 @panic USER 120 if aInitialBottom is negative.
   975 @panic USER 121 if aInitialTop is negative.
   976 @panic USER 122 if aInitialBottom is greater than the supplied value
   977        of aInitialTop.
   978 @panic USER 123 if aInitialTop is greater than the supplied value of aMaxSize.
   979 */
   980 	{
   981 	TChunkCreateInfo createInfo;
   982 	createInfo.SetDisconnected(aInitialBottom, aInitialTop, aMaxSize);
   983 	createInfo.SetGlobal(aName);
   984 	createInfo.SetOwner(aType);
   985 	return Create(createInfo);
   986 	}
   987 
   988 
   989 /**
   990 Creates a chunk of the type specified by the parameter aCreateInfo.
   991 
   992 @param aCreate	A reference to a TChunkCreateInfo object specifying the type of 
   993 				chunk to create.
   994 
   995 @return KErrNone on success, otherwise on of the system wide error codes.
   996 
   997 @panic USER 99  if the specified maximum size is negative.
   998 @panic USER 120 if any specified initial bottom is negative.
   999 @panic USER 121 if any specified initial top is negative.
  1000 @panic USER 122 if any specified initial bottom is greater than the supplied value
  1001        for the intial top.
  1002 @panic USER 123 if any specified initial top is greater than the supplied value for the maximum size.
  1003 @panic USER 214 if any of the specified attributes is invalid.
  1004 @panic USER 215 if the version number of aCreateInfo is invalid.
  1005 */
  1006 EXPORT_C TInt RChunk::Create(TChunkCreateInfo& aCreateInfo)
  1007 	{
  1008 	// Verify the version number of TChunkCreateInfo is supported
  1009 	__ASSERT_ALWAYS(aCreateInfo.iVersionNumber < TChunkCreateInfo::ESupportedVersions, 
  1010 					Panic(EChkCreateInvalidVersion));
  1011 
  1012 	TUint mapping = aCreateInfo.iType & ~TChunkCreate::ECode;
  1013 	TBool shouldBeNamed = 	aCreateInfo.iGlobal || 
  1014 							(aCreateInfo.iAttributes & TChunkCreate::ELocalNamed);
  1015 	__ASSERT_ALWAYS(mapping <= (TUint)TChunkCreate::ECache, Panic(EChkCreateInvalidType));
  1016 	__ASSERT_ALWAYS(!(aCreateInfo.iType & TChunkCreate::ECode) || !aCreateInfo.iGlobal, 
  1017 					Panic(EChkCreateInvalidType));
  1018 	__ASSERT_ALWAYS((!shouldBeNamed && aCreateInfo.iName == NULL) || 
  1019 					(shouldBeNamed && aCreateInfo.iName),
  1020 					Panic(EChkCreateInvalidName));
  1021 	__ASSERT_ALWAYS(aCreateInfo.iMaxSize >= 0, Panic(EChkCreateMaxSizeNegative));
  1022 	__ASSERT_ALWAYS(!(aCreateInfo.iAttributes & ~TChunkCreate::EChunkCreateAttMask), Panic(EChkCreateInvalidAttribute));
  1023 	if(mapping == TChunkCreate::ENormal)
  1024 		{
  1025 		// 'normal' chunks have different semantics for the meanings of
  1026 		// aInitialBottom and aInitialTop
  1027 		__ASSERT_ALWAYS(!aCreateInfo.iInitialBottom, Panic(EChkCreateInvalidBottom));
  1028 		__ASSERT_ALWAYS(aCreateInfo.iInitialTop >= 0, Panic(EChkCreateSizeNotPositive));
  1029 		__ASSERT_ALWAYS(aCreateInfo.iInitialTop <= aCreateInfo.iMaxSize, Panic(EChkCreateMaxLessThanMin));
  1030 		}
  1031 	else
  1032 		{
  1033 		__ASSERT_ALWAYS(aCreateInfo.iInitialBottom >= 0, Panic(EChkCreateBottomNegative));
  1034 		__ASSERT_ALWAYS(aCreateInfo.iInitialTop >= 0, Panic(EChkCreateTopNegative));
  1035 		__ASSERT_ALWAYS(aCreateInfo.iInitialTop >= aCreateInfo.iInitialBottom, Panic(EChkCreateTopLessThanBottom));
  1036 		__ASSERT_ALWAYS(aCreateInfo.iInitialTop <= aCreateInfo.iMaxSize, Panic(EChkCreateTopBiggerThanMax));
  1037 		}
  1038 
  1039 	TChunkCreate info;
  1040 	info.iAtt = aCreateInfo.iAttributes | (TUint)aCreateInfo.iType;
  1041 	info.iAtt |= (aCreateInfo.iGlobal)? TChunkCreate::EGlobal : TChunkCreate::ELocal;	// Add the global attribute
  1042 	info.iForceFixed = EFalse;
  1043 	info.iInitialBottom = aCreateInfo.iInitialBottom;
  1044 	info.iInitialTop = aCreateInfo.iInitialTop;
  1045 	info.iMaxSize = aCreateInfo.iMaxSize;
  1046 	info.iClearByte = aCreateInfo.iClearByte;
  1047 
  1048 	TDesC8* ptrName = NULL;
  1049 	TBuf8<KMaxKernelName> name8;
  1050 	if(aCreateInfo.iName)
  1051 		{
  1052 		TInt r = User::ValidateName(*aCreateInfo.iName);
  1053 		if(KErrNone!=r)
  1054 			return r;
  1055 		name8.Copy(*aCreateInfo.iName);
  1056 		ptrName = &name8;
  1057 		}
  1058 
  1059 	return SetReturnedHandle(Exec::ChunkCreate(aCreateInfo.iOwnerType, ptrName, info),*this);	
  1060 	}
  1061 
  1062 
  1063 EXPORT_C TInt RChunk::OpenGlobal(const TDesC &aName,TBool isReadOnly,TOwnerType aType)
  1064 /**
  1065 Opens a handle to a specific named global chunk.
  1066 
  1067 Full read/write access can be allowed or access can be limited to read only.
  1068 
  1069 By default, ownership of this process handle is vested in the current process, 
  1070 but can be vested in the current thread by passing EOwnerThread as the second 
  1071 parameter to this function.
  1072 
  1073 @param aName      A reference to the descriptor containing the name of
  1074                   the chunk to be opened.
  1075 @param isReadOnly This is currently not implemented and setting it to ETrue
  1076 				  will have no effect.
  1077 				  (Intended implementation will be as below:
  1078 				  Defines the type of access to the chunk: Specify ETrue if 
  1079                   access is limited to read only, otherwise specify EFalse
  1080                   for full read/write access.)
  1081 @param aType      An enumeration whose enumerators define ownership of
  1082                   this chunk handle. If not explicitly specified,
  1083                   EOwnerProcess is taken as default.
  1084 
  1085 @return KErrNone if successful, otherwise another of the system error codes.
  1086 */
  1087 	{
  1088 	(void) isReadOnly; // This is not currently used
  1089 	return OpenByName(aName,aType,EChunk);
  1090 	}
  1091 
  1092 
  1093 
  1094 
  1095 /**
  1096 Opens a handle to a chunk using a handle number sent by a client
  1097 to a server.
  1098 
  1099 This function is called by the server.
  1100 
  1101 @param aMessage   The message pointer.
  1102 @param aParam     An index specifying which of the four message arguments
  1103                   contains the handle number.
  1104 @param isReadOnly This is currently not implemented and setting it to ETrue
  1105 				  will have no effect.
  1106 				  (Intended implementation will be as below:
  1107 				  Defines the type of access to the chunk: Specify ETrue if 
  1108                   access is limited to read only, otherwise specify EFalse
  1109                   for full read/write access.)
  1110 @param aType      An enumeration whose enumerators define the ownership of this 
  1111                   chunk handle. If not explicitly specified, EOwnerProcess is
  1112                   taken as default. 
  1113                 
  1114 @return KErrNone, if successful;
  1115         KErrArgument, if the value of aParam is outside the range 0-3;
  1116         KErrBadHandle, if not a valid handle;
  1117         otherwise one of the other system-wide error codes.
  1118 */
  1119 EXPORT_C TInt RChunk::Open(RMessagePtr2 aMessage,TInt aParam,TBool isReadOnly,TOwnerType aType)
  1120 	{
  1121 	(void) isReadOnly; // This is not currently used
  1122 	return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),EChunk,aParam,aType));
  1123 	}
  1124 
  1125 
  1126 
  1127 
  1128 /**
  1129 Opens a handle to a chunk using a handle number passed as an
  1130 environment data item to the child process during the creation of
  1131 that child process.
  1132 
  1133 Note that this function can only be called successfully once.
  1134 
  1135 @param aArgumentIndex An index that identifies the slot in the process
  1136                       environment data that contains the handle number. This is
  1137                       a value relative to zero, i.e. 0 is the first item/slot.
  1138                       This can range from 0 to 15.
  1139 
  1140 @param aOwnerType     An enumeration whose enumerators define the ownership of
  1141                       this chunk handle. If not explicitly specified,
  1142                       EOwnerProcess is taken as default.
  1143 
  1144 @return KErrNone, if successful; 
  1145         KErrNotFound, if the slot indicated by aArgumentIndex is empty;
  1146         KErrArgument, if the slot does not contain a Semaphore handle;
  1147         otherwise one of the other system-wide error codes.
  1148         
  1149 @see RProcess::SetParameter()
  1150 */
  1151 EXPORT_C TInt RChunk::Open(TInt aArgumentIndex, TOwnerType aOwnerType)
  1152 	{
  1153 	return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, EChunk, aOwnerType));
  1154 	}
  1155 
  1156 
  1157 
  1158 
  1159 
  1160 EXPORT_C TInt RChunk::SetRestrictions(TUint aFlags)
  1161 /**
  1162 Sets or removes restrictions on the ability of the chunk to change.
  1163 
  1164 For example, to adjust, commit etc
  1165 
  1166 @param aFlags One of the values defined by TRestrictions.
  1167 
  1168 @return KErrNone if successful, otherwise another of the system error codes.
  1169 
  1170 @see RChunk::TRestrictions()
  1171 */
  1172 	{
  1173 	return Exec::ChunkSetRestrictions(iHandle,aFlags);
  1174 	}
  1175 
  1176 
  1177 
  1178 
  1179 EXPORT_C TInt RChunk::Adjust(TInt aNewSize) const
  1180 /**
  1181 Changes the number of bytes committed to the chunk.
  1182 
  1183 This value is always rounded up to the next nearest processor page boundary.
  1184 
  1185 @param aNewSize The number of bytes to be committed to this chunk.
  1186 
  1187 @return KErrNone if successful, otherwise another of the system error codes.
  1188 
  1189 @panic USER 102 if aNewSize is negative.
  1190 */
  1191 	{
  1192 
  1193 	__ASSERT_ALWAYS(aNewSize>=0,Panic(EChkAdjustNewSizeNegative));
  1194 	return Exec::ChunkAdjust(iHandle,EChunkAdjust,aNewSize,0);
  1195 	}
  1196 
  1197 
  1198 
  1199 
  1200 EXPORT_C TInt RChunk::AdjustDoubleEnded(TInt aBottom, TInt aTop) const
  1201 /**
  1202 Changes the number of bytes and the position of this double ended
  1203 chunk's committed region.
  1204 
  1205 The difference between aTop and aBottom gives the new size of the committed 
  1206 region; aBottom gives the offset of the bottom of the committed region from 
  1207 the base of the chunk's reserved region.
  1208 
  1209 Both aBottom and aTop are rounded up to the next nearest processor
  1210 page boundary.
  1211 
  1212 The function fails if this chunk is not a double ended chunk; for a standard 
  1213 chunk, use the Adjust() function.
  1214 
  1215 Note that if the initial and final committed regions intersect, the contents 
  1216 of the intersection are unchanged. Other parts of the committed region have 
  1217 undefined contents.
  1218 
  1219 Note also that:
  1220 
  1221 1. the lowest valid address in a double ended chunk is the sum of the base of 
  1222    the chunk's reserved region plus the adjusted value of aBottom
  1223 
  1224 2. the highest valid address in a double ended chunk is the the sum of the base 
  1225    of the chunk's reserved region plus the adjusted value of aTop - 1.
  1226 
  1227 @param aBottom The offset from the base of the chunk of the bottom of the 
  1228                committed region.
  1229 @param aTop    The offset from the base of the chunk of the top of the committed 
  1230                region.
  1231 
  1232 @return KErrNone if successful, otherwise another of the system error codes.
  1233 
  1234 @panic USER 124 if aBottom is negative.
  1235 @panic USER 125 if aTop is negative.
  1236 @panic USER 126 if aBottom is greater than the supplied value of aTop.
  1237 */
  1238 	{
  1239 	__ASSERT_ALWAYS(aBottom>=0,Panic(EChkAdjustBottomNegative));
  1240 	__ASSERT_ALWAYS(aTop>=0,Panic(EChkAdjustTopNegative));
  1241 	__ASSERT_ALWAYS(aTop>=aBottom,Panic(EChkAdjustTopLessThanBottom));
  1242 	return Exec::ChunkAdjust(iHandle,EChunkAdjustDoubleEnded,aBottom,aTop);
  1243 	}
  1244 
  1245 
  1246 
  1247 
  1248 EXPORT_C TInt RChunk::Commit(TInt aOffset, TInt aSize) const
  1249 /**
  1250 Commits memory to a disconnected chunk.
  1251 
  1252 Memory is committed in blocks of the MMU page size.
  1253 E.g. Commit(pageSize-1,2) which asks for the last byte of the first page
  1254 and the first byte of the second page and will result in the first 2 pages
  1255 in the chunk being committed.
  1256 For this reason it is best to only use values for aOffset and aSize which
  1257 are multiples of the MMU page size. This size can be obtained with the
  1258 following code.
  1259 @code
  1260 TInt pageSize;
  1261 HAL::Get(HAL::EMemoryPageSize,pageSize)
  1262 @endcode
  1263 
  1264 @param aOffset	The offset of the committed region from the base of the chunk's 
  1265                 reserved region.
  1266 @param aSize    The size of the committed region.
  1267 
  1268 @return KErrNone if successful, otherwise another of the system error codes.
  1269 
  1270 @panic USER 157 if anOffset is negative.
  1271 @panic USER 158 if aSize is negative.
  1272 */
  1273 	{
  1274 	__ASSERT_ALWAYS(aOffset>=0,Panic(EChkCommitOffsetNegative));
  1275 	__ASSERT_ALWAYS(aSize>=0,Panic(EChkCommitSizeNegative));
  1276 	return Exec::ChunkAdjust(iHandle,EChunkCommit,aOffset,aSize);
  1277 	}
  1278 
  1279 
  1280 
  1281 
  1282 EXPORT_C TInt RChunk::Allocate(TInt aSize) const
  1283 /**
  1284 Allocates and commits to a disconnected chunk.
  1285 
  1286 @param aSize The size of the committed region.
  1287 
  1288 @panic USER 159 if aSize is negative.
  1289 */
  1290 	{
  1291 	__ASSERT_ALWAYS(aSize>=0,Panic(EChkAllocateSizeNegative));
  1292 	return Exec::ChunkAdjust(iHandle,EChunkAllocate,aSize,0);
  1293 	}
  1294 
  1295 
  1296 
  1297 
  1298 EXPORT_C TInt RChunk::Decommit(TInt aOffset, TInt aSize) const
  1299 /**
  1300 Decommits memory from a disconnected chunk.
  1301 
  1302 Memory is decommitted in blocks of the MMU page size.
  1303 E.g. Decommit(pageSize-1,2) which asks for the last byte of the first page
  1304 and the first byte of the second page and will result in the first 2 pages
  1305 in the chunk being decommitted.
  1306 For this reason it is best to only use values for aOffset and aSize which
  1307 are multiples of the MMU page size. This size can be obtained with the
  1308 following code.
  1309 @code
  1310 TInt pageSize;
  1311 HAL::Get(HAL::EMemoryPageSize,pageSize)
  1312 @endcode
  1313 
  1314 @param aOffset The offset of the committed region from the base of the chunk's 
  1315                 reserved region;
  1316 @param aSize    The size of the committed region.
  1317 
  1318 @return KErrNone if successful, otherwise another of the system error codes.
  1319 
  1320 @panic USER 160 if anOffset is negative.
  1321 @panic USER 161 if aSize is negative.
  1322 */
  1323 	{
  1324 	__ASSERT_ALWAYS(aOffset>=0,Panic(EChkDecommitOffsetNegative));
  1325 	__ASSERT_ALWAYS(aSize>=0,Panic(EChkDecommitSizeNegative));
  1326 	return Exec::ChunkAdjust(iHandle,EChunkDecommit,aOffset,aSize);
  1327 	}
  1328 
  1329 
  1330 /* THIS IS A DELIBERATE NON DOXGEN STYLE TAG TO EXCLUDE THIS DOC FROM AUTO GENERATED DOCS
  1331 
  1332 Unlocks previously committed memory in a disconnected chunk.
  1333 
  1334 Unlocked memory is an intermediate state between committed and decommitted.
  1335 Whilst in this state, the memory must not be accessed in any way, and the
  1336 system is free to reclaim this RAM for other purposes, (it counts as free
  1337 system memory). A program may attempt to relock the memory with #Lock which,
  1338 when it succeeds, returns it to the committed state with its contents unchanged.
  1339 
  1340 This is intended for use in the implementation of memory caches for data
  1341 which can be regenerated from other sources. I.e. in situations when the
  1342 loss of cache contents is not a fatal condition.
  1343 
  1344 #Unlock may be used on memory which is already unlocked, in which case the memory
  1345 state is left unaltered. Attempting to unlock memory which is decommitted results
  1346 in an error.
  1347 
  1348 Unlocked memory may decommitted with #Decommit.
  1349 
  1350 Memory is unlocked in blocks of the MMU page size.
  1351 E.g. Unlock(pageSize-1,2) which asks for the last byte of the first page
  1352 and the first byte of the second page and will result in the first 2 pages
  1353 in the chunk being unlocked.
  1354 For this reason it is best to only use values for aOffset and aSize which
  1355 are multiples of the MMU page size. This size can be obtained with the
  1356 following code.
  1357 @code
  1358 TInt pageSize;
  1359 HAL::Get(HAL::EMemoryPageSize,pageSize)
  1360 @endcode
  1361 
  1362 @param aOffset The offset of the committed region from the base of the chunk's 
  1363                reserved region;
  1364 @param aSize   The size of the committed region.
  1365 
  1366 @return KErrNone if successful, otherwise another of the system error codes.
  1367 
  1368 @panic USER 160 if anOffset is negative.
  1369 @panic USER 161 if aSize is negative.
  1370 
  1371 @see RChunk::Lock
  1372 
  1373 @internalTechnology
  1374 */
  1375 EXPORT_C TInt RChunk::Unlock(TInt aOffset, TInt aSize)
  1376 	{
  1377 	__ASSERT_ALWAYS(aOffset>=0,Panic(EChkDecommitOffsetNegative));
  1378 	__ASSERT_ALWAYS(aSize>=0,Panic(EChkDecommitSizeNegative));
  1379 	return Exec::ChunkAdjust(iHandle,EChunkUnlock,aOffset,aSize);
  1380 	}
  1381 
  1382 /* THIS IS A DELIBERATE NON DOXGEN STYLE TAG TO EXCLUDE THIS DOC FROM AUTO GENERATED DOCS
  1383 
  1384 Locks memory in a disconnected chunk.
  1385 
  1386 This attempts to reverse the action of #Unlock and return memory to the committed
  1387 state. If any RAM in the region had been previously reclaimed by the system,
  1388 then this function fails with KErrNotFound and the whole region is decommited.
  1389 
  1390 #Lock may be used on memory which is already committed, in which case the memory
  1391 state is left unaltered. Attempting to lock memory which is decommitted results in an
  1392 error.
  1393 
  1394 Memory is locked in blocks of the MMU page size.
  1395 E.g. Lock(pageSize-1,2) which asks for the last byte of the first page
  1396 and the first byte of the second page and will result in the first 2 pages
  1397 in the chunk being locked.
  1398 For this reason it is best to only use values for aOffset and aSize which
  1399 are multiples of the MMU page size. This size can be obtained with the
  1400 following code.
  1401 @code
  1402 TInt pageSize;
  1403 HAL::Get(HAL::EMemoryPageSize,pageSize)
  1404 @endcode
  1405 
  1406 @param aOffset The offset of the unlocked region from the base of the chunk's 
  1407                reserved region.
  1408 @param aSize   The size of the unlocked region.
  1409 
  1410 @return KErrNone if successful, otherwise another of the system error codes.
  1411 
  1412 @panic USER 160 if anOffset is negative.
  1413 @panic USER 161 if aSize is negative.
  1414 
  1415 @see RChunk::Unlock
  1416 
  1417 @internalTechnology
  1418 */
  1419 EXPORT_C TInt RChunk::Lock(TInt aOffset, TInt aSize)
  1420 	{
  1421 	__ASSERT_ALWAYS(aOffset>=0,Panic(EChkDecommitOffsetNegative));
  1422 	__ASSERT_ALWAYS(aSize>=0,Panic(EChkDecommitSizeNegative));
  1423 	return Exec::ChunkAdjust(iHandle,EChunkLock,aOffset,aSize);
  1424 	}
  1425 
  1426 
  1427 /**
  1428 This can be used to determine whether the data for the chunk is demand paged
  1429 or not.
  1430 
  1431 @return ETrue if the data for the chunk is demand paged, EFalse otherwise.
  1432 */
  1433 EXPORT_C TBool RChunk::IsPaged() const
  1434 	{
  1435 	return Exec::ChunkIsPaged(iHandle);
  1436 	}
  1437 
  1438 
  1439 /**
  1440 Opens a handle to an LDD factory object by name.
  1441 
  1442 @param aName	The name of the LDD factory object to be opened.
  1443 @param aType	An enumeration whose enumerators define the ownership of this 
  1444 				LDD factory object handle.
  1445 
  1446 @return KErrNone, if successful; otherwise one of the other system wide error codes.
  1447 */
  1448 EXPORT_C TInt RDevice::Open(const TDesC &aName,TOwnerType aType)
  1449 	{
  1450 	return OpenByName(aName,aType,ELogicalDevice);
  1451 	}
  1452 
  1453 EXPORT_C TInt RBusLogicalChannel::DoCreate(const TDesC& aLogicalDevice, const TVersion& aVer, TInt aUnit, const TDesC* aPhysicalDevice, const TDesC8* anInfo, TInt aType)
  1454 //
  1455 // Call the kernel to create a channel on a device.
  1456 //
  1457 	{
  1458 	TInt r = User::ValidateName(aLogicalDevice);
  1459 	if(KErrNone!=r)
  1460 		return r;
  1461 	TBuf8<KMaxKernelName> name8;
  1462 	name8.Copy(aLogicalDevice);
  1463 
  1464 	TBuf8<KMaxKernelName> physicalDeviceName;
  1465 	TChannelCreateInfo8 info;
  1466 	info.iVersion=aVer;
  1467 	info.iUnit=aUnit;
  1468 	if(aPhysicalDevice)
  1469 		{
  1470 		physicalDeviceName.Copy(*aPhysicalDevice);
  1471 		info.iPhysicalDevice = &physicalDeviceName;
  1472 		}
  1473 	else
  1474 		info.iPhysicalDevice = NULL;
  1475 	info.iInfo=anInfo;
  1476 
  1477 	return SetReturnedHandle(Exec::ChannelCreate(name8, info, aType),*this);
  1478 	}
  1479 
  1480 
  1481 
  1482 
  1483 /**
  1484 Opens a handle to a logical channel using a handle number sent by a client
  1485 to a server.
  1486 
  1487 This function is called by the server.
  1488 
  1489 @param aMessage The message pointer.
  1490 @param aParam   An index specifying which of the four message arguments
  1491                 contains the handle number.
  1492 @param aType    An enumeration whose enumerators define the ownership of this 
  1493                 logical channel handle. If not explicitly specified,
  1494                 EOwnerProcess is taken as default. 
  1495                 
  1496 @return KErrNone, if successful;
  1497         KErrArgument, if the value of aParam is outside the range 0-3;
  1498         KErrBadHandle, if not a valid handle;
  1499         otherwise one of the other system-wide error codes.
  1500 */
  1501 EXPORT_C TInt RBusLogicalChannel::Open(RMessagePtr2 aMessage,TInt aParam,TOwnerType aType)
  1502 	{
  1503 	return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),ELogicalChannel,aParam,aType));
  1504 	}
  1505 
  1506 
  1507 
  1508 
  1509 /**
  1510 Opens a logical channel handle using a handle number passed as an
  1511 environment data item to the child process during the creation of
  1512 that child process.
  1513 
  1514 Note that this function can only be called successfully once.
  1515 
  1516 @param aArgumentIndex An index that identifies the slot in the process
  1517                       environment data that contains the handle number. This is
  1518                       a value relative to zero, i.e. 0 is the first item/slot.
  1519                       This can range from 0 to 15.
  1520 
  1521 @param aOwnerType     An enumeration whose enumerators define the ownership of
  1522                       this logical channel handle. If not explicitly specified,
  1523                       EOwnerProcess is taken as default.
  1524 
  1525 @return KErrNone, if successful; 
  1526         KErrNotFound, if the slot indicated by aArgumentIndex is empty;
  1527         KErrArgument, if the slot does not contain a logical channel handle;
  1528         otherwise one of the other system-wide error codes.
  1529 */
  1530 EXPORT_C TInt RBusLogicalChannel::Open(TInt aArgumentIndex, TOwnerType aOwnerType)
  1531 	{
  1532 	return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, ELogicalChannel, aOwnerType));
  1533 	}
  1534 
  1535 
  1536 
  1537 
  1538 EXPORT_C TInt RHandleBase::Duplicate(const RThread &aSrc,TOwnerType aType)
  1539 /**
  1540 Creates a valid handle to the kernel object for which the specified thread 
  1541 already has a handle.
  1542 	
  1543 The function assumes that this handle has been copy constructed from an existing 
  1544 handle (or the handle-number has been explicitly copied through calls to Handle() 
  1545 and SetHandle()).
  1546 	
  1547 By default, any thread in the process can use this handle to access the kernel 
  1548 side object that the handle represents. However, specifying EOwnerThread as 
  1549 the second parameter to this function, means that only the creating thread 
  1550 can use this handle to access the kernel side object; any other thread in 
  1551 this process that wants to access the kernel side object must, again, duplicate 
  1552 this handle.
  1553 	
  1554 @param aSrc  A reference to the thread containing the handle which is to be 
  1555              duplicated for this thread.
  1556 @param aType An enumeration whose enumerators define the ownership of this 
  1557              handle. If not explicitly specified, EOwnerProcess is taken
  1558              as default.
  1559              
  1560 @return KErrNone, if successful; otherwise, one of the other system wide error 
  1561         codes.
  1562 */
  1563 	{
  1564 	return Exec::HandleDuplicate(aSrc.Handle(), aType, iHandle);
  1565 	}
  1566 
  1567 
  1568 
  1569 
  1570 EXPORT_C TInt RHandleBase::Open(const TFindHandleBase& aFindHandle, TOwnerType aType)
  1571 /**
  1572 Opens a handle to a kernel side object found using a find-handle object.
  1573 
  1574 @param aFindHandle A find-handle object; an object that is used in searching
  1575                    for kernel side objects.
  1576 @param aType       An enumeration whose enumerators define the ownership of
  1577                    this handle. If not explicitly specified, EOwnerProcess
  1578                    is taken as default, and ownership is vested in the
  1579                    current process. Ownership can be vested in the current
  1580                    thread by passing the EOwnerThread enumerator.
  1581 @return KErrNone, if successful; otherwise one of the other system wide
  1582         error codes.
  1583 */
  1584 	{
  1585 	return SetReturnedHandle(Exec::FindHandleOpen(aType, aFindHandle), *this);
  1586 	}
  1587 
  1588 
  1589 
  1590 /**
  1591 	Implementation for RXxxxx::Open/OpenGlocbal(const TDesC &aName,,TOwnerType aType) functions
  1592 	@internalComponent
  1593 */
  1594 TInt RHandleBase::OpenByName(const TDesC &aName,TOwnerType aOwnerType,TInt aObjectType)
  1595 	{
  1596 	TBuf8<KMaxFullName> name8;
  1597 	name8.Copy(aName);
  1598 	return SetReturnedHandle(Exec::OpenObject((TObjectType)aObjectType,name8,aOwnerType));
  1599 	}
  1600 
  1601 TInt RHandleBase::SetReturnedHandle(TInt aHandleOrError,RHandleBase& aHandle)
  1602 //
  1603 // Set the handle value or return error
  1604 //
  1605 	{
  1606 	return aHandle.SetReturnedHandle(aHandleOrError);
  1607 	}
  1608 
  1609 
  1610 
  1611 
  1612 EXPORT_C void RHandleBase::Close()
  1613 /**
  1614 Closes the handle.
  1615 	
  1616 This has the effect of closing the associated kernel side object.
  1617 	
  1618 As the associated object is a reference counting object, it is destroyed if 
  1619 there are no other open references to it.
  1620 	
  1621 @see CObject
  1622 */
  1623 	{
  1624 
  1625 	__IF_DEBUG(Print(_L("RHandleBase::Close")));
  1626 	TInt h=iHandle;
  1627 	if (h!=KNullHandle)
  1628 		{
  1629 //
  1630 // We take a copy of the handle and set it to zero before the close in case this
  1631 // object is actually a Chunk created in its own heap in which case the close
  1632 // will destroy the object as well.
  1633 //
  1634 		iHandle=0;
  1635 		if ((h&CObjectIx::ENoClose)==0 && Exec::HandleClose(h)>0)
  1636 			DoExtendedClose();
  1637 		}
  1638 	}
  1639 
  1640 
  1641 
  1642 
  1643 void RHandleBase::DoExtendedClose()
  1644 //
  1645 // Call static data destructors following a library handle close
  1646 //
  1647 	{
  1648 	TRAPD(r,DoExtendedCloseL());	// catch attempts to leave from destructors
  1649 	__ASSERT_ALWAYS(r==KErrNone, Panic(EDllStaticDestructorLeave));
  1650 	}
  1651 
  1652 void RHandleBase::DoExtendedCloseL()
  1653 //
  1654 // Call static data destructors following a library handle close
  1655 //
  1656 	{
  1657 	TLinAddr ep[KMaxLibraryEntryPoints];
  1658 	TInt r=KErrNone;
  1659 	while (r!=KErrEof)
  1660 		{
  1661 		TInt numEps=KMaxLibraryEntryPoints;
  1662 		r=E32Loader::LibraryDetach(numEps, ep);
  1663 		if (r==KErrEof)
  1664 			break;
  1665 		TInt i;
  1666 		for (i=numEps-1; i>=0; --i)
  1667 			{
  1668 			TLibraryEntry f=(TLibraryEntry)ep[i];
  1669 			(*f)(KModuleEntryReasonProcessDetach);
  1670 			}
  1671 		r=E32Loader::LibraryDetached();
  1672 		}
  1673 	}
  1674 
  1675 
  1676 
  1677 
  1678 /**
  1679 Constructs an RMessage2 from an RMessagePtr2.
  1680 
  1681 @param aPtr A reference to an existing RMessagePtr2 object.
  1682 */
  1683 EXPORT_C RMessage2::RMessage2(const RMessagePtr2& aPtr)
  1684 	{
  1685 	iHandle = aPtr.Handle();
  1686 	Exec::MessageConstructFromPtr(iHandle, this);
  1687 	iFlags = 0;
  1688 	iSpare3 = 0;
  1689 	}
  1690 
  1691 /** Sets this message to an authorised state.  This is used only by
  1692 CPolicyServer.  This flags use by the policy server implies two things:
  1693 1) That the message has passed any appropriate security checks. (ie. one of the
  1694 static policy check, CustomSecurityCheckL, or CustomFailureActionL,
  1695 returned ETrue.)
  1696 2) That any leaves that occur subsequent to this flag being set happen _only_
  1697 in the session's ServiceL.  ie.  Nothing can leave between this flag being set
  1698 and the session's ServiceL being called.
  1699 
  1700 This is labelled as a const functions as everybody handles const RMessage2&'s.
  1701 The constness is actually referring to the underlying RMessagePtr2 not the
  1702 tranisent RMessage2 class.
  1703 
  1704 @internalComponent
  1705 */
  1706 void RMessage2::SetAuthorised() const
  1707 	{
  1708 	iFlags = ETrue;
  1709 	}
  1710 
  1711 /** Sets the authorised flag to a state of not authorised.  This is required as
  1712 there is a default constructor for RMessage2 and one cannot guarantee that
  1713 iFlags was initialised.  This is called from CPolicyServer::RunL.
  1714 
  1715 This is labelled as a const functions as everybody handles const RMessage2&'s.
  1716 The constness is actually referring to the underlying RMessagePtr2 not the
  1717 tranisent RMessage2 class.
  1718 
  1719 @internalComponent
  1720 */
  1721 void RMessage2::ClearAuthorised() const
  1722 	{
  1723 	iFlags = EFalse;
  1724 	}
  1725 
  1726 /** Returns whether this message has been authorised by CPolicyServer.  See
  1727 RMessage2::SetAuthorised for implications of this state.
  1728 @internalComponent
  1729 */
  1730 TBool RMessage2::Authorised() const
  1731 	{
  1732 	return iFlags;
  1733 	}
  1734 
  1735 
  1736 
  1737 
  1738 /**
  1739 Frees this message.
  1740 
  1741 @param aReason The completion code.
  1742 */
  1743 EXPORT_C void RMessagePtr2::Complete(TInt aReason) const
  1744 //
  1745 // Free this message. If it's a disconnect, need to switch to kernel context as we'll be
  1746 // freeing the DSession
  1747 //
  1748 	{
  1749 	TInt h=iHandle;
  1750 	const_cast<TInt&>(iHandle)=0;
  1751 	if (h)
  1752 		Exec::MessageComplete(h,aReason);
  1753 	else
  1754 		::Panic(ETMesCompletion);
  1755 	}
  1756 
  1757 
  1758 
  1759 
  1760 /**
  1761 Duplicates the specified handle in the client thread, and returns this
  1762 handle as a message completion code
  1763 
  1764 @param aHandle The handle to be duplicated.
  1765 */
  1766 EXPORT_C void RMessagePtr2::Complete(RHandleBase aHandle) const
  1767 	{
  1768 	TInt h=iHandle;
  1769 	const_cast<TInt&>(iHandle)=0;
  1770 	if (h)
  1771 		Exec::MessageCompleteWithHandle(h,aHandle.Handle());
  1772 	else
  1773 		::Panic(ETMesCompletion);
  1774 	}
  1775 
  1776 
  1777 
  1778 
  1779 /**
  1780 Gets the length of a descriptor argument in the client's process.
  1781 
  1782 @param aParam The index value identifying the argument.
  1783               This is a value in the range 0 to (KMaxMessageArguments-1)
  1784               inclusive.
  1785               
  1786 @return The length of the descriptor, if successful.
  1787         KErrArgument, if aParam has a value outside the valid range.
  1788         KErrBadDescriptor, if the message argument is not a descriptor type.
  1789 */
  1790 EXPORT_C TInt RMessagePtr2::GetDesLength(TInt aParam) const
  1791 	{
  1792 	return Exec::MessageGetDesLength(iHandle,aParam);
  1793 	}
  1794 
  1795 
  1796 
  1797 
  1798 /**
  1799 Gets the length of a descriptor argument in the client's process,
  1800 leaving on failure.
  1801 
  1802 @param aParam The index value identifying the argument.
  1803               This is a value in the range 0 to (KMaxMessageArguments-1)
  1804               inclusive.
  1805               
  1806 @return The length of the descriptor.
  1807 
  1808 @leave  KErrArgument if aParam has a value outside the valid range.
  1809 @leave  KErrBadDescriptor, if the message argument is not a descriptor type.
  1810 */
  1811 EXPORT_C TInt RMessagePtr2::GetDesLengthL(TInt aParam) const
  1812 	{
  1813 	return User::LeaveIfError(GetDesLength(aParam));
  1814 	}
  1815 
  1816 
  1817 
  1818 
  1819 /**
  1820 Gets the maximum length of a descriptor argument in the client's process.
  1821 
  1822 @param aParam The index value identifying the argument.
  1823               This is a value in the range 0 to (KMaxMessageArguments-1)
  1824               inclusive.
  1825               
  1826 @return The maximum length of the descriptor, if successful.
  1827         KErrArgument, if aParam has a value outside the valid range.
  1828         KErrBadDescriptor, if the message argument is not a descriptor type.
  1829 */
  1830 EXPORT_C TInt RMessagePtr2::GetDesMaxLength(TInt aParam) const
  1831 	{
  1832 	return Exec::MessageGetDesMaxLength(iHandle,aParam);
  1833 	}
  1834 
  1835 
  1836 
  1837 
  1838 /**
  1839 Gets the maximum length of a descriptor argument in the client's process,
  1840 leaving on failure.
  1841 
  1842 @param aParam The index value identifying the argument.
  1843               This is a value in the range 0 to (KMaxMessageArguments-1)
  1844               inclusive.
  1845               
  1846 @return The length of the descriptor.
  1847 
  1848 @leave  KErrArgument if aParam has a value outside the valid range.
  1849 @leave  KErrBadDescriptor, if the message argument is not a descriptor type.
  1850 */
  1851 EXPORT_C TInt RMessagePtr2::GetDesMaxLengthL(TInt aParam) const
  1852 	{
  1853 	return User::LeaveIfError(GetDesMaxLength(aParam));
  1854 	}
  1855 
  1856 
  1857 
  1858 
  1859 /**
  1860 Reads data from the specified offset within the 8-bit descriptor
  1861 argument, into the specified target descriptor, and leaving on failure.
  1862 
  1863 @param aParam  The index value identifying the argument.
  1864                This is a value in the range 0 to (KMaxMessageArguments-1)
  1865                inclusive.
  1866 @param aDes    The target descriptor into which the client data is
  1867                to be written.
  1868 @param aOffset The offset from the start of the client's descriptor data.
  1869                If not explicitly specified, the offset defaults to zero.
  1870 
  1871 @leave  KErrArgument if aParam has a value outside the valid range, or
  1872                      if aOffset is negative.
  1873 @leave  KErrBadDescriptor, if the message argument is not an 8-bit descriptor.
  1874 */
  1875 EXPORT_C void RMessagePtr2::ReadL(TInt aParam,TDes8& aDes,TInt aOffset) const
  1876 	{
  1877 	TInt error = Read(aParam,aDes,aOffset);
  1878 	User::LeaveIfError(error);
  1879 	}
  1880 
  1881 
  1882 
  1883 
  1884 /**
  1885 Reads data from the specified offset within the 16-bit descriptor
  1886 argument, into the specified target descriptor, and leaving on failure.
  1887 
  1888 @param aParam  The index value identifying the argument.
  1889                This is a value in the range 0 to (KMaxMessageArguments-1)
  1890                inclusive.
  1891 @param aDes    The target descriptor into which the client data is
  1892                to be written.
  1893 @param aOffset The offset from the start of the client's descriptor data.
  1894                If not explicitly specified, the offset defaults to zero.
  1895 
  1896 @leave  KErrArgument if aParam has a value outside the valid range, or
  1897                      if aOffset is negative.
  1898 @leave  KErrBadDescriptor, if the message argument is not a 16-bit descriptor.
  1899 */
  1900 EXPORT_C void RMessagePtr2::ReadL(TInt aParam,TDes16 &aDes,TInt aOffset) const
  1901 	{
  1902 	TInt error = Read(aParam,aDes,aOffset);
  1903 	User::LeaveIfError(error);
  1904 	}
  1905 
  1906 
  1907 
  1908 
  1909 /**
  1910 Writes data from the specified source descriptor to the specified offset within
  1911 the 8-bit descriptor argument, and leaving on failure.
  1912 
  1913 @param aParam  The index value identifying the argument.
  1914                This is a value in the range 0 to (KMaxMessageArguments-1)
  1915                inclusive.
  1916 @param aDes    The source descriptor containing the data to be written.
  1917 @param aOffset The offset from the start of the client's descriptor.
  1918                If not explicitly specified, the offset defaults to zero.
  1919 
  1920 @leave  KErrArgument if aParam has a value outside the valid range, or
  1921                      if aOffset is negative.
  1922 @leave  KErrBadDescriptor, if the message argument is not an 8-bit descriptor.
  1923 */
  1924 EXPORT_C void RMessagePtr2::WriteL(TInt aParam,const TDesC8& aDes,TInt aOffset) const
  1925 	{
  1926 	TInt error = Write(aParam,aDes,aOffset);
  1927 	User::LeaveIfError(error);
  1928 	}
  1929 
  1930 
  1931 
  1932 
  1933 /**
  1934 Writes data from the specified source descriptor to the specified offset within
  1935 the 16-bit descriptor argument, and leaving on failure.
  1936 
  1937 @param aParam  The index value identifying the argument.
  1938                This is a value in the range 0 to (KMaxMessageArguments-1)
  1939                inclusive.
  1940 @param aDes    The source descriptor containing the data to be written.
  1941 @param aOffset The offset from the start of the client's descriptor.
  1942                If not explicitly specified, the offset defaults to zero.
  1943 
  1944 @leave  KErrArgument if aParam has a value outside the valid range, or
  1945                      if aOffset is negative.
  1946 @leave  KErrBadDescriptor, if the message argument is not a 16-bit descriptor.
  1947 */
  1948 EXPORT_C void RMessagePtr2::WriteL(TInt aParam,const TDesC16& aDes,TInt aOffset) const
  1949 	{
  1950 	TInt error = Write(aParam,aDes,aOffset);
  1951 	User::LeaveIfError(error);
  1952 	}
  1953 
  1954 
  1955 
  1956 
  1957 /**
  1958 Reads data from the specified offset within the 8-bit descriptor
  1959 argument, into the specified target descriptor.
  1960 
  1961 @param aParam  The index value identifying the argument.
  1962                This is a value in the range 0 to (KMaxMessageArguments-1)
  1963                inclusive.
  1964 @param aDes    The target descriptor into which the client data is
  1965                to be written.
  1966 @param aOffset The offset from the start of the client's descriptor data.
  1967                If not explicitly specified, the offset defaults to zero.
  1968 
  1969 @return KErrNone, if successful;
  1970         KErrArgument if aParam has a value outside the valid range, or
  1971                      if aOffset is negative.
  1972         KErrBadDescriptor, if the message argument is not an 8-bit descriptor.
  1973 */
  1974 EXPORT_C TInt RMessagePtr2::Read(TInt aParam,TDes8& aDes,TInt aOffset) const
  1975 	{
  1976 	SIpcCopyInfo info;
  1977 	info.iFlags=KChunkShiftBy0|KIpcDirRead;
  1978 	info.iLocalLen=aDes.MaxLength();
  1979 	info.iLocalPtr=(TUint8*)aDes.Ptr();
  1980 	TInt r=Exec::MessageIpcCopy(iHandle,aParam,info,aOffset);
  1981 	if (r<0)
  1982 		return r;
  1983 	aDes.SetLength(r);
  1984 	return KErrNone;
  1985 	}
  1986 
  1987 
  1988 
  1989 
  1990 /**
  1991 Reads data from the specified offset within the 16-bit descriptor
  1992 argument, into the specified target descriptor.
  1993 
  1994 @param aParam  The index value identifying the argument.
  1995                This is a value in the range 0 to (KMaxMessageArguments-1)
  1996                inclusive.
  1997 @param aDes    The target descriptor into which the client data is
  1998                to be written.
  1999 @param aOffset The offset from the start of the client's descriptor data.
  2000                If not explicitly specified, the offset defaults to zero.
  2001                
  2002 @return KErrNone, if successful;
  2003         KErrArgument if aParam has a value outside the valid range, or
  2004                      if aOffset is negative.
  2005         KErrBadDescriptor, if the message argument is not a 16-bit descriptor.
  2006 */
  2007 EXPORT_C TInt RMessagePtr2::Read(TInt aParam,TDes16 &aDes,TInt aOffset) const
  2008 	{
  2009 	SIpcCopyInfo info;
  2010 	info.iFlags=KChunkShiftBy1|KIpcDirRead;
  2011 	info.iLocalLen=aDes.MaxLength();
  2012 	info.iLocalPtr=(TUint8*)aDes.Ptr();
  2013 	TInt r=Exec::MessageIpcCopy(iHandle,aParam,info,aOffset);
  2014 	if (r<0)
  2015 		return r;
  2016 	aDes.SetLength(r);
  2017 	return KErrNone;
  2018 	}
  2019 
  2020 
  2021 
  2022 
  2023 /**
  2024 Writes data from the specified source descriptor to the specified offset within
  2025 the 8-bit descriptor argument.
  2026 
  2027 @param aParam  The index value identifying the argument.
  2028                This is a value in the range 0 to (KMaxMessageArguments-1)
  2029                inclusive.
  2030 @param aDes    The source descriptor containing the data to be written.
  2031 @param aOffset The offset from the start of the client's descriptor.
  2032                If not explicitly specified, the offset defaults to zero.
  2033                
  2034 @return KErrNone, if successful;
  2035         KErrArgument if aParam has a value outside the valid range, or
  2036                      if aOffset is negative.
  2037         KErrBadDescriptor, if the message argument is not an 8-bit descriptor;
  2038         KErrOverflow, if the target descriptor is too small
  2039                       to containt the data.
  2040 */
  2041 EXPORT_C TInt RMessagePtr2::Write(TInt aParam,const TDesC8& aDes,TInt aOffset) const
  2042 	{
  2043 	SIpcCopyInfo info;
  2044 	info.iFlags=KChunkShiftBy0|KIpcDirWrite;
  2045 	info.iLocalLen=aDes.Length();
  2046 	info.iLocalPtr=(TUint8*)aDes.Ptr();
  2047 	return Exec::MessageIpcCopy(iHandle,aParam,info,aOffset);
  2048 	}
  2049 
  2050 
  2051 
  2052 
  2053 /**
  2054 Writes data from the specified source descriptor to the specified offset within 
  2055 the 16-bit descriptor argument.
  2056 
  2057 @param aParam  The index value identifying the argument.
  2058                This is a value in the range 0 to (KMaxMessageArguments-1)
  2059                inclusive.
  2060 @param aDes    The source descriptor containing the data to be written.
  2061 @param aOffset The offset from the start of the client's descriptor.
  2062                If not explicitly specified, the offset defaults to zero.
  2063 
  2064 @return KErrNone, if successful;
  2065         KErrArgument if aParam has a value outside the valid range, or
  2066                      if aOffset is negative.
  2067         KErrBadDescriptor, if the message argument is not an 16-bit descriptor;
  2068         KErrOverflow, if the target descriptor is too small
  2069                       to containt the data.
  2070 */
  2071 EXPORT_C TInt RMessagePtr2::Write(TInt aParam,const TDesC16& aDes,TInt aOffset) const
  2072 	{
  2073 	SIpcCopyInfo info;
  2074 	info.iFlags=KChunkShiftBy1|KIpcDirWrite;
  2075 	info.iLocalLen=aDes.Length();
  2076 	info.iLocalPtr=(TUint8*)aDes.Ptr();
  2077 	return Exec::MessageIpcCopy(iHandle,aParam,info,aOffset);
  2078 	}
  2079 
  2080 
  2081 
  2082 
  2083 /**
  2084 Panics the client.
  2085 
  2086 The length of the category name should be no greater than 16; any name with 
  2087 a length greater than 16 is truncated to 16.
  2088 
  2089 Note that this method also completes the message. A subsequent call to Complete(TInt aReason) would cause a server panic.
  2090 
  2091 @param aCategory The panic category.
  2092 @param aReason   The panic code.
  2093 */
  2094 EXPORT_C void RMessagePtr2::Panic(const TDesC& aCategory,TInt aReason) const
  2095 	{
  2096 	TBuf8<KMaxExitCategoryName> cat;
  2097 	TInt length=aCategory.Length();
  2098 	if(length>KMaxExitCategoryName)
  2099 		{
  2100 		TPtr catPtr((TUint16*)aCategory.Ptr(),KMaxExitCategoryName,KMaxExitCategoryName);
  2101 		cat.Copy(catPtr);
  2102 		}
  2103 	else
  2104 		{
  2105 		cat.Copy(aCategory);
  2106 		}
  2107 	Exec::MessageKill(iHandle,EExitPanic,aReason,&cat);
  2108 	Complete(KErrNone);
  2109 	}
  2110 
  2111 
  2112 
  2113 
  2114 /**
  2115 Kills the client.
  2116 
  2117 Note that this method also completes the message. A subsequent call to Complete(TInt aReason) would cause a server panic.
  2118 
  2119 @param aReason The reason code associated with killing the client.
  2120 */
  2121 EXPORT_C void RMessagePtr2::Kill(TInt aReason) const
  2122 	{
  2123 	Exec::MessageKill(iHandle,EExitKill,aReason,NULL);
  2124 	Complete(KErrNone);
  2125 	}
  2126 
  2127 
  2128 
  2129 
  2130 /**
  2131 Terminates the client.
  2132 
  2133 Note that this method also completes the message. A subsequent call to Complete(TInt aReason) would cause a server panic.
  2134 
  2135 @param aReason The reason code associated with terminating the client.
  2136 */
  2137 EXPORT_C void RMessagePtr2::Terminate(TInt aReason) const
  2138 	{
  2139 	Exec::MessageKill(iHandle,EExitTerminate,aReason,NULL);
  2140 	Complete(KErrNone);
  2141 	}
  2142 
  2143 
  2144 
  2145 
  2146 /**
  2147 Sets the priority of the client's process.
  2148 
  2149 @param aPriority The priority value.
  2150 
  2151 @return KErrNone, if successful, otherwise one of the other system-wide error codes.
  2152 */
  2153 EXPORT_C TInt RMessagePtr2::SetProcessPriority(TProcessPriority aPriority) const
  2154 	{
  2155 	return Exec::MessageSetProcessPriority(iHandle,aPriority);
  2156 	}
  2157 
  2158 
  2159 
  2160 /**
  2161 Opens a handle on the client thread.
  2162 
  2163 @param aClient    On successful return, the handle to the client thread.
  2164 @param aOwnerType An enumeration whose enumerators define the ownership of
  2165                   the handle. If not explicitly specified,
  2166                   EOwnerProcess is taken as default.
  2167 
  2168 @return KErrNone.
  2169 */
  2170 EXPORT_C TInt RMessagePtr2::Client(RThread& aClient, TOwnerType aOwnerType) const
  2171 	{
  2172 	return aClient.SetReturnedHandle(Exec::MessageClient(iHandle,aOwnerType));
  2173 	}
  2174 
  2175 EXPORT_C TUint RMessagePtr2::ClientProcessFlags() const
  2176 	{
  2177 	return Exec::MessageClientProcessFlags(iHandle);
  2178 	}
  2179 
  2180 EXPORT_C TBool RMessagePtr2::ClientIsRealtime() const
  2181 	{
  2182 	return (Exec::MessageClientProcessFlags(iHandle) & KThreadFlagRealtime) != 0;
  2183 	}
  2184 
  2185 
  2186 
  2187 /**
  2188 Returns the pointer to the clients TRequestStatus associated with the message.
  2189 
  2190 The return value is intended to be used as a unique identifier (for example,
  2191 to uniquely identify an asynchronous message when cancelling the request).
  2192 The memory must never be accessed directly or completed.
  2193 
  2194 @return The clients TRequestStatus (returns NULL if the request is not asynchronous)
  2195 */
  2196 EXPORT_C const TRequestStatus* RMessagePtr2::ClientStatus() const
  2197 	{
  2198 	return Exec::MessageClientStatus(iHandle);
  2199 	}
  2200 
  2201 
  2202 
  2203 EXPORT_C TInt RServer2::CreateGlobal(const TDesC& aName, TInt aMode, TInt aRole, TInt aOpts)
  2204 //
  2205 // Create a new server.
  2206 //
  2207 	{
  2208 	TInt r = User::ValidateName(aName);
  2209 	if (r != KErrNone)
  2210 		return r;
  2211 	TBuf8<KMaxKernelName> name8;
  2212 	name8.Copy(aName);
  2213 	r = Exec::ServerCreateWithOptions(&name8, aMode, aRole, aOpts);
  2214 	return SetReturnedHandle(r, *this);
  2215 	}
  2216 
  2217 EXPORT_C TInt RServer2::CreateGlobal(const TDesC& aName, TInt aMode)
  2218 	{
  2219 	return CreateGlobal(aName, aMode, EServerRole_Default, 0);
  2220 	}
  2221 
  2222 EXPORT_C TInt RServer2::CreateGlobal(const TDesC& aName)
  2223 	{
  2224 	return CreateGlobal(aName, EIpcSession_Sharable);
  2225 	}
  2226 
  2227 TInt RSessionBase::DoConnect(const TVersion &aVersion,TRequestStatus* aStatus)
  2228 	{
  2229 	extern int TVersion_size_assert[sizeof(TVersion)==sizeof(TInt)?1:-1]; // Make sure TVersion is same size as int
  2230 	(void)TVersion_size_assert;
  2231 
  2232 	TIpcArgs p(*(TInt*)&aVersion);
  2233 	TInt r;
  2234 	if(aStatus==NULL)
  2235 		r = SendSync(RMessage2::EConnect, &p);
  2236 	else
  2237 		r = SendAsync(RMessage2::EConnect, &p, aStatus);
  2238 	if (r!=KErrNone)
  2239 		Close();
  2240 	return r;
  2241 	}
  2242 
  2243 
  2244 
  2245 
  2246 /**
  2247 Creates a session with a server.
  2248 
  2249 It should be called as part of session initialisation in the derived class.
  2250 
  2251 @param aServer   The name of the server with which a session is to
  2252                  be established.
  2253 @param aVersion  The lowest version of the server with which this client
  2254                  is compatible.
  2255 @param aAsyncMessageSlots The number of message slots available to this session.
  2256                  This determines the number of outstanding requests the client
  2257                  may have with the server at any one time.
  2258                  The maximum number of slots is 255.
  2259 				 If aAsyncMessageSlots==-1 then this indicates that the session should use
  2260 				 messages from the global free pool of messages.
  2261 @param aType     The type of session to create. See TIpcSessionType.
  2262 @param aPolicy   A pointer to a TSecurityPolicy object. If this pointer is not 0 (zero)
  2263 				 then the policy is applied to the process in which the server is running.
  2264 				 If that process doesn't pass this security policy check, then the session
  2265 				 creation will fail with the error KErrPermissionDenied.
  2266 				 This security check allows clients to verify that the server has the expected
  2267 				 Platform Security attributes.
  2268 
  2269 				When a check fails the action taken is determined by the system wide Platform Security
  2270 				configuration. If PlatSecDiagnostics is ON, then a diagnostic message is emitted.
  2271 				If PlatSecEnforcement is OFF, then this function will return KErrNone even though the
  2272 				check failed.
  2273 
  2274 @param aStatus   A pointer to TRequestStatus object which will be signalled when the session
  2275 				 has been created, or in the event of an error.
  2276 				 If aStatus==0 then session creation is done synchronously.
  2277 
  2278 @return          KErrNone if successful;
  2279                  KErrArgument, if an attempt is made to specify more
  2280                  than 255 message slots;
  2281                  otherwise one of the other system-wide error codes.
  2282 */
  2283 EXPORT_C TInt RSessionBase::CreateSession(const TDesC& aServer,const TVersion& aVersion,TInt aAsyncMessageSlots,TIpcSessionType aType,const TSecurityPolicy* aPolicy, TRequestStatus* aStatus)
  2284 	{
  2285 	TInt r = User::ValidateName(aServer);
  2286 	if(KErrNone!=r)
  2287 		return r;
  2288 	TBuf8<KMaxKernelName> name8;
  2289 	name8.Copy(aServer);
  2290 	r=SetReturnedHandle(Exec::SessionCreate(name8,aAsyncMessageSlots,aPolicy,aType));
  2291 	if(r==KErrNone)
  2292 		r=DoConnect(aVersion,aStatus);
  2293 	return r;
  2294 	}
  2295 
  2296 
  2297 
  2298 
  2299 /**
  2300 Creates a session with a server.
  2301 
  2302 It should be called as part of session initialisation in the derived class.
  2303 
  2304 @param aServer   The name of the server with which a session is to
  2305                  be established.
  2306 @param aVersion  The lowest version of the server with which this client
  2307                  is compatible.
  2308 @param aAsyncMessageSlots The number of message slots available to this session.
  2309                  This determines the number of outstanding requests the client
  2310                  may have with the server at any one time.
  2311                  The maximum number of slots is 255.
  2312 				 If aAsyncMessageSlots==-1 then this indicates that the session should use
  2313 				 messages from the global free pool of messages.
  2314                  
  2315 @return          KErrNone if successful;
  2316                  KErrArgument, if an attempt is made to specify more
  2317                  than 255 message slots;
  2318                  otherwise one of the other system-wide error codes.
  2319 */
  2320 EXPORT_C TInt RSessionBase::CreateSession(const TDesC &aServer, const TVersion &aVersion, TInt aAsyncMessageSlots)
  2321 	{
  2322 	return RSessionBase::CreateSession(aServer,aVersion,aAsyncMessageSlots,EIpcSession_Unsharable,NULL,0);
  2323 	}
  2324 
  2325 
  2326 
  2327 
  2328 /**
  2329 Creates a session with a server.
  2330 
  2331 It should be called as part of session initialisation in the derived class.
  2332 
  2333 @param aServer   A handle to a server with which a session is to be established.	 
  2334 @param aVersion  The lowest version of the server with which this client
  2335                  is compatible.
  2336 @param aAsyncMessageSlots The number of message slots available to this session.
  2337                  This determines the number of outstanding requests the client
  2338                  may have with the server at any one time.
  2339                  The maximum number of slots is 255.
  2340 				 If aAsyncMessageSlots==-1 then this indicates that the session should use
  2341 				 messages from the global free pool of messages.
  2342 @param aType     The type of session to create. See TIpcSessionType.
  2343 @param aPolicy   A pointer to a TSecurityPolicy object. If this pointer is not 0 (zero)
  2344 				 then the policy is applied to the process in which the server is running.
  2345 				 If that process doesn't pass this security policy check, then the session
  2346 				 creation will fail with the error KErrPermissionDenied.
  2347 				 This security check allows clients to verify that the server has the expected
  2348 				 Platform Security attributes.
  2349 
  2350 				When a check fails the action taken is determined by the system wide Platform Security
  2351 				configuration. If PlatSecDiagnostics is ON, then a diagnostic message is emitted.
  2352 				If PlatSecEnforcement is OFF, then this function will return KErrNone even though the
  2353 				check failed.
  2354 
  2355 @param aStatus   A pointer to TRequestStatus object which will be signalled when the session
  2356 				 has been created, or in the event of an error.
  2357 				 If aStatus==0 then session creation is done synchronously.
  2358 
  2359 @return          KErrNone if successful;
  2360                  KErrArgument, if an attempt is made to specify more
  2361                  than 255 message slots;
  2362                  otherwise one of the other system-wide error codes.
  2363 */
  2364 EXPORT_C TInt RSessionBase::CreateSession(RServer2 aServer,const TVersion& aVersion,TInt aAsyncMessageSlots,TIpcSessionType aType,const TSecurityPolicy* aPolicy, TRequestStatus* aStatus)
  2365 	{
  2366 	TInt r;
  2367 	r=SetReturnedHandle(Exec::SessionCreateFromHandle(aServer.Handle(),aAsyncMessageSlots,aPolicy,aType));
  2368 	if(r==KErrNone)
  2369 		r=DoConnect(aVersion,aStatus);
  2370 	return r;
  2371 	}
  2372 
  2373 
  2374 
  2375 
  2376 /**
  2377 Creates a session with a server.
  2378 
  2379 It should be called as part of session initialisation in the derived class.
  2380 
  2381 @param aServer   A handle to a server with which a session is to be established.                
  2382 @param aVersion  The lowest version of the server with which this client
  2383                  is compatible.
  2384 @param aAsyncMessageSlots The number of message slots available to this session.
  2385                  This determines the number of outstanding requests the client
  2386                  may have with the server at any one time.
  2387                  The maximum number of slots is 255.
  2388 				 If aAsyncMessageSlots==-1 then this indicates that the session should use
  2389 				 messages from the global free pool of messages.
  2390 
  2391 @return          KErrNone if successful;
  2392                  KErrArgument, if an attempt is made to specify more
  2393                  than 255 message slots;
  2394                  otherwise one of the other system-wide error codes.
  2395 */
  2396 EXPORT_C TInt RSessionBase::CreateSession(RServer2 aServer, const TVersion &aVersion, TInt aAsyncMessageSlots)
  2397 	{
  2398 	return RSessionBase::CreateSession(aServer,aVersion,aAsyncMessageSlots,EIpcSession_Unsharable,NULL,0);
  2399 	}
  2400 
  2401 
  2402 
  2403 
  2404 /**
  2405 Opens a handle to a session using a handle number sent by a client
  2406 to a server.
  2407 
  2408 This function is called by the server.
  2409 
  2410 @param aMessage The message pointer.
  2411 @param aParam   An index specifying which of the four message arguments
  2412                 contains the handle number.
  2413 @param aType    An enumeration whose enumerators define the ownership of this 
  2414                 session handle. If not explicitly specified, EOwnerProcess
  2415 				is taken as default.
  2416                 
  2417 @return KErrNone, if successful;
  2418         KErrArgument, if the value of aParam is outside the range 0-3;
  2419         KErrBadHandle, if not a valid handle;
  2420         otherwise one of the other system-wide error codes.
  2421 */
  2422 EXPORT_C TInt RSessionBase::Open(RMessagePtr2 aMessage,TInt aParam,TOwnerType aType)
  2423 	{
  2424 	return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),ESession,aParam,aType));
  2425 	}
  2426 
  2427 
  2428 
  2429 
  2430 /**
  2431 Opens a handle to a session using a handle number sent by a client
  2432 to a server, and validate that the session's server passes a given
  2433 security policy.
  2434 
  2435 This function is called by the server.
  2436 
  2437 @param aMessage 		The message pointer.
  2438 @param aParam   		An index specifying which of the four message arguments
  2439                 		contains the handle number.
  2440 @param aServerPolicy	The policy to validate the session's server against.
  2441 @param aType    		An enumeration whose enumerators define the ownership of this 
  2442                 		session handle. If not explicitly specified, EOwnerProcess
  2443 						is taken as default.
  2444                 
  2445 @return KErrNone, if successful;
  2446         KErrArgument, if the value of aParam is outside the range 0-3;
  2447         KErrBadHandle, if not a valid handle;
  2448 		KErrServerTerminating, if the session is no longer connected to a server;
  2449 		KErrPermissionDenied, if the session's server does not pass the given security policy;
  2450         otherwise one of the other system-wide error codes.
  2451 */
  2452 EXPORT_C TInt RSessionBase::Open(RMessagePtr2 aMessage,TInt aParam,const TSecurityPolicy& aServerPolicy,TOwnerType aType)
  2453 	{
  2454 	return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),ESession,aParam,aType),aServerPolicy);
  2455 	}
  2456 
  2457 
  2458 
  2459 /**
  2460 Sets the handle-number of this session handle to the specified value after
  2461 validating that the session's server passes a given security policy.
  2462 
  2463 The function can take a (zero or positive) handle-number,
  2464 or a (negative) error number.
  2465 
  2466 If aHandleOrError represents a handle-number, then the handle-number of this handle
  2467 is set to that value, as long as the session's server passes the security policy.
  2468 If aHandleOrError represents an error number, then the handle-number of this handle is set to zero
  2469 and the negative value is returned.
  2470 
  2471 @param aHandleOrError A handle-number, if zero or positive; an error value, if negative.
  2472 @param aServerPolicy  The policy to validate the session's server against.
  2473 
  2474 @return KErrNone, if aHandle is a handle-number; KErrPermissionDenied, if the session's server
  2475         does not pass the security policy; the value of aHandleOrError, otherwise.
  2476 */
  2477 EXPORT_C TInt RSessionBase::SetReturnedHandle(TInt aHandleOrError,const TSecurityPolicy& aServerPolicy)
  2478 	{
  2479 	if(aHandleOrError<0)
  2480 		return aHandleOrError;
  2481 	
  2482 	TInt r = aServerPolicy.CheckPolicy((RSessionBase&)aHandleOrError);
  2483 	if (r!=KErrNone)
  2484 		{
  2485 		((RHandleBase&)aHandleOrError).Close();
  2486 		return r;
  2487 		}
  2488 
  2489 	iHandle=aHandleOrError;
  2490 	return KErrNone;
  2491 	}
  2492 
  2493 
  2494 
  2495 
  2496 /**
  2497 Opens a handle to a session using a handle number passed as an
  2498 environment data item to the child process during the creation of
  2499 that child process.
  2500 
  2501 Note that this function can only be called successfully once.
  2502 
  2503 @param aArgumentIndex An index that identifies the slot in the process
  2504                       environment data that contains the handle number. This is
  2505                       a value relative to zero, i.e. 0 is the first item/slot.
  2506                       This can range from 0 to 15.
  2507                       
  2508 @param aOwnerType     An enumeration whose enumerators define the ownership of
  2509                       this session handle. If not explicitly specified,
  2510                       EOwnerProcess is taken as default.
  2511                       
  2512 @return KErrNone, if successful; 
  2513         KErrNotFound, if the slot indicated by aArgumentIndex is empty;
  2514         KErrArgument, if the slot does not contain a session handle;
  2515         otherwise one of the other system-wide error codes.                      
  2516 */
  2517 EXPORT_C TInt RSessionBase::Open(TInt aArgumentIndex, TOwnerType aOwnerType)
  2518 	{
  2519 	return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, ESession, aOwnerType));
  2520 	}
  2521 
  2522 
  2523 /**
  2524 Opens a handle to a session using a handle number passed as an
  2525 environment data item to the child process during the creation of
  2526 that child process, after validating that the session's server passes
  2527 the given security policy.
  2528 
  2529 Note that this function can only be called successfully once.
  2530 
  2531 @param aArgumentIndex An index that identifies the slot in the process
  2532                       environment data that contains the handle number. This is
  2533                       a value relative to zero, i.e. 0 is the first item/slot.
  2534                       This can range from 0 to 15.
  2535 @param aServerPolicy  The policy to validate the session's server against.
  2536 @param aOwnerType     An enumeration whose enumerators define the ownership of
  2537                       this session handle. If not explicitly specified,
  2538                       EOwnerProcess is taken as default.
  2539                       
  2540 @return KErrNone, if successful; 
  2541         KErrNotFound, if the slot indicated by aArgumentIndex is empty;
  2542         KErrArgument, if the slot does not contain a session handle;
  2543 		KErrServerTerminating, if the session is no longer connected to a server;
  2544 		KErrPermissionDenied, if the session's server does not pass the given security policy;
  2545         otherwise one of the other system-wide error codes.                      
  2546 */
  2547 EXPORT_C TInt RSessionBase::Open(TInt aArgumentIndex, const TSecurityPolicy& aServerPolicy, TOwnerType aOwnerType)
  2548 	{
  2549 	return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, ESession, aOwnerType), aServerPolicy);
  2550 	}
  2551 
  2552 
  2553 EXPORT_C TInt RSessionBase::DoShare(TInt aMode)
  2554 //
  2555 // Make the session accessible to all threads in this process
  2556 //
  2557 	{
  2558 	return Exec::SessionShare(iHandle, (aMode&KCreateProtectedObject) ? EIpcSession_GlobalSharable : EIpcSession_Sharable);
  2559 	}
  2560 
  2561 
  2562 
  2563 
  2564 TInt RSessionBase::SendSync(TInt aFunction,const TIpcArgs* aArgs) const
  2565 //
  2566 // Send a synchronous message.
  2567 //
  2568 	{
  2569 	TRequestStatus s=KRequestPending;
  2570 	TInt r=Exec::SessionSendSync(iHandle,aFunction,(TAny*)aArgs,&s);
  2571 	if (r==KErrNone)
  2572 		{
  2573 		User::WaitForRequest(s);
  2574 		r=s.Int();
  2575 		}
  2576 	return r;
  2577 	}
  2578 
  2579 TInt RSessionBase::SendAsync(TInt aFunction,const TIpcArgs* aArgs,TRequestStatus *aStatus) const
  2580 //
  2581 // Send an asynchronous message.
  2582 //
  2583 	{
  2584 	if (aStatus)
  2585 		*aStatus=KRequestPending;
  2586 	return Exec::SessionSend(iHandle,aFunction,(TAny*)aArgs,aStatus);
  2587 	}
  2588 
  2589 
  2590 
  2591 
  2592 EXPORT_C TInt RMutex::CreateLocal(TOwnerType aType)
  2593 /**
  2594 Creates a mutex and opens this handle to the mutex.
  2595 
  2596 The kernel side object representing the mutex is unnamed. This means that 
  2597 it is not possible to search for the mutex, which makes it local to the current 
  2598 process.
  2599 
  2600 By default, any thread in the process can use this instance of RMutex to access 
  2601 the mutex. However, specifying EOwnerThread as the parameter to this function, 
  2602 means that only the creating thread can use this instance of RMutex to access 
  2603 the mutex; any other thread in this process that wants to access the mutex 
  2604 must duplicate this handle.
  2605 
  2606 @param aType An enumeration whose enumerators define the ownership of this 
  2607              mutex handle. If not explicitly specified, EOwnerProcess is taken
  2608              as default.
  2609              
  2610 @return KErrNone if successful, otherwise one of the system wide error codes.
  2611 
  2612 @see RHandleBase::Duplicate()
  2613 */
  2614 	{
  2615 	return SetReturnedHandle(Exec::MutexCreate(NULL,aType),*this);
  2616 	}
  2617 
  2618 
  2619 
  2620 
  2621 EXPORT_C TInt RMutex::CreateGlobal(const TDesC &aName,TOwnerType aType)
  2622 /**
  2623 Creates a global mutex and opens this handle to the mutex.
  2624 
  2625 The kernel side object representing the mutex is given the name contained 
  2626 in the specified descriptor, which makes it global. This means that any thread 
  2627 in any process can search for the mutex, using TFindMutex, and open a handle 
  2628 to it. If the specified name is empty the kernel side object representing the
  2629 mutex is unnamed and so cannot be opened by name. It can however be passed
  2630 to another process as a process parameter or via IPC.
  2631 
  2632 By default, any thread in the process can use this instance of RMutex to access 
  2633 the mutex. However, specifying EOwnerThread as the second parameter to this 
  2634 function, means that only the creating thread can use this instance of RMutex 
  2635 to access the mutex; any other thread in this process that wants to access 
  2636 the mutex must either duplicate this handle or use OpenGlobal().
  2637 
  2638 @param aName The name to be assigned to this global mutex.
  2639 @param aType An enumeration whose enumerators define the ownership of this 
  2640              mutex handle. If not explicitly specified, EOwnerProcess is
  2641              taken as default. 
  2642              
  2643 @return KErrNone if successful, otherwise one of the other system wide error 
  2644         codes. 
  2645         
  2646 @see OpenGlobal
  2647 @see RHandleBase::Duplicate()
  2648 @see TFindMutex
  2649 */
  2650 	{
  2651 	TInt r = User::ValidateName(aName);
  2652 	if(KErrNone!=r)
  2653 		return r;
  2654 	TBuf8<KMaxKernelName> name8;
  2655 	name8.Copy(aName);
  2656 	return SetReturnedHandle(Exec::MutexCreate(&name8,aType),*this);
  2657 	}
  2658 
  2659 
  2660 
  2661 
  2662 EXPORT_C TInt RMutex::OpenGlobal(const TDesC &aName,TOwnerType aType)
  2663 /**
  2664 Opens a handle to a global mutex.
  2665 
  2666 Global mutexes are identified by name.
  2667 
  2668 By default, any thread in the process can use this instance of RMutex to access 
  2669 the mutex. However, specifying EOwnerThread as the second parameter to this 
  2670 function, means that only the opening thread can use this instance of RMutex 
  2671 to access the mutex; any other thread in this process that wants to access 
  2672 the mutex must either duplicate the handle or use OpenGlobal() again.
  2673 
  2674 @param aName The name of the global mutex which is to be opened. 
  2675 @param aType An enumeration whose enumerators define the ownership of this 
  2676              mutex handle. If not explicitly specified, EOwnerProcess 
  2677              is taken as default. 
  2678              
  2679 @return KErrNone if successful, otherwise another of the system wide error 
  2680         codes. 
  2681 @see RHandleBase::Duplicate()
  2682 */
  2683 	{
  2684 	return OpenByName(aName,aType,EMutex);
  2685 	}
  2686 
  2687 
  2688 
  2689 
  2690 EXPORT_C TInt RMutex::Open(RMessagePtr2 aMessage,TInt aParam,TOwnerType aType)
  2691 /**
  2692 Opens a handle to a mutex using a handle number sent by a client
  2693 to a server.
  2694 
  2695 This function is called by the server.
  2696 
  2697 @param aMessage The message pointer.
  2698 @param aParam   An index specifying which of the four message arguments
  2699                 contains the handle number.
  2700 @param aType    An enumeration whose enumerators define the ownership of this 
  2701                 mutex handle. If not explicitly specified, EOwnerProcess is
  2702                 taken as default. 
  2703                 
  2704 @return KErrNone, if successful;
  2705         KErrArgument, if the value of aParam is outside the range 0-3;
  2706         KErrBadHandle, if not a valid handle;
  2707         otherwise one of the other system-wide error codes.
  2708 */
  2709 	{
  2710 	return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),EMutex,aParam,aType));
  2711 	}
  2712 
  2713 
  2714 
  2715 
  2716 EXPORT_C TInt RMutex::Open(TInt aArgumentIndex, TOwnerType aOwnerType)
  2717 /**
  2718 Opens a handle to a mutex using a handle number passed as an
  2719 environment data item to the child process during the creation of
  2720 that child process.
  2721 
  2722 Note that this function can only be called successfully once.
  2723 
  2724 @param aArgumentIndex An index that identifies the slot in the process
  2725                       environment data that contains the handle number. This is
  2726                       a value relative to zero, i.e. 0 is the first item/slot.
  2727                       This can range from 0 to 15.
  2728 
  2729 @param aOwnerType     An enumeration whose enumerators define the ownership of
  2730                       this mutex handle. If not explicitly specified,
  2731                       EOwnerProcess is taken as default.
  2732 
  2733 @return KErrNone, if successful; 
  2734         KErrNotFound, if the slot indicated by aArgumentIndex is empty;
  2735         KErrArgument, if the slot does not contain a mutex handle;
  2736         otherwise one of the other system-wide error codes.
  2737         
  2738 @see RProcess::SetParameter()
  2739 */
  2740 	{
  2741 	return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, EMutex, aOwnerType));
  2742 	}
  2743 
  2744 
  2745 
  2746 EXPORT_C TInt RCondVar::CreateLocal(TOwnerType aType)
  2747 /**
  2748 Creates a condition variable and opens this handle to it.
  2749 
  2750 The kernel side object representing the condition variable is unnamed and so
  2751 the condition variable cannot be found by name and hence it is local to the
  2752 current process.
  2753 
  2754 By default, any thread in the process can use this instance of RCondVar to access
  2755 the condition variable. However, specifying EOwnerThread as the parameter to this
  2756 function means that only the creating thread can use this instance of RCondVar
  2757 to access the condition variable; any other thread in this process that wants to
  2758 access the condition variable must duplicate this handle.
  2759 
  2760 @param aType	An enumeration whose enumerators define the ownership of this 
  2761 				condition variable handle. If not explicitly specified, EOwnerProcess
  2762 				is taken as default.
  2763              
  2764 @return KErrNone if successful, otherwise one of the system wide error codes.
  2765 
  2766 @see RHandleBase::Duplicate()
  2767 */
  2768 	{
  2769 	return SetReturnedHandle(Exec::CondVarCreate(NULL, aType), *this);
  2770 	}
  2771 
  2772 
  2773 
  2774 
  2775 EXPORT_C TInt RCondVar::CreateGlobal(const TDesC& aName, TOwnerType aType)
  2776 /**
  2777 Creates a global condition variable and opens this handle to it.
  2778 
  2779 If the specified name is a non-empty string the kernel side object representing
  2780 the condition variable is given the specified name and is therefore global. It
  2781 may subsequently be opened by name using the RCondVar::OpenGlobal function.
  2782 If the specified name is empty the kernel side object representing the condition
  2783 variable is unnamed and so cannot be opened by name. It can however be passed
  2784 to another process as a process parameter or via IPC.
  2785 
  2786 If the specified name is non-empty it must consist entirely of printable ASCII
  2787 characters (codes 0x20 to 0x7e inclusive) and may not contain : * or ?.
  2788 
  2789 By default, any thread in the process can use this instance of RCondVar to access
  2790 the condition variable. However, specifying EOwnerThread as the parameter to this
  2791 function means that only the creating thread can use this instance of RCondVar
  2792 to access the condition variable; any other thread in this process that wants to
  2793 access the condition variable must duplicate this handle.
  2794 
  2795 @param aName	The name to be assigned to this condition variable.
  2796 @param aType	An enumeration whose enumerators define the ownership of this 
  2797 				condition variable handle. If not explicitly specified, EOwnerProcess
  2798 				is taken as default.
  2799                           
  2800 @return KErrNone if successful, otherwise one of the other system wide error 
  2801         codes. 
  2802         
  2803 @see RCondVar::OpenGlobal()
  2804 @see RHandleBase::Duplicate()
  2805 @see RProcess::SetParameter(TInt, RHandleBase)
  2806 @see TIpcArgs::Set(TInt, RHandleBase)
  2807 @see RMessagePtr2::Complete(RHandleBase)
  2808 */
  2809 	{
  2810 	TInt r = User::ValidateName(aName);
  2811 	if (KErrNone!=r)
  2812 		return r;
  2813 	TBuf8<KMaxKernelName> name8;
  2814 	name8.Copy(aName);
  2815 	return SetReturnedHandle(Exec::CondVarCreate(&name8, aType), *this);
  2816 	}
  2817 
  2818 
  2819 
  2820 
  2821 EXPORT_C TInt RCondVar::OpenGlobal(const TDesC& aName, TOwnerType aType)
  2822 /**
  2823 Opens a handle to a global condition variable.
  2824 
  2825 Global condition variables are identified by name.
  2826 
  2827 By default, any thread in the process can use this instance of RCondVar to access
  2828 the condition variable. However, specifying EOwnerThread as the parameter to this
  2829 function means that only the creating thread can use this instance of RCondVar
  2830 to access the condition variable; any other thread in this process that wants to
  2831 access the condition variable must either duplicate this handle or use OpenGlobal
  2832 again.
  2833 
  2834 @param aName The name of the global condition variable which is to be opened. 
  2835 @param aType An enumeration whose enumerators define the ownership of this 
  2836              condition variable handle. If not explicitly specified, EOwnerProcess
  2837              is taken as default. 
  2838              
  2839 @return KErrNone if successful, otherwise another of the system wide error 
  2840         codes. 
  2841         
  2842 @see RHandleBase::Duplicate()
  2843 */
  2844 	{
  2845 	return OpenByName(aName, aType, ECondVar);
  2846 	}
  2847 
  2848 
  2849 
  2850 
  2851 EXPORT_C TInt RCondVar::Open(RMessagePtr2 aMessage, TInt aParam, TOwnerType aType)
  2852 /**
  2853 Opens a handle to a condition variable using a handle number sent by a client
  2854 to a server.
  2855 
  2856 This function is called by the server.
  2857 
  2858 @param aMessage The message pointer.
  2859 @param aParam   An index specifying which of the four message arguments
  2860                 contains the handle number.
  2861 @param aType    An enumeration whose enumerators define the ownership of this 
  2862                 condition variable handle. If not explicitly specified, EOwnerProcess
  2863 				is taken as default.
  2864                 
  2865 @return KErrNone, if successful;
  2866         KErrArgument, if the value of aParam is outside the range 0-3;
  2867         KErrBadHandle, if not a valid handle;
  2868         otherwise one of the other system-wide error codes.
  2869 */
  2870 	{
  2871 	return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(), ECondVar, aParam, aType));
  2872 	}
  2873 
  2874 
  2875 
  2876 
  2877 EXPORT_C TInt RCondVar::Open(TInt aArgumentIndex, TOwnerType aType)
  2878 /**
  2879 Opens a handle to a condition variable using a handle number passed as an
  2880 environment data item to the child process during the creation of
  2881 that child process.
  2882 
  2883 Note that this function can only be called successfully once.
  2884 
  2885 @param aArgumentIndex An index that identifies the slot in the process
  2886                       environment data that contains the handle number. This is
  2887                       a value relative to zero, i.e. 0 is the first item/slot.
  2888                       This can range from 0 to 15.
  2889 
  2890 @param aType          An enumeration whose enumerators define the ownership of
  2891                       this condition variable handle. If not explicitly specified,
  2892                       EOwnerProcess is taken as default.
  2893 
  2894 @return KErrNone, if successful; 
  2895         KErrNotFound, if the slot indicated by aArgumentIndex is empty;
  2896         KErrArgument, if the slot does not contain a condition variable handle;
  2897         otherwise one of the other system-wide error codes.
  2898         
  2899 @see RProcess::SetParameter()
  2900 */
  2901 	{
  2902 	return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, ECondVar, aType));
  2903 	}
  2904 
  2905 
  2906 
  2907 
  2908 EXPORT_C TInt RSemaphore::CreateLocal(TInt aCount,TOwnerType aType)
  2909 /**
  2910 Creates a semaphore, setting its initial count, and opens this handle to the 
  2911 semaphore.
  2912 
  2913 The kernel side object representing the semaphore is unnamed. This means that 
  2914 it is not possible to search for the semaphore, which makes it local to the 
  2915 current process.
  2916 
  2917 By default, any thread in the process can use this instance of RSemaphore 
  2918 to access the semaphore. However, specifying EOwnerThread as the second parameter 
  2919 to this function, means that only the creating thread can use this instance 
  2920 of RSemaphore to access the semaphore; any other thread in this process that 
  2921 wants to access the semaphore must duplicate this handle.
  2922 
  2923 @param aCount The initial value of the semaphore count. 
  2924 @param aType  An enumeration whose enumerators define the ownership of this 
  2925               semaphore handle. If not explicitly specified, EOwnerProcess is
  2926               taken as default. 
  2927 
  2928 @return KErrNone if successful, otherwise another of the system wide error 
  2929         codes. 
  2930         
  2931 @panic USER 105 if aCount is negative.
  2932 
  2933 @see RHandleBase::Duplicate()
  2934 */
  2935 	{
  2936 
  2937 	__ASSERT_ALWAYS(aCount>=0,Panic(ESemCreateCountNegative));
  2938 	return SetReturnedHandle(Exec::SemaphoreCreate(NULL,aCount,aType),*this);
  2939 	}
  2940 
  2941 
  2942 
  2943 
  2944 EXPORT_C TInt RSemaphore::CreateGlobal(const TDesC &aName,TInt aCount,TOwnerType aType)
  2945 /**
  2946 Creates a global semaphore, setting its initial count, and opens this handle
  2947 to the semaphore.
  2948 
  2949 The kernel side object representing the semaphore is given the name contained 
  2950 in the specified descriptor, which makes it global. This means that any thread 
  2951 in any process can search for the semaphore, using TFindSemaphore, and open 
  2952 a handle to it. If the specified name is empty the kernel side object
  2953 representing the semaphore is unnamed and so cannot be opened by name. It can
  2954 however be passed to another process as a process parameter or via IPC.
  2955 
  2956 By default, any thread in the process can use this instance of RSemaphore 
  2957 to access the semaphore. However, specifying EOwnerThread as the third
  2958 parameter to this function, means that only the creating thread can use
  2959 this instance of RSemaphore to access the semaphore; any other thread in
  2960 this process that wants to access the semaphore must either duplicate this
  2961 handle or use OpenGlobal().
  2962 
  2963 @param aName  A reference to the descriptor containing the name to be assigned 
  2964               to this global semaphore. 
  2965 @param aCount The initial value of the semaphore count.
  2966 @param aType  An enumeration whose enumerators define the ownership of this 
  2967               semaphore handle. If not explicitly specified, EOwnerProcess is
  2968               taken as default. 
  2969 
  2970 @return KErrNone if successful otherwise another of the system wide error
  2971         codes. 
  2972 
  2973 @panic USER 105 if aCount is negative.
  2974 
  2975 @see RSemaphore::OpenGlobal()
  2976 @see RHandleBase::Duplicate()
  2977 @see TFindSemaphore
  2978 */
  2979 	{
  2980 
  2981 	__ASSERT_ALWAYS(aCount>=0,Panic(ESemCreateCountNegative));
  2982 	TInt r = User::ValidateName(aName);
  2983 	if(KErrNone!=r)
  2984 		return r;
  2985 	TBuf8<KMaxKernelName> name8;
  2986 	name8.Copy(aName);
  2987 	return SetReturnedHandle(Exec::SemaphoreCreate(&name8,aCount,aType),*this);
  2988 	}
  2989 
  2990 
  2991 
  2992 
  2993 EXPORT_C TInt RSemaphore::OpenGlobal(const TDesC &aName,TOwnerType aType)
  2994 /**
  2995 Opens a handle to a global semaphore.
  2996 
  2997 Global semaphores are identified by name.
  2998 
  2999 By default, any thread in the process can use this instance of RSemaphore 
  3000 to access the semaphore. However, specifying EOwnerThread as the second parameter 
  3001 to this function, means that only the opening thread can use this instance 
  3002 of RSemaphore to access the semaphore; any other thread in this process that 
  3003 wants to access the semaphore must either duplicate the handle or use OpenGlobal() 
  3004 again.
  3005 
  3006 @param aName A reference to the descriptor containing the name of the global 
  3007              semaphore  to be opened. 
  3008 @param aType An enumeration whose enumerators define the ownership of this 
  3009              semaphore handle. If not explicitly specified, EOwnerProcess is
  3010              taken as default. 
  3011 
  3012 @return KErrNone if successful otherwise another of the system wide error
  3013         codes. 
  3014 
  3015 @see RHandleBase::Duplicate()
  3016 */
  3017 	{
  3018 	return OpenByName(aName,aType,ESemaphore);
  3019 	}
  3020 
  3021 
  3022 
  3023 
  3024 EXPORT_C TInt RSemaphore::Open(RMessagePtr2 aMessage,TInt aParam,TOwnerType aType)
  3025 /**
  3026 Opens a handle to a semaphore using a handle number sent by a client
  3027 to a server.
  3028 
  3029 This function is called by the server.
  3030 
  3031 @param aMessage The message pointer.
  3032 @param aParam   An index specifying which of the four message arguments
  3033                 contains the handle number.
  3034 @param aType    An enumeration whose enumerators define the ownership of this 
  3035                 semaphore handle. If not explicitly specified, EOwnerProcess is
  3036                 taken as default. 
  3037                 
  3038 @return KErrNone, if successful;
  3039         KErrArgument, if the value of aParam is outside the range 0-3;
  3040         KErrBadHandle, if not a valid handle;
  3041         otherwise one of the other system-wide error codes.
  3042 */
  3043 	{
  3044 	return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),ESemaphore,aParam,aType));
  3045 	}
  3046 
  3047 
  3048 
  3049 
  3050 EXPORT_C TInt RSemaphore::Open(TInt aArgumentIndex, TOwnerType aOwnerType)
  3051 /**
  3052 Opens a handle to a semaphore using a handle number passed as an
  3053 environment data item to the child process during the creation of
  3054 that child process.
  3055 
  3056 Note that this function can only be called successfully once.
  3057 
  3058 @param aArgumentIndex An index that identifies the slot in the process
  3059                       environment data that contains the handle number. This is
  3060                       a value relative to zero, i.e. 0 is the first item/slot.
  3061                       This can range from 0 to 15.
  3062 
  3063 @param aOwnerType     An enumeration whose enumerators define the ownership of
  3064                       this semaphore handle. If not explicitly specified,
  3065                       EOwnerProcess is taken as default.
  3066 
  3067 @return KErrNone, if successful; 
  3068         KErrNotFound, if the slot indicated by aArgumentIndex is empty;
  3069         KErrArgument, if the slot does not contain a Semaphore handle;
  3070         otherwise one of the other system-wide error codes.
  3071         
  3072 @see RProcess::SetParameter()
  3073 */
  3074 	{
  3075 	return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, ESemaphore, aOwnerType));
  3076 	}
  3077 
  3078 
  3079 
  3080 
  3081 EXPORT_C TInt RCriticalSection::CreateLocal(TOwnerType aType)
  3082 /**
  3083 Creates a critical section and opens this handle to the critical section.
  3084 
  3085 The kernel side object representing the critical section is unnamed. This 
  3086 means that it is not possible to search for the critical section, which makes 
  3087 it local to the current process.
  3088 
  3089 By default, any thread in the process can use this instance of RCriticalSection 
  3090 to access the critical section. However, specifying EOwnerThread as the parameter 
  3091 to this function, means that only the creating thread can use this instance 
  3092 of RCriticalSection to access the critical section; any other thread in this 
  3093 process that wants to access the critical section must duplicate this handle.
  3094 
  3095 @param aType An enumeration whose enumerators define the ownership of this 
  3096              critical section handle. If not explicitly specified,
  3097              EOwnerProcess is taken as default. 
  3098              
  3099 @return KErrNone if successful otherwise another of the system wide error codes.
  3100 
  3101 @see RHandleBase::Duplicate()
  3102 */
  3103 	{
  3104 
  3105 	iBlocked=1;
  3106 	return(RSemaphore::CreateLocal(0,aType));
  3107 	}
  3108 
  3109 
  3110 
  3111 /**
  3112 Creates a local fast semaphore, and opens this handle to the 
  3113 semaphore.
  3114 
  3115 @param aType  An enumeration whose enumerators define the ownership of this 
  3116               semaphore handle. If not explicitly specified, EOwnerProcess is
  3117               taken as default. 
  3118 
  3119 @return KErrNone if successful, otherwise one of the system wide error 
  3120         codes. 
  3121 
  3122 @see RSemaphore::CreateLocal()
  3123 */
  3124 EXPORT_C TInt RFastLock::CreateLocal(TOwnerType aType)
  3125 	{
  3126 
  3127 	iCount=0;
  3128 	return RSemaphore::CreateLocal(0,aType);
  3129 	}
  3130 
  3131 
  3132 
  3133 
  3134 EXPORT_C TInt RTimer::CreateLocal()
  3135 //
  3136 // Create a local timer.
  3137 //
  3138 /**
  3139 Creates a thread-relative timer.
  3140 
  3141 @return KErrNone if successful, otherwise another of the
  3142         system-wide error codes.
  3143 */
  3144 	{
  3145 	return SetReturnedHandle(Exec::TimerCreate(),*this);
  3146 	}
  3147 
  3148 
  3149 
  3150 
  3151 EXPORT_C TInt RProcess::Open(const TDesC &aName,TOwnerType aType)
  3152 /**
  3153 Opens a handle to a specifically named process.
  3154 
  3155 By default, ownership of this process handle is vested in the current process, 
  3156 but can be vested in the current thread by passing EOwnerThread as the second 
  3157 parameter to this function.
  3158 
  3159 @param aName A reference to the descriptor containing the name of the process 
  3160              to be opened.
  3161 @param aType An enumeration whose enumerators define the ownership of this 
  3162              thread handle. If not explicitly specified, EOwnerProcess is
  3163              taken as default.
  3164              
  3165 @return KErrNone, if successful, otherwise one of the other system-wide error 
  3166         codes.
  3167 */
  3168 	{
  3169 	return OpenByName(aName,aType,EProcess);
  3170 	}
  3171 
  3172 
  3173 
  3174 
  3175 EXPORT_C TInt RProcess::Open(TProcessId aId,TOwnerType aType)
  3176 /**
  3177 Opens a handle to the process whose process Id matches
  3178 the specified process ID.
  3179 
  3180 By default, ownership of this process handle is vested in the current process, 
  3181 but can be vested in the current thread by passing EOwnerThread as the second 
  3182 parameter to this function.
  3183 
  3184 @param aId   The process Id used to find the process.
  3185 @param aType An enumeration whose enumerators define the ownership of this 
  3186              process handle. If not explicitly specified, EOwnerProcess is
  3187              taken as default.
  3188              
  3189 @return KErrNone, if successful, otherwise one of the other system-wide error
  3190         codes.
  3191 */
  3192 	{
  3193 
  3194 	TUint id=*(TUint*)&aId;
  3195 	return SetReturnedHandle(Exec::ProcessOpenById(id,aType),*this);
  3196 	}
  3197 
  3198 
  3199 
  3200 
  3201 EXPORT_C TInt User::RenameProcess(const TDesC &aName)
  3202 /**
  3203 Assigns a new name to the current process, replacing any existing name.
  3204 
  3205 When a process is created, its default name is the name portion of the filename 
  3206 from which the executable is loaded.
  3207 
  3208 The new name must be a valid name and it must also be such that the process's 
  3209 new fullname remains unique amongst processes. 
  3210 
  3211 @param aName A reference to the descriptor containing the new name of the 
  3212              process.
  3213              
  3214 @return KErrNone, if successful, or if the new and old names are identical;
  3215         KErrBadName, if aName is an invalid;
  3216         otherwise one of the other system-wide error codes.
  3217 */
  3218 	{
  3219 	TBuf8<KMaxKernelName> name8;
  3220 	name8.Copy(aName);
  3221 	return Exec::ProcessRename(KCurrentProcessHandle,name8);
  3222 	}
  3223 
  3224 
  3225 
  3226 
  3227 /**
  3228 Ends this process, and all of its threads, specifying a reason code.
  3229 
  3230 This function is intended to be used if a process is exiting under normal
  3231 conditions.
  3232 
  3233 If the process is system permanent, the entire system is rebooted.
  3234 
  3235 @param aReason The reason to be associated with the ending of this process.
  3236 
  3237 @capability PowerMgmt  except when one of the following situations is true:
  3238 					   1. the process calling this function is the same as the 
  3239 					      process to be terminated.
  3240 					   2. the process calling this function created the process
  3241 					      to be terminated, but has not yet resumed that process.
  3242 
  3243 @see User::SetProcessCritical()
  3244 @see User::ProcessCritical()
  3245 */
  3246 EXPORT_C void RProcess::Kill(TInt aReason)
  3247 	{
  3248 	Exec::ProcessKill(iHandle,EExitKill,aReason,NULL);
  3249 	}
  3250 
  3251 
  3252 /**
  3253 Ends this process, and all of its threads, specifying a reason code.
  3254 
  3255 This function is intended to be used if a process is exiting under abnormal
  3256 conditions, for example if an error condition has been detected.
  3257 
  3258 If the process is system critical or system permanent, the entire system is
  3259 rebooted.
  3260 
  3261 @param aReason The reason to be associated with the ending of this process.
  3262 
  3263 @capability PowerMgmt  except when one of the following situations is true:
  3264 					   1. the process calling this function is the same as the 
  3265 					      process to be terminated.
  3266 					   2. the process calling this function created the process
  3267 					      to be terminated, but has not yet resumed that process.
  3268 
  3269 @see User::SetProcessCritical()
  3270 @see User::ProcessCritical()
  3271 */
  3272 EXPORT_C void RProcess::Terminate(TInt aReason)
  3273 	{
  3274 	Exec::ProcessKill(iHandle,EExitTerminate,aReason,NULL);
  3275 	}
  3276 
  3277 
  3278 
  3279 /**
  3280 Panics the process and all of its owned threads, specifying the panic category
  3281 name and reason code.
  3282 
  3283 The length of the category name should be no greater than 16; any name with 
  3284 a length greater than 16 is truncated to 16.
  3285 
  3286 If the process is system critical or system permanent, the entire system is
  3287 rebooted.
  3288 
  3289 @param aCategory A reference to the descriptor containing the text which
  3290                  defines the category name for this panic.
  3291 @param aReason   The panic number.
  3292 
  3293 @capability PowerMgmt  except when one of the following situations is true:
  3294 					   1. the process calling this function is the same as the 
  3295 					      process to be terminated.
  3296 					   2. the process calling this function created the process
  3297 					      to be terminated, but has not yet resumed that process.
  3298 
  3299 @see User::SetProcessCritical()
  3300 @see User::ProcessCritical()
  3301 */
  3302 EXPORT_C void RProcess::Panic(const TDesC &aCategory,TInt aReason)
  3303 	{
  3304 	TBuf8<KMaxExitCategoryName> name8;
  3305 	TInt length=aCategory.Length();
  3306 	if(length>KMaxExitCategoryName)
  3307 		{
  3308 		TPtr catPtr((TUint16*)aCategory.Ptr(),KMaxExitCategoryName,KMaxExitCategoryName);
  3309 		name8.Copy(catPtr);
  3310 		}
  3311 	else
  3312 		{
  3313 		name8.Copy(aCategory);
  3314 		}
  3315 	Exec::ProcessKill(iHandle,EExitPanic,aReason,&name8);
  3316 	}
  3317 
  3318 
  3319 
  3320 
  3321 EXPORT_C void RProcess::Logon(TRequestStatus &aStatus) const
  3322 /**
  3323 Requests notification when this process dies, normally or otherwise.
  3324 
  3325 A request for notification is an asynchronous request, and completes:
  3326 
  3327 - when the process terminates
  3328 - if the outstanding request is cancelled by a call to RProcess::LogonCancel().
  3329 
  3330 A request for notification requires memory to be allocated; if this is
  3331 unavailable, then the call to Logon() returns, and the asynchronous request
  3332 completes immediately.
  3333 
  3334 @param aStatus A reference to the request status object.
  3335                This contains the reason code describing the reason for  
  3336                the termination of the process, i.e. the value returned by a call to RProcess::ExitReason().
  3337                Alternatively, this is set to:
  3338                KErrCancel, if an outstanding request is cancelled;
  3339                KErrNoMemory, if there is insufficient memory to deal with the request. 
  3340 
  3341 @see RProcess::LogonCancel()
  3342 @see RProcess::ExitReason()
  3343 */
  3344 	{
  3345 
  3346 	aStatus=KRequestPending;
  3347 	Exec::ProcessLogon(iHandle,&aStatus,EFalse);
  3348 	}
  3349 
  3350 
  3351 
  3352 
  3353 EXPORT_C TInt RProcess::LogonCancel(TRequestStatus &aStatus) const
  3354 /**
  3355 Cancels an outstanding request for notification of the death of this process.
  3356 
  3357 A request for notification must previously have been made, otherwise the function 
  3358 returns KErrGeneral.
  3359 
  3360 The caller passes a reference to the same request status object as was passed 
  3361 in the original call to Logon().
  3362 
  3363 @param aStatus A reference to the same request status object used in
  3364                the original call to Logon().
  3365                
  3366 @return KErrGeneral, if there is no outstanding request; KErrNone otherwise.
  3367 
  3368 @see RProcess::Logon()
  3369 */
  3370 	{
  3371 	return Exec::ProcessLogonCancel(iHandle,&aStatus,EFalse);
  3372 	}
  3373 
  3374 
  3375 
  3376 
  3377 /**
  3378 Creates a Rendezvous request with the process.
  3379 
  3380 The request is an asynchronous request, and completes:
  3381 
  3382 - when a call is made to RProcess::Rendezvous(TInt aReason).
  3383 - if the outstanding request is cancelled by a call to RProcess::RendezvousCancel()
  3384 - if the process exits
  3385 - if the process panics.
  3386 
  3387 Note that a request requires memory to be allocated; if this is unavailable,
  3388 then this call to Rendezvous() returns, and the asynchronous request
  3389 completes immediately.
  3390 
  3391 @param aStatus A reference to the request status object.
  3392                The Rendezvous completes normally when 
  3393                RProcess::Rendezvous(TInt aReason) is called, and this 
  3394                request status object will contain this reason code.
  3395                If the process exits or panics, then this is the process exit
  3396                reason value, i.e. the same value returned by RProcess::ExitReason().
  3397                Alternatively, this is set to:
  3398                KErrCancel, if an outstanding request is cancelled;
  3399                KErrNoMemory, if there is insufficient memory to deal with the request.
  3400 
  3401 @see RProcess::Rendezvous(TInt aReason)
  3402 @see RProcess::RendezvousCancel(TRequestStatus& aStatus)
  3403 */
  3404 EXPORT_C void RProcess::Rendezvous(TRequestStatus& aStatus) const
  3405 	{
  3406 	aStatus=KRequestPending;
  3407 	Exec::ProcessLogon(iHandle,&aStatus,ETrue);
  3408 	}
  3409 
  3410 
  3411 
  3412 
  3413 /**
  3414 Cancels a previously requested Rendezvous with the process.
  3415 
  3416 The request completes with the value KErrCancel (if it was still outstanding).
  3417 
  3418 @param aStatus A reference to the same request status object used in
  3419                the original call to Rendezvous(TRequestStatus& aStatus).
  3420 
  3421 @return KErrGeneral, if there is no outstanding request, KErrNone otherwise.
  3422 
  3423 @see RProcess::Rendezvous(TRequestStatus &aStatus)
  3424 */
  3425 EXPORT_C TInt RProcess::RendezvousCancel(TRequestStatus& aStatus) const
  3426 	{
  3427 	return Exec::ProcessLogonCancel(iHandle,&aStatus,ETrue);
  3428 	}
  3429 
  3430 
  3431 
  3432 
  3433 /**
  3434 Completes all Rendezvous' with the current process.
  3435 
  3436 @param aReason The reason code used to complete all rendezvous requests
  3437 
  3438 @see RProcess::Rendezvous(TRequestStatus& aStatus)
  3439 */
  3440 EXPORT_C void RProcess::Rendezvous(TInt aReason)
  3441 	{
  3442 	Exec::ProcessRendezvous(aReason);
  3443 	}
  3444 
  3445 
  3446 /**
  3447 This can be used to determine whether the data for the process is demand paged
  3448 by default or not.
  3449 
  3450 @return ETrue if the default for the process's data is to be demand paged, 
  3451 		EFalse otherwise.
  3452 
  3453 @prototype
  3454 */
  3455 EXPORT_C TBool RProcess::DefaultDataPaged() const
  3456 	{
  3457 	return Exec::ProcessDefaultDataPaged(iHandle);
  3458 	}
  3459 
  3460 
  3461 //
  3462 // Class TThreadCreateInfo
  3463 //
  3464 
  3465 /**
  3466 Constructor where the basic properties of the thread to be created are specified.
  3467 
  3468 NOTE - TThreadCreateInfo::SetCreateHeap() or TThreadCreateInfo::SetUseHeap() must
  3469 be invoked on this TThreadCreateInfo to set the type of the thread to be created
  3470 before being passed as a paramter to RThread::Create().
  3471 
  3472 @param aName        The name to be assigned to the thread.
  3473 					KNullDesC, to create an anonymous thread.
  3474 @param aFunction    A pointer to a function. Control passes to this function
  3475                     when the thread is first resumed, i.e. when the thread
  3476                     is initially scheduled to run.
  3477 @param aStackSize   The size of the new thread's stack.
  3478 @param aPtr         A pointer to data to be passed as a parameter to
  3479                     the thread function when the thread is initially scheduled
  3480                     to run. If the thread function does not need any data then
  3481                     this pointer can be NULL.
  3482 */
  3483 EXPORT_C TThreadCreateInfo::TThreadCreateInfo(const TDesC &aName, TThreadFunction aFunction, 
  3484 											TInt aStackSize, TAny* aPtr) :
  3485 	iVersionNumber(EVersion0), iName(&aName), iFunction(aFunction), 
  3486 	iStackSize(aStackSize),	iParameter(aPtr), iOwner(EOwnerProcess), iHeap(NULL), 
  3487 	iHeapMinSize(0), iHeapMaxSize(0), iAttributes(0)
  3488 	{
  3489 	};
  3490 
  3491 
  3492 /**
  3493 Sets the thread to be created to create its own heap.
  3494 
  3495 @param aHeapMinSize The minimum size for the new thread's heap.
  3496 @param aHeapMaxSize The maximum size for the new thread's heap.
  3497 */
  3498 EXPORT_C void TThreadCreateInfo::SetCreateHeap(TInt aHeapMinSize, TInt aHeapMaxSize)
  3499 	{
  3500 	iHeapMinSize = aHeapMinSize;
  3501 	iHeapMaxSize = aHeapMaxSize;
  3502 	}
  3503 
  3504 
  3505 /**
  3506 Sets the thread to be created to use the heap whose handle is pointed to by 
  3507 aAllocator. If this is NULL, then the thread uses the heap of the creating thread.
  3508 
  3509 @param aAllocator A pointer to the handle of the heap belonging to another thread 
  3510                   which this thread is to use.
  3511 */
  3512 EXPORT_C void TThreadCreateInfo::SetUseHeap(const RAllocator *aAllocator)
  3513 	{
  3514 	iHeap = (aAllocator)? (RAllocator*)aAllocator : GetHeap();
  3515 	}
  3516 
  3517 
  3518 /**
  3519 Sets the owner the thread to be created. Any previous calls 
  3520 to this method will be overridden for this TThreadCreateInfo object.
  3521 
  3522 @param aOwner	The owner of the thread to be created.
  3523 */
  3524 EXPORT_C void TThreadCreateInfo::SetOwner(const TOwnerType aOwner)
  3525 	{
  3526 	iOwner = aOwner;
  3527 	}
  3528 
  3529 
  3530 /**
  3531 Sets the data paging attributes of the thread to be created. Any previous calls 
  3532 to this method will be overridden for this TThreadCreateInfo object.
  3533 
  3534 @param aPaging	The paging attributes for the thread to be created.
  3535 */
  3536 EXPORT_C void TThreadCreateInfo::SetPaging(const TThreadPagingAtt aPaging)
  3537 	{
  3538 	iAttributes &= ~EThreadCreateFlagPagingMask;
  3539 	if (aPaging == EPaged)
  3540 		iAttributes |= EThreadCreateFlagPaged;
  3541 	if (aPaging == EUnpaged)
  3542 		iAttributes |= EThreadCreateFlagUnpaged;
  3543 	}
  3544 
  3545 
  3546 /**
  3547 Creates a thread belonging to the current process, and opens this handle
  3548 to that thread.  The thread will have the properties as defined by the parameter
  3549 aCreateInfo.
  3550 
  3551 @param 	aCreateInfo		A reference to a TThreadCreateInfo object specifying 
  3552 						the properties of thread to create.
  3553 
  3554 @return KErrNone if successful, otherwise one of the other system-wide error codes.
  3555         KErrAlreadyExists will be returned if there is another thread in this process with the
  3556         specified name.
  3557 
  3558 @panic USER 109 if the stack size specified for the thread is negative.
  3559 @panic USER 110 if the specified minimum heap size is less than KMinHeapSize.
  3560 @panic USER 111 if the specified maximum heap size is less than the specified minimum heap size.
  3561 */
  3562 EXPORT_C TInt RThread::Create(const TThreadCreateInfo& aCreateInfo)
  3563 	{
  3564 	__ASSERT_ALWAYS(aCreateInfo.iStackSize >= 0, ::Panic(EThrdStackSizeNegative));
  3565 	if (!aCreateInfo.iHeap)
  3566 		{// Creating a new heap so verify the parameters.
  3567 		__ASSERT_ALWAYS(aCreateInfo.iHeapMinSize >= KMinHeapSize,::Panic(EThrdHeapMinTooSmall));
  3568 		__ASSERT_ALWAYS(aCreateInfo.iHeapMaxSize >= aCreateInfo.iHeapMinSize,::Panic(EThrdHeapMaxLessThanMin));
  3569 		}
  3570 
  3571 	TInt r = User::ValidateName(*aCreateInfo.iName);
  3572 	if(KErrNone!=r)
  3573 		return r;	
  3574 
  3575 	SStdEpocThreadCreateInfo8 info;
  3576 	info.iFunction = aCreateInfo.iFunction;
  3577 	info.iUserStackSize = aCreateInfo.iStackSize;
  3578 	info.iUserStack = NULL;
  3579 	info.iAllocator = aCreateInfo.iHeap;
  3580 	info.iHeapInitialSize = aCreateInfo.iHeapMinSize;
  3581 	info.iHeapMaxSize = aCreateInfo.iHeapMaxSize;
  3582 	info.iPtr = aCreateInfo.iParameter;
  3583 	info.iTotalSize = sizeof(info);
  3584 	info.iFlags = aCreateInfo.iAttributes;
  3585 
  3586 	TBuf8<KMaxKernelName> n;
  3587 	n.Copy(*aCreateInfo.iName);
  3588 
  3589 	return SetReturnedHandle(Exec::ThreadCreate(n, aCreateInfo.iOwner, info),*this);
  3590 	}
  3591 
  3592 
  3593 EXPORT_C TInt RThread::Create(const TDesC &aName,TThreadFunction aFunction,TInt aStackSize,TInt aHeapMinSize,TInt aHeapMaxSize,TAny *aPtr,TOwnerType aType)
  3594 /**
  3595 Creates a thread belonging to the current process, and opens this handle
  3596 to that thread.
  3597 
  3598 A new heap is created for this thread.
  3599 
  3600 By default, ownership of this thread handle is vested in the current process,
  3601 but can be vested in the current thread by passing EOwnerThread as
  3602 the second parameter to this function.
  3603 
  3604 If KNullDesC is specified for the name, then an anonymous thread will be created.
  3605 Anonymous threads are not global, and cannot be opened by other processes.
  3606 
  3607 @param aName        The name to be assigned to this thread.
  3608 					KNullDesC, to create an anonymous thread.
  3609 @param aFunction    A pointer to a function.. Control passes to this function
  3610                     when the thread is first resumed, i.e. when the thread
  3611                     is initially scheduled to run.
  3612 @param aStackSize   The size of the new thread's stack.
  3613 @param aHeapMinSize The minimum size for the new thread's heap.
  3614 @param aHeapMaxSize The maximum size for the new thread's heap.
  3615 @param aPtr         A pointer to data to be passed as a parameter to
  3616                     the thread function when the thread is initially scheduled
  3617                     to run. If the thread function does not need any data then
  3618                     this pointer can be NULL. It must be ensured that the memory 
  3619                     pointed to by this pointer is still valid when accessed by 
  3620                     the new thread, e.g. if aPtr points to data on the stack.
  3621 @param aType        An enumeration whose enumerators define the ownership of
  3622                     this thread handle. If not explicitly specified,
  3623                     EOwnerProcess is taken as default.
  3624 
  3625 @return KErrNone if successful, otherwise one of the other system-wide error codes.
  3626         KErrAlreadyExists will be returned if there is another thread in this process with the
  3627         specified name.
  3628 
  3629 @panic USER 109 if aStackSize is negative.
  3630 @panic USER 110 if aHeapMinSize is less than KMinHeapSize.
  3631 @panic USER 111 if aHeapMaxSize is less than aHeapMinSize.
  3632 */
  3633 	{
  3634 	TThreadCreateInfo createInfo(aName, aFunction, aStackSize, aPtr);
  3635 	createInfo.SetOwner(aType);
  3636 	createInfo.SetCreateHeap(aHeapMinSize, aHeapMaxSize);
  3637 	return Create(createInfo);
  3638 	}
  3639 
  3640 
  3641 
  3642 
  3643 EXPORT_C TInt RThread::Create(const TDesC& aName, TThreadFunction aFunction, TInt aStackSize, RAllocator* aAllocator, TAny* aPtr, TOwnerType aType)
  3644 /**
  3645 Creates a thread belonging to the current process, and opens this handle to 
  3646 that thread.
  3647 	
  3648 This thread uses the heap whose handle is pointed to by 
  3649 aAllocator. If this is NULL, then the thread uses the heap of the creating thread.
  3650 	
  3651 By default, ownership of this thread handle is vested in the current process, 
  3652 but can be vested in the current thread by passing EOwnerThread as the second 
  3653 parameter to this function.
  3654 
  3655 If KNullDesC is specified for the name, then an anonymous thread will be created.
  3656 Anonymous threads are not global, and cannot be opened by other processes.
  3657 
  3658 @param aName      The name to be assigned to this thread.
  3659 				  KNullDesC, to create an anonymous thread.
  3660 @param aFunction  A pointer to a function. Control passes to this function when 
  3661 	              the thread is first resumed, i.e. when the thread is
  3662 	              initially scheduled to run.
  3663 @param aStackSize The size of the new thread's stack.
  3664 @param aAllocator A pointer to the handle of the heap belonging to another thread 
  3665                   which this thread is to use.
  3666 @param aPtr       A pointer to data to be passed as a parameter to the thread
  3667                   function when the thread is initially scheduled to run.
  3668                   If the thread function does not need any data,
  3669                   then this pointer can be NULL. It must be ensured that the 
  3670                   memory pointed to by this pointer is still valid when accessed 
  3671                   by the new thread, e.g. if aPtr points to data on the stack.
  3672 @param aType      An enumeration whose enumerators define the ownership of this 
  3673                   thread handle. If not explicitly specified, EOwnerProcess is
  3674                   taken as default.
  3675 
  3676 @return KErrNone if successful otherwise one of the other system-wide error codes.
  3677         KErrAlreadyExists will be returned if there is another thread in this process with the
  3678         specified name.
  3679 
  3680 @panic USER 109 if aStackSize is negative.
  3681 */
  3682 	{
  3683 	TThreadCreateInfo createInfo(aName, aFunction, aStackSize, aPtr);
  3684 	createInfo.SetOwner(aType);
  3685 	createInfo.SetUseHeap(aAllocator);
  3686 	return Create(createInfo);
  3687 	}
  3688 
  3689 
  3690 
  3691 
  3692 EXPORT_C TInt RThread::Open(const TDesC &aName,TOwnerType aType)
  3693 /**
  3694 Opens a handle to specifically named thread.
  3695 
  3696 By default, ownership of this thread handle is vested in the
  3697 current process, but can be vested in the current thread by passing
  3698 EOwnerThread as the second parameter to this function.
  3699 
  3700 @param aName A reference to the descriptor containing the full name of the
  3701 			 thread that is already running.
  3702 @param aType An enumeration whose enumerators define the ownership of this
  3703              thread handle. If not explicitly specified, EOwnerProcess is taken
  3704              as default.
  3705 
  3706 @return KErrNone, if successful, otherwise one of the other	system-wide
  3707         error codes.
  3708 */
  3709 	{
  3710 	return OpenByName(aName,aType,EThread);
  3711 	}
  3712 
  3713 
  3714 
  3715 
  3716 EXPORT_C TInt RThread::Open(TThreadId aId,TOwnerType aType)
  3717 /**
  3718 Opens a handle to the thread with a specific thread Id.
  3719 
  3720 By default, ownership of this thread handle is vested in the
  3721 current process, but can be vested in the current thread by passing
  3722 EOwnerThread as the second parameter to this function.
  3723 
  3724 @param aId   The thread Id used to find the thread.
  3725 @param aType An enumeration whose enumerators define the ownership of this
  3726              thread handle. If not explicitly specified, EOwnerProcess is taken
  3727              as default.
  3728 
  3729 @return KErrNone, if successful, otherwise one of the other	system-wide
  3730         error codes.
  3731 */
  3732 //
  3733 // Open an already running thread in any process.
  3734 //
  3735 	{
  3736 
  3737 	TUint id=*(TUint*)&aId;
  3738 	return SetReturnedHandle(Exec::ThreadOpenById(id,aType),*this);
  3739 	}
  3740 
  3741 
  3742 
  3743 
  3744 EXPORT_C TInt RThread::Process(RProcess &aProcess) const
  3745 /**
  3746 Opens a process-relative handle to the process which owns this thread.
  3747 
  3748 The caller must construct a default RProcess object and pass this to
  3749 the function. 
  3750 On return, aProcess is the open process-relative handle to the process owning 
  3751 this thread.
  3752 
  3753 The return value indicates the success or failure of this function.
  3754 
  3755 @param aProcess A reference to a default RProcess handle; on successful return 
  3756                 from this function, this is the process-relative handle
  3757                 to the process which owns this thread.
  3758                 
  3759 @return KErrNone, if successful, otherwise one of the other system-wide error 
  3760         codes.
  3761 */
  3762 	{
  3763 	return SetReturnedHandle(Exec::ThreadProcess(iHandle),aProcess);
  3764 	}
  3765 
  3766 
  3767 
  3768 
  3769 EXPORT_C TInt User::RenameThread(const TDesC &aName)
  3770 /**
  3771 Assigns a new name to the current thread, replacing any existing name that
  3772 may have been set.
  3773 
  3774 The new name must be a valid name and it must also be such that the thread's 
  3775 new fullname remains unique amongst threads. 
  3776 The length of the new name must be less than or equal to 80 (maximum length of 
  3777 kernel objects) otherwise a panic is raised.  
  3778 
  3779 @param aName A reference to the descriptor containing the new name for the 
  3780              thread.
  3781              
  3782 @return KErrNone if successful, otherwise one of the other system-wide error 
  3783         codes.
  3784 */
  3785 	{
  3786 	TBuf8<KMaxKernelName> name8;
  3787 	name8.Copy(aName);
  3788 	return Exec::ThreadRename(KCurrentThreadHandle,name8);
  3789 	}
  3790 
  3791 
  3792 
  3793 
  3794 EXPORT_C void RThread::Kill(TInt aReason)
  3795 /**
  3796 Ends the thread, specifying a reason code. 
  3797 
  3798 This function is dangerous and should be used only in cases where the target 
  3799 thread cannot end itself via the normal methods of calling User::Exit() or 
  3800 completing its thread function. A hypothetical example might be where a thread 
  3801 gets 'stuck' in a third-party DLL.
  3802 
  3803 The target thread gets no opportunity to execute any clean-up code, therefore 
  3804 incautious use of this function may lead to memory leaks. 
  3805 
  3806 It is functionally identical to RThread::Terminate(), the only difference 
  3807 between the two is a legacy distinction between a 'normal' reason for exiting
  3808 (use Kill) and an 'abnormal' reason (use Terminate). The choice of function 
  3809 is reflected in the return value of RThread::ExitType().
  3810 
  3811 The thread must be in the current process otherwise a panic is raised.
  3812 
  3813 If the thread is process permanent, or the thread is the last thread in the
  3814 process, then the process is also killed.  If the thread is system permanent, 
  3815 the entire system is rebooted.
  3816 
  3817 WARNING: If the target thread uses a shared heap then use of this function will 
  3818 cause an internal array used for thread-local storage (TLS) to be leaked. This 
  3819 leak is specific to ARM platforms which implement the CP15 feature and will
  3820 not occur on other platforms.
  3821 
  3822 @param aReason The reason to be associated with the ending of this thread.
  3823 
  3824 @see User::Exit()
  3825 @see User::SetCritical()
  3826 @see User::Critical()
  3827 @see RThread::Terminate()
  3828 @see RThread::ExitType()
  3829 */
  3830 	{
  3831 
  3832 	Exec::ThreadKill(iHandle,EExitKill,aReason,NULL);
  3833 	}
  3834 
  3835 
  3836 
  3837 
  3838 EXPORT_C void RThread::Terminate(TInt aReason)
  3839 /**
  3840 Ends the thread, specifying a reason code. 
  3841 
  3842 This function is dangerous and should be used only in cases where the target 
  3843 thread cannot end itself via the normal methods of calling User::Exit() or 
  3844 completing its thread function. A hypothetical example might be where a thread 
  3845 gets 'stuck' in a third-party DLL.
  3846 
  3847 The target thread gets no opportunity to execute any clean-up code, therefore 
  3848 incautious use of this function may lead to memory leaks. 
  3849 
  3850 It is functionally identical to RThread::Kill(), the only difference 
  3851 between the two is a legacy distinction between a 'normal' reason for exiting
  3852 (use Kill) and an 'abnormal' reason (use Terminate). The choice of function 
  3853 is reflected in the return value of RThread::ExitType().
  3854 
  3855 The thread must be in the current process otherwise a panic is raised.
  3856 
  3857 If the thread is process critical or process permanent, or the thread is the 
  3858 last thread in the process, then the process is also terminated.  If the thread
  3859 is system critical or system permanent, the entire system is rebooted.
  3860 
  3861 WARNING: If the target thread uses a shared heap then use of this function will 
  3862 cause an internal array used for thread-local storage (TLS) to be leaked. This 
  3863 leak is specific to ARM platforms which implement the CP15 feature and will
  3864 not occur on other platforms.
  3865 
  3866 @param aReason The reason to be associated with the ending of this thread.
  3867 
  3868 @see User::Exit()
  3869 @see User::SetCritical()
  3870 @see User::Critical()
  3871 @see RThread::Kill()
  3872 @see RThread::ExitType()
  3873 */
  3874 	{
  3875 
  3876 	Exec::ThreadKill(iHandle,EExitTerminate,aReason,NULL);
  3877 	}
  3878 
  3879 
  3880 
  3881 
  3882 EXPORT_C void RThread::Panic(const TDesC &aCategory,TInt aReason)
  3883 /**
  3884 Panics this thread, specifying the panic category name and reason.
  3885 
  3886 The length of the category name should be no greater than 16; any name with 
  3887 a length greater than 16 is truncated to 16.
  3888 
  3889 The calling thread, i.e. the thread in which this function is called, must be
  3890 in the same process as this target thread, otherwise the calling thread
  3891 is itself panicked.
  3892 
  3893 If the thread is process critical or process permanent, the process also panics.
  3894 If the thread is system critical or system permanent, the entire system is
  3895 rebooted.
  3896 
  3897 @param aCategory A reference to the descriptor containing the text which defines 
  3898                  the category name for this panic.
  3899 @param aReason The panic number.
  3900 
  3901 @panic KERN-EXEC 46 if this target thread's process is not the same as the
  3902                     calling thread's process. 
  3903 
  3904 @see User::SetCritical()
  3905 @see User::Critical()
  3906 */
  3907 	{
  3908 	
  3909 	TBuf8<KMaxExitCategoryName> cat;
  3910 	TInt len = aCategory.Length();
  3911 	if(len>KMaxExitCategoryName)
  3912 		{
  3913 		TPtr aCatPtr((TUint16*)aCategory.Ptr(),KMaxExitCategoryName,KMaxExitCategoryName);
  3914 		cat.Copy(aCatPtr);
  3915 		}
  3916 	else
  3917 		cat.Copy(aCategory);
  3918 	Exec::ThreadKill(iHandle,EExitPanic,aReason,&cat);
  3919 	}
  3920 
  3921 
  3922 
  3923 
  3924 EXPORT_C void RThread::Logon(TRequestStatus &aStatus) const
  3925 /**
  3926 Requests notification when this thread dies, normally or otherwise.
  3927 
  3928 A request for notification is an asynchronous request, and completes:
  3929 
  3930 - when the thread terminates
  3931 - if the outstanding request is cancelled by a call to RThread::LogonCancel().
  3932 
  3933 A request for notification requires memory to be allocated; if this is
  3934 unavailable, then the call to Logon() returns, and the asynchronous request
  3935 completes immediately.
  3936 
  3937 Note that even when a thread has died, it is not possible to create a new thread with the same name
  3938 until all handles on the dead thread have been closed.  If this is attempted, the call to
  3939 RThread::Create will fail with KErrAlreadyExists.
  3940 
  3941 @param aStatus A reference to the request status object.
  3942                This contains the reason code describing the reason for  
  3943                the termination of the thread, i.e. the value returned by a call to RThread::ExitReason().
  3944                Alternatively, this is set to:
  3945                KErrCancel, if an outstanding request is cancelled;
  3946                KErrNoMemory, if there is insufficient memory to deal with the request. 
  3947 
  3948 @see RThread::LogonCancel()
  3949 @see RThread::ExitReason()
  3950 @see RThread::Create()
  3951 */
  3952 	{
  3953 
  3954 	aStatus=KRequestPending;
  3955 	Exec::ThreadLogon(iHandle,&aStatus,EFalse);
  3956 	}
  3957 
  3958 
  3959 
  3960 
  3961 EXPORT_C TInt RThread::LogonCancel(TRequestStatus &aStatus) const
  3962 /**
  3963 Cancels an outstanding request for notification of the death of this thread.
  3964 
  3965 A request for notification must previously have been made, otherwise
  3966 the function returns KErrGeneral.
  3967 
  3968 The caller passes a reference to the same request status object as was passed 
  3969 in the original call to Logon().
  3970 
  3971 @param aStatus A reference to the same request status object used in
  3972                the original call to Logon().
  3973                
  3974 @return KErrGeneral, if there is no outstanding request, KErrNone otherwise.
  3975 */
  3976 	{
  3977 	return Exec::ThreadLogonCancel(iHandle,&aStatus,EFalse);
  3978 	}
  3979 
  3980 
  3981 
  3982 
  3983 /**
  3984 Creates a Rendezvous request with the thread.
  3985 
  3986 The request is an asynchronous request, and completes:
  3987 
  3988 - when the thread next calls RThread::Rendezvous(TInt aReason)
  3989 - if the outstanding request is cancelled by a call to RThread::RendezvousCancel()
  3990 - if the thread exits
  3991 - if the thread panics.
  3992 
  3993 Note that a request requires memory to be allocated; if this is unavailable,
  3994 then this call to Rendezvous() returns, and the asynchronous request
  3995 completes immediately.
  3996 
  3997 @param aStatus A reference to the request status object.
  3998                The Rendezvous completes normally when 
  3999                RThread::Rendezvous(TInt aReason) is called, and this 
  4000                request status object will contain this reason code.               
  4001                If the thread exits or panics, then this is the thread exit
  4002                reason value, i.e. the same value returned by RThread::ExitReason().
  4003                Alternatively, this is set to:
  4004                KErrCancel, if an outstanding request is cancelled;
  4005                KErrNoMemory, if there is insufficient memory to deal with the request.
  4006 
  4007 @see RThread::Rendezvous(TInt aReason)
  4008 @see RThread::RendezvousCancel(TRequestStatus& aStatus)
  4009 */
  4010 EXPORT_C void RThread::Rendezvous(TRequestStatus& aStatus) const
  4011 
  4012 	{
  4013 	aStatus=KRequestPending;
  4014 	Exec::ThreadLogon(iHandle,&aStatus,ETrue);
  4015 	}
  4016 
  4017 
  4018 
  4019 
  4020 /**
  4021 Cancels a previously requested Rendezvous with the thread
  4022 
  4023 The request completes with the value KErrCancel (if it was still outstanding).
  4024 
  4025 @param aStatus A reference to the same request status object used in
  4026                the original call to Rendezvous(TRequestStatus& aStatus).
  4027 
  4028 @return KErrGeneral, if there is no outstanding request, KErrNone otherwise.
  4029 
  4030 @see RThread::Rendezvous(TRequestStatus& aStatus)
  4031 */
  4032 EXPORT_C TInt RThread::RendezvousCancel(TRequestStatus& aStatus) const
  4033 	{
  4034 	return Exec::ThreadLogonCancel(iHandle,&aStatus,ETrue);
  4035 	}
  4036 
  4037 
  4038 
  4039 
  4040 /**
  4041 Completes all Rendezvous' with the current thread.
  4042 
  4043 @param aReason The reason code used to complete all rendezvous requests
  4044 
  4045 @see RThread::Rendezvous(TRequestStatus& aStatus)
  4046 */
  4047 EXPORT_C void RThread::Rendezvous(TInt aReason)
  4048 	{
  4049 	Exec::ThreadRendezvous(aReason);
  4050 	}
  4051 
  4052 
  4053 
  4054 
  4055 EXPORT_C TBusLocalDrive::TBusLocalDrive()
  4056 //
  4057 // Constructor
  4058 //
  4059 	: iStatus(KErrNotReady)
  4060 	{}
  4061 
  4062 
  4063 
  4064 
  4065 EXPORT_C TInt TBusLocalDrive::Read(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt aThreadHandle,TInt aOffset,TInt aFlags)
  4066 //
  4067 // Read from the connected drive, and pass flags to driver
  4068 //
  4069 	{
  4070 	return RLocalDrive::Read(aPos,aLength,aTrg,aThreadHandle,aOffset,aFlags);
  4071 	}
  4072 
  4073 
  4074 
  4075 
  4076 EXPORT_C TInt TBusLocalDrive::Read(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt aThreadHandle,TInt anOffset)
  4077 //
  4078 // Read from the connected drive.
  4079 //
  4080 	{
  4081 
  4082 	return RLocalDrive::Read(aPos,aLength,aTrg,aThreadHandle,anOffset);
  4083 	}
  4084 
  4085 
  4086 
  4087 
  4088 EXPORT_C TInt TBusLocalDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aThreadHandle,TInt aOffset,TInt aFlags)
  4089 //
  4090 // Write to the connected drive and pass flags to driver
  4091 //
  4092 	{
  4093 
  4094 	return RLocalDrive::Write(aPos,aLength,aSrc,aThreadHandle,aOffset,aFlags);
  4095 	}
  4096 
  4097 
  4098 
  4099 
  4100 EXPORT_C TInt TBusLocalDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aThreadHandle,TInt anOffset)
  4101 //
  4102 // Write to the connected drive.
  4103 //
  4104 	{
  4105 
  4106 	return RLocalDrive::Write(aPos,aLength,aSrc,aThreadHandle,anOffset);
  4107 	}
  4108 
  4109 
  4110 
  4111 
  4112 EXPORT_C TInt TBusLocalDrive::Read(TInt64 aPos,TInt aLength,TDes8& aTrg)
  4113 //
  4114 // Read from the connected drive.
  4115 //
  4116 	{
  4117 
  4118 	return RLocalDrive::Read(aPos,aLength,aTrg);
  4119 	}
  4120 
  4121 
  4122 
  4123 
  4124 EXPORT_C TInt TBusLocalDrive::Write(TInt64 aPos,const TDesC8& aSrc)
  4125 //
  4126 // Write to the connected drive.
  4127 //
  4128 	{
  4129 
  4130 	return RLocalDrive::Write(aPos,aSrc);
  4131 	}
  4132 
  4133 
  4134 
  4135 
  4136 EXPORT_C TInt TBusLocalDrive::Caps(TDes8& anInfo)
  4137 //
  4138 // Get the connected drive's capabilities info.
  4139 //
  4140 	{
  4141 
  4142 	return RLocalDrive::Caps(anInfo);
  4143 	}
  4144 
  4145 
  4146 
  4147 
  4148 const TInt KDefaultMaxBytesPerFormat=0x00004000;// 16K
  4149 const TInt KFormatSectorSize=0x00000200;		// 512
  4150 const TInt KFormatSectorShift=9;	
  4151 
  4152 EXPORT_C TInt TBusLocalDrive::Format(TFormatInfo &anInfo)
  4153 //
  4154 // Format the connected drive.
  4155 //
  4156 	{
  4157 	if (anInfo.i512ByteSectorsFormatted<0)
  4158 		return KErrArgument;
  4159 	if (!anInfo.iFormatIsCurrent)
  4160 		{
  4161 		anInfo.iFormatIsCurrent=ETrue;
  4162 		anInfo.i512ByteSectorsFormatted=0;
  4163 		anInfo.iMaxBytesPerFormat=KDefaultMaxBytesPerFormat;
  4164 
  4165 		// Get the capabilities of the drive.  If extra info is supported,
  4166 		// Then overrise the default KMaxBytesPerFormat
  4167 		TLocalDriveCapsV3Buf caps;
  4168 		Caps(caps);
  4169 		anInfo.iMaxBytesPerFormat = caps().iMaxBytesPerFormat ? caps().iMaxBytesPerFormat : KDefaultMaxBytesPerFormat;
  4170 		}
  4171 	TInt64 pos=TInt64(anInfo.i512ByteSectorsFormatted)<<KFormatSectorShift;
  4172 	TInt length=anInfo.iMaxBytesPerFormat;
  4173 	TInt r=RLocalDrive::Format(pos,length);
  4174 
  4175 	// A positive return code specifies that the format step
  4176 	// has been adjusted (possibly to account for the partition offset)
  4177 	if(r > 0)
  4178 		{
  4179 		length = r;
  4180 		r = KErrNone;
  4181 		}
  4182 
  4183 	if (r==KErrNone)
  4184 		{
  4185 		length+=KFormatSectorSize-1;
  4186 		length>>=KFormatSectorShift;
  4187 		anInfo.i512ByteSectorsFormatted+=length;
  4188 		}
  4189 	
  4190 	if (r==KErrEof)
  4191 		anInfo.iFormatIsCurrent=EFalse;
  4192 
  4193 	return r;
  4194 	}
  4195 
  4196 
  4197 
  4198 
  4199 EXPORT_C TInt TBusLocalDrive::Format(TInt64 aPos, TInt aLength)
  4200 //
  4201 // Format the connected drive.
  4202 //
  4203 	{
  4204 	TInt r = KErrNone;
  4205 
  4206 	do
  4207 		{
  4208 		if((r = RLocalDrive::Format(aPos, aLength)) > 0)
  4209 			{
  4210 			aPos += r;
  4211 			aLength -= r;
  4212 			if (aLength == 0)
  4213 				r = KErrNone;
  4214 			}
  4215 		}		
  4216 	while(r > 0);
  4217 	return(r);
  4218 	}
  4219 
  4220 
  4221 
  4222 
  4223 EXPORT_C TInt TBusLocalDrive::ControlIO(TInt aCommand, TAny* aParam1, TAny* aParam2)
  4224 //
  4225 // Control IO
  4226 // NB: If in a data-paging environment and this drive is the data-paging drive, this API will 
  4227 // return KErrNotSupported if either aParam1 or aParam2 are non-NULL to avoid the possibility
  4228 // of taking a data paging fault in the media driver's thread.
  4229 // For this reason, this function has been deprecated
  4230 
  4231 // @deprecated Callers of this function should use one of the other overloads 
  4232 //
  4233 	{
  4234 	return(RLocalDrive::ControlIO(aCommand,aParam1,aParam2));
  4235 	}
  4236 
  4237 
  4238 EXPORT_C TInt TBusLocalDrive::ControlIO(TInt aCommand, TDes8& aBuf, TInt aParam)
  4239 //
  4240 // Control IO 
  4241 // In a data-paging environment, this API allows the passed descriptor to be pinned in the context 
  4242 // of the client's thread to avoid taking a data paging fault in the media driver's thread
  4243 //
  4244 	{
  4245 	if (aBuf.MaxLength() == 0)
  4246 		return KErrArgument;
  4247 	return(RLocalDrive::ControlIO(aCommand, aBuf, aParam));
  4248 	}
  4249 
  4250 
  4251 EXPORT_C TInt TBusLocalDrive::ControlIO(TInt aCommand, TDesC8& aBuf, TInt aParam)
  4252 //
  4253 // Control IO 
  4254 // In a data-paging environment, this API allows the passed descriptor to be pinned in the context 
  4255 // of the client's thread to avoid taking a data paging fault in the media driver's thread
  4256 //
  4257 	{
  4258 	if (aBuf.Length() == 0)
  4259 		return KErrArgument;
  4260 	return(RLocalDrive::ControlIO(aCommand, aBuf, aParam));
  4261 	}
  4262 
  4263 EXPORT_C TInt TBusLocalDrive::ControlIO(TInt aCommand, TInt aParam1, TInt aParam2)
  4264 	{
  4265 	return(RLocalDrive::ControlIO(aCommand, aParam1, aParam2));
  4266 	}
  4267 
  4268 
  4269 
  4270 EXPORT_C TInt TBusLocalDrive::SetMountInfo(const TDesC8* aMountInfo,TInt aMessageHandle)
  4271 //
  4272 // Set the mount information on the local drive
  4273 //
  4274 	{
  4275 
  4276 	return RLocalDrive::SetMountInfo(aMountInfo,aMessageHandle);
  4277 	}
  4278 
  4279 
  4280 
  4281 
  4282 EXPORT_C TInt TBusLocalDrive::ForceRemount(TUint aFlags)
  4283 //
  4284 // Force a remount on the local drive
  4285 //
  4286 	{
  4287 
  4288 	TInt err = RLocalDrive::ForceMediaChange(aFlags);
  4289 	if(err != KErrNone)
  4290 		return err;
  4291 
  4292 	if(aFlags & ELocDrvRemountForceMediaChange)
  4293 		err = CheckMount();
  4294 
  4295 	return err;
  4296 	}
  4297 
  4298 
  4299 
  4300 
  4301 EXPORT_C TInt TBusLocalDrive::GetLastErrorInfo(TDes8& aErrorInfo)
  4302 //
  4303 // Get information on the local drives last error
  4304 //
  4305 	{
  4306 	
  4307 	return RLocalDrive::GetLastErrorInfo(aErrorInfo);
  4308 	}
  4309 
  4310 
  4311 
  4312 
  4313 EXPORT_C TLocalDriveCaps::TLocalDriveCaps()
  4314 //
  4315 // Constructor
  4316 //
  4317 	:	iSize(0),
  4318 		iType(EMediaNotPresent),
  4319 		iConnectionBusType(EConnectionBusInternal),
  4320 		iDriveAtt(0),
  4321 		iMediaAtt(0),
  4322 		iBaseAddress(NULL),
  4323 		iFileSystemId(0)
  4324 	{}
  4325 
  4326 
  4327 
  4328 
  4329 /**
  4330 @capability TCB
  4331 */
  4332 EXPORT_C TInt TBusLocalDrive::Connect(TInt aDriveNumber,TBool &aChangedFlag)
  4333 //
  4334 // Connect to the drive.
  4335 //
  4336 	{
  4337 
  4338 	return RLocalDrive::Connect(aDriveNumber, aChangedFlag);
  4339 	}
  4340 
  4341 
  4342 
  4343 
  4344 EXPORT_C void TBusLocalDrive::Disconnect()
  4345 //
  4346 // Disconnect from the drive.
  4347 //
  4348 	{
  4349 
  4350 	Close();
  4351 	}
  4352 
  4353 
  4354 
  4355 
  4356 EXPORT_C TInt TBusLocalDrive::Enlarge(TInt aLength)
  4357 //
  4358 // Increase the size of the connected drive by the specified length (in bytes).
  4359 //
  4360 	{
  4361 
  4362 	return RLocalDrive::Enlarge(aLength);
  4363 	}
  4364 
  4365 
  4366 
  4367 
  4368 EXPORT_C TInt TBusLocalDrive::ReduceSize(TInt aPos,TInt aLength)
  4369 //
  4370 // Reduce the size of the connected drive by removing the specified length
  4371 // (in bytes) starting at the specified position.
  4372 //
  4373 	{
  4374 
  4375 	return RLocalDrive::Reduce(aPos, aLength);
  4376 	}
  4377 
  4378 
  4379 
  4380 
  4381 /**
  4382 Attempt to unlock a password-enabled drive and optionally store the password in the password store.
  4383 
  4384 @param aPassword A descriptor containing the password data.
  4385 @param aStorePassword If ETrue, the password is added to the password store.
  4386 
  4387 @return KErrNone, if successful.
  4388 		KErrAlreadyExists, if the drive is already unlocked.
  4389 		KErrAccessDenied, if the drive unlock operation fails.
  4390 
  4391 @see TBusLocalDrive::SetPassword
  4392 @see TBusLocalDrive::Clear
  4393 @see TBusLocalDrive::ErasePassword
  4394 */
  4395 EXPORT_C TInt TBusLocalDrive::Unlock(const TDesC8& aPassword, TBool aStorePassword)
  4396    	{
  4397 	TInt err = CheckMount();
  4398 	if (err != KErrNone)
  4399 		return err;
  4400 
  4401 	if (!(Status() & KMediaAttLocked))
  4402 		return KErrAlreadyExists;
  4403 
  4404 	err = RLocalDrive::Unlock(aPassword, aStorePassword);
  4405 
  4406 	if(err == KErrLocked)
  4407 		err = KErrAccessDenied;
  4408 
  4409 	return err;
  4410    	}
  4411 
  4412 
  4413 
  4414 
  4415 /**
  4416 Attempt to lock password-enabled drive and optionally store the new password in the password store.
  4417 
  4418 @param aOldPassword A descriptor containing old password.
  4419 @param aNewPassword A descriptor containing new password.
  4420 @param aStorePassword If ETrue, the password is added to the password store.
  4421 
  4422 @return KErrNone, if successful.
  4423 		KErrAccessDenied, if the drive is already locked or the old password is incorrect.
  4424 
  4425 @see TBusLocalDrive::Unlock
  4426 @see TBusLocalDrive::Clear
  4427 @see TBusLocalDrive::ErasePassword
  4428 */
  4429 EXPORT_C TInt TBusLocalDrive::SetPassword(const TDesC8& aOldPassword, const TDesC8& aNewPassword, TBool aStorePassword)
  4430    	{
  4431 	TInt err = CheckMount();
  4432 	if (err != KErrNone)
  4433 		return err;
  4434 
  4435 	if (Status() & KMediaAttLocked)
  4436 		return KErrAccessDenied;
  4437 
  4438 	err = RLocalDrive::SetPassword(aOldPassword, aNewPassword, aStorePassword);
  4439 	if(err == KErrLocked)
  4440 		err = KErrAccessDenied;
  4441 
  4442 	return err;
  4443 	}
  4444 
  4445 
  4446 
  4447 
  4448 /**
  4449 Clears a password from a card - controller sets password to null.
  4450 volume will not be password-enabled next time it is powered up.
  4451 The password is cleared from the password store.
  4452 
  4453 @param aPassword A descriptor containing the password.
  4454 
  4455 @return KErrNone, if successful.
  4456 		KErrAccessDenied, if the drive is already locked or the password is incorrect.
  4457 
  4458 @see TBusLocalDrive::Unlock
  4459 @see TBusLocalDrive::SetPassword
  4460 @see TBusLocalDrive::ErasePassword
  4461 */
  4462 EXPORT_C TInt TBusLocalDrive::Clear(const TDesC8& aPassword)
  4463    	{
  4464 	TInt err = CheckMount();
  4465 	if (err != KErrNone)
  4466 		return err;
  4467 
  4468 	if (Status() & KMediaAttLocked)
  4469 		return KErrAccessDenied;
  4470 
  4471 	err = RLocalDrive::Clear(aPassword);
  4472 	if(err == KErrLocked)
  4473 		err = KErrAccessDenied;
  4474 
  4475 	return err;
  4476    	}
  4477 
  4478 
  4479 
  4480 
  4481 /**
  4482 Forcibly unlock a password-enabled drive.
  4483 KErrAccessDenied is returned if the drive is already mounted (and therefore unlocked)
  4484 or if the drive is not already mounted and the operation fails.
  4485 
  4486 @return KErrNone, if successful.
  4487 		KErrAccessDenied, if the drive is not locked or the operation is not supported.
  4488 
  4489 @see TBusLocalDrive::Unlock
  4490 @see TBusLocalDrive::SetPassword
  4491 @see TBusLocalDrive::ErasePassword
  4492 */
  4493 EXPORT_C TInt TBusLocalDrive::ErasePassword()
  4494    	{
  4495 	TInt err = CheckMount();
  4496 	if (err != KErrNone)
  4497 		return err;
  4498 
  4499 	if (!(Status() & KMediaAttLocked))
  4500 		return KErrAccessDenied;
  4501 
  4502 	err = RLocalDrive::ErasePassword();
  4503 	if(err != KErrNone)
  4504 		err = KErrAccessDenied;
  4505 
  4506 	return err;
  4507    	}
  4508 
  4509 
  4510 
  4511 
  4512 TInt TBusLocalDrive::CheckMount()
  4513 //
  4514 // Check the local drive can be, or is mounted
  4515 //
  4516 	{
  4517 	TLocalDriveCaps caps;
  4518 	TPckg<TLocalDriveCaps> capsPckg(caps);
  4519 	TInt err = RLocalDrive::Caps(capsPckg);
  4520 	iStatus = caps.iMediaAtt;
  4521 	return err;
  4522 	}
  4523 
  4524 
  4525 
  4526 /**
  4527 Write the password store to the peripheral bus controller.
  4528 
  4529 @return
  4530 	- KErrNone if Successful
  4531 	- KErrOverflow If aBuf is longer than TPasswordStore::EMaxPasswordLength
  4532 	- KErrCorrupt If store in aBuf is malformed. 
  4533 
  4534 @param aBuf Data to replace the current password store.
  4535 */
  4536 EXPORT_C TInt TBusLocalDrive::WritePasswordData(const TDesC8& aBuf)
  4537    	{
  4538 	return RLocalDrive::WritePasswordData(aBuf);
  4539 	}
  4540 
  4541 
  4542 
  4543 
  4544 EXPORT_C TInt TBusLocalDrive::ReadPasswordData(TDes8& aBuf)
  4545 //
  4546 // Read the entire password store from the peripheral bus controller.
  4547 //
  4548 	{
  4549 	return RLocalDrive::ReadPasswordData(aBuf);
  4550    	}
  4551 
  4552 
  4553 
  4554 
  4555 EXPORT_C TInt TBusLocalDrive::PasswordStoreLengthInBytes()
  4556 //
  4557 // Return the number of bytes used by peripheral bus controller password store.
  4558 //
  4559 	{
  4560 	return RLocalDrive::PasswordStoreLengthInBytes();
  4561 	}
  4562 
  4563 
  4564 
  4565 
  4566 EXPORT_C TInt TBusLocalDrive::DeleteNotify(TInt64 aPos, TInt aLength)
  4567 //
  4568 // Notify the media driver that an area of the partition has been deleted.
  4569 // This is used by certain media (e.g NAND flash) for garbage collection.
  4570 //
  4571 	{
  4572 	return RLocalDrive::DeleteNotify(aPos, aLength);
  4573 	}
  4574 
  4575 
  4576 /**
  4577 Query a property of the media device
  4578 
  4579 @prototype
  4580 @internalTechnology
  4581 */
  4582 EXPORT_C TInt TBusLocalDrive::QueryDevice(TQueryDevice aQueryDevice, TDes8 &aBuf)
  4583 	{
  4584 	return RLocalDrive::QueryDevice(aQueryDevice, aBuf);
  4585 	}
  4586 
  4587 
  4588 EXPORT_C void User::__DbgMarkStart(TBool aKernel)
  4589 /**
  4590 Marks the start of heap cell checking for the current thread's default heap,
  4591 or for the kernel heap.
  4592 	
  4593 If earlier calls to __DbgMarkStart() have been made, then this
  4594 call to __DbgMarkStart() marks the start of a new nested level of
  4595 heap cell checking.
  4596 	
  4597 Every call to __DbgMarkStart() should be matched by a later call
  4598 to __DbgMarkEnd() to verify that the number of heap cells allocated, at
  4599 the current nested level, is as expected.
  4600 This expected number of heap cells is passed to __DbgMarkEnd() 
  4601 as a parameter; however, the most common expected number is zero, reflecting 
  4602 the fact that the most common requirement is to check that all memory allocated
  4603 since a previous call to __DbgStartCheck() has been freed.
  4604 	
  4605 @param aKernel ETrue, if checking is being done for the kernel heap;
  4606                EFalse, if checking is being done for the current thread's
  4607                default heap.
  4608 */
  4609 	{
  4610 
  4611 	if (aKernel)
  4612 		Exec::KernelHeapDebug(EDbgMarkStart,0,NULL);
  4613 	else
  4614 		GetHeap()->__DbgMarkStart();
  4615 	}
  4616 
  4617 
  4618 
  4619 
  4620 EXPORT_C void User::__DbgMarkCheck(TBool aKernel, TBool aCountAll, TInt aCount, const TUint8* aFileName, TInt aLineNum)
  4621 //
  4622 // Call CheckNum for the default heap
  4623 //
  4624 /**
  4625 Checks the current number of allocated heap cells for the current thread's default 
  4626 heap, or the kernel heap.
  4627 
  4628 If aCountAll is true, the function checks that the total number of
  4629 allocated cells on the heap is the same as aCount. If aCountAll is false,
  4630 the function checks that the number of allocated cells at the current nested
  4631 level is the same as aCount.
  4632 
  4633 If checking fails, the function raises a panic. Information about the failure 
  4634 is put into the panic category, which takes the form:
  4635 
  4636 ALLOC COUNT\\rExpected aaa\\rAllocated bbb\\rLn: ccc ddd
  4637 
  4638 Where aaa is the value aCount, bbb is the number of allocated heap cells, 
  4639 ccc is a line number, copied from aLineNum, and ddd is a file name, copied 
  4640 from the descriptor aFileName.
  4641 
  4642 Note that the panic number is 1.
  4643 
  4644 @param aKernel   ETrue, if checking is being done for the kernel heap;
  4645                  EFalse, if checking is being done for the current thread's
  4646                  default heap.
  4647 @param aCountAll If true, the function checks that the total number of
  4648                  allocated cells on the heap is the same as aCount.
  4649                  If false, the function checks that the number of allocated
  4650                  cells at the current nested level is the same as aCount.
  4651 @param aCount    The expected number of allocated cells.
  4652 @param aFileName A filename; this is displayed as part of the panic category, 
  4653                  if the check fails.
  4654 @param aLineNum  A line number; this is displayed as part of the panic category, 
  4655                  if the check fails.
  4656 */
  4657 	{
  4658 
  4659 	if (!aKernel)
  4660 		GetHeap()->__DbgMarkCheck(aCountAll,aCount,aFileName,aLineNum);
  4661 	else
  4662 		{
  4663 		TPtrC8 filename(aFileName);
  4664 		TKernelHeapMarkCheckInfo info;
  4665 		info.iCountAll=aCountAll;
  4666 		info.iFileName=&filename;
  4667 		info.iLineNum=aLineNum;
  4668 		Exec::KernelHeapDebug(EDbgMarkCheck,aCount,&info);
  4669 		}
  4670 	}
  4671 
  4672 
  4673 
  4674 
  4675 EXPORT_C TUint32 User::__DbgMarkEnd(TBool aKernel, TInt aCount)
  4676 //
  4677 // Call CheckHeap for the default heap
  4678 //
  4679 /**
  4680 Marks the end of heap cell checking at the current nested level for the current
  4681 thread's default heap, or the kernel heap.
  4682 
  4683 The function checks that the number of heap cells allocated, at the current
  4684 nested level, is aCount. The most common value for aCount is zero, reflecting
  4685 the fact that the most common requirement is to check that all memory allocated
  4686 since a previous call to __DbgStartCheck() has been freed.
  4687 
  4688 A call to this function should match an earlier call to __DbgMarkStart().
  4689 If there are more calls to this function than calls to __DbgMarkStart(), then
  4690 this function raises a USER 51 panic.
  4691 
  4692 If the check fails for a user heap, the function raises an ALLOC: nnnnnnnn
  4693 panic, where nnnnnnnn is a hexadecimal pointer to the first orphaned heap
  4694 cell.
  4695 
  4696 If the check fails for the kernel heap, the kernel server raises a KERN-EXEC 17
  4697 panic.
  4698 
  4699 @param aKernel   ETrue, if checking is being done for the kernel heap;
  4700                  EFalse, if checking is being done for the current thread's
  4701                  default heap.
  4702 @param aCount    The number of allocated heap cells expected.
  4703 
  4704 @return Zero always.
  4705 */
  4706 	{
  4707 
  4708 	if (!aKernel)
  4709 		{
  4710 		TUint32 badCell=GetHeap()->__DbgMarkEnd(aCount);
  4711 		if (badCell!=0)
  4712 			{
  4713 			TBuf<0x10> info=_L("ALLOC: ");
  4714 			info.AppendFormat(_L("%x\n"), badCell);
  4715 			User::Panic(info,0);
  4716 			}
  4717 		return(badCell);
  4718 		}
  4719 	else
  4720 		Exec::KernelHeapDebug(EDbgMarkEnd,aCount,NULL);
  4721 	return(0);
  4722 	}
  4723 
  4724 
  4725 
  4726 
  4727 EXPORT_C void User::__DbgSetAllocFail(TBool aKernel, RAllocator::TAllocFail aType, TInt aRate)
  4728 //
  4729 // Set the failure rate for allocating from the default user heap
  4730 //
  4731 /**
  4732 Simulates a heap allocation failure for the current thread's default heap,
  4733 or the kernel heap.
  4734 
  4735 The failure occurs on subsequent calls to new or any of the functions which
  4736 allocate memory from the heap.
  4737 
  4738 The timing of the allocation failure depends on the type of allocation failure
  4739 requested, i.e. on the value of aType.
  4740 
  4741 The simulation of heap allocation failure is cancelled if aType is given
  4742 the value RAllocator::ENone.
  4743 
  4744 Notes:
  4745 
  4746 1. If the failure type is RHeap::EFailNext, the next attempt to allocate from
  4747    the heap fails; however, no further failures will occur.
  4748 
  4749 2. For failure types RHeap::EFailNext and RHeap::ENone, set aRate to 1.
  4750 
  4751 @param aKernel   ETrue, if checking is being done for the kernel heap;
  4752                  EFalse, if checking is being done for the current thread's
  4753                  default heap.
  4754 @param aType     An enumeration which indicates how to simulate heap
  4755                  allocation failure.
  4756 @param aRate     The rate of failure; when aType is RAllocator::EDeterministic,
  4757                  heap allocation fails every aRate attempts.
  4758 */
  4759 	{
  4760 
  4761 	if (aKernel)
  4762 		Exec::KernelHeapDebug(EDbgSetAllocFail,aType,(TAny*)aRate);
  4763 	else
  4764 		GetHeap()->__DbgSetAllocFail(aType,aRate);
  4765 	}
  4766 
  4767 /**
  4768 Simulates a heap allocation failure for the current thread's default heap,
  4769 or the kernel heap.
  4770 
  4771 The aBurst failures will occur after subsequent calls to new or any of the 
  4772 functions which allocate memory from the heap.
  4773 
  4774 The timing of the allocation failures will depend on the type of allocation failure
  4775 requested, i.e. on the value of aType.
  4776 
  4777 The simulation of heap allocation failure is cancelled if aType is given
  4778 the value RAllocator::ENone.
  4779 
  4780 
  4781 @param aKernel   ETrue, if checking is being done for the kernel heap;
  4782                  EFalse, if checking is being done for the current thread's
  4783                  default heap.
  4784 @param aType     An enumeration which indicates how to simulate heap
  4785                  allocation failure.
  4786 @param aRate     The rate of failure; when aType is RAllocator::EDeterministic,
  4787                  heap allocation fails every aRate attempts.
  4788 @param aBurst    The number of consecutive allocations that should fail.
  4789 
  4790 */
  4791 EXPORT_C void User::__DbgSetBurstAllocFail(TBool aKernel, RAllocator::TAllocFail aType, TUint aRate, TUint aBurst)
  4792 	{
  4793 	if (aKernel)
  4794 		{
  4795 		SRAllocatorBurstFail burstFail;
  4796 		burstFail.iRate = aRate;
  4797 		burstFail.iBurst = aBurst;
  4798 		Exec::KernelHeapDebug(EDbgSetBurstAllocFail, aType, (TAny*)&burstFail);
  4799 		}
  4800 	else
  4801 		GetHeap()->__DbgSetBurstAllocFail(aType, aRate, aBurst);	
  4802 	}
  4803 
  4804 
  4805 /**
  4806 Returns the number of heap allocation failures the current debug allocator fail
  4807 function has caused so far.
  4808 
  4809 This is intended to only be used with fail types RAllocator::EFailNext,
  4810 RAllocator::EBurstFailNext, RAllocator::EDeterministic and
  4811 RAllocator::EBurstDeterministic.  The return value is unreliable for 
  4812 all other fail types.
  4813 
  4814 @return The number of heap allocation failures the current debug fail 
  4815 function has caused.
  4816 
  4817 @see RAllocator::TAllocFail
  4818 */
  4819 EXPORT_C TUint User::__DbgCheckFailure(TBool aKernel)
  4820 	{
  4821 	TUint r;
  4822 	if (aKernel)
  4823 		Exec::KernelHeapDebug(EDbgCheckFailure, 0, (TAny*)&r);
  4824 	else
  4825 		r = GetHeap()->__DbgCheckFailure();
  4826 	return r;
  4827 	}
  4828 
  4829 EXPORT_C TInt RProcess::Create(const TDesC &aFileName,const TDesC &aCommand,TOwnerType aType)
  4830 /**
  4831 Starts a new process, loading the specified executable.
  4832 
  4833 The executable can be in ROM or RAM.
  4834 
  4835 By default, ownership of this process handle is vested in the current process, 
  4836 but can be vested in the current thread by specifying EOwnerThread as the 
  4837 third parameter to this function.
  4838 
  4839 @param aFileName A descriptor containing the full path name of the executable 
  4840                  to be loaded. If this name has no file extension,
  4841                  an extension of .EXE is appended. The length of the resulting
  4842                  full path name must not be greater than KMaxFileName.
  4843                  The length of the file name itself must not be greater
  4844                  than KMaxProcessName. If no path is specified, the system will 
  4845 				 look in \\sys\\bin on all drives.
  4846 @param aCommand  A descriptor containing data passed as an argument to
  4847                  the thread function of the new process's main thread,
  4848                  when it is first scheduled.
  4849 @param aType     Defines the ownership of this process handle. If not
  4850                  specified, EOwnerProcess is the default.
  4851                 
  4852 @return KErrNone if successful, otherwise one of the other system-wide error codes.
  4853 */
  4854 	{
  4855 
  4856 	return Create(aFileName, aCommand, TUidType(), aType);
  4857 	}
  4858 
  4859 
  4860 
  4861 
  4862 EXPORT_C TInt RProcess::Create(const TDesC &aFileName,const TDesC &aCommand,const TUidType &aUidType, TOwnerType aType)
  4863 /**
  4864 Starts a new process, loading the specified executable which matches
  4865 the specified UID type.
  4866 
  4867 The executable can be in ROM or RAM.
  4868 
  4869 By default, ownership of this process handle is vested in the current process, 
  4870 but can be vested in the current thread by specifying EOwnerThread as the 
  4871 fourth parameter.
  4872 
  4873 @param aFileName A descriptor containing the full path name of the executable 
  4874                  to be loaded. If this name has no file extension,
  4875                  an extension of .EXE is appended. The length of the resulting
  4876                  full path name must not be greater than KMaxFileName.
  4877                  The length of the file name itself must not be greater
  4878                  than KMaxProcessName. If no path is specified, the system will 
  4879 				 look in \\sys\\bin on all drives.
  4880 @param aCommand  A descriptor containing data passed as an argument to
  4881                  the thread function of the new process's main thread,
  4882                  when it is first scheduled.
  4883 @param aUidType  A UID type (a triplet of UIDs) which the executable must match. 
  4884 @param aType     Defines the ownership of this process handle. If not specified, 
  4885                  EOwnerProcess is the default.
  4886 				 
  4887 @return KErrNone if successful, otherwise one of the other system-wide error
  4888         codes.
  4889 */
  4890 	{
  4891 
  4892 	RLoader loader;
  4893 	TInt r=loader.Connect();
  4894 	if (r==KErrNone)
  4895 		r=loader.LoadProcess(iHandle,aFileName,aCommand,aUidType,aType);
  4896 	loader.Close();
  4897 	return r;
  4898 	}
  4899 
  4900 
  4901 EXPORT_C TInt RProcess::CreateWithStackOverride(const TDesC& aFileName,const TDesC& aCommand, const TUidType &aUidType, TInt aMinStackSize, TOwnerType aType)
  4902 /**
  4903 Starts a new process, loading the specified executable which matches
  4904 the specified UID type and the minimum stack size is the specified value.
  4905 
  4906 The executable can be in ROM or RAM.
  4907 
  4908 By default, ownership of this process handle is vested in the current process, 
  4909 but can be vested in the current thread by specifying EOwnerThread as the 
  4910 fourth parameter.
  4911 
  4912 
  4913 @param aFileName A descriptor containing the full path name of the executable 
  4914                  to be loaded. If this name has no file extension,
  4915                  an extension of .EXE is appended. The length of the resulting
  4916                  full path name must not be greater than KMaxFileName.
  4917                  The length of the file name itself must not be greater
  4918                  than KMaxProcessName. If no path is specified, the system will 
  4919 				 look in \\sys\\bin on all drives.
  4920 @param aCommand  A descriptor containing data passed as an argument to
  4921                  the thread function of the new process's main thread,
  4922                  when it is first scheduled.
  4923 @param aUidType  A UID type (a triplet of UIDs) which the executable must match. 
  4924 @param aMinStackSize Minimum stack size of the new process. If this is less than
  4925                  than the stack size set in the image header of the executable,
  4926                  the minimum stack size will be set to the image header stack
  4927                  size.
  4928 @param aType     Defines the ownership of this process handle. If not specified, 
  4929                  EOwnerProcess is the default.
  4930                  
  4931 @return KErrNone if successful, otherwise one of the other system-wide error
  4932         codes.
  4933 */
  4934 	{
  4935 
  4936 	RLoader loader;
  4937 	TInt r=loader.Connect();
  4938 	if (r==KErrNone)
  4939 	{
  4940 		r=loader.LoadProcess(iHandle,aFileName,aCommand,aUidType,aMinStackSize,aType);
  4941 	}
  4942 	loader.Close();
  4943 	return r;
  4944 	} 
  4945 
  4946 
  4947 
  4948 EXPORT_C TInt User::LoadLogicalDevice(const TDesC &aFileName)
  4949 /**
  4950 Loads the logical device driver (LDD) DLL with the specified filename.
  4951 
  4952 The function searches the system path for the LDD DLL, and loads it. It then 
  4953 makes a kernel server call that:
  4954 
  4955 1. creates the LDD factory object, an instance of a DLogicalDevice derived
  4956    class; this involves checking the first UID value to make sure that the DLL
  4957    is a  valid LDD before proceeding to call the exported function at
  4958    ordinal 1, which  creates the LDD factory object on the kernel heap
  4959 
  4960 2. calls the LDD factory object's Install() function to complete the installation
  4961 
  4962 3. adds the new LDD factory object to the kernel's list of LDD factory objects.
  4963 
  4964 @param aFileName A reference to the descriptor containing the name of the 
  4965                  physical device driver DLL. If the filename has no extension,
  4966                  .LDD is assumed by default.
  4967                  
  4968 @return KErrNone if successful or one of the system-wide error codes.
  4969 */
  4970 	{
  4971 	RLoader loader;
  4972 	return loader.LoadDeviceDriver(aFileName, 0);
  4973 	}
  4974 
  4975 
  4976 
  4977 
  4978 EXPORT_C TInt User::FreeLogicalDevice(const TDesC &aDeviceName)
  4979 /**
  4980 Frees the logical device driver DLL associated with a specified driver name.
  4981 
  4982 @param aDeviceName The name of the logical device driver object. This must 
  4983                    match the name set during installation of the logical
  4984                    device. Typically, this is done in an implementation
  4985                    of DLogicalDevice::Install() through a call to SetName().
  4986                    Note that the name is rarely the same as the device's
  4987                    filename. The name of a logical device driver object
  4988                    can be discovered by using TFindLogicalDevice.
  4989                    
  4990 @return KErrNone if successful or one of the system-wide error codes.  KErrNone
  4991 		will be	returned if the device is not found as it may have already been 
  4992 		freed.
  4993 */
  4994 	{
  4995 	TBuf8<KMaxFullName> aDeviceName8;
  4996 	aDeviceName8.Copy(aDeviceName);
  4997 	return Exec::DeviceFree(aDeviceName8,0);
  4998 	}
  4999 
  5000 
  5001 
  5002 
  5003 EXPORT_C TInt User::LoadPhysicalDevice(const TDesC &aFileName)
  5004 /**
  5005 Loads the physical device driver (PDD) DLL with the specified filename.
  5006 
  5007 The function searches the system path for the PDD DLL, and loads it. It then 
  5008 makes a kernel server call that:
  5009 
  5010 1. creates the PDD factory object, an instance of a DPhysicalDevice derived class;
  5011    this involves checking the first UID value to make sure that the DLL is a 
  5012    valid PDD before proceeding to call the exported function at ordinal 1, which 
  5013    creates the PDD factory object on the kernel heap
  5014 
  5015 2. calls the PDD factory object's Install() function to complete the installation
  5016 
  5017 2. adds the new PDD factory object to the kernel's list of PDD factory objects.
  5018 
  5019 @param aFileName A reference to the descriptor containing the name of the 
  5020                  physical device driver DLL. If the filename has no extension,
  5021                  .PDD is assumed by default.
  5022                  
  5023 @return KErrNone if successful or one of the system-wide error codes.
  5024 */
  5025 	{
  5026 	RLoader loader;
  5027 	return loader.LoadDeviceDriver(aFileName, 1);
  5028 	}
  5029 
  5030 
  5031 
  5032 
  5033 /**
  5034 Frees the physical device driver DLL associated with a specified driver name.
  5035 	
  5036 @param aDeviceName The name of the physical device driver object. This must 
  5037                    match the name set during installation of the physical
  5038                    device. Typically, this is done in an implementation of
  5039                    DPhysicalDevice::Install() through a call to SetName().
  5040                    Note that the name is rarely the same as the device's
  5041                    filename. The name of a physical device driver object can
  5042                    be discovered by using TFindPhysicalDevice.
  5043                    
  5044 @return KErrNone if successful or one of the system-wide error codes.  KErrNone 
  5045 		will be	returned if the device is not found as it may have already 
  5046 		been freed.
  5047 */
  5048 EXPORT_C TInt User::FreePhysicalDevice(const TDesC &aDeviceName)
  5049 
  5050 	{
  5051 	TBuf8<KMaxFullName> aDeviceName8;
  5052 	aDeviceName8.Copy(aDeviceName);
  5053 	return Exec::DeviceFree(aDeviceName8,1);
  5054 	}
  5055 
  5056 
  5057 
  5058 
  5059 EXPORT_C TInt RLoader::Connect()
  5060 //
  5061 // Connect with the loader.
  5062 //
  5063 	{
  5064 	_LIT(KLoaderServerName,"!Loader");
  5065 	return CreateSession(KLoaderServerName,Version(),0);
  5066 	}
  5067 
  5068 TVersion RLoader::Version() const
  5069 //
  5070 // Return the client side version number.
  5071 //
  5072 	{
  5073 
  5074 	return TVersion(KLoaderMajorVersionNumber,KLoaderMinorVersionNumber,KE32BuildVersionNumber);
  5075 	}
  5076 
  5077 TInt RLoader::LoadProcess(TInt& aHandle, const TDesC& aFileName, const TDesC& aCommand, const TUidType& aUidType, TOwnerType aType)
  5078 //
  5079 // Execute another process.
  5080 //
  5081 	{
  5082 
  5083 	return (LoadProcess(aHandle, aFileName, aCommand, aUidType, KDefaultStackSize, aType)); 
  5084 		
  5085 	}
  5086 
  5087 
  5088 /**
  5089 	Execute another process.
  5090 
  5091 	@param aHandle
  5092 	@param aFileName
  5093 	@param aCommand
  5094 	@param aUidType
  5095 	@param aMinStackSize
  5096 	@param aType
  5097 
  5098 	@return
  5099 		KErrNone		if process created
  5100 		KErrBadName		if aFileName.Length() > KMaxFileName
  5101 		KErrArgument	if aMinStackSize < 0
  5102 			
  5103 */
  5104 TInt RLoader::LoadProcess(TInt& aHandle, const TDesC& aFileName, const TDesC& aCommand, const TUidType& aUidType, TInt aMinStackSize, TOwnerType aType)
  5105 	{
  5106 		
  5107 	__IF_DEBUG(Print(_L("RLoader::LoadProcess started with %d bytes stack.\n"), aMinStackSize));
  5108 	
  5109 	if( 0 > aMinStackSize )
  5110 		return KErrArgument;
  5111 
  5112 	TLdrInfo info;
  5113 	info.iRequestedUids=aUidType; // match these uids only
  5114 	info.iOwnerType=aType;
  5115 	
  5116 	info.iMinStackSize=aMinStackSize;  	
  5117 		
  5118 	if (aFileName.Length()>KMaxFileName)
  5119 		return KErrBadName;
  5120 	
  5121 	TPckg<TLdrInfo> infoBuf(info);
  5122 	
  5123 	TInt r = SendReceive(ELoadProcess, TIpcArgs((TDes8*)&infoBuf, (const TDesC*)&aFileName, (const TDesC*)&aCommand) );
  5124 	aHandle = info.iHandle;
  5125 	__IF_DEBUG(Print(_L("LoadProcess returning %d"),r));
  5126 	return r;
  5127 	}
  5128 
  5129 /**
  5130     Check if the hash for the given library exists and optionally validate it.
  5131 
  5132     @param aFileName		the same as for RLoader::LoadLibrary
  5133     @param aValidateHash	if ETrue this function will validate library hash if it exists. Requires fully specified aFileName.
  5134 
  5135     @return
  5136 	    KErrNotSupported 	this feature is not supported by the emulator
  5137 	    KErrNone     		if aValidateHash=EFalse, it means that the hash exists; if  aValidateHash=ETrue, hash exists and valid, 
  5138 	    KErrCorrupt	        if aValidateHash=ETrue, the library hash exists but NOT valid, 
  5139 	    KErrNotFound	    no hash found
  5140         KErrArgument		bad file name
  5141 
  5142 */
  5143 EXPORT_C TInt RLoader::CheckLibraryHash(const TDesC& aFileName, TBool aValidateHash/*=EFalse*/)
  5144     {
  5145     __IF_DEBUG(Print(_L("RLoader::CheckLibraryHash")));
  5146 
  5147 	TLdrInfo info;
  5148 	TPckg<TLdrInfo> infoBuf(info);
  5149 	info.iOwnerType=EOwnerThread;
  5150 
  5151     TInt r = SendReceive(ECheckLibraryHash, TIpcArgs((TDes8*)&infoBuf, (const TDesC*)&aFileName, aValidateHash) );
  5152 
  5153 	return r;
  5154     }
  5155 
  5156 EXPORT_C TInt RLoader::LoadLibrary(TInt& aHandle, const TDesC& aFileName, const TDesC& aPath, const TUidType& aUidType, TUint32 aModuleVersion)
  5157 //
  5158 // Load a DLL
  5159 //
  5160 	{
  5161 
  5162 	__IF_DEBUG(Print(_L("RLoader::LoadLibrary")));
  5163 	TLdrInfo info;
  5164 	TPckg<TLdrInfo> infoBuf(info);
  5165 	info.iRequestedUids=aUidType; // match these uids only
  5166 	info.iOwnerType=EOwnerThread;
  5167 	info.iRequestedVersion=aModuleVersion;
  5168 	if (aFileName.Length()>KMaxFileName)
  5169 		return KErrBadName;
  5170 	aHandle=0;
  5171 
  5172 	TInt r=E32Loader::WaitDllLock();
  5173 	if (r==KErrNone)
  5174 		{
  5175 		r = SendReceive(ELoadLibrary, TIpcArgs((TDes8*)&infoBuf, (const TDesC*)&aFileName, (const TDesC*)&aPath) );
  5176 		aHandle=info.iHandle;
  5177 		if (r!=KErrNone)
  5178 			E32Loader::ReleaseDllLock();
  5179 		}
  5180 	__IF_DEBUG(Print(_L("LoadLibrary returning %d"),r));
  5181 	return r;
  5182 	}
  5183 
  5184 
  5185 EXPORT_C TInt RLoader::GetInfo(const TDesC& aFileName, TDes8& aInfoBuf)
  5186 //
  5187 // Get capabilities of a DLL
  5188 //
  5189 	{
  5190 	__IF_DEBUG(Print(_L("RLoader::GetInfo")));
  5191 	TLdrInfo info;
  5192 	TPckg<TLdrInfo> infoBuf(info);
  5193 	info.iOwnerType=EOwnerThread;
  5194 	if (aFileName.Length()>KMaxFileName)
  5195 		return KErrBadName;
  5196 	TInt r = SendReceive(EGetInfo, TIpcArgs((TDes8*)&infoBuf, (const TDesC*)&aFileName, (TDes8*)&aInfoBuf) );
  5197 	__IF_DEBUG(Print(_L("GetInfo returning %d"),r));
  5198 	return r;
  5199 	}
  5200 
  5201 
  5202 EXPORT_C TInt RLoader::Delete(const TDesC& aFileName)
  5203 /**
  5204 	Ask the loader to delete a file.  This function should be used instead
  5205 	of RFs::Delete where the supplied file may be a paged executable, although
  5206 	it can be used for any file.  A file that is currently paged may be moved
  5207 	by the system, and deleted later, when the file is no longer needed. This means
  5208 	that using this function may not immediately release the disk space associated
  5209 	with the file.
  5210 
  5211 	@param	aFileName		Fully-qualified filename.
  5212 	@return					Symbian OS error code.  Additionally, KErrBadName is
  5213 							returned if the supplied filename is not fully qualified..
  5214 	@capability Tcb
  5215 	@capability AllFiles
  5216  */
  5217 	{
  5218 	__IF_DEBUG(Printf(">RLoader::Delete,%S", &aFileName));
  5219 	TInt r = SendReceive(ELdrDelete, TIpcArgs(0, &aFileName));
  5220 	__IF_DEBUG(Printf("<RLoader::Delete,%d", r));
  5221 	return r;
  5222 	}
  5223 
  5224 #ifdef __WINS__
  5225 
  5226 #include <emulator.h>
  5227 
  5228 TInt RLoader::GetInfoFromHeader(const TDesC8& aHeader, TDes8& aInfoBuf)
  5229 	{
  5230 	__IF_DEBUG(Print(_L("RLoader::GetInfoFromHeader")));
  5231 
  5232 	TInt r = KErrNone;
  5233 
  5234 	Emulator::TModule module;
  5235 	module.iBase = aHeader.Ptr();
  5236 	TProcessCreateInfo info;
  5237 	module.GetInfo(info);
  5238 
  5239 	RLibrary::TInfoV2 ret_info;
  5240 	memclr(&ret_info,sizeof(ret_info));
  5241 	ret_info.iModuleVersion = info.iModuleVersion;
  5242 	ret_info.iUids = info.iUids;
  5243 	*(SSecurityInfo*)&ret_info.iSecurityInfo = info.iS;
  5244 	ret_info.iHardwareFloatingPoint = EFpTypeNone;
  5245 	TPckg<RLibrary::TInfoV2> ret_pckg(ret_info);
  5246 	if (aInfoBuf.MaxLength() < ret_pckg.Length())
  5247 		ret_pckg.SetLength(aInfoBuf.MaxLength());
  5248 	aInfoBuf=ret_pckg;
  5249 
  5250 	__IF_DEBUG(Print(_L("GetInfoFromHeader returning %d"),r));
  5251 	return r;
  5252 	}
  5253 
  5254 #else // not __WINS__ ...
  5255 
  5256 TInt RLoader::GetInfoFromHeader(const TDesC8& aHeader, TDes8& aInfoBuf)
  5257 	{
  5258 	__IF_DEBUG(Print(_L("RLoader::GetInfoFromHeader")));
  5259 	TInt r = SendReceive(EGetInfoFromHeader, TIpcArgs(&aHeader, &aInfoBuf) );
  5260 	__IF_DEBUG(Print(_L("GetInfoFromHeader returning %d"),r));
  5261 	return r;
  5262 	}
  5263 
  5264 #endif // __WINS__
  5265 
  5266 TInt RLoader::LoadDeviceDriver(const TDesC& aFileName, TInt aDeviceType)
  5267 	{
  5268 	TInt r=Connect();
  5269 	if (r==KErrNone)
  5270 		{
  5271 		TInt m = aDeviceType ? ELoadPhysicalDevice : ELoadLogicalDevice;
  5272 		r = SendReceive(m, TIpcArgs(0, (const TDesC*)&aFileName, 0) );
  5273 		Close();
  5274 		}
  5275 	return r;
  5276 	}
  5277 
  5278 TInt RLoader::LoadLocale(const TDesC& aLocaleDllName, TLibraryFunction* aExportList)
  5279 	{
  5280 	TInt r=Connect();
  5281 	if (r==KErrNone)
  5282 		{
  5283 		TInt size = KNumLocaleExports * sizeof(TLibraryFunction);
  5284 		TPtr8 functionListBuf((TUint8*)aExportList, size, size);
  5285 		r = SendReceive(ELoadLocale, TIpcArgs(0, (const TDesC*)&aLocaleDllName, &functionListBuf) );
  5286 		Close();
  5287 		}
  5288 	return r;
  5289 	}
  5290 
  5291 EXPORT_C TInt RLoader::DebugFunction(TInt aFunction, TInt a1, TInt a2, TInt a3)
  5292 	{
  5293 	return SendReceive(ELoaderDebugFunction, TIpcArgs(aFunction, a1, a2, a3) );
  5294 	}
  5295 
  5296 EXPORT_C TInt RLoader::CancelLazyDllUnload()
  5297 	{
  5298 	return SendReceive(ELoaderCancelLazyDllUnload, TIpcArgs() );
  5299 	}
  5300 
  5301 #ifdef __USERSIDE_THREAD_DATA__
  5302 
  5303 EXPORT_C TInt UserSvr::DllSetTls(TInt aHandle, TAny* aPtr)
  5304 //
  5305 // Set the value of the Thread Local Storage variable.
  5306 //
  5307 	{
  5308 	return LocalThreadData()->DllSetTls(aHandle, KDllUid_Default, aPtr);
  5309 	}
  5310 
  5311 EXPORT_C TInt UserSvr::DllSetTls(TInt aHandle, TInt aDllUid, TAny* aPtr)
  5312 //
  5313 // Set the value of the Thread Local Storage variable.
  5314 //
  5315 	{
  5316 	return LocalThreadData()->DllSetTls(aHandle, aDllUid, aPtr);
  5317 	}
  5318 
  5319 EXPORT_C void UserSvr::DllFreeTls(TInt aHandle)
  5320 //
  5321 // Remove the Thread Local Storage variable.
  5322 //
  5323 	{
  5324 	return LocalThreadData()->DllFreeTls(aHandle);
  5325 	}
  5326 
  5327 #else
  5328 
  5329 EXPORT_C TInt UserSvr::DllSetTls(TInt aHandle, TAny* aPtr)
  5330 //
  5331 // Set the value of the Thread Local Storage variable.
  5332 //
  5333 	{
  5334 	return Exec::DllSetTls(aHandle, KDllUid_Default, aPtr);
  5335 	}
  5336 
  5337 EXPORT_C TInt UserSvr::DllSetTls(TInt aHandle, TInt aDllUid, TAny* aPtr)
  5338 //
  5339 // Set the value of the Thread Local Storage variable.
  5340 //
  5341 	{
  5342 	return Exec::DllSetTls(aHandle, aDllUid, aPtr);
  5343 	}
  5344 
  5345 EXPORT_C void UserSvr::DllFreeTls(TInt aHandle)
  5346 //
  5347 // Remove the Thread Local Storage variable.
  5348 //
  5349 	{
  5350 	Exec::DllFreeTls(aHandle);
  5351 	}
  5352 
  5353 #endif
  5354 
  5355 
  5356 
  5357 
  5358 EXPORT_C TInt RChangeNotifier::Create()
  5359 /**
  5360 Creates a change notifier, and opens this handle to that change notifier.
  5361 
  5362 Ownership of this change notifier is vested in the current process.
  5363 
  5364 @return KErrNone if successful, otherwise one of the other system-wide error codes.
  5365 */
  5366 	{
  5367 	return SetReturnedHandle(Exec::ChangeNotifierCreate(EOwnerProcess),*this);
  5368 	}
  5369 
  5370 
  5371 
  5372 
  5373 EXPORT_C TInt RUndertaker::Create()
  5374 /**
  5375 Creates a thread-death notifier, and opens this handle to
  5376 that thread-death notifier.
  5377 
  5378 Ownership of this thread-death notifier is vested in the current process.
  5379 
  5380 @return KErrNone, if successful; otherwise one of
  5381         the other system-wide error codes.
  5382 */
  5383 	{
  5384 	return SetReturnedHandle(Exec::UndertakerCreate(EOwnerProcess),*this);
  5385 	}
  5386 
  5387 
  5388 
  5389 
  5390 EXPORT_C TInt RUndertaker::Logon(TRequestStatus& aStatus, TInt& aThreadHandle) const
  5391 /**
  5392 Issues a request for notification of the death of a thread.
  5393 
  5394 When another thread dies, the request completes and the TRequestStatus object
  5395 contains the value KErrDied; in addition, aThreadHandle contains
  5396 the handle-number of the dying thread.
  5397 
  5398 The requesting thread can construct a proper handle for the dying thread
  5399 using the code:
  5400 
  5401 @code
  5402 {
  5403 RThread r;
  5404 r.SetHandle(aThreadHandle);
  5405 ...r.Close();
  5406 }
  5407 @endcode
  5408 
  5409 Alternatively, if an outstanding request is cancelled by a call
  5410 to LogonCancel(), then the request completes with the value KErrCancel.
  5411 
  5412 Note that if a request completes normally, i.e. not as a result of
  5413 a LogonCancel(), then the handle to the dying thread must be closed
  5414 when there is no further interest in it.
  5415 
  5416 @param aStatus       A reference to the request status object.
  5417 @param aThreadHandle The handle-number representing the dying thread.
  5418 
  5419 @return KErrInUse if there is an outstanding request; KErrNone otherwise.
  5420 
  5421 @see RUndertaker::LogonCancel()
  5422 */
  5423 	{
  5424 	aStatus=KRequestPending;
  5425 	return Exec::UndertakerLogon(iHandle,aStatus,aThreadHandle);
  5426 	}
  5427 
  5428 
  5429 
  5430 
  5431 EXPORT_C TInt RUndertaker::LogonCancel() const
  5432 /**
  5433 Cancels an outstanding notification request to the thread-death notifier.
  5434 
  5435 @return KErrGeneral, if there is no outstanding notification request; KErrNone otherwise.
  5436 
  5437 @see RUndertaker::Logon()
  5438 */
  5439 	{
  5440 	return Exec::UndertakerLogonCancel(iHandle);
  5441 	}
  5442 
  5443 
  5444 
  5445 
  5446 /**
  5447 Sets the machine configuration.
  5448 
  5449 @param aConfig Descriptor containing the machine configuration data
  5450 
  5451 @return KErrNone, if sucessful, otherwise one of the other system-wide
  5452         error codes.
  5453 
  5454 @capability WriteDeviceData
  5455 */
  5456 EXPORT_C TInt User::SetMachineConfiguration(const TDesC8& aConfig)
  5457     {
  5458 	return Exec::SetMachineConfiguration(aConfig);
  5459     }
  5460 
  5461 
  5462 
  5463 
  5464 EXPORT_C TInt User::CompressAllHeaps()
  5465 /**
  5466 Compresses all the chunks containing heaps.
  5467 
  5468 @deprecated This function is no longer supported, and calling it has no effect.
  5469 
  5470 @return KErrNone
  5471 */
  5472 	{
  5473 
  5474 	return KErrNone;	// don't do this any more
  5475 	}
  5476 
  5477 
  5478 
  5479 
  5480 EXPORT_C TInt UserSvr::ChangeLocale(const TDesC& aLocaleDllName)
  5481 	{
  5482 	if(aLocaleDllName.Length() == 0)
  5483 		{
  5484 		//support reverting to defaults
  5485 		TInt r = UserSvr::LocalePropertiesSetDefaults();
  5486 		if(r == KErrNone)
  5487 			Exec::SetUTCTimeAndOffset(0,0,ETimeSetOffset,EChangesLocale);
  5488 		return r;
  5489 		}
  5490 	TExtendedLocale locale;
  5491 	TInt r = locale.LoadLocale(aLocaleDllName);
  5492 	if(r == KErrNone)
  5493 		{
  5494 		r = locale.SaveSystemSettings();
  5495 		}
  5496 	return r;
  5497 	}
  5498 
  5499 EXPORT_C TInt UserSvr::ResetMachine(TMachineStartupType aType)
  5500 //
  5501 //	Reset the machine. Currently only aType==EStartupWarmReset is supported.
  5502 //
  5503 	{
  5504 
  5505 	return Exec::ResetMachine(aType);
  5506 	}
  5507