diff -r 000000000000 -r a41df078684a kernel/eka/euser/us_ksvr.cpp --- /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 +#include +#include + +//#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()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 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 name8; + name8.Copy(aLogicalDevice); + + TBuf8 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 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(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(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 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 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 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 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 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 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 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 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 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 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 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)< 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 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 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 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 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 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 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 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(" + +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 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); + } +