--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/euser/us_ksvr.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,5492 @@
+// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32\euser\us_ksvr.cpp
+//
+//
+
+#include "us_std.h"
+#include "us_data.h"
+#include <e32svr.h>
+#include <e32uid.h>
+#include <e32ldr.h>
+
+//#define __DEBUG_IMAGE__ 1
+#if defined(__DEBUG_IMAGE__) && defined (__EPOC32__)
+#define __IF_DEBUG(t) {RDebug::t;}
+#else
+#define __IF_DEBUG(t)
+#endif
+
+//
+// class RNotifier
+//
+
+/**
+Requests the extended notifier server to start the notifier identified by
+the specified UID.
+
+The request is synchronous; the call returns when the request is complete.
+
+The notifier may not be started immediately if a higher priority notifier is
+already active. In this case, the notifier is queued until it has the highest
+priority outstanding request for the channel(s) it operates on.
+
+@param aNotifierUid The UID identifying the notifier.
+@param aBuffer Data that can be passed to the notifier; the format and meaning
+ of this depends on the notifier.
+
+@return KErrNone, if successful;
+ KErrNotFound, if there is no notifier matching the specified UID;
+ KErrAlreadyExists, if the notifier has already been started, or has
+ an outstanding start request. It may also return with one of the other
+ system-wide error codes, if the notifier cannot be started by
+ the server due to low memory or it leaves from its server side
+ call to StartL().
+
+@see CServer
+*/
+EXPORT_C TInt RNotifier::StartNotifier(TUid aNotifierUid, const TDesC8& aBuffer)
+ {
+ return SendReceive(EStartNotifier, TIpcArgs(
+ (TInt)aNotifierUid.iUid,
+ &aBuffer,
+ (TAny*)NULL // No resonse required
+ ));
+ }
+
+
+
+
+/**
+Requests the extended notifier server to start the notifier identified by
+the specified UID.
+
+The request is synchronous; the call returns when the request is complete.
+
+The notifier may not start immediately if a higher priority notifier is
+already active. In this case, the notifier is queued until it has the highest
+priority outstanding request for the channel(s) it operates on.
+This can also cause unexpected behaviour: the function can return
+before the notifier has been started with the added consequence that no response
+data is written.
+
+For this reason, this function has been deprecated. Instead, use
+RNotifier::StartNotifierAndGetResponse(), or if there is no need to wait for a
+response, use the two argument overload of RNotifier::StartNotifier().
+
+@param aNotifierUid The UID identifying the notifier.
+@param aBuffer Data that can be passed to the notifier; the format and meaning
+ of this depends on the notifier.
+@param aResponse Response data; the format
+ and meaning of this depends on the notifier.
+
+@return KErrNone, if successful;
+ KErrNotFound, if there is no notifier matching the specified UID;
+ KErrAlreadyExists, if the notifier has already been started, or has
+ an outstanding start request. It may also return with one of the other
+ system-wide error codes, if the notifier cannot be started by
+ the server due to low memory or it leaves from its server side
+ call to StartL().
+
+@see CServer
+
+@deprecated use RNotifier::StartNotifierAndGetResponse(), or if there is no
+ need to wait for a response, use the two argument overload
+ of RNotifier::StartNotifier()
+*/
+EXPORT_C TInt RNotifier::StartNotifier(TUid aNotifierUid, const TDesC8& aBuffer, TDes8& aResponse)
+ {
+ return SendReceive(EStartNotifier, TIpcArgs(
+ (TInt)aNotifierUid.iUid,
+ &aBuffer,
+ &aResponse
+ ));
+ }
+
+/*
+This function has never been implemented on any Symbian OS version.
+It always returns KErrNotSupported.
+@publishedPartner
+@removed
+*/
+EXPORT_C TInt RNotifier::StartNotifier(TUid aNotifierDllUid,TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
+ {
+ return SendReceive(EStartNotifierFromSpecifiedDll, TIpcArgs(
+ (TInt)aNotifierUid.iUid,
+ &aBuffer,
+ &aResponse,
+ (TInt)aNotifierDllUid.iUid
+ ));
+ }
+
+/**
+Requests the extended notifier server to cancel the notifier identified by
+the specified UID.
+
+The request is synchronous; the call returns when the request is complete.
+
+Any notifier that was queued pending the completion of aNotifierUid will be
+automatically started.
+
+@param aNotifierUid The UID identifying the notifier.
+
+@return KErrNone, if successful;
+ KErrNotFound, if there is no notifier matching the specified UID.
+*/
+EXPORT_C TInt RNotifier::CancelNotifier(TUid aNotifierUid)
+ {
+ return SendReceive(ECancelNotifier, TIpcArgs( (TInt)aNotifierUid.iUid ));
+ }
+
+/**
+Requests the extended notifier server to update the active notifier identified by
+the specified UID.
+
+The request is synchronous; the call returns when the request is complete.
+
+@param aNotifierUid The UID identifying the notifier.
+@param aBuffer Data that can be passed to the notifier; the format and meaning
+ of this depends on the notifier.
+@param aResponse Reserved for future use.
+
+@return KErrNone, if successful;
+ KErrNotFound, if there is no notifier matching the specified UID.
+*/
+EXPORT_C TInt RNotifier::UpdateNotifier(TUid aNotifierUid, const TDesC8& aBuffer,TDes8& aResponse)
+ {
+ return SendReceive(EUpdateNotifier, TIpcArgs(
+ (TInt)aNotifierUid.iUid,
+ &aBuffer,
+ &aResponse
+ ));
+ }
+
+/**
+Requests the extended notifier server to update the active notifier identified by
+the specified UID.
+
+This is an asynchronous request.It may be called multiple times for
+some notifier implementations; see specific notifier documentation for exact details.
+
+@param aRs The request status. On request completion, contains:
+ KErrNone, if successful; otherwise, one of the other system
+ wide error codes.
+@param aNotifierUid The UID identifying the notifier.
+@param aBuffer Data that can be passed to the notifier; the format and meaning
+ of this depends on the notifier.
+@param aResponse Reserved for future use.
+
+*/
+EXPORT_C void RNotifier::UpdateNotifierAndGetResponse(TRequestStatus& aRs, TUid aNotifierUid, const TDesC8& aBuffer, TDes8& aResponse)
+ {
+ SendReceive(EUpdateNotifierAndGetResponse, TIpcArgs(
+ (TInt)aNotifierUid.iUid,
+ &aBuffer,
+ &aResponse
+ ), aRs);
+ }
+
+/**
+Requests the extended notifier server to start the notifier identified by
+the specified UID.
+
+This is an asynchronous request.It may be called multiple times for
+some notifier implementations; see specific notifier documentation for exact details.
+
+@param aRs The request status. On request completion, contains:
+ KErrNone, if successful; otherwise, one of the other system
+ wide error codes.
+@param aNotifierUid The UID identifying the notifier.
+@param aBuffer Data that can be passed to the notifier; the format
+ and meaning of this depends on the notifier.
+@param aResponse Response data; the format
+ and meaning of this depends on the notifier.
+*/
+EXPORT_C void RNotifier::StartNotifierAndGetResponse(TRequestStatus& aRs,TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
+ {
+ SendReceive(EStartNotifierAndGetResponse, TIpcArgs(
+ (TInt)aNotifierUid.iUid,
+ &aBuffer,
+ &aResponse
+ ), aRs);
+ }
+
+
+
+
+/**
+@publishedPartner
+@removed
+
+This function has never been implemented on any Symbian OS version.
+The request always completes with KErrNotSupported.
+*/
+EXPORT_C void RNotifier::StartNotifierAndGetResponse(TRequestStatus& aRs,TUid aNotifierDllUid,TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
+ {
+ SendReceive(EStartNotifierFromSpecifiedDllAndGetResponse, TIpcArgs(
+ (TInt)aNotifierUid.iUid,
+ &aBuffer,
+ &aResponse,
+ (TInt)aNotifierDllUid.iUid
+ ), aRs);
+ }
+
+
+
+
+/**
+@publishedPartner
+@removed
+
+This function has never been implemented on any Symbian OS version.
+It always returns KErrNotSupported.
+*/
+EXPORT_C TInt RNotifier::UnloadNotifiers(TUid /*aNotifierUid*/)
+ {
+ return KErrNotSupported;
+ }
+
+
+
+
+/**
+@publishedPartner
+@removed
+
+This function has never been implemented on any Symbian OS version.
+It always returns KErrNotSupported.
+*/
+EXPORT_C TInt RNotifier::LoadNotifiers(TUid /*aNotifierUid*/)
+ {
+ return KErrNotSupported;
+ }
+
+
+
+
+/**
+Default constructor.
+*/
+EXPORT_C RNotifier::RNotifier()
+ : iButtonVal(NULL,0),
+ iCombinedBuffer(NULL)
+ {}
+
+
+
+
+/**
+Connects to the extended notifier server, creating a session with that server.
+Note: Notifier server is started during window server start-up sequence.
+
+The function must be called before any other function.
+
+@return KErrNone, if successful, otherwise one of the other system-wide error codes
+*/
+EXPORT_C TInt RNotifier::Connect()
+ {
+ return CreateSession(__NOTIFIER_NAME,TVersion(KNotifierMajorVersionNumber,KNotifierMinorVersionNumber,KNotifierBuildVersionNumber),-1);
+ }
+
+
+
+
+/**
+Launches a simple two line dialog that displays two lines of text.
+
+This is an asynchronous request that completes when the dialog exits.
+
+@param aLine1 A descriptor containing the first line of text to be displayed.
+@param aLine2 A descriptor containing the second line of text to be displayed.
+@param aBut1 A descriptor containing text to be displayed in the first button.
+@param aBut2 A descriptor containing text to be displayed in the (optional) second button.
+@param aButtonVal An integer value which is set when the dialog exits. It is set to:
+ 0, if the first button is selected;
+ 1, if the second button is selected.
+@param aStatus The request status object. If the request completes normally, this is set to KErrNone.
+*/
+EXPORT_C void RNotifier::Notify(const TDesC& aLine1,const TDesC& aLine2,const TDesC& aBut1,const TDesC& aBut2, TInt& aButtonVal, TRequestStatus& aStatus)
+ {
+ const TInt requiredLengthOfCombinedBuffer=aLine1.Length()+aLine2.Length()+aBut1.Length()+aBut2.Length();
+ if ((iCombinedBuffer!=NULL) && (iCombinedBuffer->Des().MaxLength()<requiredLengthOfCombinedBuffer))
+ {
+ delete iCombinedBuffer;
+ iCombinedBuffer=NULL;
+ }
+ if (iCombinedBuffer==NULL)
+ {
+ iCombinedBuffer=HBufC::New(requiredLengthOfCombinedBuffer);
+ }
+ if (iCombinedBuffer==NULL)
+ {
+ // report the error back via the TRequestStatus
+ TRequestStatus* status=&aStatus;
+ User::RequestComplete(status,KErrNoMemory);
+ }
+ else
+ {
+ TPtr combinedBufferForNotify(iCombinedBuffer->Des());
+ combinedBufferForNotify = aLine1;
+ combinedBufferForNotify.Append(aLine2);
+ combinedBufferForNotify.Append(aBut1);
+ combinedBufferForNotify.Append(aBut2);
+ iButtonVal.Set(REINTERPRET_CAST(TUint8*,&aButtonVal),sizeof(TInt),sizeof(TInt));
+ __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
+ SendReceive(ENotifierNotify,TIpcArgs(&iButtonVal,iCombinedBuffer,(aLine1.Length()<<16)|aLine2.Length(),(aBut1.Length()<<16)|aBut2.Length()),aStatus);
+ }
+ }
+
+
+
+
+/**
+Not implemented by the server.
+*/
+EXPORT_C void RNotifier::NotifyCancel()
+ {
+ SendReceive(ENotifierNotifyCancel,TIpcArgs()); // ignores any returned error
+ }
+
+
+
+
+/**
+Closes the notifier.
+*/
+EXPORT_C void RNotifier::Close()
+ {
+ delete iCombinedBuffer;
+ iCombinedBuffer=NULL;
+ RSessionBase::Close();
+ }
+
+
+
+
+/**
+@internalAll
+*/
+EXPORT_C TInt RNotifier::InfoPrint(const TDesC& aDes)
+ {
+ return SendReceive(ENotifierInfoPrint, TIpcArgs(&aDes));
+ }
+
+
+//
+// Class TChunkCreateInfo
+//
+
+/**
+Default constructor.
+
+This defaults the chunk to be created to be local, to have no attributes set
+and to use the default clear byte.
+
+A local chunk is private to the process creating it and is not
+intended for access by other user processes.
+*/
+EXPORT_C TChunkCreateInfo::TChunkCreateInfo() :
+ // Specifing individual initialisers for members instead of using memclear
+ // so that Coverity doesn't complain about uninitialised local variables in
+ // calls to e.g., TChunkCreateInfo::SetPaging().
+ iVersionNumber(0),
+ iType(TChunkCreate::ENormal),
+ iGlobal(EFalse),
+ iMaxSize(0),
+ iOwnerType(EOwnerProcess),
+ iName(NULL),
+ iInitialBottom(0),
+ iInitialTop(0),
+ iAttributes(TChunkCreate::EPagingUnspec),
+ iClearByte(KChunkClearByteDefault)
+ {
+ }
+
+
+/**
+Sets the chunk to be created to have a committed region that always starts at the
+bottom of the reserved region.
+
+
+@param aSize The number of bytes committed to this chunk.
+@param aMaxSize The maximum size to which the reserved region of this chunk
+ can grow.
+@param aType An enumeration whose enumerators define the ownership of this
+ chunk handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+@see RChunk::CreateLocal()
+*/
+EXPORT_C void TChunkCreateInfo::SetNormal(TInt aInitialSize, TInt aMaxSize)
+ {
+ iType = TChunkCreate::ENormal | TChunkCreate::EData;
+ iInitialBottom = 0;
+ iInitialTop = aInitialSize;
+ iMaxSize = aMaxSize;
+ }
+
+
+/**
+Sets the chunk to be created to be user writable and to be marked by the kernel
+as containing code.
+This can only be set on local chunks.
+
+@param aInitialSize The number of bytes committed to this chunk.
+@param aMaxSize The maximum size to which the reserved region of this chunk
+ can grow.
+@see RChunk::CreateLocalCode()
+*/
+EXPORT_C void TChunkCreateInfo::SetCode(TInt aInitialSize, TInt aMaxSize)
+ {
+ iType = TChunkCreate::ENormal | TChunkCreate::ECode;
+ iInitialBottom = 0;
+ iInitialTop = aInitialSize;
+ iMaxSize = aMaxSize;
+ }
+
+
+/**
+Sets the chunk to be created to have a commited region that that can be any
+contiguous subset of the reserved region.
+
+@param aInitialBottom The offset of the bottom of the new committed region
+ from the base of the chunk's reserved region.
+@param aInitialTop The offset of the top of the new committed region from
+ the base of the chunk's reserved region.
+@param aMaxSize The maximum size to which the reserved region of
+ this chunk can grow.
+@see RChunk::CreateDoubleEndedLocal()
+*/
+EXPORT_C void TChunkCreateInfo::SetDoubleEnded(TInt aInitialBottom, TInt aInitialTop, TInt aMaxSize)
+ {
+ iType = TChunkCreate::EDoubleEnded | TChunkCreate::EData;
+ iInitialBottom = aInitialBottom;
+ iInitialTop = aInitialTop;
+ iMaxSize = aMaxSize;
+ }
+
+/**
+Set the chunk to be created to have a committed region consisting of an
+arbitrary set of MMU pages within the reserved region.
+
+@param aInitialBottom The offset of the bottom of the new committed region
+ from the base of the chunk's reserved region.
+@param aInitialTop The offset of the top of the new committed region
+ from the base of the chunk's reserved region.
+@param aMaxSize The maximum size to which the reserved region of
+ this chunk can grow.
+@see RChunk::CreateDisconnectedLocal()
+*/
+EXPORT_C void TChunkCreateInfo::SetDisconnected(TInt aInitialBottom, TInt aInitialTop, TInt aMaxSize)
+ {
+ iType = TChunkCreate::EDisconnected | TChunkCreate::EData;
+ iInitialBottom = aInitialBottom;
+ iInitialTop = aInitialTop;
+ iMaxSize = aMaxSize;
+ }
+
+
+/**
+Sets the chunk to be created to be a thread heap chunk.
+For internal use only.
+
+@param aInitialSize The number of bytes committed to this chunk.
+@param aMaxSize The maximum size to which the reserved region of this chunk
+ can grow.
+@param aName The name to be given to the chunk to be created
+@internalComponent
+*/
+void TChunkCreateInfo::SetThreadHeap(TInt aInitialSize, TInt aMaxSize, const TDesC& aName)
+ {
+ iType = TChunkCreate::ENormal | TChunkCreate::EData;
+ iInitialBottom = 0;
+ iInitialTop = aInitialSize;
+ iMaxSize = aMaxSize;
+ iAttributes |= TChunkCreate::ELocalNamed;
+ iName = &aName;
+ iOwnerType = EOwnerThread;
+ }
+
+/**
+Sets the owner of the chunk to be created.
+@param aType The owner of the chunk to be created.
+*/
+EXPORT_C void TChunkCreateInfo::SetOwner(TOwnerType aType)
+ {
+ iOwnerType = aType;
+ }
+
+/**
+Sets the chunk to be created to be global, i.e. it is potentially visible
+to all processes and is intended for access by other user processes.
+
+@param aName A reference to a descriptor containing the name to be
+ assigned to the global chunk. The length of
+ the descriptor must be no greater than that allowed for
+ a TKName type.
+*/
+EXPORT_C void TChunkCreateInfo::SetGlobal(const TDesC& aName)
+ {
+ iName = &aName;
+ iGlobal = ETrue;
+ }
+
+/**
+Sets the byte value that all memory committed to the chunk will be cleared to.
+@param TUint8 aClearByte.
+*/
+EXPORT_C void TChunkCreateInfo::SetClearByte(TUint8 aClearByte)
+ {
+ iClearByte = aClearByte;
+ }
+
+
+/**
+Sets the data paging attributes for the chunk to be created. Any previous calls
+to this method will be overridden for this TChunkCreateInfo object.
+
+@param aPaging The data paging attributes of the chunk to be created.
+
+@prototype
+*/
+EXPORT_C void TChunkCreateInfo::SetPaging(const TChunkPagingAtt aPaging)
+ {
+ __ASSERT_COMPILE(TChunkCreate::EPagingUnspec == 0);
+ iAttributes &= ~TChunkCreate::EPagingMask;
+ if (aPaging == EPaged)
+ iAttributes |= TChunkCreate::EPaged;
+ if (aPaging == EUnpaged)
+ iAttributes |= TChunkCreate::EUnpaged;
+ }
+
+
+EXPORT_C void TChunkCreateInfo::SetCache(TInt aMaxSize)
+ {
+ iType = TChunkCreate::ECache | TChunkCreate::EData;
+ iInitialBottom = 0;
+ iInitialTop = 0;
+ iMaxSize = aMaxSize;
+ SetPaging(EUnpaged);
+ }
+
+
+//
+// class RChunk
+//
+
+EXPORT_C TInt RChunk::CreateLocal(TInt aSize,TInt aMaxSize,TOwnerType aType)
+/**
+Creates a local chunk.
+
+The chunk is local to the process creating it; i.e. it is private to the process
+creating it and is not intended for access by other user processes.
+
+aMaxSize specifies the maximum size of the chunk and aSize specifies the number
+of bytes to be committed on creation of the chunk. Both values are rounded
+up to the next nearest processor page boundary value if they are not already
+on a processor page boundary.
+
+The committed region always starts at the bottom of the reserved region.
+
+By default, ownership of this chunk handle is vested in the current process.
+Ownership of the chunk handle can be vested in the current thread by passing
+EOwnerThread as the third parameter to this function.
+
+@param aSize The number of bytes committed to this chunk.
+@param aMaxSize The maximum size to which the reserved region of this chunk
+ can grow.
+@param aType An enumeration whose enumerators define the ownership of this
+ chunk handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone if successful, otherwise another of the system-wide error
+ codes.
+
+@panic USER 99 if aMaxSize is negative.
+@panic USER 100 if aSize is negative.
+@panic USER 101 if aSize is greater than or equal to the supplied
+ value of aMaxSize.
+*/
+ {
+ TChunkCreateInfo createInfo;
+ createInfo.SetNormal(aSize, aMaxSize);
+ createInfo.SetOwner(aType);
+ return Create(createInfo);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::CreateLocalCode(TInt aSize,TInt aMaxSize,TOwnerType aType)
+/**
+Creates a user writable chunk that is marked by the kernel as containing code.
+
+The chunk is local to the process creating it, i.e. it is private to the process
+creating it and is not intended for access by other user processes.
+
+On systems using a Harvard cache, this type of chunk removes the need to flush
+the instruction cache (I-Cache) on a context switch. However, the instruction
+Translation Look-aside Buffer (ITLB) still needs to be flushed when switching
+to or from a process with one of these chunks in its address space. Systems with
+a dynamic branch predictor may also need to flush their branch target buffer when
+switching from one process using this type of chunk to another.
+
+@param aSize The number of bytes committed to this chunk.
+@param aMaxSize The maximum size to which the reserved region of this chunk
+ can grow.
+@param aType An enumeration whose enumerators define the ownership of this
+ chunk handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone if successful, otherwise another of the system-wide error
+ codes.
+
+@panic USER 99 if aMaxSize is negative.
+@panic USER 100 if aSize is negative.
+@panic USER 101 if aSize is greater than or equal to the supplied
+ value of aMaxSize.
+
+@see UserHeap::ChunkHeap
+@see User::IMB_Range
+*/
+ {
+ TChunkCreateInfo createInfo;
+ createInfo.SetCode(aSize, aMaxSize);
+ createInfo.SetOwner(aType);
+ return Create(createInfo);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::CreateGlobal(const TDesC &aName,TInt aSize,TInt aMaxSize,TOwnerType aType)
+/**
+Creates a global chunk.
+
+The chunk is global; i.e. it is potentially visible to all processes and is
+intended for access by other user processes.
+
+aMaxSize specifies the maximum size of the chunk and aSize specifies the number
+of bytes to be committed on creation of the chunk. Both values are rounded
+up to the next nearest processor page boundary value ,if they are not already
+on a processor page boundary value.
+
+The committed region always starts at the bottom of the reserved region.
+
+The descriptor aName contains the name to be assigned to this global chunk. If
+this name is empty, the chunk will be anonymous. Anonymous chunks cannot be
+accessed by other processes unless the creator explicitly passes them a handle
+to the chunk - this can be used to transfer large amounts of data between
+processes in a secure fashion.
+
+By default, ownership of this chunk handle is vested in the current process.
+Ownership of the chunk handle can be vested in the current thread by passing
+EOwnerThread as the third parameter to this function.
+
+@param aName A reference to a descriptor containing the name to be assigned
+ to this global chunk. The length of the descriptor must be no
+ greater than that allowed for a TKName type.
+@param aSize The number of bytes committed to this chunk.
+@param aMaxSize The maximum size to which the reserved region of this chunk
+ can grow.
+@param aType An enumeration whose enumerators define the ownership of this
+ chunk handle. If not explicitly specified, EOwnerProcess is taken
+ as default.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 99 if aMaxSize is negative.
+@panic USER 100 if aSize is negative.
+@panic USER 101 if aSize is greater than or equal to the supplied
+ value of aMaxSize.
+*/
+ {
+ TChunkCreateInfo createInfo;
+ createInfo.SetNormal(aSize, aMaxSize);
+ createInfo.SetGlobal(aName);
+ createInfo.SetOwner(aType);
+ return Create(createInfo);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::CreateDoubleEndedLocal(TInt aInitialBottom, TInt aInitialTop,TInt aMaxSize,TOwnerType aType)
+/**
+Creates a local, double ended, chunk.
+
+The chunk is local to the process creating it; i.e. it is private to
+the process creating it and is not intended for access by other
+user processes.
+
+The committed region of a double ended chunk can be any contiguous subset
+of the reserved region.
+
+aMaxSize specifies the maximum size of the chunk.
+
+The difference between aInitialTop and aInitialBottom gives the number of
+bytes to be committed, on creation of the chunk; aInitialBottom gives the
+offset of the bottom of the committed region from the base of the chunk's
+reserved region; aInitialTop gives the offset of the top of the committed
+region from the base of the chunk's reserved region.
+
+Both aInitialBottom and aInitialTop are rounded up to the next nearest
+processor page boundary value, if they are not already on
+a processor page boundary value.
+
+By default, ownership of this chunk handle is vested in the current process.
+Ownership of the chunk handle can be vested in the current thread by passing
+EOwnerThread as the third parameter to this function.
+
+Note that:
+
+1. the lowest valid address in a double ended chunk is the sum of the base of
+ the chunk's reserved region plus the adjusted value of aInitialBottom
+
+2. the highest valid address in a double ended chunk is the the sum of the base
+ of the chunk's reserved region plus the adjusted value of aInitialTop - 1.
+
+@param aInitialBottom The offset of the bottom of the new committed region
+ from the base of the chunk's reserved region.
+@param aInitialTop The offset of the top of the new committed region from
+ the base of the chunk's reserved region.
+@param aMaxSize The maximum size to which the reserved region of
+ this chunk can grow.
+@param aType An enumeration whose enumerators define the ownership of
+ this chunk handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 99 if aMaxSize is negative.
+@panic USER 120 if aInitialBottom is negative.
+@panic USER 121 if aInitialTop is negative.
+@panic USER 122 if aInitialBottom is greater than the supplied value
+ of aInitialTop.
+@panic USER 123 if aInitialTop is greater than the supplied value of aMaxSize.
+*/
+ {
+ TChunkCreateInfo createInfo;
+ createInfo.SetDoubleEnded(aInitialBottom, aInitialTop, aMaxSize);
+ createInfo.SetOwner(aType);
+ return Create(createInfo);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::CreateDoubleEndedGlobal(const TDesC &aName,TInt aInitialBottom,TInt aInitialTop,TInt aMaxSize,TOwnerType aType)
+/**
+Creates a global, double ended, chunk.
+
+The chunk is global; i.e. it is visible to all processes and is intended
+for access by other user processes.
+
+The committed region of a double ended chunk can be any contiguous subset
+of the reserved region.
+
+aMaxSize specifies the maximum size of the chunk.
+
+The difference between aInitialTop and aInitialBottom gives the number of
+bytes to be committed, on creation of the chunk; aInitialBottom gives the
+offset of the bottom of the committed region from the base of the chunk's
+reserved region; aInitialTop gives the offset of the top of the committed
+region from the base of the chunk's reserved region.
+
+Both aInitialBottom and aInitialTop are rounded up to the next nearest
+processor page boundary value, if they are not already on a processor page
+boundary value.
+
+The descriptor aName contains the name to be assigned to this global chunk.
+
+By default, ownership of this chunk handle is vested in the current process.
+Ownership of the chunk handle can be vested in the current thread by passing
+EOwnerThread as the third parameter to this function.
+
+Note that:
+
+1. the lowest valid address in a double ended chunk is the sum of the base of
+ the chunk's reserved region plus the adjusted value of aInitialBottom
+
+2. the highest valid address in a double ended chunk is the the sum of the base
+ of the chunk's reserved region plus the adjusted value of aInitialTop - 1.
+
+@param aName A reference to a descriptor containing the name to be
+ assigned to this global chunk. The length of
+ the descriptor must be no greater than that allowed for
+ a TKName type.
+@param aInitialBottom The offset of the bottom of the new committed region
+ from the base of the chunk's reserved region.
+@param aInitialTop The offset of the top of the new committed region from
+ the base of the chunk's reserved region.
+@param aMaxSize The maximum size to which the reserved region of
+ this chunk can grow.
+@param aType An enumeration whose enumerators define the ownership of
+ this chunk handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 99 if aMaxSize is negative.
+@panic USER 120 if aInitialBottom is negative.
+@panic USER 121 if aInitialTop is negative.
+@panic USER 122 if aInitialBottom is greater than the supplied value
+ of aInitialTop.
+@panic USER 123 if aInitialTop is greater than the supplied value of aMaxSize.
+@panic USER 163 if aName is empty.
+*/
+ {
+ TChunkCreateInfo createInfo;
+ createInfo.SetDoubleEnded(aInitialBottom, aInitialTop, aMaxSize);
+ createInfo.SetGlobal(aName);
+ createInfo.SetOwner(aType);
+ return Create(createInfo);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::CreateDisconnectedLocal(TInt aInitialBottom, TInt aInitialTop,TInt aMaxSize,TOwnerType aType)
+/**
+Creates a local, disconnected chunk.
+
+The chunk is local to the process creating it; i.e. it is private to
+the process creating it and is not intended for access by other
+user processes.
+
+A disconnected chunk has a committed region consisting of an arbitrary set
+of MMU pages within the reserved region, i.e. each page-sized address range
+within the reserved region which begins on a page boundary may be committed
+independently.
+
+aMaxSize specifies the maximum size of the chunk.
+
+The difference between aInitialTop and aInitialBottom gives the number of
+bytes to be committed, on creation of the chunk; aInitialBottom gives the
+offset of the bottom of the committed region from the base of the chunk's
+reserved region; aInitialTop gives the offset of the top of the committed
+region from the base of the chunk's reserved region.
+
+Both aInitialBottom and aInitialTop are rounded up to the next nearest
+processor page boundary value, if they are not already on
+a processor page boundary value.
+
+By default, ownership of this chunk handle is vested in the current process.
+Ownership of the chunk handle can be vested in the current thread by passing
+EOwnerThread as the third parameter to this function.
+
+@param aInitialBottom The offset of the bottom of the new committed region
+ from the base of the chunk's reserved region.
+@param aInitialTop The offset of the top of the new committed region from
+ the base of the chunk's reserved region.
+@param aMaxSize The maximum size to which the reserved region of
+ this chunk can grow.
+@param aType An enumeration whose enumerators define the ownership of
+ this chunk handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 99 if aMaxSize is negative.
+@panic USER 120 if aInitialBottom is negative.
+@panic USER 121 if aInitialTop is negative.
+@panic USER 122 if aInitialBottom is greater than the supplied value
+ of aInitialTop.
+@panic USER 123 if aInitialTop is greater than the supplied value of aMaxSize.
+*/
+ {
+ TChunkCreateInfo createInfo;
+ createInfo.SetDisconnected(aInitialBottom, aInitialTop, aMaxSize);
+ createInfo.SetOwner(aType);
+ return Create(createInfo);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::CreateDisconnectedGlobal(const TDesC &aName,TInt aInitialBottom,TInt aInitialTop,TInt aMaxSize,TOwnerType aType)
+/**
+Creates a global, disconnected, chunk.
+
+The chunk is global; i.e. it is visible to all processes and is intended
+for access by other user processes.
+
+A disconnected chunk has a committed region consisting of an arbitrary set
+of MMU pages within the reserved region, i.e. each page-sized address range
+within the reserved region which begins on a page boundary may be committed
+independently.
+
+aMaxSize specifies the maximum size of the chunk.
+
+The difference between aInitialTop and aInitialBottom gives the number of
+bytes to be committed, on creation of the chunk; aInitialBottom gives the
+offset of the bottom of the committed region from the base of the chunk's
+reserved region; aInitialTop gives the offset of the top of the committed
+region from the base of the chunk's reserved region.
+
+Both aInitialBottom and aInitialTop are rounded up to the next nearest
+processor page boundary value, if they are not already on a processor page
+boundary value.
+
+The descriptor aName contains the name to be assigned to this global chunk.
+
+By default, ownership of this chunk handle is vested in the current process.
+Ownership of the chunk handle can be vested in the current thread by passing
+EOwnerThread as the third parameter to this function.
+
+@param aName A reference to a descriptor containing the name to be
+ assigned to this global chunk. The length of
+ the descriptor must be no greater than that allowed for
+ a TKName type.
+@param aInitialBottom The offset of the bottom of the new committed region
+ from the base of the chunk's reserved region.
+@param aInitialTop The offset of the top of the new committed region from
+ the base of the chunk's reserved region.
+@param aMaxSize The maximum size to which the reserved region of
+ this chunk can grow.
+@param aType An enumeration whose enumerators define the ownership of
+ this chunk handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 99 if aMaxSize is negative.
+@panic USER 120 if aInitialBottom is negative.
+@panic USER 121 if aInitialTop is negative.
+@panic USER 122 if aInitialBottom is greater than the supplied value
+ of aInitialTop.
+@panic USER 123 if aInitialTop is greater than the supplied value of aMaxSize.
+*/
+ {
+ TChunkCreateInfo createInfo;
+ createInfo.SetDisconnected(aInitialBottom, aInitialTop, aMaxSize);
+ createInfo.SetGlobal(aName);
+ createInfo.SetOwner(aType);
+ return Create(createInfo);
+ }
+
+
+/**
+Creates a chunk of the type specified by the parameter aCreateInfo.
+
+@param aCreate A reference to a TChunkCreateInfo object specifying the type of
+ chunk to create.
+
+@return KErrNone on success, otherwise on of the system wide error codes.
+
+@panic USER 99 if the specified maximum size is negative.
+@panic USER 120 if any specified initial bottom is negative.
+@panic USER 121 if any specified initial top is negative.
+@panic USER 122 if any specified initial bottom is greater than the supplied value
+ for the intial top.
+@panic USER 123 if any specified initial top is greater than the supplied value for the maximum size.
+@panic USER 214 if any of the specified attributes is invalid.
+@panic USER 215 if the version number of aCreateInfo is invalid.
+*/
+EXPORT_C TInt RChunk::Create(TChunkCreateInfo& aCreateInfo)
+ {
+ // Verify the version number of TChunkCreateInfo is supported
+ __ASSERT_ALWAYS(aCreateInfo.iVersionNumber < TChunkCreateInfo::ESupportedVersions,
+ Panic(EChkCreateInvalidVersion));
+
+ TUint mapping = aCreateInfo.iType & ~TChunkCreate::ECode;
+ TBool shouldBeNamed = aCreateInfo.iGlobal ||
+ (aCreateInfo.iAttributes & TChunkCreate::ELocalNamed);
+ __ASSERT_ALWAYS(mapping <= (TUint)TChunkCreate::ECache, Panic(EChkCreateInvalidType));
+ __ASSERT_ALWAYS(!(aCreateInfo.iType & TChunkCreate::ECode) || !aCreateInfo.iGlobal,
+ Panic(EChkCreateInvalidType));
+ __ASSERT_ALWAYS((!shouldBeNamed && aCreateInfo.iName == NULL) ||
+ (shouldBeNamed && aCreateInfo.iName),
+ Panic(EChkCreateInvalidName));
+ __ASSERT_ALWAYS(aCreateInfo.iMaxSize >= 0, Panic(EChkCreateMaxSizeNegative));
+ __ASSERT_ALWAYS(!(aCreateInfo.iAttributes & ~TChunkCreate::EChunkCreateAttMask), Panic(EChkCreateInvalidAttribute));
+ if(mapping == TChunkCreate::ENormal)
+ {
+ // 'normal' chunks have different semantics for the meanings of
+ // aInitialBottom and aInitialTop
+ __ASSERT_ALWAYS(!aCreateInfo.iInitialBottom, Panic(EChkCreateInvalidBottom));
+ __ASSERT_ALWAYS(aCreateInfo.iInitialTop >= 0, Panic(EChkCreateSizeNotPositive));
+ __ASSERT_ALWAYS(aCreateInfo.iInitialTop <= aCreateInfo.iMaxSize, Panic(EChkCreateMaxLessThanMin));
+ }
+ else
+ {
+ __ASSERT_ALWAYS(aCreateInfo.iInitialBottom >= 0, Panic(EChkCreateBottomNegative));
+ __ASSERT_ALWAYS(aCreateInfo.iInitialTop >= 0, Panic(EChkCreateTopNegative));
+ __ASSERT_ALWAYS(aCreateInfo.iInitialTop >= aCreateInfo.iInitialBottom, Panic(EChkCreateTopLessThanBottom));
+ __ASSERT_ALWAYS(aCreateInfo.iInitialTop <= aCreateInfo.iMaxSize, Panic(EChkCreateTopBiggerThanMax));
+ }
+
+ TChunkCreate info;
+ info.iAtt = aCreateInfo.iAttributes | (TUint)aCreateInfo.iType;
+ info.iAtt |= (aCreateInfo.iGlobal)? TChunkCreate::EGlobal : TChunkCreate::ELocal; // Add the global attribute
+ info.iForceFixed = EFalse;
+ info.iInitialBottom = aCreateInfo.iInitialBottom;
+ info.iInitialTop = aCreateInfo.iInitialTop;
+ info.iMaxSize = aCreateInfo.iMaxSize;
+ info.iClearByte = aCreateInfo.iClearByte;
+
+ TDesC8* ptrName = NULL;
+ TBuf8<KMaxKernelName> name8;
+ if(aCreateInfo.iName)
+ {
+ TInt r = User::ValidateName(*aCreateInfo.iName);
+ if(KErrNone!=r)
+ return r;
+ name8.Copy(*aCreateInfo.iName);
+ ptrName = &name8;
+ }
+
+ return SetReturnedHandle(Exec::ChunkCreate(aCreateInfo.iOwnerType, ptrName, info),*this);
+ }
+
+
+EXPORT_C TInt RChunk::OpenGlobal(const TDesC &aName,TBool isReadOnly,TOwnerType aType)
+/**
+Opens a handle to a specific named global chunk.
+
+Full read/write access can be allowed or access can be limited to read only.
+
+By default, ownership of this process handle is vested in the current process,
+but can be vested in the current thread by passing EOwnerThread as the second
+parameter to this function.
+
+@param aName A reference to the descriptor containing the name of
+ the chunk to be opened.
+@param isReadOnly This is currently not implemented and setting it to ETrue
+ will have no effect.
+ (Intended implementation will be as below:
+ Defines the type of access to the chunk: Specify ETrue if
+ access is limited to read only, otherwise specify EFalse
+ for full read/write access.)
+@param aType An enumeration whose enumerators define ownership of
+ this chunk handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+*/
+ {
+ (void) isReadOnly; // This is not currently used
+ return OpenByName(aName,aType,EChunk);
+ }
+
+
+
+
+/**
+Opens a handle to a chunk using a handle number sent by a client
+to a server.
+
+This function is called by the server.
+
+@param aMessage The message pointer.
+@param aParam An index specifying which of the four message arguments
+ contains the handle number.
+@param isReadOnly This is currently not implemented and setting it to ETrue
+ will have no effect.
+ (Intended implementation will be as below:
+ Defines the type of access to the chunk: Specify ETrue if
+ access is limited to read only, otherwise specify EFalse
+ for full read/write access.)
+@param aType An enumeration whose enumerators define the ownership of this
+ chunk handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone, if successful;
+ KErrArgument, if the value of aParam is outside the range 0-3;
+ KErrBadHandle, if not a valid handle;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RChunk::Open(RMessagePtr2 aMessage,TInt aParam,TBool isReadOnly,TOwnerType aType)
+ {
+ (void) isReadOnly; // This is not currently used
+ return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),EChunk,aParam,aType));
+ }
+
+
+
+
+/**
+Opens a handle to a chunk using a handle number passed as an
+environment data item to the child process during the creation of
+that child process.
+
+Note that this function can only be called successfully once.
+
+@param aArgumentIndex An index that identifies the slot in the process
+ environment data that contains the handle number. This is
+ a value relative to zero, i.e. 0 is the first item/slot.
+ This can range from 0 to 15.
+
+@param aOwnerType An enumeration whose enumerators define the ownership of
+ this chunk handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone, if successful;
+ KErrNotFound, if the slot indicated by aArgumentIndex is empty;
+ KErrArgument, if the slot does not contain a Semaphore handle;
+ otherwise one of the other system-wide error codes.
+
+@see RProcess::SetParameter()
+*/
+EXPORT_C TInt RChunk::Open(TInt aArgumentIndex, TOwnerType aOwnerType)
+ {
+ return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, EChunk, aOwnerType));
+ }
+
+
+
+
+
+EXPORT_C TInt RChunk::SetRestrictions(TUint aFlags)
+/**
+Sets or removes restrictions on the ability of the chunk to change.
+
+For example, to adjust, commit etc
+
+@param aFlags One of the values defined by TRestrictions.
+
+@see RChunk::TRestrictions()
+*/
+ {
+ return Exec::ChunkSetRestrictions(iHandle,aFlags);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::Adjust(TInt aNewSize) const
+/**
+Changes the number of bytes committed to the chunk.
+
+This value is always rounded up to the next nearest processor page boundary.
+
+@param aNewSize The number of bytes to be committed to this chunk.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 102 if aNewSize is negative.
+*/
+ {
+
+ __ASSERT_ALWAYS(aNewSize>=0,Panic(EChkAdjustNewSizeNegative));
+ return Exec::ChunkAdjust(iHandle,EChunkAdjust,aNewSize,0);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::AdjustDoubleEnded(TInt aBottom, TInt aTop) const
+/**
+Changes the number of bytes and the position of this double ended
+chunk's committed region.
+
+The difference between aTop and aBottom gives the new size of the committed
+region; aBottom gives the offset of the bottom of the committed region from
+the base of the chunk's reserved region.
+
+Both aBottom and aTop are rounded up to the next nearest processor
+page boundary.
+
+The function fails if this chunk is not a double ended chunk; for a standard
+chunk, use the Adjust() function.
+
+Note that if the initial and final committed regions intersect, the contents
+of the intersection are unchanged. Other parts of the committed region have
+undefined contents.
+
+Note also that:
+
+1. the lowest valid address in a double ended chunk is the sum of the base of
+ the chunk's reserved region plus the adjusted value of aBottom
+
+2. the highest valid address in a double ended chunk is the the sum of the base
+ of the chunk's reserved region plus the adjusted value of aTop - 1.
+
+@param aBottom The offset from the base of the chunk of the bottom of the
+ committed region.
+@param aTop The offset from the base of the chunk of the top of the committed
+ region.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 124 if aBottom is negative.
+@panic USER 125 if aTop is negative.
+@panic USER 126 if aBottom is greater than the supplied value of aTop.
+*/
+ {
+ __ASSERT_ALWAYS(aBottom>=0,Panic(EChkAdjustBottomNegative));
+ __ASSERT_ALWAYS(aTop>=0,Panic(EChkAdjustTopNegative));
+ __ASSERT_ALWAYS(aTop>=aBottom,Panic(EChkAdjustTopLessThanBottom));
+ return Exec::ChunkAdjust(iHandle,EChunkAdjustDoubleEnded,aBottom,aTop);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::Commit(TInt aOffset, TInt aSize) const
+/**
+Commits memory to a disconnected chunk.
+
+Memory is committed in blocks of the MMU page size.
+E.g. Commit(pageSize-1,2) which asks for the last byte of the first page
+and the first byte of the second page and will result in the first 2 pages
+in the chunk being committed.
+For this reason it is best to only use values for aOffset and aSize which
+are multiples of the MMU page size. This size can be obtained with the
+following code.
+@code
+TInt pageSize;
+HAL::Get(HAL::EMemoryPageSize,pageSize)
+@endcode
+
+@param aOffset The offset of the committed region from the base of the chunk's
+ reserved region.
+@param aSize The size of the committed region.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 157 if anOffset is negative.
+@panic USER 158 if aSize is negative.
+*/
+ {
+ __ASSERT_ALWAYS(aOffset>=0,Panic(EChkCommitOffsetNegative));
+ __ASSERT_ALWAYS(aSize>=0,Panic(EChkCommitSizeNegative));
+ return Exec::ChunkAdjust(iHandle,EChunkCommit,aOffset,aSize);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::Allocate(TInt aSize) const
+/**
+Allocates and commits to a disconnected chunk.
+
+@param aSize The size of the committed region.
+
+@panic USER 159 if aSize is negative.
+*/
+ {
+ __ASSERT_ALWAYS(aSize>=0,Panic(EChkAllocateSizeNegative));
+ return Exec::ChunkAdjust(iHandle,EChunkAllocate,aSize,0);
+ }
+
+
+
+
+EXPORT_C TInt RChunk::Decommit(TInt aOffset, TInt aSize) const
+/**
+Decommits memory from a disconnected chunk.
+
+Memory is decommitted in blocks of the MMU page size.
+E.g. Decommit(pageSize-1,2) which asks for the last byte of the first page
+and the first byte of the second page and will result in the first 2 pages
+in the chunk being decommitted.
+For this reason it is best to only use values for aOffset and aSize which
+are multiples of the MMU page size. This size can be obtained with the
+following code.
+@code
+TInt pageSize;
+HAL::Get(HAL::EMemoryPageSize,pageSize)
+@endcode
+
+@param aOffset The offset of the committed region from the base of the chunk's
+ reserved region;
+@param aSize The size of the committed region.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 160 if anOffset is negative.
+@panic USER 161 if aSize is negative.
+*/
+ {
+ __ASSERT_ALWAYS(aOffset>=0,Panic(EChkDecommitOffsetNegative));
+ __ASSERT_ALWAYS(aSize>=0,Panic(EChkDecommitSizeNegative));
+ return Exec::ChunkAdjust(iHandle,EChunkDecommit,aOffset,aSize);
+ }
+
+
+/* THIS IS A DELIBERATE NON DOXGEN STYLE TAG TO EXCLUDE THIS DOC FROM AUTO GENERATED DOCS
+
+Unlocks previously committed memory in a disconnected chunk.
+
+Unlocked memory is an intermediate state between committed and decommitted.
+Whilst in this state, the memory must not be accessed in any way, and the
+system is free to reclaim this RAM for other purposes, (it counts as free
+system memory). A program may attempt to relock the memory with #Lock which,
+when it succeeds, returns it to the committed state with its contents unchanged.
+
+This is intended for use in the implementation of memory caches for data
+which can be regenerated from other sources. I.e. in situations when the
+loss of cache contents is not a fatal condition.
+
+#Unlock may be used on memory which is already unlocked, in which case the memory
+state is left unaltered. Attempting to unlock memory which is decommitted results
+in an error.
+
+Unlocked memory may decommitted with #Decommit.
+
+Memory is unlocked in blocks of the MMU page size.
+E.g. Unlock(pageSize-1,2) which asks for the last byte of the first page
+and the first byte of the second page and will result in the first 2 pages
+in the chunk being unlocked.
+For this reason it is best to only use values for aOffset and aSize which
+are multiples of the MMU page size. This size can be obtained with the
+following code.
+@code
+TInt pageSize;
+HAL::Get(HAL::EMemoryPageSize,pageSize)
+@endcode
+
+@param aOffset The offset of the committed region from the base of the chunk's
+ reserved region;
+@param aSize The size of the committed region.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 160 if anOffset is negative.
+@panic USER 161 if aSize is negative.
+
+@see RChunk::Lock
+
+@internalTechnology
+*/
+EXPORT_C TInt RChunk::Unlock(TInt aOffset, TInt aSize)
+ {
+ __ASSERT_ALWAYS(aOffset>=0,Panic(EChkDecommitOffsetNegative));
+ __ASSERT_ALWAYS(aSize>=0,Panic(EChkDecommitSizeNegative));
+ return Exec::ChunkAdjust(iHandle,EChunkUnlock,aOffset,aSize);
+ }
+
+/* THIS IS A DELIBERATE NON DOXGEN STYLE TAG TO EXCLUDE THIS DOC FROM AUTO GENERATED DOCS
+
+Locks memory in a disconnected chunk.
+
+This attempts to reverse the action of #Unlock and return memory to the committed
+state. If any RAM in the region had been previously reclaimed by the system,
+then this function fails with KErrNotFound and the whole region is decommited.
+
+#Lock may be used on memory which is already committed, in which case the memory
+state is left unaltered. Attempting to lock memory which is decommitted results in an
+error.
+
+Memory is locked in blocks of the MMU page size.
+E.g. Lock(pageSize-1,2) which asks for the last byte of the first page
+and the first byte of the second page and will result in the first 2 pages
+in the chunk being locked.
+For this reason it is best to only use values for aOffset and aSize which
+are multiples of the MMU page size. This size can be obtained with the
+following code.
+@code
+TInt pageSize;
+HAL::Get(HAL::EMemoryPageSize,pageSize)
+@endcode
+
+@param aOffset The offset of the unlocked region from the base of the chunk's
+ reserved region.
+@param aSize The size of the unlocked region.
+
+@return KErrNone if successful, otherwise another of the system error codes.
+
+@panic USER 160 if anOffset is negative.
+@panic USER 161 if aSize is negative.
+
+@see RChunk::Unlock
+
+@internalTechnology
+*/
+EXPORT_C TInt RChunk::Lock(TInt aOffset, TInt aSize)
+ {
+ __ASSERT_ALWAYS(aOffset>=0,Panic(EChkDecommitOffsetNegative));
+ __ASSERT_ALWAYS(aSize>=0,Panic(EChkDecommitSizeNegative));
+ return Exec::ChunkAdjust(iHandle,EChunkLock,aOffset,aSize);
+ }
+
+
+/**
+This can be used to determine whether the data for the chunk is demand paged
+or not.
+
+@return ETrue if the data for the chunk is demand paged, EFalse otherwise.
+*/
+EXPORT_C TBool RChunk::IsPaged() const
+ {
+ return Exec::ChunkIsPaged(iHandle);
+ }
+
+
+/**
+Opens a handle to an LDD factory object by name.
+
+@param aName The name of the LDD factory object to be opened.
+@param aType An enumeration whose enumerators define the ownership of this
+ LDD factory object handle.
+
+@return KErrNone, if successful; otherwise one of the other system wide error codes.
+*/
+EXPORT_C TInt RDevice::Open(const TDesC &aName,TOwnerType aType)
+ {
+ return OpenByName(aName,aType,ELogicalDevice);
+ }
+
+EXPORT_C TInt RBusLogicalChannel::DoCreate(const TDesC& aLogicalDevice, const TVersion& aVer, TInt aUnit, const TDesC* aPhysicalDevice, const TDesC8* anInfo, TInt aType)
+//
+// Call the kernel to create a channel on a device.
+//
+ {
+ TInt r = User::ValidateName(aLogicalDevice);
+ if(KErrNone!=r)
+ return r;
+ TBuf8<KMaxKernelName> name8;
+ name8.Copy(aLogicalDevice);
+
+ TBuf8<KMaxKernelName> physicalDeviceName;
+ TChannelCreateInfo8 info;
+ info.iVersion=aVer;
+ info.iUnit=aUnit;
+ if(aPhysicalDevice)
+ {
+ physicalDeviceName.Copy(*aPhysicalDevice);
+ info.iPhysicalDevice = &physicalDeviceName;
+ }
+ else
+ info.iPhysicalDevice = NULL;
+ info.iInfo=anInfo;
+
+ return SetReturnedHandle(Exec::ChannelCreate(name8, info, aType),*this);
+ }
+
+
+
+
+/**
+Opens a handle to a logical channel using a handle number sent by a client
+to a server.
+
+This function is called by the server.
+
+@param aMessage The message pointer.
+@param aParam An index specifying which of the four message arguments
+ contains the handle number.
+@param aType An enumeration whose enumerators define the ownership of this
+ logical channel handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone, if successful;
+ KErrArgument, if the value of aParam is outside the range 0-3;
+ KErrBadHandle, if not a valid handle;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RBusLogicalChannel::Open(RMessagePtr2 aMessage,TInt aParam,TOwnerType aType)
+ {
+ return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),ELogicalChannel,aParam,aType));
+ }
+
+
+
+
+/**
+Opens a logical channel handle using a handle number passed as an
+environment data item to the child process during the creation of
+that child process.
+
+Note that this function can only be called successfully once.
+
+@param aArgumentIndex An index that identifies the slot in the process
+ environment data that contains the handle number. This is
+ a value relative to zero, i.e. 0 is the first item/slot.
+ This can range from 0 to 15.
+
+@param aOwnerType An enumeration whose enumerators define the ownership of
+ this logical channel handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone, if successful;
+ KErrNotFound, if the slot indicated by aArgumentIndex is empty;
+ KErrArgument, if the slot does not contain a logical channel handle;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RBusLogicalChannel::Open(TInt aArgumentIndex, TOwnerType aOwnerType)
+ {
+ return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, ELogicalChannel, aOwnerType));
+ }
+
+
+
+
+EXPORT_C TInt RHandleBase::Duplicate(const RThread &aSrc,TOwnerType aType)
+/**
+Creates a valid handle to the kernel object for which the specified thread
+already has a handle.
+
+The function assumes that this handle has been copy constructed from an existing
+handle (or the handle-number has been explicitly copied through calls to Handle()
+and SetHandle()).
+
+By default, any thread in the process can use this handle to access the kernel
+side object that the handle represents. However, specifying EOwnerThread as
+the second parameter to this function, means that only the creating thread
+can use this handle to access the kernel side object; any other thread in
+this process that wants to access the kernel side object must, again, duplicate
+this handle.
+
+@param aSrc A reference to the thread containing the handle which is to be
+ duplicated for this thread.
+@param aType An enumeration whose enumerators define the ownership of this
+ handle. If not explicitly specified, EOwnerProcess is taken
+ as default.
+
+@return KErrNone, if successful; otherwise, one of the other system wide error
+ codes.
+*/
+ {
+ return Exec::HandleDuplicate(aSrc.Handle(), aType, iHandle);
+ }
+
+
+
+
+EXPORT_C TInt RHandleBase::Open(const TFindHandleBase& aFindHandle, TOwnerType aType)
+/**
+Opens a handle to a kernel side object found using a find-handle object.
+
+@param aFindHandle A find-handle object; an object that is used in searching
+ for kernel side objects.
+@param aType An enumeration whose enumerators define the ownership of
+ this handle. If not explicitly specified, EOwnerProcess
+ is taken as default, and ownership is vested in the
+ current process. Ownership can be vested in the current
+ thread by passing the EOwnerThread enumerator.
+@return KErrNone, if successful; otherwise one of the other system wide
+ error codes.
+*/
+ {
+ return SetReturnedHandle(Exec::FindHandleOpen(aType, aFindHandle), *this);
+ }
+
+
+
+/**
+ Implementation for RXxxxx::Open/OpenGlocbal(const TDesC &aName,,TOwnerType aType) functions
+ @internalComponent
+*/
+TInt RHandleBase::OpenByName(const TDesC &aName,TOwnerType aOwnerType,TInt aObjectType)
+ {
+ TBuf8<KMaxFullName> name8;
+ name8.Copy(aName);
+ return SetReturnedHandle(Exec::OpenObject((TObjectType)aObjectType,name8,aOwnerType));
+ }
+
+TInt RHandleBase::SetReturnedHandle(TInt aHandleOrError,RHandleBase& aHandle)
+//
+// Set the handle value or return error
+//
+ {
+ return aHandle.SetReturnedHandle(aHandleOrError);
+ }
+
+
+
+
+EXPORT_C void RHandleBase::Close()
+/**
+Closes the handle.
+
+This has the effect of closing the associated kernel side object.
+
+As the associated object is a reference counting object, it is destroyed if
+there are no other open references to it.
+
+@see CObject
+*/
+ {
+
+ __IF_DEBUG(Print(_L("RHandleBase::Close")));
+ TInt h=iHandle;
+ if (h!=KNullHandle)
+ {
+//
+// We take a copy of the handle and set it to zero before the close in case this
+// object is actually a Chunk created in its own heap in which case the close
+// will destroy the object as well.
+//
+ iHandle=0;
+ if ((h&CObjectIx::ENoClose)==0 && Exec::HandleClose(h)>0)
+ DoExtendedClose();
+ }
+ }
+
+
+
+
+void RHandleBase::DoExtendedClose()
+//
+// Call static data destructors following a library handle close
+//
+ {
+ TRAPD(r,DoExtendedCloseL()); // catch attempts to leave from destructors
+ __ASSERT_ALWAYS(r==KErrNone, Panic(EDllStaticDestructorLeave));
+ }
+
+void RHandleBase::DoExtendedCloseL()
+//
+// Call static data destructors following a library handle close
+//
+ {
+ TLinAddr ep[KMaxLibraryEntryPoints];
+ TInt r=KErrNone;
+ while (r!=KErrEof)
+ {
+ TInt numEps=KMaxLibraryEntryPoints;
+ r=E32Loader::LibraryDetach(numEps, ep);
+ if (r==KErrEof)
+ break;
+ TInt i;
+ for (i=numEps-1; i>=0; --i)
+ {
+ TLibraryEntry f=(TLibraryEntry)ep[i];
+ (*f)(KModuleEntryReasonProcessDetach);
+ }
+ r=E32Loader::LibraryDetached();
+ }
+ }
+
+
+
+
+/**
+Constructs an RMessage2 from an RMessagePtr2.
+
+@param aPtr A reference to an existing RMessagePtr2 object.
+*/
+EXPORT_C RMessage2::RMessage2(const RMessagePtr2& aPtr)
+ {
+ iHandle = aPtr.Handle();
+ Exec::MessageConstructFromPtr(iHandle, this);
+ iFlags = 0;
+ iSpare3 = 0;
+ }
+
+/** Sets this message to an authorised state. This is used only by
+CPolicyServer. This flags use by the policy server implies two things:
+1) That the message has passed any appropriate security checks. (ie. one of the
+static policy check, CustomSecurityCheckL, or CustomFailureActionL,
+returned ETrue.)
+2) That any leaves that occur subsequent to this flag being set happen _only_
+in the session's ServiceL. ie. Nothing can leave between this flag being set
+and the session's ServiceL being called.
+
+This is labelled as a const functions as everybody handles const RMessage2&'s.
+The constness is actually referring to the underlying RMessagePtr2 not the
+tranisent RMessage2 class.
+
+@internalComponent
+*/
+void RMessage2::SetAuthorised() const
+ {
+ iFlags = ETrue;
+ }
+
+/** Sets the authorised flag to a state of not authorised. This is required as
+there is a default constructor for RMessage2 and one cannot guarantee that
+iFlags was initialised. This is called from CPolicyServer::RunL.
+
+This is labelled as a const functions as everybody handles const RMessage2&'s.
+The constness is actually referring to the underlying RMessagePtr2 not the
+tranisent RMessage2 class.
+
+@internalComponent
+*/
+void RMessage2::ClearAuthorised() const
+ {
+ iFlags = EFalse;
+ }
+
+/** Returns whether this message has been authorised by CPolicyServer. See
+RMessage2::SetAuthorised for implications of this state.
+@internalComponent
+*/
+TBool RMessage2::Authorised() const
+ {
+ return iFlags;
+ }
+
+
+
+
+/**
+Frees this message.
+
+@param aReason The completion code.
+*/
+EXPORT_C void RMessagePtr2::Complete(TInt aReason) const
+//
+// Free this message. If it's a disconnect, need to switch to kernel context as we'll be
+// freeing the DSession
+//
+ {
+ TInt h=iHandle;
+ const_cast<TInt&>(iHandle)=0;
+ if (h)
+ Exec::MessageComplete(h,aReason);
+ else
+ ::Panic(ETMesCompletion);
+ }
+
+
+
+
+/**
+Duplicates the specified handle in the client thread, and returns this
+handle as a message completion code
+
+@param aHandle The handle to be duplicated.
+*/
+EXPORT_C void RMessagePtr2::Complete(RHandleBase aHandle) const
+ {
+ TInt h=iHandle;
+ const_cast<TInt&>(iHandle)=0;
+ if (h)
+ Exec::MessageCompleteWithHandle(h,aHandle.Handle());
+ else
+ ::Panic(ETMesCompletion);
+ }
+
+
+
+
+/**
+Gets the length of a descriptor argument in the client's process.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+
+@return The length of the descriptor, if successful.
+ KErrArgument, if aParam has a value outside the valid range.
+ KErrBadDescriptor, if the message argument is not a descriptor type.
+*/
+EXPORT_C TInt RMessagePtr2::GetDesLength(TInt aParam) const
+ {
+ return Exec::MessageGetDesLength(iHandle,aParam);
+ }
+
+
+
+
+/**
+Gets the length of a descriptor argument in the client's process,
+leaving on failure.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+
+@return The length of the descriptor.
+
+@leave KErrArgument if aParam has a value outside the valid range.
+@leave KErrBadDescriptor, if the message argument is not a descriptor type.
+*/
+EXPORT_C TInt RMessagePtr2::GetDesLengthL(TInt aParam) const
+ {
+ return User::LeaveIfError(GetDesLength(aParam));
+ }
+
+
+
+
+/**
+Gets the maximum length of a descriptor argument in the client's process.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+
+@return The maximum length of the descriptor, if successful.
+ KErrArgument, if aParam has a value outside the valid range.
+ KErrBadDescriptor, if the message argument is not a descriptor type.
+*/
+EXPORT_C TInt RMessagePtr2::GetDesMaxLength(TInt aParam) const
+ {
+ return Exec::MessageGetDesMaxLength(iHandle,aParam);
+ }
+
+
+
+
+/**
+Gets the maximum length of a descriptor argument in the client's process,
+leaving on failure.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+
+@return The length of the descriptor.
+
+@leave KErrArgument if aParam has a value outside the valid range.
+@leave KErrBadDescriptor, if the message argument is not a descriptor type.
+*/
+EXPORT_C TInt RMessagePtr2::GetDesMaxLengthL(TInt aParam) const
+ {
+ return User::LeaveIfError(GetDesMaxLength(aParam));
+ }
+
+
+
+
+/**
+Reads data from the specified offset within the 8-bit descriptor
+argument, into the specified target descriptor, and leaving on failure.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+@param aDes The target descriptor into which the client data is
+ to be written.
+@param aOffset The offset from the start of the client's descriptor data.
+ If not explicitly specified, the offset defaults to zero.
+
+@leave KErrArgument if aParam has a value outside the valid range, or
+ if aOffset is negative.
+@leave KErrBadDescriptor, if the message argument is not an 8-bit descriptor.
+*/
+EXPORT_C void RMessagePtr2::ReadL(TInt aParam,TDes8& aDes,TInt aOffset) const
+ {
+ TInt error = Read(aParam,aDes,aOffset);
+ User::LeaveIfError(error);
+ }
+
+
+
+
+/**
+Reads data from the specified offset within the 16-bit descriptor
+argument, into the specified target descriptor, and leaving on failure.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+@param aDes The target descriptor into which the client data is
+ to be written.
+@param aOffset The offset from the start of the client's descriptor data.
+ If not explicitly specified, the offset defaults to zero.
+
+@leave KErrArgument if aParam has a value outside the valid range, or
+ if aOffset is negative.
+@leave KErrBadDescriptor, if the message argument is not a 16-bit descriptor.
+*/
+EXPORT_C void RMessagePtr2::ReadL(TInt aParam,TDes16 &aDes,TInt aOffset) const
+ {
+ TInt error = Read(aParam,aDes,aOffset);
+ User::LeaveIfError(error);
+ }
+
+
+
+
+/**
+Writes data from the specified source descriptor to the specified offset within
+the 8-bit descriptor argument, and leaving on failure.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+@param aDes The source descriptor containing the data to be written.
+@param aOffset The offset from the start of the client's descriptor.
+ If not explicitly specified, the offset defaults to zero.
+
+@leave KErrArgument if aParam has a value outside the valid range, or
+ if aOffset is negative.
+@leave KErrBadDescriptor, if the message argument is not an 8-bit descriptor.
+*/
+EXPORT_C void RMessagePtr2::WriteL(TInt aParam,const TDesC8& aDes,TInt aOffset) const
+ {
+ TInt error = Write(aParam,aDes,aOffset);
+ User::LeaveIfError(error);
+ }
+
+
+
+
+/**
+Writes data from the specified source descriptor to the specified offset within
+the 16-bit descriptor argument, and leaving on failure.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+@param aDes The source descriptor containing the data to be written.
+@param aOffset The offset from the start of the client's descriptor.
+ If not explicitly specified, the offset defaults to zero.
+
+@leave KErrArgument if aParam has a value outside the valid range, or
+ if aOffset is negative.
+@leave KErrBadDescriptor, if the message argument is not a 16-bit descriptor.
+*/
+EXPORT_C void RMessagePtr2::WriteL(TInt aParam,const TDesC16& aDes,TInt aOffset) const
+ {
+ TInt error = Write(aParam,aDes,aOffset);
+ User::LeaveIfError(error);
+ }
+
+
+
+
+/**
+Reads data from the specified offset within the 8-bit descriptor
+argument, into the specified target descriptor.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+@param aDes The target descriptor into which the client data is
+ to be written.
+@param aOffset The offset from the start of the client's descriptor data.
+ If not explicitly specified, the offset defaults to zero.
+
+@return KErrNone, if successful;
+ KErrArgument if aParam has a value outside the valid range, or
+ if aOffset is negative.
+ KErrBadDescriptor, if the message argument is not an 8-bit descriptor.
+*/
+EXPORT_C TInt RMessagePtr2::Read(TInt aParam,TDes8& aDes,TInt aOffset) const
+ {
+ SIpcCopyInfo info;
+ info.iFlags=KChunkShiftBy0|KIpcDirRead;
+ info.iLocalLen=aDes.MaxLength();
+ info.iLocalPtr=(TUint8*)aDes.Ptr();
+ TInt r=Exec::MessageIpcCopy(iHandle,aParam,info,aOffset);
+ if (r<0)
+ return r;
+ aDes.SetLength(r);
+ return KErrNone;
+ }
+
+
+
+
+/**
+Reads data from the specified offset within the 16-bit descriptor
+argument, into the specified target descriptor.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+@param aDes The target descriptor into which the client data is
+ to be written.
+@param aOffset The offset from the start of the client's descriptor data.
+ If not explicitly specified, the offset defaults to zero.
+
+@return KErrNone, if successful;
+ KErrArgument if aParam has a value outside the valid range, or
+ if aOffset is negative.
+ KErrBadDescriptor, if the message argument is not a 16-bit descriptor.
+*/
+EXPORT_C TInt RMessagePtr2::Read(TInt aParam,TDes16 &aDes,TInt aOffset) const
+ {
+ SIpcCopyInfo info;
+ info.iFlags=KChunkShiftBy1|KIpcDirRead;
+ info.iLocalLen=aDes.MaxLength();
+ info.iLocalPtr=(TUint8*)aDes.Ptr();
+ TInt r=Exec::MessageIpcCopy(iHandle,aParam,info,aOffset);
+ if (r<0)
+ return r;
+ aDes.SetLength(r);
+ return KErrNone;
+ }
+
+
+
+
+/**
+Writes data from the specified source descriptor to the specified offset within
+the 8-bit descriptor argument.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+@param aDes The source descriptor containing the data to be written.
+@param aOffset The offset from the start of the client's descriptor.
+ If not explicitly specified, the offset defaults to zero.
+
+@return KErrNone, if successful;
+ KErrArgument if aParam has a value outside the valid range, or
+ if aOffset is negative.
+ KErrBadDescriptor, if the message argument is not an 8-bit descriptor;
+ KErrOverflow, if the target descriptor is too small
+ to containt the data.
+*/
+EXPORT_C TInt RMessagePtr2::Write(TInt aParam,const TDesC8& aDes,TInt aOffset) const
+ {
+ SIpcCopyInfo info;
+ info.iFlags=KChunkShiftBy0|KIpcDirWrite;
+ info.iLocalLen=aDes.Length();
+ info.iLocalPtr=(TUint8*)aDes.Ptr();
+ return Exec::MessageIpcCopy(iHandle,aParam,info,aOffset);
+ }
+
+
+
+
+/**
+Writes data from the specified source descriptor to the specified offset within
+the 16-bit descriptor argument.
+
+@param aParam The index value identifying the argument.
+ This is a value in the range 0 to (KMaxMessageArguments-1)
+ inclusive.
+@param aDes The source descriptor containing the data to be written.
+@param aOffset The offset from the start of the client's descriptor.
+ If not explicitly specified, the offset defaults to zero.
+
+@return KErrNone, if successful;
+ KErrArgument if aParam has a value outside the valid range, or
+ if aOffset is negative.
+ KErrBadDescriptor, if the message argument is not an 16-bit descriptor;
+ KErrOverflow, if the target descriptor is too small
+ to containt the data.
+*/
+EXPORT_C TInt RMessagePtr2::Write(TInt aParam,const TDesC16& aDes,TInt aOffset) const
+ {
+ SIpcCopyInfo info;
+ info.iFlags=KChunkShiftBy1|KIpcDirWrite;
+ info.iLocalLen=aDes.Length();
+ info.iLocalPtr=(TUint8*)aDes.Ptr();
+ return Exec::MessageIpcCopy(iHandle,aParam,info,aOffset);
+ }
+
+
+
+
+/**
+Panics the client.
+
+The length of the category name should be no greater than 16; any name with
+a length greater than 16 is truncated to 16.
+
+Note that this method also completes the message. A subsequent call to Complete(TInt aReason) would cause a server panic.
+
+@param aCategory The panic category.
+@param aReason The panic code.
+*/
+EXPORT_C void RMessagePtr2::Panic(const TDesC& aCategory,TInt aReason) const
+ {
+ TBuf8<KMaxExitCategoryName> cat;
+ TInt length=aCategory.Length();
+ if(length>KMaxExitCategoryName)
+ {
+ TPtr catPtr((TUint16*)aCategory.Ptr(),KMaxExitCategoryName,KMaxExitCategoryName);
+ cat.Copy(catPtr);
+ }
+ else
+ {
+ cat.Copy(aCategory);
+ }
+ Exec::MessageKill(iHandle,EExitPanic,aReason,&cat);
+ Complete(KErrNone);
+ }
+
+
+
+
+/**
+Kills the client.
+
+Note that this method also completes the message. A subsequent call to Complete(TInt aReason) would cause a server panic.
+
+@param aReason The reason code associated with killing the client.
+*/
+EXPORT_C void RMessagePtr2::Kill(TInt aReason) const
+ {
+ Exec::MessageKill(iHandle,EExitKill,aReason,NULL);
+ Complete(KErrNone);
+ }
+
+
+
+
+/**
+Terminates the client.
+
+Note that this method also completes the message. A subsequent call to Complete(TInt aReason) would cause a server panic.
+
+@param aReason The reason code associated with terminating the client.
+*/
+EXPORT_C void RMessagePtr2::Terminate(TInt aReason) const
+ {
+ Exec::MessageKill(iHandle,EExitTerminate,aReason,NULL);
+ Complete(KErrNone);
+ }
+
+
+
+
+/**
+Sets the priority of the client's process.
+
+@param aPriority The priority value.
+
+@return KErrNone, if successful, otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RMessagePtr2::SetProcessPriority(TProcessPriority aPriority) const
+ {
+ return Exec::MessageSetProcessPriority(iHandle,aPriority);
+ }
+
+
+
+/**
+Opens a handle on the client thread.
+
+@param aClient On successful return, the handle to the client thread.
+@param aOwnerType An enumeration whose enumerators define the ownership of
+ the handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone.
+*/
+EXPORT_C TInt RMessagePtr2::Client(RThread& aClient, TOwnerType aOwnerType) const
+ {
+ return aClient.SetReturnedHandle(Exec::MessageClient(iHandle,aOwnerType));
+ }
+
+EXPORT_C TUint RMessagePtr2::ClientProcessFlags() const
+ {
+ return Exec::MessageClientProcessFlags(iHandle);
+ }
+
+EXPORT_C TBool RMessagePtr2::ClientIsRealtime() const
+ {
+ return (Exec::MessageClientProcessFlags(iHandle) & KThreadFlagRealtime) != 0;
+ }
+
+
+
+/**
+Returns the pointer to the clients TRequestStatus associated with the message.
+
+The return value is intended to be used as a unique identifier (for example,
+to uniquely identify an asynchronous message when cancelling the request).
+The memory must never be accessed directly or completed.
+
+@return The clients TRequestStatus (returns NULL if the request is not asynchronous)
+*/
+EXPORT_C const TRequestStatus* RMessagePtr2::ClientStatus() const
+ {
+ return Exec::MessageClientStatus(iHandle);
+ }
+
+
+
+EXPORT_C TInt RServer2::CreateGlobal(const TDesC& aName, TInt aMode, TInt aRole, TInt aOpts)
+//
+// Create a new server.
+//
+ {
+ TInt r = User::ValidateName(aName);
+ if (r != KErrNone)
+ return r;
+ TBuf8<KMaxKernelName> name8;
+ name8.Copy(aName);
+ r = Exec::ServerCreateWithOptions(&name8, aMode, aRole, aOpts);
+ return SetReturnedHandle(r, *this);
+ }
+
+EXPORT_C TInt RServer2::CreateGlobal(const TDesC& aName, TInt aMode)
+ {
+ return CreateGlobal(aName, aMode, EServerRole_Default, 0);
+ }
+
+EXPORT_C TInt RServer2::CreateGlobal(const TDesC& aName)
+ {
+ return CreateGlobal(aName, EIpcSession_Sharable);
+ }
+
+TInt RSessionBase::DoConnect(const TVersion &aVersion,TRequestStatus* aStatus)
+ {
+ extern int TVersion_size_assert[sizeof(TVersion)==sizeof(TInt)?1:-1]; // Make sure TVersion is same size as int
+ (void)TVersion_size_assert;
+
+ TIpcArgs p(*(TInt*)&aVersion);
+ TInt r;
+ if(aStatus==NULL)
+ r = SendSync(RMessage2::EConnect, &p);
+ else
+ r = SendAsync(RMessage2::EConnect, &p, aStatus);
+ if (r!=KErrNone)
+ Close();
+ return r;
+ }
+
+
+
+
+/**
+Creates a session with a server.
+
+It should be called as part of session initialisation in the derived class.
+
+@param aServer The name of the server with which a session is to
+ be established.
+@param aVersion The lowest version of the server with which this client
+ is compatible.
+@param aAsyncMessageSlots The number of message slots available to this session.
+ This determines the number of outstanding requests the client
+ may have with the server at any one time.
+ The maximum number of slots is 255.
+ If aAsyncMessageSlots==-1 then this indicates that the session should use
+ messages from the global free pool of messages.
+@param aType The type of session to create. See TIpcSessionType.
+@param aPolicy A pointer to a TSecurityPolicy object. If this pointer is not 0 (zero)
+ then the policy is applied to the process in which the server is running.
+ If that process doesn't pass this security policy check, then the session
+ creation will fail with the error KErrPermissionDenied.
+ This security check allows clients to verify that the server has the expected
+ Platform Security attributes.
+
+ When a check fails the action taken is determined by the system wide Platform Security
+ configuration. If PlatSecDiagnostics is ON, then a diagnostic message is emitted.
+ If PlatSecEnforcement is OFF, then this function will return KErrNone even though the
+ check failed.
+
+@param aStatus A pointer to TRequestStatus object which will be signalled when the session
+ has been created, or in the event of an error.
+ If aStatus==0 then session creation is done synchronously.
+
+@return KErrNone if successful;
+ KErrArgument, if an attempt is made to specify more
+ than 255 message slots;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RSessionBase::CreateSession(const TDesC& aServer,const TVersion& aVersion,TInt aAsyncMessageSlots,TIpcSessionType aType,const TSecurityPolicy* aPolicy, TRequestStatus* aStatus)
+ {
+ TInt r = User::ValidateName(aServer);
+ if(KErrNone!=r)
+ return r;
+ TBuf8<KMaxKernelName> name8;
+ name8.Copy(aServer);
+ r=SetReturnedHandle(Exec::SessionCreate(name8,aAsyncMessageSlots,aPolicy,aType));
+ if(r==KErrNone)
+ r=DoConnect(aVersion,aStatus);
+ return r;
+ }
+
+
+
+
+/**
+Creates a session with a server.
+
+It should be called as part of session initialisation in the derived class.
+
+@param aServer The name of the server with which a session is to
+ be established.
+@param aVersion The lowest version of the server with which this client
+ is compatible.
+@param aAsyncMessageSlots The number of message slots available to this session.
+ This determines the number of outstanding requests the client
+ may have with the server at any one time.
+ The maximum number of slots is 255.
+ If aAsyncMessageSlots==-1 then this indicates that the session should use
+ messages from the global free pool of messages.
+
+@return KErrNone if successful;
+ KErrArgument, if an attempt is made to specify more
+ than 255 message slots;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RSessionBase::CreateSession(const TDesC &aServer, const TVersion &aVersion, TInt aAsyncMessageSlots)
+ {
+ return RSessionBase::CreateSession(aServer,aVersion,aAsyncMessageSlots,EIpcSession_Unsharable,NULL,0);
+ }
+
+
+
+
+/**
+Creates a session with a server.
+
+It should be called as part of session initialisation in the derived class.
+
+@param aServer A handle to a server with which a session is to be established.
+@param aVersion The lowest version of the server with which this client
+ is compatible.
+@param aAsyncMessageSlots The number of message slots available to this session.
+ This determines the number of outstanding requests the client
+ may have with the server at any one time.
+ The maximum number of slots is 255.
+ If aAsyncMessageSlots==-1 then this indicates that the session should use
+ messages from the global free pool of messages.
+@param aType The type of session to create. See TIpcSessionType.
+@param aPolicy A pointer to a TSecurityPolicy object. If this pointer is not 0 (zero)
+ then the policy is applied to the process in which the server is running.
+ If that process doesn't pass this security policy check, then the session
+ creation will fail with the error KErrPermissionDenied.
+ This security check allows clients to verify that the server has the expected
+ Platform Security attributes.
+
+ When a check fails the action taken is determined by the system wide Platform Security
+ configuration. If PlatSecDiagnostics is ON, then a diagnostic message is emitted.
+ If PlatSecEnforcement is OFF, then this function will return KErrNone even though the
+ check failed.
+
+@param aStatus A pointer to TRequestStatus object which will be signalled when the session
+ has been created, or in the event of an error.
+ If aStatus==0 then session creation is done synchronously.
+
+@return KErrNone if successful;
+ KErrArgument, if an attempt is made to specify more
+ than 255 message slots;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RSessionBase::CreateSession(RServer2 aServer,const TVersion& aVersion,TInt aAsyncMessageSlots,TIpcSessionType aType,const TSecurityPolicy* aPolicy, TRequestStatus* aStatus)
+ {
+ TInt r;
+ r=SetReturnedHandle(Exec::SessionCreateFromHandle(aServer.Handle(),aAsyncMessageSlots,aPolicy,aType));
+ if(r==KErrNone)
+ r=DoConnect(aVersion,aStatus);
+ return r;
+ }
+
+
+
+
+/**
+Creates a session with a server.
+
+It should be called as part of session initialisation in the derived class.
+
+@param aServer A handle to a server with which a session is to be established.
+@param aVersion The lowest version of the server with which this client
+ is compatible.
+@param aAsyncMessageSlots The number of message slots available to this session.
+ This determines the number of outstanding requests the client
+ may have with the server at any one time.
+ The maximum number of slots is 255.
+ If aAsyncMessageSlots==-1 then this indicates that the session should use
+ messages from the global free pool of messages.
+
+@return KErrNone if successful;
+ KErrArgument, if an attempt is made to specify more
+ than 255 message slots;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RSessionBase::CreateSession(RServer2 aServer, const TVersion &aVersion, TInt aAsyncMessageSlots)
+ {
+ return RSessionBase::CreateSession(aServer,aVersion,aAsyncMessageSlots,EIpcSession_Unsharable,NULL,0);
+ }
+
+
+
+
+/**
+Opens a handle to a session using a handle number sent by a client
+to a server.
+
+This function is called by the server.
+
+@param aMessage The message pointer.
+@param aParam An index specifying which of the four message arguments
+ contains the handle number.
+@param aType An enumeration whose enumerators define the ownership of this
+ session handle. If not explicitly specified, EOwnerProcess
+ is taken as default.
+
+@return KErrNone, if successful;
+ KErrArgument, if the value of aParam is outside the range 0-3;
+ KErrBadHandle, if not a valid handle;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RSessionBase::Open(RMessagePtr2 aMessage,TInt aParam,TOwnerType aType)
+ {
+ return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),ESession,aParam,aType));
+ }
+
+
+
+
+/**
+Opens a handle to a session using a handle number sent by a client
+to a server, and validate that the session's server passes a given
+security policy.
+
+This function is called by the server.
+
+@param aMessage The message pointer.
+@param aParam An index specifying which of the four message arguments
+ contains the handle number.
+@param aServerPolicy The policy to validate the session's server against.
+@param aType An enumeration whose enumerators define the ownership of this
+ session handle. If not explicitly specified, EOwnerProcess
+ is taken as default.
+
+@return KErrNone, if successful;
+ KErrArgument, if the value of aParam is outside the range 0-3;
+ KErrBadHandle, if not a valid handle;
+ KErrServerTerminating, if the session is no longer connected to a server;
+ KErrPermissionDenied, if the session's server does not pass the given security policy;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RSessionBase::Open(RMessagePtr2 aMessage,TInt aParam,const TSecurityPolicy& aServerPolicy,TOwnerType aType)
+ {
+ return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),ESession,aParam,aType),aServerPolicy);
+ }
+
+
+
+/**
+Sets the handle-number of this session handle to the specified value after
+validating that the session's server passes a given security policy.
+
+The function can take a (zero or positive) handle-number,
+or a (negative) error number.
+
+If aHandleOrError represents a handle-number, then the handle-number of this handle
+is set to that value, as long as the session's server passes the security policy.
+If aHandleOrError represents an error number, then the handle-number of this handle is set to zero
+and the negative value is returned.
+
+@param aHandleOrError A handle-number, if zero or positive; an error value, if negative.
+@param aServerPolicy The policy to validate the session's server against.
+
+@return KErrNone, if aHandle is a handle-number; KErrPermissionDenied, if the session's server
+ does not pass the security policy; the value of aHandleOrError, otherwise.
+*/
+EXPORT_C TInt RSessionBase::SetReturnedHandle(TInt aHandleOrError,const TSecurityPolicy& aServerPolicy)
+ {
+ if(aHandleOrError<0)
+ return aHandleOrError;
+
+ TInt r = aServerPolicy.CheckPolicy((RSessionBase&)aHandleOrError);
+ if (r!=KErrNone)
+ {
+ ((RHandleBase&)aHandleOrError).Close();
+ return r;
+ }
+
+ iHandle=aHandleOrError;
+ return KErrNone;
+ }
+
+
+
+
+/**
+Opens a handle to a session using a handle number passed as an
+environment data item to the child process during the creation of
+that child process.
+
+Note that this function can only be called successfully once.
+
+@param aArgumentIndex An index that identifies the slot in the process
+ environment data that contains the handle number. This is
+ a value relative to zero, i.e. 0 is the first item/slot.
+ This can range from 0 to 15.
+
+@param aOwnerType An enumeration whose enumerators define the ownership of
+ this session handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone, if successful;
+ KErrNotFound, if the slot indicated by aArgumentIndex is empty;
+ KErrArgument, if the slot does not contain a session handle;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RSessionBase::Open(TInt aArgumentIndex, TOwnerType aOwnerType)
+ {
+ return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, ESession, aOwnerType));
+ }
+
+
+/**
+Opens a handle to a session using a handle number passed as an
+environment data item to the child process during the creation of
+that child process, after validating that the session's server passes
+the given security policy.
+
+Note that this function can only be called successfully once.
+
+@param aArgumentIndex An index that identifies the slot in the process
+ environment data that contains the handle number. This is
+ a value relative to zero, i.e. 0 is the first item/slot.
+ This can range from 0 to 15.
+@param aServerPolicy The policy to validate the session's server against.
+@param aOwnerType An enumeration whose enumerators define the ownership of
+ this session handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone, if successful;
+ KErrNotFound, if the slot indicated by aArgumentIndex is empty;
+ KErrArgument, if the slot does not contain a session handle;
+ KErrServerTerminating, if the session is no longer connected to a server;
+ KErrPermissionDenied, if the session's server does not pass the given security policy;
+ otherwise one of the other system-wide error codes.
+*/
+EXPORT_C TInt RSessionBase::Open(TInt aArgumentIndex, const TSecurityPolicy& aServerPolicy, TOwnerType aOwnerType)
+ {
+ return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, ESession, aOwnerType), aServerPolicy);
+ }
+
+
+EXPORT_C TInt RSessionBase::DoShare(TInt aMode)
+//
+// Make the session accessible to all threads in this process
+//
+ {
+ return Exec::SessionShare(iHandle, (aMode&KCreateProtectedObject) ? EIpcSession_GlobalSharable : EIpcSession_Sharable);
+ }
+
+
+
+
+TInt RSessionBase::SendSync(TInt aFunction,const TIpcArgs* aArgs) const
+//
+// Send a synchronous message.
+//
+ {
+ TRequestStatus s=KRequestPending;
+ TInt r=Exec::SessionSendSync(iHandle,aFunction,(TAny*)aArgs,&s);
+ if (r==KErrNone)
+ {
+ User::WaitForRequest(s);
+ r=s.Int();
+ }
+ return r;
+ }
+
+TInt RSessionBase::SendAsync(TInt aFunction,const TIpcArgs* aArgs,TRequestStatus *aStatus) const
+//
+// Send an asynchronous message.
+//
+ {
+ if (aStatus)
+ *aStatus=KRequestPending;
+ return Exec::SessionSend(iHandle,aFunction,(TAny*)aArgs,aStatus);
+ }
+
+
+
+
+EXPORT_C TInt RMutex::CreateLocal(TOwnerType aType)
+/**
+Creates a mutex and opens this handle to the mutex.
+
+The kernel side object representing the mutex is unnamed. This means that
+it is not possible to search for the mutex, which makes it local to the current
+process.
+
+By default, any thread in the process can use this instance of RMutex to access
+the mutex. However, specifying EOwnerThread as the parameter to this function,
+means that only the creating thread can use this instance of RMutex to access
+the mutex; any other thread in this process that wants to access the mutex
+must duplicate this handle.
+
+@param aType An enumeration whose enumerators define the ownership of this
+ mutex handle. If not explicitly specified, EOwnerProcess is taken
+ as default.
+
+@return KErrNone if successful, otherwise one of the system wide error codes.
+
+@see RHandleBase::Duplicate()
+*/
+ {
+ return SetReturnedHandle(Exec::MutexCreate(NULL,aType),*this);
+ }
+
+
+
+
+EXPORT_C TInt RMutex::CreateGlobal(const TDesC &aName,TOwnerType aType)
+/**
+Creates a global mutex and opens this handle to the mutex.
+
+The kernel side object representing the mutex is given the name contained
+in the specified descriptor, which makes it global. This means that any thread
+in any process can search for the mutex, using TFindMutex, and open a handle
+to it. If the specified name is empty the kernel side object representing the
+mutex is unnamed and so cannot be opened by name. It can however be passed
+to another process as a process parameter or via IPC.
+
+By default, any thread in the process can use this instance of RMutex to access
+the mutex. However, specifying EOwnerThread as the second parameter to this
+function, means that only the creating thread can use this instance of RMutex
+to access the mutex; any other thread in this process that wants to access
+the mutex must either duplicate this handle or use OpenGlobal().
+
+@param aName The name to be assigned to this global mutex.
+@param aType An enumeration whose enumerators define the ownership of this
+ mutex handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone if successful, otherwise one of the other system wide error
+ codes.
+
+@see OpenGlobal
+@see RHandleBase::Duplicate()
+@see TFindMutex
+*/
+ {
+ TInt r = User::ValidateName(aName);
+ if(KErrNone!=r)
+ return r;
+ TBuf8<KMaxKernelName> name8;
+ name8.Copy(aName);
+ return SetReturnedHandle(Exec::MutexCreate(&name8,aType),*this);
+ }
+
+
+
+
+EXPORT_C TInt RMutex::OpenGlobal(const TDesC &aName,TOwnerType aType)
+/**
+Opens a handle to a global mutex.
+
+Global mutexes are identified by name.
+
+By default, any thread in the process can use this instance of RMutex to access
+the mutex. However, specifying EOwnerThread as the second parameter to this
+function, means that only the opening thread can use this instance of RMutex
+to access the mutex; any other thread in this process that wants to access
+the mutex must either duplicate the handle or use OpenGlobal() again.
+
+@param aName The name of the global mutex which is to be opened.
+@param aType An enumeration whose enumerators define the ownership of this
+ mutex handle. If not explicitly specified, EOwnerProcess
+ is taken as default.
+
+@return KErrNone if successful, otherwise another of the system wide error
+ codes.
+@see RHandleBase::Duplicate()
+*/
+ {
+ return OpenByName(aName,aType,EMutex);
+ }
+
+
+
+
+EXPORT_C TInt RMutex::Open(RMessagePtr2 aMessage,TInt aParam,TOwnerType aType)
+/**
+Opens a handle to a mutex using a handle number sent by a client
+to a server.
+
+This function is called by the server.
+
+@param aMessage The message pointer.
+@param aParam An index specifying which of the four message arguments
+ contains the handle number.
+@param aType An enumeration whose enumerators define the ownership of this
+ mutex handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone, if successful;
+ KErrArgument, if the value of aParam is outside the range 0-3;
+ KErrBadHandle, if not a valid handle;
+ otherwise one of the other system-wide error codes.
+*/
+ {
+ return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),EMutex,aParam,aType));
+ }
+
+
+
+
+EXPORT_C TInt RMutex::Open(TInt aArgumentIndex, TOwnerType aOwnerType)
+/**
+Opens a handle to a mutex using a handle number passed as an
+environment data item to the child process during the creation of
+that child process.
+
+Note that this function can only be called successfully once.
+
+@param aArgumentIndex An index that identifies the slot in the process
+ environment data that contains the handle number. This is
+ a value relative to zero, i.e. 0 is the first item/slot.
+ This can range from 0 to 15.
+
+@param aOwnerType An enumeration whose enumerators define the ownership of
+ this mutex handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone, if successful;
+ KErrNotFound, if the slot indicated by aArgumentIndex is empty;
+ KErrArgument, if the slot does not contain a mutex handle;
+ otherwise one of the other system-wide error codes.
+
+@see RProcess::SetParameter()
+*/
+ {
+ return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, EMutex, aOwnerType));
+ }
+
+
+
+EXPORT_C TInt RCondVar::CreateLocal(TOwnerType aType)
+/**
+Creates a condition variable and opens this handle to it.
+
+The kernel side object representing the condition variable is unnamed and so
+the condition variable cannot be found by name and hence it is local to the
+current process.
+
+By default, any thread in the process can use this instance of RCondVar to access
+the condition variable. However, specifying EOwnerThread as the parameter to this
+function means that only the creating thread can use this instance of RCondVar
+to access the condition variable; any other thread in this process that wants to
+access the condition variable must duplicate this handle.
+
+@param aType An enumeration whose enumerators define the ownership of this
+ condition variable handle. If not explicitly specified, EOwnerProcess
+ is taken as default.
+
+@return KErrNone if successful, otherwise one of the system wide error codes.
+
+@see RHandleBase::Duplicate()
+*/
+ {
+ return SetReturnedHandle(Exec::CondVarCreate(NULL, aType), *this);
+ }
+
+
+
+
+EXPORT_C TInt RCondVar::CreateGlobal(const TDesC& aName, TOwnerType aType)
+/**
+Creates a global condition variable and opens this handle to it.
+
+If the specified name is a non-empty string the kernel side object representing
+the condition variable is given the specified name and is therefore global. It
+may subsequently be opened by name using the RCondVar::OpenGlobal function.
+If the specified name is empty the kernel side object representing the condition
+variable is unnamed and so cannot be opened by name. It can however be passed
+to another process as a process parameter or via IPC.
+
+If the specified name is non-empty it must consist entirely of printable ASCII
+characters (codes 0x20 to 0x7e inclusive) and may not contain : * or ?.
+
+By default, any thread in the process can use this instance of RCondVar to access
+the condition variable. However, specifying EOwnerThread as the parameter to this
+function means that only the creating thread can use this instance of RCondVar
+to access the condition variable; any other thread in this process that wants to
+access the condition variable must duplicate this handle.
+
+@param aName The name to be assigned to this condition variable.
+@param aType An enumeration whose enumerators define the ownership of this
+ condition variable handle. If not explicitly specified, EOwnerProcess
+ is taken as default.
+
+@return KErrNone if successful, otherwise one of the other system wide error
+ codes.
+
+@see RCondVar::OpenGlobal()
+@see RHandleBase::Duplicate()
+@see RProcess::SetParameter(TInt, RHandleBase)
+@see TIpcArgs::Set(TInt, RHandleBase)
+@see RMessagePtr2::Complete(RHandleBase)
+*/
+ {
+ TInt r = User::ValidateName(aName);
+ if (KErrNone!=r)
+ return r;
+ TBuf8<KMaxKernelName> name8;
+ name8.Copy(aName);
+ return SetReturnedHandle(Exec::CondVarCreate(&name8, aType), *this);
+ }
+
+
+
+
+EXPORT_C TInt RCondVar::OpenGlobal(const TDesC& aName, TOwnerType aType)
+/**
+Opens a handle to a global condition variable.
+
+Global condition variables are identified by name.
+
+By default, any thread in the process can use this instance of RCondVar to access
+the condition variable. However, specifying EOwnerThread as the parameter to this
+function means that only the creating thread can use this instance of RCondVar
+to access the condition variable; any other thread in this process that wants to
+access the condition variable must either duplicate this handle or use OpenGlobal
+again.
+
+@param aName The name of the global condition variable which is to be opened.
+@param aType An enumeration whose enumerators define the ownership of this
+ condition variable handle. If not explicitly specified, EOwnerProcess
+ is taken as default.
+
+@return KErrNone if successful, otherwise another of the system wide error
+ codes.
+
+@see RHandleBase::Duplicate()
+*/
+ {
+ return OpenByName(aName, aType, ECondVar);
+ }
+
+
+
+
+EXPORT_C TInt RCondVar::Open(RMessagePtr2 aMessage, TInt aParam, TOwnerType aType)
+/**
+Opens a handle to a condition variable using a handle number sent by a client
+to a server.
+
+This function is called by the server.
+
+@param aMessage The message pointer.
+@param aParam An index specifying which of the four message arguments
+ contains the handle number.
+@param aType An enumeration whose enumerators define the ownership of this
+ condition variable handle. If not explicitly specified, EOwnerProcess
+ is taken as default.
+
+@return KErrNone, if successful;
+ KErrArgument, if the value of aParam is outside the range 0-3;
+ KErrBadHandle, if not a valid handle;
+ otherwise one of the other system-wide error codes.
+*/
+ {
+ return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(), ECondVar, aParam, aType));
+ }
+
+
+
+
+EXPORT_C TInt RCondVar::Open(TInt aArgumentIndex, TOwnerType aType)
+/**
+Opens a handle to a condition variable using a handle number passed as an
+environment data item to the child process during the creation of
+that child process.
+
+Note that this function can only be called successfully once.
+
+@param aArgumentIndex An index that identifies the slot in the process
+ environment data that contains the handle number. This is
+ a value relative to zero, i.e. 0 is the first item/slot.
+ This can range from 0 to 15.
+
+@param aType An enumeration whose enumerators define the ownership of
+ this condition variable handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone, if successful;
+ KErrNotFound, if the slot indicated by aArgumentIndex is empty;
+ KErrArgument, if the slot does not contain a condition variable handle;
+ otherwise one of the other system-wide error codes.
+
+@see RProcess::SetParameter()
+*/
+ {
+ return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, ECondVar, aType));
+ }
+
+
+
+
+EXPORT_C TInt RSemaphore::CreateLocal(TInt aCount,TOwnerType aType)
+/**
+Creates a semaphore, setting its initial count, and opens this handle to the
+semaphore.
+
+The kernel side object representing the semaphore is unnamed. This means that
+it is not possible to search for the semaphore, which makes it local to the
+current process.
+
+By default, any thread in the process can use this instance of RSemaphore
+to access the semaphore. However, specifying EOwnerThread as the second parameter
+to this function, means that only the creating thread can use this instance
+of RSemaphore to access the semaphore; any other thread in this process that
+wants to access the semaphore must duplicate this handle.
+
+@param aCount The initial value of the semaphore count.
+@param aType An enumeration whose enumerators define the ownership of this
+ semaphore handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone if successful, otherwise another of the system wide error
+ codes.
+
+@panic USER 105 if aCount is negative.
+
+@see RHandleBase::Duplicate()
+*/
+ {
+
+ __ASSERT_ALWAYS(aCount>=0,Panic(ESemCreateCountNegative));
+ return SetReturnedHandle(Exec::SemaphoreCreate(NULL,aCount,aType),*this);
+ }
+
+
+
+
+EXPORT_C TInt RSemaphore::CreateGlobal(const TDesC &aName,TInt aCount,TOwnerType aType)
+/**
+Creates a global semaphore, setting its initial count, and opens this handle
+to the semaphore.
+
+The kernel side object representing the semaphore is given the name contained
+in the specified descriptor, which makes it global. This means that any thread
+in any process can search for the semaphore, using TFindSemaphore, and open
+a handle to it. If the specified name is empty the kernel side object
+representing the semaphore is unnamed and so cannot be opened by name. It can
+however be passed to another process as a process parameter or via IPC.
+
+By default, any thread in the process can use this instance of RSemaphore
+to access the semaphore. However, specifying EOwnerThread as the third
+parameter to this function, means that only the creating thread can use
+this instance of RSemaphore to access the semaphore; any other thread in
+this process that wants to access the semaphore must either duplicate this
+handle or use OpenGlobal().
+
+@param aName A reference to the descriptor containing the name to be assigned
+ to this global semaphore.
+@param aCount The initial value of the semaphore count.
+@param aType An enumeration whose enumerators define the ownership of this
+ semaphore handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone if successful otherwise another of the system wide error
+ codes.
+
+@panic USER 105 if aCount is negative.
+
+@see RSemaphore::OpenGlobal()
+@see RHandleBase::Duplicate()
+@see TFindSemaphore
+*/
+ {
+
+ __ASSERT_ALWAYS(aCount>=0,Panic(ESemCreateCountNegative));
+ TInt r = User::ValidateName(aName);
+ if(KErrNone!=r)
+ return r;
+ TBuf8<KMaxKernelName> name8;
+ name8.Copy(aName);
+ return SetReturnedHandle(Exec::SemaphoreCreate(&name8,aCount,aType),*this);
+ }
+
+
+
+
+EXPORT_C TInt RSemaphore::OpenGlobal(const TDesC &aName,TOwnerType aType)
+/**
+Opens a handle to a global semaphore.
+
+Global semaphores are identified by name.
+
+By default, any thread in the process can use this instance of RSemaphore
+to access the semaphore. However, specifying EOwnerThread as the second parameter
+to this function, means that only the opening thread can use this instance
+of RSemaphore to access the semaphore; any other thread in this process that
+wants to access the semaphore must either duplicate the handle or use OpenGlobal()
+again.
+
+@param aName A reference to the descriptor containing the name of the global
+ semaphore to be opened.
+@param aType An enumeration whose enumerators define the ownership of this
+ semaphore handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone if successful otherwise another of the system wide error
+ codes.
+
+@see RHandleBase::Duplicate()
+*/
+ {
+ return OpenByName(aName,aType,ESemaphore);
+ }
+
+
+
+
+EXPORT_C TInt RSemaphore::Open(RMessagePtr2 aMessage,TInt aParam,TOwnerType aType)
+/**
+Opens a handle to a semaphore using a handle number sent by a client
+to a server.
+
+This function is called by the server.
+
+@param aMessage The message pointer.
+@param aParam An index specifying which of the four message arguments
+ contains the handle number.
+@param aType An enumeration whose enumerators define the ownership of this
+ semaphore handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone, if successful;
+ KErrArgument, if the value of aParam is outside the range 0-3;
+ KErrBadHandle, if not a valid handle;
+ otherwise one of the other system-wide error codes.
+*/
+ {
+ return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),ESemaphore,aParam,aType));
+ }
+
+
+
+
+EXPORT_C TInt RSemaphore::Open(TInt aArgumentIndex, TOwnerType aOwnerType)
+/**
+Opens a handle to a semaphore using a handle number passed as an
+environment data item to the child process during the creation of
+that child process.
+
+Note that this function can only be called successfully once.
+
+@param aArgumentIndex An index that identifies the slot in the process
+ environment data that contains the handle number. This is
+ a value relative to zero, i.e. 0 is the first item/slot.
+ This can range from 0 to 15.
+
+@param aOwnerType An enumeration whose enumerators define the ownership of
+ this semaphore handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone, if successful;
+ KErrNotFound, if the slot indicated by aArgumentIndex is empty;
+ KErrArgument, if the slot does not contain a Semaphore handle;
+ otherwise one of the other system-wide error codes.
+
+@see RProcess::SetParameter()
+*/
+ {
+ return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, ESemaphore, aOwnerType));
+ }
+
+
+
+
+EXPORT_C TInt RCriticalSection::CreateLocal(TOwnerType aType)
+/**
+Creates a critical section and opens this handle to the critical section.
+
+The kernel side object representing the critical section is unnamed. This
+means that it is not possible to search for the critical section, which makes
+it local to the current process.
+
+By default, any thread in the process can use this instance of RCriticalSection
+to access the critical section. However, specifying EOwnerThread as the parameter
+to this function, means that only the creating thread can use this instance
+of RCriticalSection to access the critical section; any other thread in this
+process that wants to access the critical section must duplicate this handle.
+
+@param aType An enumeration whose enumerators define the ownership of this
+ critical section handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone if successful otherwise another of the system wide error codes.
+
+@see RHandleBase::Duplicate()
+*/
+ {
+
+ iBlocked=1;
+ return(RSemaphore::CreateLocal(0,aType));
+ }
+
+
+
+/**
+Creates a local fast semaphore, and opens this handle to the
+semaphore.
+
+@param aType An enumeration whose enumerators define the ownership of this
+ semaphore handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone if successful, otherwise one of the system wide error
+ codes.
+
+@see RSemaphore::CreateLocal()
+*/
+EXPORT_C TInt RFastLock::CreateLocal(TOwnerType aType)
+ {
+
+ iCount=0;
+ return RSemaphore::CreateLocal(0,aType);
+ }
+
+
+
+
+EXPORT_C TInt RTimer::CreateLocal()
+//
+// Create a local timer.
+//
+/**
+Creates a thread-relative timer.
+
+@return KErrNone if successful, otherwise another of the
+ system-wide error codes.
+*/
+ {
+ return SetReturnedHandle(Exec::TimerCreate(),*this);
+ }
+
+
+
+
+EXPORT_C TInt RProcess::Open(const TDesC &aName,TOwnerType aType)
+/**
+Opens a handle to a specifically named process.
+
+By default, ownership of this process handle is vested in the current process,
+but can be vested in the current thread by passing EOwnerThread as the second
+parameter to this function.
+
+@param aName A reference to the descriptor containing the name of the process
+ to be opened.
+@param aType An enumeration whose enumerators define the ownership of this
+ thread handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone, if successful, otherwise one of the other system-wide error
+ codes.
+*/
+ {
+ return OpenByName(aName,aType,EProcess);
+ }
+
+
+
+
+EXPORT_C TInt RProcess::Open(TProcessId aId,TOwnerType aType)
+/**
+Opens a handle to the process whose process Id matches
+the specified process ID.
+
+By default, ownership of this process handle is vested in the current process,
+but can be vested in the current thread by passing EOwnerThread as the second
+parameter to this function.
+
+@param aId The process Id used to find the process.
+@param aType An enumeration whose enumerators define the ownership of this
+ process handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone, if successful, otherwise one of the other system-wide error
+ codes.
+*/
+ {
+
+ TUint id=*(TUint*)&aId;
+ return SetReturnedHandle(Exec::ProcessOpenById(id,aType),*this);
+ }
+
+
+
+
+EXPORT_C TInt User::RenameProcess(const TDesC &aName)
+/**
+Assigns a new name to the current process, replacing any existing name.
+
+When a process is created, its default name is the name portion of the filename
+from which the executable is loaded.
+
+The new name must be a valid name and it must also be such that the process's
+new fullname remains unique amongst processes.
+
+@param aName A reference to the descriptor containing the new name of the
+ process.
+
+@return KErrNone, if successful, or if the new and old names are identical;
+ KErrBadName, if aName is an invalid;
+ otherwise one of the other system-wide error codes.
+*/
+ {
+ TBuf8<KMaxKernelName> name8;
+ name8.Copy(aName);
+ return Exec::ProcessRename(KCurrentProcessHandle,name8);
+ }
+
+
+
+
+/**
+Ends this process, and all of its threads, specifying a reason code.
+
+This function is intended to be used if a process is exiting under normal
+conditions.
+
+If the process is system permanent, the entire system is rebooted.
+
+@param aReason The reason to be associated with the ending of this process.
+
+@capability PowerMgmt except when one of the following situations is true:
+ 1. the process calling this function is the same as the
+ process to be terminated.
+ 2. the process calling this function created the process
+ to be terminated, but has not yet resumed that process.
+
+@see User::SetProcessCritical()
+@see User::ProcessCritical()
+*/
+EXPORT_C void RProcess::Kill(TInt aReason)
+ {
+ Exec::ProcessKill(iHandle,EExitKill,aReason,NULL);
+ }
+
+
+/**
+Ends this process, and all of its threads, specifying a reason code.
+
+This function is intended to be used if a process is exiting under abnormal
+conditions, for example if an error condition has been detected.
+
+If the process is system critical or system permanent, the entire system is
+rebooted.
+
+@param aReason The reason to be associated with the ending of this process.
+
+@capability PowerMgmt except when one of the following situations is true:
+ 1. the process calling this function is the same as the
+ process to be terminated.
+ 2. the process calling this function created the process
+ to be terminated, but has not yet resumed that process.
+
+@see User::SetProcessCritical()
+@see User::ProcessCritical()
+*/
+EXPORT_C void RProcess::Terminate(TInt aReason)
+ {
+ Exec::ProcessKill(iHandle,EExitTerminate,aReason,NULL);
+ }
+
+
+
+/**
+Panics the process and all of its owned threads, specifying the panic category
+name and reason code.
+
+The length of the category name should be no greater than 16; any name with
+a length greater than 16 is truncated to 16.
+
+If the process is system critical or system permanent, the entire system is
+rebooted.
+
+@param aCategory A reference to the descriptor containing the text which
+ defines the category name for this panic.
+@param aReason The panic number.
+
+@capability PowerMgmt except when one of the following situations is true:
+ 1. the process calling this function is the same as the
+ process to be terminated.
+ 2. the process calling this function created the process
+ to be terminated, but has not yet resumed that process.
+
+@see User::SetProcessCritical()
+@see User::ProcessCritical()
+*/
+EXPORT_C void RProcess::Panic(const TDesC &aCategory,TInt aReason)
+ {
+ TBuf8<KMaxExitCategoryName> name8;
+ TInt length=aCategory.Length();
+ if(length>KMaxExitCategoryName)
+ {
+ TPtr catPtr((TUint16*)aCategory.Ptr(),KMaxExitCategoryName,KMaxExitCategoryName);
+ name8.Copy(catPtr);
+ }
+ else
+ {
+ name8.Copy(aCategory);
+ }
+ Exec::ProcessKill(iHandle,EExitPanic,aReason,&name8);
+ }
+
+
+
+
+EXPORT_C void RProcess::Logon(TRequestStatus &aStatus) const
+/**
+Requests notification when this process dies, normally or otherwise.
+
+A request for notification is an asynchronous request, and completes:
+
+- when the process terminates
+- if the outstanding request is cancelled by a call to RProcess::LogonCancel().
+
+A request for notification requires memory to be allocated; if this is
+unavailable, then the call to Logon() returns, and the asynchronous request
+completes immediately.
+
+@param aStatus A reference to the request status object.
+ This contains the reason code describing the reason for
+ the termination of the process, i.e. the value returned by a call to RProcess::ExitReason().
+ Alternatively, this is set to:
+ KErrCancel, if an outstanding request is cancelled;
+ KErrNoMemory, if there is insufficient memory to deal with the request.
+
+@see RProcess::LogonCancel()
+@see RProcess::ExitReason()
+*/
+ {
+
+ aStatus=KRequestPending;
+ Exec::ProcessLogon(iHandle,&aStatus,EFalse);
+ }
+
+
+
+
+EXPORT_C TInt RProcess::LogonCancel(TRequestStatus &aStatus) const
+/**
+Cancels an outstanding request for notification of the death of this process.
+
+A request for notification must previously have been made, otherwise the function
+returns KErrGeneral.
+
+The caller passes a reference to the same request status object as was passed
+in the original call to Logon().
+
+@param aStatus A reference to the same request status object used in
+ the original call to Logon().
+
+@return KErrGeneral, if there is no outstanding request; KErrNone otherwise.
+
+@see RProcess::Logon()
+*/
+ {
+ return Exec::ProcessLogonCancel(iHandle,&aStatus,EFalse);
+ }
+
+
+
+
+/**
+Creates a Rendezvous request with the process.
+
+The request is an asynchronous request, and completes:
+
+- when a call is made to RProcess::Rendezvous(TInt aReason).
+- if the outstanding request is cancelled by a call to RProcess::RendezvousCancel()
+- if the process exits
+- if the process panics.
+
+Note that a request requires memory to be allocated; if this is unavailable,
+then this call to Rendezvous() returns, and the asynchronous request
+completes immediately.
+
+@param aStatus A reference to the request status object.
+ The Rendezvous completes normally when
+ RProcess::Rendezvous(TInt aReason) is called, and this
+ request status object will contain this reason code.
+ If the process exits or panics, then this is the process exit
+ reason value, i.e. the same value returned by RProcess::ExitReason().
+ Alternatively, this is set to:
+ KErrCancel, if an outstanding request is cancelled;
+ KErrNoMemory, if there is insufficient memory to deal with the request.
+
+@see RProcess::Rendezvous(TInt aReason)
+@see RProcess::RendezvousCancel(TRequestStatus& aStatus)
+*/
+EXPORT_C void RProcess::Rendezvous(TRequestStatus& aStatus) const
+ {
+ aStatus=KRequestPending;
+ Exec::ProcessLogon(iHandle,&aStatus,ETrue);
+ }
+
+
+
+
+/**
+Cancels a previously requested Rendezvous with the process.
+
+The request completes with the value KErrCancel (if it was still outstanding).
+
+@param aStatus A reference to the same request status object used in
+ the original call to Rendezvous(TRequestStatus& aStatus).
+
+@return KErrGeneral, if there is no outstanding request, KErrNone otherwise.
+
+@see RProcess::Rendezvous(TRequestStatus &aStatus)
+*/
+EXPORT_C TInt RProcess::RendezvousCancel(TRequestStatus& aStatus) const
+ {
+ return Exec::ProcessLogonCancel(iHandle,&aStatus,ETrue);
+ }
+
+
+
+
+/**
+Completes all Rendezvous' with the current process.
+
+@param aReason The reason code used to complete all rendezvous requests
+
+@see RProcess::Rendezvous(TRequestStatus& aStatus)
+*/
+EXPORT_C void RProcess::Rendezvous(TInt aReason)
+ {
+ Exec::ProcessRendezvous(aReason);
+ }
+
+
+/**
+This can be used to determine whether the data for the process is demand paged
+by default or not.
+
+@return ETrue if the default for the process's data is to be demand paged,
+ EFalse otherwise.
+
+@prototype
+*/
+EXPORT_C TBool RProcess::DefaultDataPaged() const
+ {
+ return Exec::ProcessDefaultDataPaged(iHandle);
+ }
+
+
+//
+// Class TThreadCreateInfo
+//
+
+/**
+Constructor where the basic properties of the thread to be created are specified.
+
+NOTE - TThreadCreateInfo::SetCreateHeap() or TThreadCreateInfo::SetUseHeap() must
+be invoked on this TThreadCreateInfo to set the type of the thread to be created
+before being passed as a paramter to RThread::Create().
+
+@param aName The name to be assigned to the thread.
+ KNullDesC, to create an anonymous thread.
+@param aFunction A pointer to a function. Control passes to this function
+ when the thread is first resumed, i.e. when the thread
+ is initially scheduled to run.
+@param aStackSize The size of the new thread's stack.
+@param aPtr A pointer to data to be passed as a parameter to
+ the thread function when the thread is initially scheduled
+ to run. If the thread function does not need any data then
+ this pointer can be NULL.
+*/
+EXPORT_C TThreadCreateInfo::TThreadCreateInfo(const TDesC &aName, TThreadFunction aFunction,
+ TInt aStackSize, TAny* aPtr) :
+ iVersionNumber(EVersion0), iName(&aName), iFunction(aFunction),
+ iStackSize(aStackSize), iParameter(aPtr), iOwner(EOwnerProcess), iHeap(NULL),
+ iHeapMinSize(0), iHeapMaxSize(0), iAttributes(0)
+ {
+ };
+
+
+/**
+Sets the thread to be created to create its own heap.
+
+@param aHeapMinSize The minimum size for the new thread's heap.
+@param aHeapMaxSize The maximum size for the new thread's heap.
+*/
+EXPORT_C void TThreadCreateInfo::SetCreateHeap(TInt aHeapMinSize, TInt aHeapMaxSize)
+ {
+ iHeapMinSize = aHeapMinSize;
+ iHeapMaxSize = aHeapMaxSize;
+ }
+
+
+/**
+Sets the thread to be created to use the heap whose handle is pointed to by
+aAllocator. If this is NULL, then the thread uses the heap of the creating thread.
+
+@param aAllocator A pointer to the handle of the heap belonging to another thread
+ which this thread is to use.
+*/
+EXPORT_C void TThreadCreateInfo::SetUseHeap(const RAllocator *aAllocator)
+ {
+ iHeap = (aAllocator)? (RAllocator*)aAllocator : GetHeap();
+ }
+
+
+/**
+Sets the owner the thread to be created. Any previous calls
+to this method will be overridden for this TThreadCreateInfo object.
+
+@param aOwner The owner of the thread to be created.
+*/
+EXPORT_C void TThreadCreateInfo::SetOwner(const TOwnerType aOwner)
+ {
+ iOwner = aOwner;
+ }
+
+
+/**
+Sets the data paging attributes of the thread to be created. Any previous calls
+to this method will be overridden for this TThreadCreateInfo object.
+
+@param aPaging The paging attributes for the thread to be created.
+*/
+EXPORT_C void TThreadCreateInfo::SetPaging(const TThreadPagingAtt aPaging)
+ {
+ iAttributes &= ~EThreadCreateFlagPagingMask;
+ if (aPaging == EPaged)
+ iAttributes |= EThreadCreateFlagPaged;
+ if (aPaging == EUnpaged)
+ iAttributes |= EThreadCreateFlagUnpaged;
+ }
+
+
+/**
+Creates a thread belonging to the current process, and opens this handle
+to that thread. The thread will have the properties as defined by the parameter
+aCreateInfo.
+
+@param aCreateInfo A reference to a TThreadCreateInfo object specifying
+ the properties of thread to create.
+
+@return KErrNone if successful, otherwise one of the other system-wide error codes.
+ KErrAlreadyExists will be returned if there is another thread in this process with the
+ specified name.
+
+@panic USER 109 if the stack size specified for the thread is negative.
+@panic USER 110 if the specified minimum heap size is less than KMinHeapSize.
+@panic USER 111 if the specified maximum heap size is less than the specified minimum heap size.
+*/
+EXPORT_C TInt RThread::Create(const TThreadCreateInfo& aCreateInfo)
+ {
+ __ASSERT_ALWAYS(aCreateInfo.iStackSize >= 0, ::Panic(EThrdStackSizeNegative));
+ if (!aCreateInfo.iHeap)
+ {// Creating a new heap so verify the parameters.
+ __ASSERT_ALWAYS(aCreateInfo.iHeapMinSize >= KMinHeapSize,::Panic(EThrdHeapMinTooSmall));
+ __ASSERT_ALWAYS(aCreateInfo.iHeapMaxSize >= aCreateInfo.iHeapMinSize,::Panic(EThrdHeapMaxLessThanMin));
+ }
+
+ TInt r = User::ValidateName(*aCreateInfo.iName);
+ if(KErrNone!=r)
+ return r;
+
+ SStdEpocThreadCreateInfo8 info;
+ info.iFunction = aCreateInfo.iFunction;
+ info.iUserStackSize = aCreateInfo.iStackSize;
+ info.iUserStack = NULL;
+ info.iAllocator = aCreateInfo.iHeap;
+ info.iHeapInitialSize = aCreateInfo.iHeapMinSize;
+ info.iHeapMaxSize = aCreateInfo.iHeapMaxSize;
+ info.iPtr = aCreateInfo.iParameter;
+ info.iTotalSize = sizeof(info);
+ info.iFlags = aCreateInfo.iAttributes;
+
+ TBuf8<KMaxKernelName> n;
+ n.Copy(*aCreateInfo.iName);
+
+ return SetReturnedHandle(Exec::ThreadCreate(n, aCreateInfo.iOwner, info),*this);
+ }
+
+
+EXPORT_C TInt RThread::Create(const TDesC &aName,TThreadFunction aFunction,TInt aStackSize,TInt aHeapMinSize,TInt aHeapMaxSize,TAny *aPtr,TOwnerType aType)
+/**
+Creates a thread belonging to the current process, and opens this handle
+to that thread.
+
+A new heap is created for this thread.
+
+By default, ownership of this thread handle is vested in the current process,
+but can be vested in the current thread by passing EOwnerThread as
+the second parameter to this function.
+
+If KNullDesC is specified for the name, then an anonymous thread will be created.
+Anonymous threads are not global, and cannot be opened by other processes.
+
+@param aName The name to be assigned to this thread.
+ KNullDesC, to create an anonymous thread.
+@param aFunction A pointer to a function.. Control passes to this function
+ when the thread is first resumed, i.e. when the thread
+ is initially scheduled to run.
+@param aStackSize The size of the new thread's stack.
+@param aHeapMinSize The minimum size for the new thread's heap.
+@param aHeapMaxSize The maximum size for the new thread's heap.
+@param aPtr A pointer to data to be passed as a parameter to
+ the thread function when the thread is initially scheduled
+ to run. If the thread function does not need any data then
+ this pointer can be NULL. It must be ensured that the memory
+ pointed to by this pointer is still valid when accessed by
+ the new thread, e.g. if aPtr points to data on the stack.
+@param aType An enumeration whose enumerators define the ownership of
+ this thread handle. If not explicitly specified,
+ EOwnerProcess is taken as default.
+
+@return KErrNone if successful, otherwise one of the other system-wide error codes.
+ KErrAlreadyExists will be returned if there is another thread in this process with the
+ specified name.
+
+@panic USER 109 if aStackSize is negative.
+@panic USER 110 if aHeapMinSize is less than KMinHeapSize.
+@panic USER 111 if aHeapMaxSize is less than aHeapMinSize.
+*/
+ {
+ TThreadCreateInfo createInfo(aName, aFunction, aStackSize, aPtr);
+ createInfo.SetOwner(aType);
+ createInfo.SetCreateHeap(aHeapMinSize, aHeapMaxSize);
+ return Create(createInfo);
+ }
+
+
+
+
+EXPORT_C TInt RThread::Create(const TDesC& aName, TThreadFunction aFunction, TInt aStackSize, RAllocator* aAllocator, TAny* aPtr, TOwnerType aType)
+/**
+Creates a thread belonging to the current process, and opens this handle to
+that thread.
+
+This thread uses the heap whose handle is pointed to by
+aAllocator. If this is NULL, then the thread uses the heap of the creating thread.
+
+By default, ownership of this thread handle is vested in the current process,
+but can be vested in the current thread by passing EOwnerThread as the second
+parameter to this function.
+
+If KNullDesC is specified for the name, then an anonymous thread will be created.
+Anonymous threads are not global, and cannot be opened by other processes.
+
+@param aName The name to be assigned to this thread.
+ KNullDesC, to create an anonymous thread.
+@param aFunction A pointer to a function. Control passes to this function when
+ the thread is first resumed, i.e. when the thread is
+ initially scheduled to run.
+@param aStackSize The size of the new thread's stack.
+@param aAllocator A pointer to the handle of the heap belonging to another thread
+ which this thread is to use.
+@param aPtr A pointer to data to be passed as a parameter to the thread
+ function when the thread is initially scheduled to run.
+ If the thread function does not need any data,
+ then this pointer can be NULL. It must be ensured that the
+ memory pointed to by this pointer is still valid when accessed
+ by the new thread, e.g. if aPtr points to data on the stack.
+@param aType An enumeration whose enumerators define the ownership of this
+ thread handle. If not explicitly specified, EOwnerProcess is
+ taken as default.
+
+@return KErrNone if successful otherwise one of the other system-wide error codes.
+ KErrAlreadyExists will be returned if there is another thread in this process with the
+ specified name.
+
+@panic USER 109 if aStackSize is negative.
+*/
+ {
+ TThreadCreateInfo createInfo(aName, aFunction, aStackSize, aPtr);
+ createInfo.SetOwner(aType);
+ createInfo.SetUseHeap(aAllocator);
+ return Create(createInfo);
+ }
+
+
+
+
+EXPORT_C TInt RThread::Open(const TDesC &aName,TOwnerType aType)
+/**
+Opens a handle to specifically named thread.
+
+By default, ownership of this thread handle is vested in the
+current process, but can be vested in the current thread by passing
+EOwnerThread as the second parameter to this function.
+
+@param aName A reference to the descriptor containing the full name of the
+ thread that is already running.
+@param aType An enumeration whose enumerators define the ownership of this
+ thread handle. If not explicitly specified, EOwnerProcess is taken
+ as default.
+
+@return KErrNone, if successful, otherwise one of the other system-wide
+ error codes.
+*/
+ {
+ return OpenByName(aName,aType,EThread);
+ }
+
+
+
+
+EXPORT_C TInt RThread::Open(TThreadId aId,TOwnerType aType)
+/**
+Opens a handle to the thread with a specific thread Id.
+
+By default, ownership of this thread handle is vested in the
+current process, but can be vested in the current thread by passing
+EOwnerThread as the second parameter to this function.
+
+@param aId The thread Id used to find the thread.
+@param aType An enumeration whose enumerators define the ownership of this
+ thread handle. If not explicitly specified, EOwnerProcess is taken
+ as default.
+
+@return KErrNone, if successful, otherwise one of the other system-wide
+ error codes.
+*/
+//
+// Open an already running thread in any process.
+//
+ {
+
+ TUint id=*(TUint*)&aId;
+ return SetReturnedHandle(Exec::ThreadOpenById(id,aType),*this);
+ }
+
+
+
+
+EXPORT_C TInt RThread::Process(RProcess &aProcess) const
+/**
+Opens a process-relative handle to the process which owns this thread.
+
+The caller must construct a default RProcess object and pass this to
+the function.
+On return, aProcess is the open process-relative handle to the process owning
+this thread.
+
+The return value indicates the success or failure of this function.
+
+@param aProcess A reference to a default RProcess handle; on successful return
+ from this function, this is the process-relative handle
+ to the process which owns this thread.
+
+@return KErrNone, if successful, otherwise one of the other system-wide error
+ codes.
+*/
+ {
+ return SetReturnedHandle(Exec::ThreadProcess(iHandle),aProcess);
+ }
+
+
+
+
+EXPORT_C TInt User::RenameThread(const TDesC &aName)
+/**
+Assigns a new name to the current thread, replacing any existing name that
+may have been set.
+
+The new name must be a valid name and it must also be such that the thread's
+new fullname remains unique amongst threads.
+The length of the new name must be less than or equal to 80 (maximum length of
+kernel objects) otherwise a panic is raised.
+
+@param aName A reference to the descriptor containing the new name for the
+ thread.
+
+@return KErrNone if successful, otherwise one of the other system-wide error
+ codes.
+*/
+ {
+ TBuf8<KMaxKernelName> name8;
+ name8.Copy(aName);
+ return Exec::ThreadRename(KCurrentThreadHandle,name8);
+ }
+
+
+
+
+EXPORT_C void RThread::Kill(TInt aReason)
+/**
+Ends the thread, specifying a reason code.
+
+This function is dangerous and should be used only in cases where the target
+thread cannot end itself via the normal methods of calling User::Exit() or
+completing its thread function. A hypothetical example might be where a thread
+gets 'stuck' in a third-party DLL.
+
+The target thread gets no opportunity to execute any clean-up code, therefore
+incautious use of this function may lead to memory leaks.
+
+It is functionally identical to RThread::Terminate(), the only difference
+between the two is a legacy distinction between a 'normal' reason for exiting
+(use Kill) and an 'abnormal' reason (use Terminate). The choice of function
+is reflected in the return value of RThread::ExitType().
+
+The thread must be in the current process otherwise a panic is raised.
+
+If the thread is process permanent, or the thread is the last thread in the
+process, then the process is also killed. If the thread is system permanent,
+the entire system is rebooted.
+
+WARNING: If the target thread uses a shared heap then use of this function will
+cause an internal array used for thread-local storage (TLS) to be leaked. This
+leak is specific to ARM platforms which implement the CP15 feature and will
+not occur on other platforms.
+
+@param aReason The reason to be associated with the ending of this thread.
+
+@see User::Exit()
+@see User::SetCritical()
+@see User::Critical()
+@see RThread::Terminate()
+@see RThread::ExitType()
+*/
+ {
+
+ Exec::ThreadKill(iHandle,EExitKill,aReason,NULL);
+ }
+
+
+
+
+EXPORT_C void RThread::Terminate(TInt aReason)
+/**
+Ends the thread, specifying a reason code.
+
+This function is dangerous and should be used only in cases where the target
+thread cannot end itself via the normal methods of calling User::Exit() or
+completing its thread function. A hypothetical example might be where a thread
+gets 'stuck' in a third-party DLL.
+
+The target thread gets no opportunity to execute any clean-up code, therefore
+incautious use of this function may lead to memory leaks.
+
+It is functionally identical to RThread::Kill(), the only difference
+between the two is a legacy distinction between a 'normal' reason for exiting
+(use Kill) and an 'abnormal' reason (use Terminate). The choice of function
+is reflected in the return value of RThread::ExitType().
+
+The thread must be in the current process otherwise a panic is raised.
+
+If the thread is process critical or process permanent, or the thread is the
+last thread in the process, then the process is also terminated. If the thread
+is system critical or system permanent, the entire system is rebooted.
+
+WARNING: If the target thread uses a shared heap then use of this function will
+cause an internal array used for thread-local storage (TLS) to be leaked. This
+leak is specific to ARM platforms which implement the CP15 feature and will
+not occur on other platforms.
+
+@param aReason The reason to be associated with the ending of this thread.
+
+@see User::Exit()
+@see User::SetCritical()
+@see User::Critical()
+@see RThread::Kill()
+@see RThread::ExitType()
+*/
+ {
+
+ Exec::ThreadKill(iHandle,EExitTerminate,aReason,NULL);
+ }
+
+
+
+
+EXPORT_C void RThread::Panic(const TDesC &aCategory,TInt aReason)
+/**
+Panics this thread, specifying the panic category name and reason.
+
+The length of the category name should be no greater than 16; any name with
+a length greater than 16 is truncated to 16.
+
+The calling thread, i.e. the thread in which this function is called, must be
+in the same process as this target thread, otherwise the calling thread
+is itself panicked.
+
+If the thread is process critical or process permanent, the process also panics.
+If the thread is system critical or system permanent, the entire system is
+rebooted.
+
+@param aCategory A reference to the descriptor containing the text which defines
+ the category name for this panic.
+@param aReason The panic number.
+
+@panic KERN-EXEC 46 if this target thread's process is not the same as the
+ calling thread's process.
+
+@see User::SetCritical()
+@see User::Critical()
+*/
+ {
+
+ TBuf8<KMaxExitCategoryName> cat;
+ TInt len = aCategory.Length();
+ if(len>KMaxExitCategoryName)
+ {
+ TPtr aCatPtr((TUint16*)aCategory.Ptr(),KMaxExitCategoryName,KMaxExitCategoryName);
+ cat.Copy(aCatPtr);
+ }
+ else
+ cat.Copy(aCategory);
+ Exec::ThreadKill(iHandle,EExitPanic,aReason,&cat);
+ }
+
+
+
+
+EXPORT_C void RThread::Logon(TRequestStatus &aStatus) const
+/**
+Requests notification when this thread dies, normally or otherwise.
+
+A request for notification is an asynchronous request, and completes:
+
+- when the thread terminates
+- if the outstanding request is cancelled by a call to RThread::LogonCancel().
+
+A request for notification requires memory to be allocated; if this is
+unavailable, then the call to Logon() returns, and the asynchronous request
+completes immediately.
+
+Note that even when a thread has died, it is not possible to create a new thread with the same name
+until all handles on the dead thread have been closed. If this is attempted, the call to
+RThread::Create will fail with KErrAlreadyExists.
+
+@param aStatus A reference to the request status object.
+ This contains the reason code describing the reason for
+ the termination of the thread, i.e. the value returned by a call to RThread::ExitReason().
+ Alternatively, this is set to:
+ KErrCancel, if an outstanding request is cancelled;
+ KErrNoMemory, if there is insufficient memory to deal with the request.
+
+@see RThread::LogonCancel()
+@see RThread::ExitReason()
+@see RThread::Create()
+*/
+ {
+
+ aStatus=KRequestPending;
+ Exec::ThreadLogon(iHandle,&aStatus,EFalse);
+ }
+
+
+
+
+EXPORT_C TInt RThread::LogonCancel(TRequestStatus &aStatus) const
+/**
+Cancels an outstanding request for notification of the death of this thread.
+
+A request for notification must previously have been made, otherwise
+the function returns KErrGeneral.
+
+The caller passes a reference to the same request status object as was passed
+in the original call to Logon().
+
+@param aStatus A reference to the same request status object used in
+ the original call to Logon().
+
+@return KErrGeneral, if there is no outstanding request, KErrNone otherwise.
+*/
+ {
+ return Exec::ThreadLogonCancel(iHandle,&aStatus,EFalse);
+ }
+
+
+
+
+/**
+Creates a Rendezvous request with the thread.
+
+The request is an asynchronous request, and completes:
+
+- when the thread next calls RThread::Rendezvous(TInt aReason)
+- if the outstanding request is cancelled by a call to RThread::RendezvousCancel()
+- if the thread exits
+- if the thread panics.
+
+Note that a request requires memory to be allocated; if this is unavailable,
+then this call to Rendezvous() returns, and the asynchronous request
+completes immediately.
+
+@param aStatus A reference to the request status object.
+ The Rendezvous completes normally when
+ RThread::Rendezvous(TInt aReason) is called, and this
+ request status object will contain this reason code.
+ If the thread exits or panics, then this is the thread exit
+ reason value, i.e. the same value returned by RThread::ExitReason().
+ Alternatively, this is set to:
+ KErrCancel, if an outstanding request is cancelled;
+ KErrNoMemory, if there is insufficient memory to deal with the request.
+
+@see RThread::Rendezvous(TInt aReason)
+@see RThread::RendezvousCancel(TRequestStatus& aStatus)
+*/
+EXPORT_C void RThread::Rendezvous(TRequestStatus& aStatus) const
+
+ {
+ aStatus=KRequestPending;
+ Exec::ThreadLogon(iHandle,&aStatus,ETrue);
+ }
+
+
+
+
+/**
+Cancels a previously requested Rendezvous with the thread
+
+The request completes with the value KErrCancel (if it was still outstanding).
+
+@param aStatus A reference to the same request status object used in
+ the original call to Rendezvous(TRequestStatus& aStatus).
+
+@return KErrGeneral, if there is no outstanding request, KErrNone otherwise.
+
+@see RThread::Rendezvous(TRequestStatus& aStatus)
+*/
+EXPORT_C TInt RThread::RendezvousCancel(TRequestStatus& aStatus) const
+ {
+ return Exec::ThreadLogonCancel(iHandle,&aStatus,ETrue);
+ }
+
+
+
+
+/**
+Completes all Rendezvous' with the current thread.
+
+@param aReason The reason code used to complete all rendezvous requests
+
+@see RThread::Rendezvous(TRequestStatus& aStatus)
+*/
+EXPORT_C void RThread::Rendezvous(TInt aReason)
+ {
+ Exec::ThreadRendezvous(aReason);
+ }
+
+
+
+
+EXPORT_C TBusLocalDrive::TBusLocalDrive()
+//
+// Constructor
+//
+ : iStatus(KErrNotReady)
+ {}
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::Read(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt aThreadHandle,TInt aOffset,TInt aFlags)
+//
+// Read from the connected drive, and pass flags to driver
+//
+ {
+ return RLocalDrive::Read(aPos,aLength,aTrg,aThreadHandle,aOffset,aFlags);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::Read(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt aThreadHandle,TInt anOffset)
+//
+// Read from the connected drive.
+//
+ {
+
+ return RLocalDrive::Read(aPos,aLength,aTrg,aThreadHandle,anOffset);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aThreadHandle,TInt aOffset,TInt aFlags)
+//
+// Write to the connected drive and pass flags to driver
+//
+ {
+
+ return RLocalDrive::Write(aPos,aLength,aSrc,aThreadHandle,aOffset,aFlags);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aThreadHandle,TInt anOffset)
+//
+// Write to the connected drive.
+//
+ {
+
+ return RLocalDrive::Write(aPos,aLength,aSrc,aThreadHandle,anOffset);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::Read(TInt64 aPos,TInt aLength,TDes8& aTrg)
+//
+// Read from the connected drive.
+//
+ {
+
+ return RLocalDrive::Read(aPos,aLength,aTrg);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::Write(TInt64 aPos,const TDesC8& aSrc)
+//
+// Write to the connected drive.
+//
+ {
+
+ return RLocalDrive::Write(aPos,aSrc);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::Caps(TDes8& anInfo)
+//
+// Get the connected drive's capabilities info.
+//
+ {
+
+ return RLocalDrive::Caps(anInfo);
+ }
+
+
+
+
+const TInt KDefaultMaxBytesPerFormat=0x00004000;// 16K
+const TInt KFormatSectorSize=0x00000200; // 512
+const TInt KFormatSectorShift=9;
+
+EXPORT_C TInt TBusLocalDrive::Format(TFormatInfo &anInfo)
+//
+// Format the connected drive.
+//
+ {
+ if (anInfo.i512ByteSectorsFormatted<0)
+ return KErrArgument;
+ if (!anInfo.iFormatIsCurrent)
+ {
+ anInfo.iFormatIsCurrent=ETrue;
+ anInfo.i512ByteSectorsFormatted=0;
+ anInfo.iMaxBytesPerFormat=KDefaultMaxBytesPerFormat;
+
+ // Get the capabilities of the drive. If extra info is supported,
+ // Then overrise the default KMaxBytesPerFormat
+ TLocalDriveCapsV3Buf caps;
+ Caps(caps);
+ anInfo.iMaxBytesPerFormat = caps().iMaxBytesPerFormat ? caps().iMaxBytesPerFormat : KDefaultMaxBytesPerFormat;
+ }
+ TInt64 pos=TInt64(anInfo.i512ByteSectorsFormatted)<<KFormatSectorShift;
+ TInt length=anInfo.iMaxBytesPerFormat;
+ TInt r=RLocalDrive::Format(pos,length);
+
+ // A positive return code specifies that the format step
+ // has been adjusted (possibly to account for the partition offset)
+ if(r > 0)
+ {
+ length = r;
+ r = KErrNone;
+ }
+
+ if (r==KErrNone)
+ {
+ length+=KFormatSectorSize-1;
+ length>>=KFormatSectorShift;
+ anInfo.i512ByteSectorsFormatted+=length;
+ }
+
+ if (r==KErrEof)
+ anInfo.iFormatIsCurrent=EFalse;
+
+ return r;
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::Format(TInt64 aPos, TInt aLength)
+//
+// Format the connected drive.
+//
+ {
+ TInt r = KErrNone;
+
+ do
+ {
+ if((r = RLocalDrive::Format(aPos, aLength)) > 0)
+ {
+ aPos += r;
+ aLength -= r;
+ if (aLength == 0)
+ r = KErrNone;
+ }
+ }
+ while(r > 0);
+ return(r);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::ControlIO(TInt aCommand, TAny* aParam1, TAny* aParam2)
+//
+// Control IO
+// NB: If in a data-paging environment and this drive is the data-paging drive, this API will
+// return KErrNotSupported if either aParam1 or aParam2 are non-NULL to avoid the possibility
+// of taking a data paging fault in the media driver's thread.
+// For this reason, this function has been deprecated
+
+// @deprecated Callers of this function should use one of the other overloads
+//
+ {
+ return(RLocalDrive::ControlIO(aCommand,aParam1,aParam2));
+ }
+
+
+EXPORT_C TInt TBusLocalDrive::ControlIO(TInt aCommand, TDes8& aBuf, TInt aParam)
+//
+// Control IO
+// In a data-paging environment, this API allows the passed descriptor to be pinned in the context
+// of the client's thread to avoid taking a data paging fault in the media driver's thread
+//
+ {
+ if (aBuf.MaxLength() == 0)
+ return KErrArgument;
+ return(RLocalDrive::ControlIO(aCommand, aBuf, aParam));
+ }
+
+
+EXPORT_C TInt TBusLocalDrive::ControlIO(TInt aCommand, TDesC8& aBuf, TInt aParam)
+//
+// Control IO
+// In a data-paging environment, this API allows the passed descriptor to be pinned in the context
+// of the client's thread to avoid taking a data paging fault in the media driver's thread
+//
+ {
+ if (aBuf.Length() == 0)
+ return KErrArgument;
+ return(RLocalDrive::ControlIO(aCommand, aBuf, aParam));
+ }
+
+EXPORT_C TInt TBusLocalDrive::ControlIO(TInt aCommand, TInt aParam1, TInt aParam2)
+ {
+ return(RLocalDrive::ControlIO(aCommand, aParam1, aParam2));
+ }
+
+
+
+EXPORT_C TInt TBusLocalDrive::SetMountInfo(const TDesC8* aMountInfo,TInt aMessageHandle)
+//
+// Set the mount information on the local drive
+//
+ {
+
+ return RLocalDrive::SetMountInfo(aMountInfo,aMessageHandle);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::ForceRemount(TUint aFlags)
+//
+// Force a remount on the local drive
+//
+ {
+
+ TInt err = RLocalDrive::ForceMediaChange(aFlags);
+ if(err != KErrNone)
+ return err;
+
+ if(aFlags & ELocDrvRemountForceMediaChange)
+ err = CheckMount();
+
+ return err;
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::GetLastErrorInfo(TDes8& aErrorInfo)
+//
+// Get information on the local drives last error
+//
+ {
+
+ return RLocalDrive::GetLastErrorInfo(aErrorInfo);
+ }
+
+
+
+
+EXPORT_C TLocalDriveCaps::TLocalDriveCaps()
+//
+// Constructor
+//
+ : iSize(0),
+ iType(EMediaNotPresent),
+ iBattery(EBatNotSupported),
+ iDriveAtt(0),
+ iMediaAtt(0),
+ iBaseAddress(NULL),
+ iFileSystemId(0)
+ {}
+
+
+
+
+/**
+@capability TCB
+*/
+EXPORT_C TInt TBusLocalDrive::Connect(TInt aDriveNumber,TBool &aChangedFlag)
+//
+// Connect to the drive.
+//
+ {
+
+ return RLocalDrive::Connect(aDriveNumber, aChangedFlag);
+ }
+
+
+
+
+EXPORT_C void TBusLocalDrive::Disconnect()
+//
+// Disconnect from the drive.
+//
+ {
+
+ Close();
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::Enlarge(TInt aLength)
+//
+// Increase the size of the connected drive by the specified length (in bytes).
+//
+ {
+
+ return RLocalDrive::Enlarge(aLength);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::ReduceSize(TInt aPos,TInt aLength)
+//
+// Reduce the size of the connected drive by removing the specified length
+// (in bytes) starting at the specified position.
+//
+ {
+
+ return RLocalDrive::Reduce(aPos, aLength);
+ }
+
+
+
+
+/**
+Attempt to unlock a password-enabled drive and optionally store the password in the password store.
+
+@param aPassword A descriptor containing the password data.
+@param aStorePassword If ETrue, the password is added to the password store.
+
+@return KErrNone, if successful.
+ KErrAlreadyExists, if the drive is already unlocked.
+ KErrAccessDenied, if the drive unlock operation fails.
+
+@see TBusLocalDrive::SetPassword
+@see TBusLocalDrive::Clear
+@see TBusLocalDrive::ErasePassword
+*/
+EXPORT_C TInt TBusLocalDrive::Unlock(const TDesC8& aPassword, TBool aStorePassword)
+ {
+ TInt err = CheckMount();
+ if (err != KErrNone)
+ return err;
+
+ if (!(Status() & KMediaAttLocked))
+ return KErrAlreadyExists;
+
+ err = RLocalDrive::Unlock(aPassword, aStorePassword);
+
+ if(err == KErrLocked)
+ err = KErrAccessDenied;
+
+ return err;
+ }
+
+
+
+
+/**
+Attempt to lock password-enabled drive and optionally store the new password in the password store.
+
+@param aOldPassword A descriptor containing old password.
+@param aNewPassword A descriptor containing new password.
+@param aStorePassword If ETrue, the password is added to the password store.
+
+@return KErrNone, if successful.
+ KErrAccessDenied, if the drive is already locked or the old password is incorrect.
+
+@see TBusLocalDrive::Unlock
+@see TBusLocalDrive::Clear
+@see TBusLocalDrive::ErasePassword
+*/
+EXPORT_C TInt TBusLocalDrive::SetPassword(const TDesC8& aOldPassword, const TDesC8& aNewPassword, TBool aStorePassword)
+ {
+ TInt err = CheckMount();
+ if (err != KErrNone)
+ return err;
+
+ if (Status() & KMediaAttLocked)
+ return KErrAccessDenied;
+
+ err = RLocalDrive::SetPassword(aOldPassword, aNewPassword, aStorePassword);
+ if(err == KErrLocked)
+ err = KErrAccessDenied;
+
+ return err;
+ }
+
+
+
+
+/**
+Clears a password from a card - controller sets password to null.
+volume will not be password-enabled next time it is powered up.
+The password is cleared from the password store.
+
+@param aPassword A descriptor containing the password.
+
+@return KErrNone, if successful.
+ KErrAccessDenied, if the drive is already locked or the password is incorrect.
+
+@see TBusLocalDrive::Unlock
+@see TBusLocalDrive::SetPassword
+@see TBusLocalDrive::ErasePassword
+*/
+EXPORT_C TInt TBusLocalDrive::Clear(const TDesC8& aPassword)
+ {
+ TInt err = CheckMount();
+ if (err != KErrNone)
+ return err;
+
+ if (Status() & KMediaAttLocked)
+ return KErrAccessDenied;
+
+ err = RLocalDrive::Clear(aPassword);
+ if(err == KErrLocked)
+ err = KErrAccessDenied;
+
+ return err;
+ }
+
+
+
+
+/**
+Forcibly unlock a password-enabled drive.
+KErrAccessDenied is returned if the drive is already mounted (and therefore unlocked)
+or if the drive is not already mounted and the operation fails.
+
+@return KErrNone, if successful.
+ KErrAccessDenied, if the drive is not locked or the operation is not supported.
+
+@see TBusLocalDrive::Unlock
+@see TBusLocalDrive::SetPassword
+@see TBusLocalDrive::ErasePassword
+*/
+EXPORT_C TInt TBusLocalDrive::ErasePassword()
+ {
+ TInt err = CheckMount();
+ if (err != KErrNone)
+ return err;
+
+ if (!(Status() & KMediaAttLocked))
+ return KErrAccessDenied;
+
+ err = RLocalDrive::ErasePassword();
+ if(err != KErrNone)
+ err = KErrAccessDenied;
+
+ return err;
+ }
+
+
+
+
+TInt TBusLocalDrive::CheckMount()
+//
+// Check the local drive can be, or is mounted
+//
+ {
+ TLocalDriveCaps caps;
+ TPckg<TLocalDriveCaps> capsPckg(caps);
+ TInt err = RLocalDrive::Caps(capsPckg);
+ iStatus = caps.iMediaAtt;
+ return err;
+ }
+
+
+
+/**
+Write the password store to the peripheral bus controller.
+
+@return
+ - KErrNone if Successful
+ - KErrOverflow If aBuf is longer than TPasswordStore::EMaxPasswordLength
+ - KErrCorrupt If store in aBuf is malformed.
+
+@param aBuf Data to replace the current password store.
+*/
+EXPORT_C TInt TBusLocalDrive::WritePasswordData(const TDesC8& aBuf)
+ {
+ return RLocalDrive::WritePasswordData(aBuf);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::ReadPasswordData(TDes8& aBuf)
+//
+// Read the entire password store from the peripheral bus controller.
+//
+ {
+ return RLocalDrive::ReadPasswordData(aBuf);
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::PasswordStoreLengthInBytes()
+//
+// Return the number of bytes used by peripheral bus controller password store.
+//
+ {
+ return RLocalDrive::PasswordStoreLengthInBytes();
+ }
+
+
+
+
+EXPORT_C TInt TBusLocalDrive::DeleteNotify(TInt64 aPos, TInt aLength)
+//
+// Notify the media driver that an area of the partition has been deleted.
+// This is used by certain media (e.g NAND flash) for garbage collection.
+//
+ {
+ return RLocalDrive::DeleteNotify(aPos, aLength);
+ }
+
+
+/**
+Query a property of the media device
+
+@prototype
+@internalTechnology
+*/
+EXPORT_C TInt TBusLocalDrive::QueryDevice(TQueryDevice aQueryDevice, TDes8 &aBuf)
+ {
+ return RLocalDrive::QueryDevice(aQueryDevice, aBuf);
+ }
+
+
+EXPORT_C void User::__DbgMarkStart(TBool aKernel)
+/**
+Marks the start of heap cell checking for the current thread's default heap,
+or for the kernel heap.
+
+If earlier calls to __DbgMarkStart() have been made, then this
+call to __DbgMarkStart() marks the start of a new nested level of
+heap cell checking.
+
+Every call to __DbgMarkStart() should be matched by a later call
+to __DbgMarkEnd() to verify that the number of heap cells allocated, at
+the current nested level, is as expected.
+This expected number of heap cells is passed to __DbgMarkEnd()
+as a parameter; however, the most common expected number is zero, reflecting
+the fact that the most common requirement is to check that all memory allocated
+since a previous call to __DbgStartCheck() has been freed.
+
+@param aKernel ETrue, if checking is being done for the kernel heap;
+ EFalse, if checking is being done for the current thread's
+ default heap.
+*/
+ {
+
+ if (aKernel)
+ Exec::KernelHeapDebug(EDbgMarkStart,0,NULL);
+ else
+ GetHeap()->__DbgMarkStart();
+ }
+
+
+
+
+EXPORT_C void User::__DbgMarkCheck(TBool aKernel, TBool aCountAll, TInt aCount, const TUint8* aFileName, TInt aLineNum)
+//
+// Call CheckNum for the default heap
+//
+/**
+Checks the current number of allocated heap cells for the current thread's default
+heap, or the kernel heap.
+
+If aCountAll is true, the function checks that the total number of
+allocated cells on the heap is the same as aCount. If aCountAll is false,
+the function checks that the number of allocated cells at the current nested
+level is the same as aCount.
+
+If checking fails, the function raises a panic. Information about the failure
+is put into the panic category, which takes the form:
+
+ALLOC COUNT\\rExpected aaa\\rAllocated bbb\\rLn: ccc ddd
+
+Where aaa is the value aCount, bbb is the number of allocated heap cells,
+ccc is a line number, copied from aLineNum, and ddd is a file name, copied
+from the descriptor aFileName.
+
+Note that the panic number is 1.
+
+@param aKernel ETrue, if checking is being done for the kernel heap;
+ EFalse, if checking is being done for the current thread's
+ default heap.
+@param aCountAll If true, the function checks that the total number of
+ allocated cells on the heap is the same as aCount.
+ If false, the function checks that the number of allocated
+ cells at the current nested level is the same as aCount.
+@param aCount The expected number of allocated cells.
+@param aFileName A filename; this is displayed as part of the panic category,
+ if the check fails.
+@param aLineNum A line number; this is displayed as part of the panic category,
+ if the check fails.
+*/
+ {
+
+ if (!aKernel)
+ GetHeap()->__DbgMarkCheck(aCountAll,aCount,aFileName,aLineNum);
+ else
+ {
+ TPtrC8 filename(aFileName);
+ TKernelHeapMarkCheckInfo info;
+ info.iCountAll=aCountAll;
+ info.iFileName=&filename;
+ info.iLineNum=aLineNum;
+ Exec::KernelHeapDebug(EDbgMarkCheck,aCount,&info);
+ }
+ }
+
+
+
+
+EXPORT_C TUint32 User::__DbgMarkEnd(TBool aKernel, TInt aCount)
+//
+// Call CheckHeap for the default heap
+//
+/**
+Marks the end of heap cell checking at the current nested level for the current
+thread's default heap, or the kernel heap.
+
+The function checks that the number of heap cells allocated, at the current
+nested level, is aCount. The most common value for aCount is zero, reflecting
+the fact that the most common requirement is to check that all memory allocated
+since a previous call to __DbgStartCheck() has been freed.
+
+A call to this function should match an earlier call to __DbgMarkStart().
+If there are more calls to this function than calls to __DbgMarkStart(), then
+this function raises a USER 51 panic.
+
+If the check fails for a user heap, the function raises an ALLOC: nnnnnnnn
+panic, where nnnnnnnn is a hexadecimal pointer to the first orphaned heap
+cell.
+
+If the check fails for the kernel heap, the kernel server raises a KERN-EXEC 17
+panic.
+
+@param aKernel ETrue, if checking is being done for the kernel heap;
+ EFalse, if checking is being done for the current thread's
+ default heap.
+@param aCount The number of allocated heap cells expected.
+
+@return Zero always.
+*/
+ {
+
+ if (!aKernel)
+ {
+ TUint32 badCell=GetHeap()->__DbgMarkEnd(aCount);
+ if (badCell!=0)
+ {
+ TBuf<0x10> info=_L("ALLOC: ");
+ info.AppendFormat(_L("%x\n"), badCell);
+ User::Panic(info,0);
+ }
+ return(badCell);
+ }
+ else
+ Exec::KernelHeapDebug(EDbgMarkEnd,aCount,NULL);
+ return(0);
+ }
+
+
+
+
+EXPORT_C void User::__DbgSetAllocFail(TBool aKernel, RAllocator::TAllocFail aType, TInt aRate)
+//
+// Set the failure rate for allocating from the default user heap
+//
+/**
+Simulates a heap allocation failure for the current thread's default heap,
+or the kernel heap.
+
+The failure occurs on subsequent calls to new or any of the functions which
+allocate memory from the heap.
+
+The timing of the allocation failure depends on the type of allocation failure
+requested, i.e. on the value of aType.
+
+The simulation of heap allocation failure is cancelled if aType is given
+the value RAllocator::ENone.
+
+Notes:
+
+1. If the failure type is RHeap::EFailNext, the next attempt to allocate from
+ the heap fails; however, no further failures will occur.
+
+2. For failure types RHeap::EFailNext and RHeap::ENone, set aRate to 1.
+
+@param aKernel ETrue, if checking is being done for the kernel heap;
+ EFalse, if checking is being done for the current thread's
+ default heap.
+@param aType An enumeration which indicates how to simulate heap
+ allocation failure.
+@param aRate The rate of failure; when aType is RAllocator::EDeterministic,
+ heap allocation fails every aRate attempts.
+*/
+ {
+
+ if (aKernel)
+ Exec::KernelHeapDebug(EDbgSetAllocFail,aType,(TAny*)aRate);
+ else
+ GetHeap()->__DbgSetAllocFail(aType,aRate);
+ }
+
+/**
+Simulates a heap allocation failure for the current thread's default heap,
+or the kernel heap.
+
+The aBurst failures will occur after subsequent calls to new or any of the
+functions which allocate memory from the heap.
+
+The timing of the allocation failures will depend on the type of allocation failure
+requested, i.e. on the value of aType.
+
+The simulation of heap allocation failure is cancelled if aType is given
+the value RAllocator::ENone.
+
+
+@param aKernel ETrue, if checking is being done for the kernel heap;
+ EFalse, if checking is being done for the current thread's
+ default heap.
+@param aType An enumeration which indicates how to simulate heap
+ allocation failure.
+@param aRate The rate of failure; when aType is RAllocator::EDeterministic,
+ heap allocation fails every aRate attempts.
+@param aBurst The number of consecutive allocations that should fail.
+
+*/
+EXPORT_C void User::__DbgSetBurstAllocFail(TBool aKernel, RAllocator::TAllocFail aType, TUint aRate, TUint aBurst)
+ {
+ if (aKernel)
+ {
+ SRAllocatorBurstFail burstFail;
+ burstFail.iRate = aRate;
+ burstFail.iBurst = aBurst;
+ Exec::KernelHeapDebug(EDbgSetBurstAllocFail, aType, (TAny*)&burstFail);
+ }
+ else
+ GetHeap()->__DbgSetBurstAllocFail(aType, aRate, aBurst);
+ }
+
+
+/**
+Returns the number of heap allocation failures the current debug allocator fail
+function has caused so far.
+
+This is intended to only be used with fail types RAllocator::EFailNext,
+RAllocator::EBurstFailNext, RAllocator::EDeterministic and
+RAllocator::EBurstDeterministic. The return value is unreliable for
+all other fail types.
+
+@return The number of heap allocation failures the current debug fail
+function has caused.
+
+@see RAllocator::TAllocFail
+*/
+EXPORT_C TUint User::__DbgCheckFailure(TBool aKernel)
+ {
+ TUint r;
+ if (aKernel)
+ Exec::KernelHeapDebug(EDbgCheckFailure, 0, (TAny*)&r);
+ else
+ r = GetHeap()->__DbgCheckFailure();
+ return r;
+ }
+
+EXPORT_C TInt RProcess::Create(const TDesC &aFileName,const TDesC &aCommand,TOwnerType aType)
+/**
+Starts a new process, loading the specified executable.
+
+The executable can be in ROM or RAM.
+
+By default, ownership of this process handle is vested in the current process,
+but can be vested in the current thread by specifying EOwnerThread as the
+third parameter to this function.
+
+@param aFileName A descriptor containing the full path name of the executable
+ to be loaded. If this name has no file extension,
+ an extension of .EXE is appended. The length of the resulting
+ full path name must not be greater than KMaxFileName.
+ The length of the file name itself must not be greater
+ than KMaxProcessName. If no path is specified, the system will
+ look in \\sys\\bin on all drives.
+@param aCommand A descriptor containing data passed as an argument to
+ the thread function of the new process's main thread,
+ when it is first scheduled.
+@param aType Defines the ownership of this process handle. If not
+ specified, EOwnerProcess is the default.
+
+@return KErrNone if successful, otherwise one of the other system-wide error codes.
+*/
+ {
+
+ return Create(aFileName, aCommand, TUidType(), aType);
+ }
+
+
+
+
+EXPORT_C TInt RProcess::Create(const TDesC &aFileName,const TDesC &aCommand,const TUidType &aUidType, TOwnerType aType)
+/**
+Starts a new process, loading the specified executable which matches
+the specified UID type.
+
+The executable can be in ROM or RAM.
+
+By default, ownership of this process handle is vested in the current process,
+but can be vested in the current thread by specifying EOwnerThread as the
+fourth parameter.
+
+@param aFileName A descriptor containing the full path name of the executable
+ to be loaded. If this name has no file extension,
+ an extension of .EXE is appended. The length of the resulting
+ full path name must not be greater than KMaxFileName.
+ The length of the file name itself must not be greater
+ than KMaxProcessName. If no path is specified, the system will
+ look in \\sys\\bin on all drives.
+@param aCommand A descriptor containing data passed as an argument to
+ the thread function of the new process's main thread,
+ when it is first scheduled.
+@param aUidType A UID type (a triplet of UIDs) which the executable must match.
+@param aType Defines the ownership of this process handle. If not specified,
+ EOwnerProcess is the default.
+
+@return KErrNone if successful, otherwise one of the other system-wide error
+ codes.
+*/
+ {
+
+ RLoader loader;
+ TInt r=loader.Connect();
+ if (r==KErrNone)
+ r=loader.LoadProcess(iHandle,aFileName,aCommand,aUidType,aType);
+ loader.Close();
+ return r;
+ }
+
+
+EXPORT_C TInt RProcess::CreateWithStackOverride(const TDesC& aFileName,const TDesC& aCommand, const TUidType &aUidType, TInt aMinStackSize, TOwnerType aType)
+/**
+Starts a new process, loading the specified executable which matches
+the specified UID type and the minimum stack size is the specified value.
+
+The executable can be in ROM or RAM.
+
+By default, ownership of this process handle is vested in the current process,
+but can be vested in the current thread by specifying EOwnerThread as the
+fourth parameter.
+
+
+@param aFileName A descriptor containing the full path name of the executable
+ to be loaded. If this name has no file extension,
+ an extension of .EXE is appended. The length of the resulting
+ full path name must not be greater than KMaxFileName.
+ The length of the file name itself must not be greater
+ than KMaxProcessName. If no path is specified, the system will
+ look in \\sys\\bin on all drives.
+@param aCommand A descriptor containing data passed as an argument to
+ the thread function of the new process's main thread,
+ when it is first scheduled.
+@param aUidType A UID type (a triplet of UIDs) which the executable must match.
+@param aMinStackSize Minimum stack size of the new process.
+@param aType Defines the ownership of this process handle. If not specified,
+ EOwnerProcess is the default.
+
+@return KErrNone if successful, otherwise one of the other system-wide error
+ codes.
+*/
+ {
+
+ RLoader loader;
+ TInt r=loader.Connect();
+ if (r==KErrNone)
+ {
+ r=loader.LoadProcess(iHandle,aFileName,aCommand,aUidType,aMinStackSize,aType);
+ }
+ loader.Close();
+ return r;
+ }
+
+
+
+EXPORT_C TInt User::LoadLogicalDevice(const TDesC &aFileName)
+/**
+Loads the logical device driver (LDD) DLL with the specified filename.
+
+The function searches the system path for the LDD DLL, and loads it. It then
+makes a kernel server call that:
+
+1. creates the LDD factory object, an instance of a DLogicalDevice derived
+ class; this involves checking the first UID value to make sure that the DLL
+ is a valid LDD before proceeding to call the exported function at
+ ordinal 1, which creates the LDD factory object on the kernel heap
+
+2. calls the LDD factory object's Install() function to complete the installation
+
+3. adds the new LDD factory object to the kernel's list of LDD factory objects.
+
+@param aFileName A reference to the descriptor containing the name of the
+ physical device driver DLL. If the filename has no extension,
+ .LDD is assumed by default.
+
+@return KErrNone if successful or one of the system-wide error codes.
+*/
+ {
+ RLoader loader;
+ return loader.LoadDeviceDriver(aFileName, 0);
+ }
+
+
+
+
+EXPORT_C TInt User::FreeLogicalDevice(const TDesC &aDeviceName)
+/**
+Frees the logical device driver DLL associated with a specified driver name.
+
+@param aDeviceName The name of the logical device driver object. This must
+ match the name set during installation of the logical
+ device. Typically, this is done in an implementation
+ of DLogicalDevice::Install() through a call to SetName().
+ Note that the name is rarely the same as the device's
+ filename. The name of a logical device driver object
+ can be discovered by using TFindLogicalDevice.
+
+@return KErrNone if successful or one of the system-wide error codes. KErrNone
+ will be returned if the device is not found as it may have already been
+ freed.
+*/
+ {
+ TBuf8<KMaxFullName> aDeviceName8;
+ aDeviceName8.Copy(aDeviceName);
+ return Exec::DeviceFree(aDeviceName8,0);
+ }
+
+
+
+
+EXPORT_C TInt User::LoadPhysicalDevice(const TDesC &aFileName)
+/**
+Loads the physical device driver (PDD) DLL with the specified filename.
+
+The function searches the system path for the PDD DLL, and loads it. It then
+makes a kernel server call that:
+
+1. creates the PDD factory object, an instance of a DPhysicalDevice derived class;
+ this involves checking the first UID value to make sure that the DLL is a
+ valid PDD before proceeding to call the exported function at ordinal 1, which
+ creates the PDD factory object on the kernel heap
+
+2. calls the PDD factory object's Install() function to complete the installation
+
+2. adds the new PDD factory object to the kernel's list of PDD factory objects.
+
+@param aFileName A reference to the descriptor containing the name of the
+ physical device driver DLL. If the filename has no extension,
+ .PDD is assumed by default.
+
+@return KErrNone if successful or one of the system-wide error codes.
+*/
+ {
+ RLoader loader;
+ return loader.LoadDeviceDriver(aFileName, 1);
+ }
+
+
+
+
+/**
+Frees the physical device driver DLL associated with a specified driver name.
+
+@param aDeviceName The name of the physical device driver object. This must
+ match the name set during installation of the physical
+ device. Typically, this is done in an implementation of
+ DPhysicalDevice::Install() through a call to SetName().
+ Note that the name is rarely the same as the device's
+ filename. The name of a physical device driver object can
+ be discovered by using TFindPhysicalDevice.
+
+@return KErrNone if successful or one of the system-wide error codes. KErrNone
+ will be returned if the device is not found as it may have already
+ been freed.
+*/
+EXPORT_C TInt User::FreePhysicalDevice(const TDesC &aDeviceName)
+
+ {
+ TBuf8<KMaxFullName> aDeviceName8;
+ aDeviceName8.Copy(aDeviceName);
+ return Exec::DeviceFree(aDeviceName8,1);
+ }
+
+
+
+
+EXPORT_C TInt RLoader::Connect()
+//
+// Connect with the loader.
+//
+ {
+ _LIT(KLoaderServerName,"!Loader");
+ return CreateSession(KLoaderServerName,Version(),0);
+ }
+
+TVersion RLoader::Version() const
+//
+// Return the client side version number.
+//
+ {
+
+ return TVersion(KLoaderMajorVersionNumber,KLoaderMinorVersionNumber,KE32BuildVersionNumber);
+ }
+
+TInt RLoader::LoadProcess(TInt& aHandle, const TDesC& aFileName, const TDesC& aCommand, const TUidType& aUidType, TOwnerType aType)
+//
+// Execute another process.
+//
+ {
+
+ return (LoadProcess(aHandle, aFileName, aCommand, aUidType, KDefaultStackSize, aType));
+
+ }
+
+
+/**
+ Execute another process.
+
+ @param aHandle
+ @param aFileName
+ @param aCommand
+ @param aUidType
+ @param aMinStackSize
+ @param aType
+
+ @return
+ KErrNone if process created
+ KErrBadName if aFileName.Length() > KMaxFileName
+ KErrArgument if aMinStackSize < 0
+
+*/
+TInt RLoader::LoadProcess(TInt& aHandle, const TDesC& aFileName, const TDesC& aCommand, const TUidType& aUidType, TInt aMinStackSize, TOwnerType aType)
+ {
+
+ __IF_DEBUG(Print(_L("RLoader::LoadProcess started with %d bytes stack.\n"), aMinStackSize));
+
+ if( 0 > aMinStackSize )
+ return KErrArgument;
+
+ TLdrInfo info;
+ info.iRequestedUids=aUidType; // match these uids only
+ info.iOwnerType=aType;
+
+ info.iMinStackSize=aMinStackSize;
+
+ if (aFileName.Length()>KMaxFileName)
+ return KErrBadName;
+
+ TPckg<TLdrInfo> infoBuf(info);
+
+ TInt r = SendReceive(ELoadProcess, TIpcArgs((TDes8*)&infoBuf, (const TDesC*)&aFileName, (const TDesC*)&aCommand) );
+ aHandle = info.iHandle;
+ __IF_DEBUG(Print(_L("LoadProcess returning %d"),r));
+ return r;
+ }
+
+/**
+ Check if the hash for the given library exists and optionally validate it.
+
+ @param aFileName the same as for RLoader::LoadLibrary
+ @param aValidateHash if ETrue this function will validate library hash if it exists. Requires fully specified aFileName.
+
+ @return
+ KErrNotSupported this feature is not supported by the emulator
+ KErrNone if aValidateHash=EFalse, it means that the hash exists; if aValidateHash=ETrue, hash exists and valid,
+ KErrCorrupt if aValidateHash=ETrue, the library hash exists but NOT valid,
+ KErrNotFound no hash found
+ KErrArgument bad file name
+
+*/
+EXPORT_C TInt RLoader::CheckLibraryHash(const TDesC& aFileName, TBool aValidateHash/*=EFalse*/)
+ {
+ __IF_DEBUG(Print(_L("RLoader::CheckLibraryHash")));
+
+ TLdrInfo info;
+ TPckg<TLdrInfo> infoBuf(info);
+ info.iOwnerType=EOwnerThread;
+
+ TInt r = SendReceive(ECheckLibraryHash, TIpcArgs((TDes8*)&infoBuf, (const TDesC*)&aFileName, aValidateHash) );
+
+ return r;
+ }
+
+EXPORT_C TInt RLoader::LoadLibrary(TInt& aHandle, const TDesC& aFileName, const TDesC& aPath, const TUidType& aUidType, TUint32 aModuleVersion)
+//
+// Load a DLL
+//
+ {
+
+ __IF_DEBUG(Print(_L("RLoader::LoadLibrary")));
+ TLdrInfo info;
+ TPckg<TLdrInfo> infoBuf(info);
+ info.iRequestedUids=aUidType; // match these uids only
+ info.iOwnerType=EOwnerThread;
+ info.iRequestedVersion=aModuleVersion;
+ if (aFileName.Length()>KMaxFileName)
+ return KErrBadName;
+ aHandle=0;
+
+ TInt r=E32Loader::WaitDllLock();
+ if (r==KErrNone)
+ {
+ r = SendReceive(ELoadLibrary, TIpcArgs((TDes8*)&infoBuf, (const TDesC*)&aFileName, (const TDesC*)&aPath) );
+ aHandle=info.iHandle;
+ if (r!=KErrNone)
+ E32Loader::ReleaseDllLock();
+ }
+ __IF_DEBUG(Print(_L("LoadLibrary returning %d"),r));
+ return r;
+ }
+
+
+EXPORT_C TInt RLoader::GetInfo(const TDesC& aFileName, TDes8& aInfoBuf)
+//
+// Get capabilities of a DLL
+//
+ {
+ __IF_DEBUG(Print(_L("RLoader::GetInfo")));
+ TLdrInfo info;
+ TPckg<TLdrInfo> infoBuf(info);
+ info.iOwnerType=EOwnerThread;
+ if (aFileName.Length()>KMaxFileName)
+ return KErrBadName;
+ TInt r = SendReceive(EGetInfo, TIpcArgs((TDes8*)&infoBuf, (const TDesC*)&aFileName, (TDes8*)&aInfoBuf) );
+ __IF_DEBUG(Print(_L("GetInfo returning %d"),r));
+ return r;
+ }
+
+
+EXPORT_C TInt RLoader::Delete(const TDesC& aFileName)
+/**
+ Ask the loader to delete a file. This function should be used instead
+ of RFs::Delete where the supplied file may be a paged executable, although
+ it can be used for any file. A file that is currently paged may be moved
+ by the system, and deleted later, when the file is no longer needed. This means
+ that using this function may not immediately release the disk space associated
+ with the file.
+
+ @param aFileName Fully-qualified filename.
+ @return Symbian OS error code. Additionally, KErrBadName is
+ returned if the supplied filename is not fully qualified..
+ @capability Tcb
+ @capability AllFiles
+ */
+ {
+ __IF_DEBUG(Printf(">RLoader::Delete,%S", &aFileName));
+ TInt r = SendReceive(ELdrDelete, TIpcArgs(0, &aFileName));
+ __IF_DEBUG(Printf("<RLoader::Delete,%d", r));
+ return r;
+ }
+
+#ifdef __WINS__
+
+#include <emulator.h>
+
+TInt RLoader::GetInfoFromHeader(const TDesC8& aHeader, TDes8& aInfoBuf)
+ {
+ __IF_DEBUG(Print(_L("RLoader::GetInfoFromHeader")));
+
+ TInt r = KErrNone;
+
+ Emulator::TModule module;
+ module.iBase = aHeader.Ptr();
+ TProcessCreateInfo info;
+ module.GetInfo(info);
+
+ RLibrary::TInfoV2 ret_info;
+ memclr(&ret_info,sizeof(ret_info));
+ ret_info.iModuleVersion = info.iModuleVersion;
+ ret_info.iUids = info.iUids;
+ *(SSecurityInfo*)&ret_info.iSecurityInfo = info.iS;
+ ret_info.iHardwareFloatingPoint = EFpTypeNone;
+ TPckg<RLibrary::TInfoV2> ret_pckg(ret_info);
+ if (aInfoBuf.MaxLength() < ret_pckg.Length())
+ ret_pckg.SetLength(aInfoBuf.MaxLength());
+ aInfoBuf=ret_pckg;
+
+ __IF_DEBUG(Print(_L("GetInfoFromHeader returning %d"),r));
+ return r;
+ }
+
+#else // not __WINS__ ...
+
+TInt RLoader::GetInfoFromHeader(const TDesC8& aHeader, TDes8& aInfoBuf)
+ {
+ __IF_DEBUG(Print(_L("RLoader::GetInfoFromHeader")));
+ TInt r = SendReceive(EGetInfoFromHeader, TIpcArgs(&aHeader, &aInfoBuf) );
+ __IF_DEBUG(Print(_L("GetInfoFromHeader returning %d"),r));
+ return r;
+ }
+
+#endif // __WINS__
+
+TInt RLoader::LoadDeviceDriver(const TDesC& aFileName, TInt aDeviceType)
+ {
+ TInt r=Connect();
+ if (r==KErrNone)
+ {
+ TInt m = aDeviceType ? ELoadPhysicalDevice : ELoadLogicalDevice;
+ r = SendReceive(m, TIpcArgs(0, (const TDesC*)&aFileName, 0) );
+ Close();
+ }
+ return r;
+ }
+
+TInt RLoader::LoadLocale(const TDesC& aLocaleDllName, TLibraryFunction* aExportList)
+ {
+ TInt r=Connect();
+ if (r==KErrNone)
+ {
+ TInt size = KNumLocaleExports * sizeof(TLibraryFunction);
+ TPtr8 functionListBuf((TUint8*)aExportList, size, size);
+ r = SendReceive(ELoadLocale, TIpcArgs(0, (const TDesC*)&aLocaleDllName, &functionListBuf) );
+ Close();
+ }
+ return r;
+ }
+
+EXPORT_C TInt RLoader::DebugFunction(TInt aFunction, TInt a1, TInt a2, TInt a3)
+ {
+ return SendReceive(ELoaderDebugFunction, TIpcArgs(aFunction, a1, a2, a3) );
+ }
+
+EXPORT_C TInt RLoader::CancelLazyDllUnload()
+ {
+ return SendReceive(ELoaderCancelLazyDllUnload, TIpcArgs() );
+ }
+
+#ifdef __USERSIDE_THREAD_DATA__
+
+EXPORT_C TInt UserSvr::DllSetTls(TInt aHandle, TAny* aPtr)
+//
+// Set the value of the Thread Local Storage variable.
+//
+ {
+ return LocalThreadData()->DllSetTls(aHandle, KDllUid_Default, aPtr);
+ }
+
+EXPORT_C TInt UserSvr::DllSetTls(TInt aHandle, TInt aDllUid, TAny* aPtr)
+//
+// Set the value of the Thread Local Storage variable.
+//
+ {
+ return LocalThreadData()->DllSetTls(aHandle, aDllUid, aPtr);
+ }
+
+EXPORT_C void UserSvr::DllFreeTls(TInt aHandle)
+//
+// Remove the Thread Local Storage variable.
+//
+ {
+ return LocalThreadData()->DllFreeTls(aHandle);
+ }
+
+#else
+
+EXPORT_C TInt UserSvr::DllSetTls(TInt aHandle, TAny* aPtr)
+//
+// Set the value of the Thread Local Storage variable.
+//
+ {
+ return Exec::DllSetTls(aHandle, KDllUid_Default, aPtr);
+ }
+
+EXPORT_C TInt UserSvr::DllSetTls(TInt aHandle, TInt aDllUid, TAny* aPtr)
+//
+// Set the value of the Thread Local Storage variable.
+//
+ {
+ return Exec::DllSetTls(aHandle, aDllUid, aPtr);
+ }
+
+EXPORT_C void UserSvr::DllFreeTls(TInt aHandle)
+//
+// Remove the Thread Local Storage variable.
+//
+ {
+ Exec::DllFreeTls(aHandle);
+ }
+
+#endif
+
+
+
+
+EXPORT_C TInt RChangeNotifier::Create()
+/**
+Creates a change notifier, and opens this handle to that change notifier.
+
+Ownership of this change notifier is vested in the current process.
+
+@return KErrNone if successful, otherwise one of the other system-wide error codes.
+*/
+ {
+ return SetReturnedHandle(Exec::ChangeNotifierCreate(EOwnerProcess),*this);
+ }
+
+
+
+
+EXPORT_C TInt RUndertaker::Create()
+/**
+Creates a thread-death notifier, and opens this handle to
+that thread-death notifier.
+
+Ownership of this thread-death notifier is vested in the current process.
+
+@return KErrNone, if successful; otherwise one of
+ the other system-wide error codes.
+*/
+ {
+ return SetReturnedHandle(Exec::UndertakerCreate(EOwnerProcess),*this);
+ }
+
+
+
+
+EXPORT_C TInt RUndertaker::Logon(TRequestStatus& aStatus, TInt& aThreadHandle) const
+/**
+Issues a request for notification of the death of a thread.
+
+When another thread dies, the request completes and the TRequestStatus object
+contains the value KErrDied; in addition, aThreadHandle contains
+the handle-number of the dying thread.
+
+The requesting thread can construct a proper handle for the dying thread
+using the code:
+
+@code
+{
+RThread r;
+r.SetHandle(aThreadHandle);
+...r.Close();
+}
+@endcode
+
+Alternatively, if an outstanding request is cancelled by a call
+to LogonCancel(), then the request completes with the value KErrCancel.
+
+Note that if a request completes normally, i.e. not as a result of
+a LogonCancel(), then the handle to the dying thread must be closed
+when there is no further interest in it.
+
+@param aStatus A reference to the request status object.
+@param aThreadHandle The handle-number representing the dying thread.
+
+@return KErrInUse if there is an outstanding request; KErrNone otherwise.
+
+@see RUndertaker::LogonCancel()
+*/
+ {
+ aStatus=KRequestPending;
+ return Exec::UndertakerLogon(iHandle,aStatus,aThreadHandle);
+ }
+
+
+
+
+EXPORT_C TInt RUndertaker::LogonCancel() const
+/**
+Cancels an outstanding notification request to the thread-death notifier.
+
+@return KErrGeneral, if there is no outstanding notification request; KErrNone otherwise.
+
+@see RUndertaker::Logon()
+*/
+ {
+ return Exec::UndertakerLogonCancel(iHandle);
+ }
+
+
+
+
+/**
+Sets the machine configuration.
+
+@param aConfig Descriptor containing the machine configuration data
+
+@return KErrNone, if sucessful, otherwise one of the other system-wide
+ error codes.
+
+@capability WriteDeviceData
+*/
+EXPORT_C TInt User::SetMachineConfiguration(const TDesC8& aConfig)
+ {
+ return Exec::SetMachineConfiguration(aConfig);
+ }
+
+
+
+
+EXPORT_C TInt User::CompressAllHeaps()
+/**
+Compresses all the chunks containing heaps.
+
+@deprecated This function is no longer supported, and calling it has no effect.
+
+@return KErrNone
+*/
+ {
+
+ return KErrNone; // don't do this any more
+ }
+
+
+
+
+EXPORT_C TInt UserSvr::ChangeLocale(const TDesC& aLocaleDllName)
+ {
+ if(aLocaleDllName.Length() == 0)
+ {
+ //support reverting to defaults
+ TInt r = UserSvr::LocalePropertiesSetDefaults();
+ if(r == KErrNone)
+ Exec::SetUTCTimeAndOffset(0,0,ETimeSetOffset,EChangesLocale);
+ return r;
+ }
+ TExtendedLocale locale;
+ TInt r = locale.LoadLocale(aLocaleDllName);
+ if(r == KErrNone)
+ {
+ r = locale.SaveSystemSettings();
+ }
+ return r;
+ }
+
+EXPORT_C TInt UserSvr::ResetMachine(TMachineStartupType aType)
+//
+// Reset the machine. Currently only aType==EStartupWarmReset is supported.
+//
+ {
+
+ return Exec::ResetMachine(aType);
+ }
+