kernel/eka/include/kernel/kernel.h
changeset 0 a41df078684a
child 4 56f325a607ea
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/kernel/kernel.h	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,2968 @@
+// Copyright (c) 1994-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\include\kernel\kernel.h
+// Public header for device drivers
+// 
+// WARNING: This file contains some APIs which are internal and are subject
+//          to change without notice. Such APIs should therefore not be used
+//          outside the Kernel and Hardware Services package.
+//
+
+
+#ifndef __K32STD_H__
+#define __K32STD_H__
+
+#include <kernel/klib.h>
+#include <e32kpan.h>
+#include <u32std.h>
+#include <e32ldr.h>
+#include <e32event.h>
+#include <e32event_private.h>
+#include <d32locd.h>
+#include <kernel/localise.h>
+#include <nkern.h>
+#include <kernel/sproperty.h>
+
+class DObject;
+class DObjectCon;
+class DThread;
+class DCodeSeg;
+class DProcess;
+class DLibrary;
+class DMutex;
+class DSemaphore;
+class DChunk;
+class DShPool;
+class DShBuf;
+
+
+/** Data type for physical addresses
+@publishedPartner
+@released
+*/
+typedef TUint32 TPhysAddr;
+
+
+/**
+A constant representing an invalid physical address.
+@publishedPartner
+@released
+*/
+const TPhysAddr KPhysAddrInvalid=0xFFFFFFFFu;
+
+
+/** @internalComponent */
+_LIT(KLitKernExec, "KERN-EXEC");
+
+/********************************************
+ * HAL entry array
+ ********************************************/
+
+/** @internalTechnology */
+const TInt KMaxHalGroups=32;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Defines the signature for a HAL handler function.
+*/
+typedef TInt (*THalFunc)(TAny*,TInt,TAny*,TAny*);
+
+/** @internalTechnology */
+const TInt KMaxHalEntries=8;
+
+/** @internalTechnology */
+struct SHalEntry
+	{
+	THalFunc iFunction;
+	TAny* iPtr;
+	};
+
+/** @internalTechnology */
+struct SHalEntry2 : public SHalEntry
+	{
+	SHalEntry* iExtendedEntries;
+	};
+
+/********************************************
+ * Exports from layer 1 of the kernel
+ ********************************************/
+class TThreadMessage;
+class DObjectCon;
+class DPowerModel;
+class TSuperPage;
+class TMachineConfig;
+
+/********************************************
+ * Thread creation info block
+ ********************************************/
+
+/**
+@publishedPartner
+@released
+
+Defines a set of thread types.
+*/
+enum TThreadType
+	{
+	/** The thread is the initial thread
+		@internalComponent
+	*/
+	EThreadInitial,
+
+	/** The thread runs in supervisor mode */
+	EThreadSupervisor,
+
+	/** The thread runs in supervisor mode and has no handles array */
+	EThreadMinimalSupervisor,
+
+	/** The thread runs in user mode */
+	EThreadUser,
+
+	/** The thread is the initial thread on a non-boot processor (SMP only)
+		@internalComponent
+	*/
+	EThreadAPInitial,
+	};
+
+/********************************************
+ * Kernel Mutex Ordering
+ ********************************************/
+const TUint8 KMutexOrdNone				= 0xff; /**< @internalComponent */
+const TUint8 KMutexOrdUser				= 0xfe; /**< @internalComponent */
+
+/**
+Mutex order value for general purpose use. This value is higher than any used internally
+by the kernel, therefore there are no mutex ordering restrictions that limit which kernel
+functions may be called whilst a mutex of this order is held.
+@see Kern::MutexCreate()
+@publishedPartner
+@released
+*/
+const TUint8 KMutexOrdGeneral7			= 0xf7;
+
+/**
+Mutex order value for general purpose use. This value is higher than any used internally
+by the kernel, therefore there are no mutex ordering restrictions that limit which kernel
+functions may be called whilst a mutex of this order is held.
+@see Kern::MutexCreate()
+@publishedPartner
+@released
+*/
+const TUint8 KMutexOrdGeneral6			= 0xf6;
+
+/**
+Mutex order value for general purpose use. This value is higher than any used internally
+by the kernel, therefore there are no mutex ordering restrictions that limit which kernel
+functions may be called whilst a mutex of this order is held.
+@see Kern::MutexCreate()
+@publishedPartner
+@released
+*/
+const TUint8 KMutexOrdGeneral5			= 0xf5;
+
+/**
+Mutex order value for general purpose use. This value is higher than any used internally
+by the kernel, therefore there are no mutex ordering restrictions that limit which kernel
+functions may be called whilst a mutex of this order is held.
+@see Kern::MutexCreate()
+@publishedPartner
+@released
+*/
+const TUint8 KMutexOrdGeneral4			= 0xf4;
+
+/**
+Mutex order value for general purpose use. This value is higher than any used internally
+by the kernel, therefore there are no mutex ordering restrictions that limit which kernel
+functions may be called whilst a mutex of this order is held.
+@see Kern::MutexCreate()
+@publishedPartner
+@released
+*/
+const TUint8 KMutexOrdGeneral3			= 0xf3;
+
+/**
+Mutex order value for general purpose use. This value is higher than any used internally
+by the kernel, therefore there are no mutex ordering restrictions that limit which kernel
+functions may be called whilst a mutex of this order is held.
+@see Kern::MutexCreate()
+@publishedPartner
+@released
+*/
+const TUint8 KMutexOrdGeneral2			= 0xf2;
+
+/**
+Mutex order value for general purpose use. This value is higher than any used internally
+by the kernel, therefore there are no mutex ordering restrictions that limit which kernel
+functions may be called whilst a mutex of this order is held.
+@see Kern::MutexCreate()
+@publishedPartner
+@released
+*/
+const TUint8 KMutexOrdGeneral1			= 0xf1;
+
+/**
+Mutex order value for general purpose use. This value is higher than any used internally
+by the kernel, therefore there are no mutex ordering restrictions that limit which kernel
+functions may be called whilst a mutex of this order is held.
+@see Kern::MutexCreate()
+@publishedPartner
+@released
+*/
+const TUint8 KMutexOrdGeneral0			= 0xf0;
+
+
+const TUint8 KMutexOrdRamDrive			= KMutexOrdGeneral7; /**< @internalComponent */
+const TUint8 KMutexOrdShPool			= 0x68; /**< @internalComponent */
+const TUint8 KMutexOrdCodeSegLock		= 0x60; /**< @internalComponent */
+const TUint8 KMutexOrdPubSub2			= 0x5e; /**< @internalComponent */
+
+/**
+@internalComponent
+@prototype
+*/
+const TUint8 KMutexOrdPageIn			= 0x5c;
+
+const TUint8 KMutexOrdRamDefrag			= 0x59; /**< @internalComponent */
+const TUint8 KMutexOrdPowerMgr			= 0x58; /**< @internalComponent */
+const TUint8 KMutexOrdPubSub			= 0x50; /**< @internalComponent */
+const TUint8 KMutexOrdProcessLock		= 0x48; /**< @internalComponent */
+const TUint8 KMutexOrdDebug				= 0x47; /**< @internalComponent */
+const TUint8 KMutexOrdTimer				= 0x40; /**< @internalComponent */
+const TUint8 KMutexOrdObjectCon2		= 0x38;	/**< @internalComponent */ // servers
+const TUint8 KMutexOrdHandle			= 0x30; /**< @internalComponent */
+const TUint8 KMutexOrdObjectCon			= 0x28; /**< @internalComponent */
+const TUint8 KMutexOrdMachineConfig		= 0x20; /**< @internalComponent */
+const TUint8 KMutexOrdHwChunk			= 0x10; /**< @internalComponent */
+const TUint8 KMutexOrdKernelHeap		= 0x08; /**< @internalComponent */
+const TUint8 KMutexOrdRamAlloc			= 0x04; /**< @internalComponent */
+#if defined(__MEMMODEL_FLEXIBLE__)
+const TUint8 KMutexOrdSyncPhysMem		= 0x03; /**< @internalComponent */
+#endif
+const TUint8 KMutexOrdPageOut			= 0x02; /**< @internalComponent */
+const TUint8 KMutexOrdResourceManager	= 0x01; /**< @internalComponent */
+
+
+/********************************************
+ * Kernel Extension Priority Ordering
+ ********************************************/
+
+/**
+@internalComponent
+@prototype 9.5
+*/
+const TUint8 KExtensionMaximumPriority = 0xff;
+
+/**
+@internalComponent
+@prototype 9.5
+*/
+const TUint8 KExtensionStandardPriority = 0;
+
+
+/**
+Defines a function type that implements a polling operation.
+
+A function of this type takes a single TAny* type argument, and returns
+a TBool type, and is passed as an argument to Kern::PollingWait().
+
+@see Kern::PollingWait()
+
+@publishedPartner
+@released
+*/
+typedef TBool (*TPollFunction)(TAny*);
+
+
+
+
+/**
+Structure used to specify parameters to Kern::ChunkCreate()
+@see Kern::ChunkCreate()
+@publishedPartner
+@released
+*/
+class TChunkCreateInfo
+    {
+public:
+    /**
+    Enumeration representing the type of chunk to be created.
+    */
+    enum TType
+        {
+        /**
+        A chunk which may only be opened by one user side process at a time.
+        Chunks of this type are slightly more efficient than the 
+        ESharedKernelMultiple type when used on the Moving Memory Model.
+        */
+        ESharedKernelSingle = 9,
+
+        /**
+        A chunk which may be opened by any number of user side processes.
+        */
+        ESharedKernelMultiple = 10,
+        };
+
+    /**
+    The chunk type to be created.
+    @see TChunkCreateInfo::TType
+    */
+    TType iType;
+
+    /**
+    The size of linear address space to reserve for this chunk.
+    */
+    TInt iMaxSize;
+
+    /**
+    Caching attributes for the chunks memory.
+
+    This is a value constructed from the TMappingAttributes values.
+    E.g. EMapAttrFullyBlocking (no caching) or EMapAttrCachedMax (full caching).
+
+    Note that if the MMU doesn't support the requested attributes then a lesser
+    cached attribute will be used. The actual value used is returned in aMapAttr of
+    Kern::ChunkCreate()
+
+    @see TMappingAttributes
+    */
+    TUint32 iMapAttr;
+
+    /**
+    Set to true if the chunk is to own its committed memory. In which case all
+    memory committed to the chunk will come from the system's free pool and will be
+    returned there when the chunk is destroyed.
+    */
+    TUint8 iOwnsMemory;
+
+    /**
+    @internalComponent
+    Reserved for future expansion.
+    */
+    TInt8 iSpare8[3];
+
+    /**
+    Pointer to a DFC which will be queued on destruction of chunk.
+    */
+    TDfc* iDestroyedDfc;
+
+    /**
+    @internalComponent
+    Reserved for future expansion.
+    */
+    TInt32 iSpare32[2];
+public:
+    /**
+    Constructor which zeros all member data.
+    */
+    inline TChunkCreateInfo()
+        { memset(this,0,sizeof(*this)); }
+    };
+
+
+
+/**
+Generic kernel hook function.
+@internalComponent
+*/
+typedef TInt (*TKernelHookFn)();
+
+/**
+Available kernel hooks.
+@internalComponent
+*/
+enum TKernelHookType
+	{
+	EHookTrace,
+	EHookNanoWait,
+	EHookInitialTime,
+	
+	ENumKernelHooks
+	};
+
+
+/*
+Specifies the origin of the log when calling trace handler hook.
+@publishedPartner
+@released
+*/
+enum TTraceSource
+	{
+	/**
+	User side tracing
+	@see User::DebugPrint
+	*/
+	EUserTrace,
+	/**
+	Kernel tracing
+	@see Kern::Print
+	*/
+	EKernelTrace,
+	/**
+	Platform security tracing
+	*/
+	EPlatSecTrace,
+	};
+
+/*
+Trace handler hook
+@param aText      Debug log. The content of the descriptor resides in kernel memory.
+@param aTraceType Identifies the origin of the debug log.
+@see TTraceHandlerType
+@return Specifies whether the log is processed or not.
+        If ETrue,  the log is processed. Kernel will drop the log (it won't be passed to trace port - UART)
+        If EFalse, the log is not processed. Kernel will pass the log to the trace port, as well.
+@publishedPartner
+@released
+*/
+typedef TBool (*TTraceHandler)(const TDesC8& /*aText*/, TTraceSource /*aTraceSource*/);
+
+
+/**
+Defines the prototype of the kernel hook for the Kern::NanoWait implementation.
+@see Kern::NanoWait
+@see Kern::SetNanoWaitHandler
+@publishedPartner
+@released
+*/
+typedef void (*TNanoWaitHandler)(TUint32 aInterval);
+
+
+/**
+Defines the prototype of the kernel hook to get the initial system time.
+
+The hook is called during boot to get the inital system time.  It should attempt
+to read the time from the hardware RTC.  If the contents of the RTC are invalid
+it should return KErrCorrupt.
+ 
+@return The time in seconds from 00:00:00 01-01-2000, or one of the
+system-wide error codes.
+
+@see Kern::SetInitialTimeHandler
+@see P::InitSystemTime
+@publishedPartner
+@released
+*/
+typedef TInt (*TInitialTimeHandler)();
+
+
+/**
+A thread's realtime state.
+
+Some non-realtime behaviour can be detected by the kernel. When it does so, action is taken
+depending on the thread state:
+   
+-	ERealtimeStateOff - no action.
+-	ERealtimeStateOn - the the thread will be panicked with KERN-EXEC 61 (EIllegalFunctionForRealtimeThread).
+-	ERealtimeStateWarn - no action. However, if the kernel trace flag KREALTIME is enabled
+	then tracing will be emitted as if the thread state was ERealtimeStateOn.
+
+@publishedPartner
+@released
+*/
+enum TThreadRealtimeState
+	{
+	ERealtimeStateOff,	/**< Thread is not realtime */
+	ERealtimeStateOn,	/**< Thread is realtime */
+	ERealtimeStateWarn	/**< Thread is realtime but doesn't want this enforced */
+	};
+
+
+/**
+A DFC queue intended to be created and destroyed as needed.
+
+This class extends the TDfcQue class with a destroy method.
+
+@publishedPartner
+@released
+*/
+class TDynamicDfcQue : public TDfcQue
+	{
+public:
+	TDynamicDfcQue();
+	IMPORT_C void Destroy();
+	IMPORT_C void SetRealtimeState(TThreadRealtimeState aNewState);
+private:	
+	TDfc iKillDfc;
+	};
+
+
+/**
+An object representing an asynchronous request from a user thread, containing a TRequestStatus
+pointer.
+
+It can be queued for completion when the thread next returns to user-mode, to move the impact of any
+page faults from the thread posting the completion to the thread that made the request.
+
+@publishedPartner
+@released
+*/
+class TClientRequest : public TUserModeCallback
+	{
+public:
+	IMPORT_C TInt SetStatus(TRequestStatus*);
+	IMPORT_C void Reset();
+	IMPORT_C TRequestStatus* StatusPtr();
+	IMPORT_C TBool IsReady();
+public:
+	void Close();
+protected:
+	enum TState
+		{
+		EFree,
+		EReady,
+		EInUse,
+		EClosing,
+		EBad
+		};
+	TClientRequest(TUserModeCallbackFunc aCallback = CallbackFunc);
+	~TClientRequest();
+	TState State();
+	static TState GetState(T_UintPtr aStatus);
+	TBool StartComplete(DThread* aThread, TInt aReason);
+	void EndComplete(DThread* aThread);
+	static void CallbackFunc(TAny* aData, TUserModeCallbackReason aReason);
+private:
+	static TDfc DeadClientCleanupDfc;
+	static void DoDeadClientCleanup(TAny*);
+private:
+	T_UintPtr MakeFree();
+public:
+	volatile T_UintPtr iStatus;		// holds TRequestStatus pointer and state flag bits
+	TInt iResult;
+	friend class Kern;
+	friend class K;
+	};
+
+
+/**
+Base classs for TClientDataRequest.
+
+@internalTechnology
+*/
+class TClientDataRequestBase : public TClientRequest
+	{
+public:
+	/**
+	Set the destination in the client's address space where the data will be copied to when the
+	request is completed.	
+	@publishedPartner
+	@released
+	*/
+	inline void SetDestPtr(TAny* aPtr) { iDestPtr = aPtr; } /**< */
+	/**
+	Get the destination address in the client's address space.
+	@publishedPartner
+	@released
+	*/
+	inline TAny* DestPtr() { return iDestPtr; }
+	/**
+	Get the local address of the buffer where the structure data will be held until it is copied to
+	the client.
+	@publishedPartner
+	@released
+	*/
+	inline TUint8* Buffer() { return (TUint8*)this + _ALIGN_UP(sizeof(*this), 8); }
+protected:
+	TClientDataRequestBase(TInt aBufferSize);
+	~TClientDataRequestBase() { }	// call Close(), don't delete
+	static void CallbackFunc(TAny* aData, TUserModeCallbackReason aReason);
+public:
+	TInt iSize;
+	TAny* iDestPtr;
+	friend class Kern;
+	};
+
+/**
+An object representing an asynchronous request from a user thread that involves copying a small
+fixed-size structure to the client.  It contains a TRequestStatus pointer and a buffer to hold the
+structure.
+
+It can be queued for completion when the thread next returns to user-mode, to move the impact of any
+page faults from the thread posting the completion to the thread that made the request.
+
+@publishedPartner
+@released
+*/
+template <class T>
+class TClientDataRequest : public TClientDataRequestBase
+	{
+public:
+	T& Data() { return *(T*)Buffer(); }
+private:
+	TClientDataRequest();
+	~TClientDataRequest();	// call Close(), don't delete
+	};
+
+/**
+Base classs for TClientDataRequest2.
+
+@prototype
+@internalTechnology
+*/
+class TClientDataRequestBase2 : public TClientRequest
+	{
+public:
+	inline void SetDestPtr1(TAny* aPtr) { iDestPtr1 = aPtr; }
+	inline TAny* DestPtr1() { return iDestPtr1; }
+	inline TUint8* Buffer1() { return (TUint8*)this + _ALIGN_UP(sizeof(*this), 8); }
+	inline void SetDestPtr2(TAny* aPtr) { iDestPtr2 = aPtr; }
+	inline TAny* DestPtr2() { return iDestPtr2; }
+	inline TUint8* Buffer2() { return Buffer1() + _ALIGN_UP(iSize1, 8); }
+protected:
+	TClientDataRequestBase2(TInt aBufferSize1, TInt aBufferSize2);
+	~TClientDataRequestBase2() { }	// call Close(), don't delete
+	static void CallbackFunc(TAny* aData, TUserModeCallbackReason aReason);
+public:
+	TInt iSize1;
+	TAny* iDestPtr1;
+	TInt iSize2;
+	TAny* iDestPtr2;
+	friend class Kern;
+	};
+
+/**
+An object representing an asynchronous request from a user thread that involves copying two small
+fixed-size structures to the client.  It contains a TRequestStatus pointer and two buffer to hold
+the structures.
+
+It can be queued for completion when the thread next returns to user-mode, to move the impact of any
+page faults from the thread posting the completion to the thread that made the request.
+
+@prototype
+@internalTechnology
+*/
+template <class T1, class T2>
+class TClientDataRequest2 : public TClientDataRequestBase2
+	{
+public:
+	T1& Data1() { return *(T1*)Buffer1(); }
+	T2& Data2() { return *(T2*)Buffer2(); }
+private:
+	TClientDataRequest2();
+	~TClientDataRequest2();	// call Close(), don't delete
+	};
+
+/**
+A parsed descriptor header.
+
+This has the same internal structure as TRawDesHeader but the header data is stored in a parsed
+representation.
+
+@see TRawDesHeader.
+
+@prototype
+@internalTechnology
+*/
+class TDesHeader
+	{
+public:
+	enum { KConstMaxLength = (TUint)KErrBadDescriptor };
+	inline TDesHeader();
+	/// Set the contents of this object
+	inline void Set(TUint32 aTypeAndLength, TLinAddr aDataPtr, TUint aMaxLength = KConstMaxLength);
+	/// Reset the object to its initial un-set state
+	inline void Unset();
+	/// Determine whether this object has been set to a valid descriptor header
+	inline TBool IsSet() const;
+	/// Set both type and length fields in one operation
+	inline void SetTypeAndLength(TUint32 aTypeAndLength);
+	// Accessors
+	inline const TUint32& TypeAndLength() const;
+	inline TDesType Type() const;
+	inline TInt Length() const;
+	inline TBool IsWriteable() const;
+	inline TInt MaxLength() const;
+	inline TLinAddr DataPtr() const;
+private:
+	enum { KUnsetFlag = 0xffffffff };
+	TUint32 iData[3];
+	};
+
+inline TDesHeader::TDesHeader()
+	{
+	iData[0] = (TUint32)KUnsetFlag;
+	}
+
+inline void TDesHeader::Set(TUint32 aTypeAndLength, TLinAddr aDataPtr, TUint aMaxLength)
+	{
+	iData[0] = aTypeAndLength;
+	iData[1] = aMaxLength;
+	iData[2] = aDataPtr;
+	}
+
+inline void TDesHeader::Unset()
+	{
+	iData[0] = (TUint32)KUnsetFlag;
+	}
+
+inline TBool TDesHeader::IsSet() const
+	{
+	return iData[0] != KUnsetFlag;
+	}
+
+inline void TDesHeader::SetTypeAndLength(TUint32 aTypeAndLength)
+	{
+	iData[0] = aTypeAndLength;
+	}
+
+inline const TUint32& TDesHeader::TypeAndLength() const
+	{
+	return iData[0];
+	}
+
+inline TDesType TDesHeader::Type() const
+	{
+	return (TDesType)(iData[0] >> KShiftDesType);
+	}
+
+inline TInt TDesHeader::Length() const
+	{
+	return (TInt)(iData[0] & KMaskDesLength);
+	}
+
+inline TBool TDesHeader::IsWriteable() const
+	{
+	return iData[1] != KConstMaxLength;
+	}
+
+inline TInt TDesHeader::MaxLength() const
+	{
+	return (TInt)iData[1];
+	}
+
+inline TLinAddr TDesHeader::DataPtr() const
+	{
+	return (TLinAddr)iData[2];
+	}
+
+/**
+An object representing a client buffer that resides in user-side memory.
+
+TClientBuffer objects can be used to specify memory to pin using Kern::PinVirtualMemory
+@see, and can be read and written using Kern::ThreadBufRead and Kern::ThreadBufWrite.
+
+@see TClientBufferRequest
+@see Kern::PinVirtualMemory
+@see Kern::UnpinVirtualMemory
+@see Kern::ThreadBufRead
+@see Kern::ThreadBufWrite
+
+@publishedPartner
+@released
+*/
+class TClientBuffer
+	{
+public:
+	IMPORT_C TClientBuffer();
+	IMPORT_C TInt SetFromDescriptor(TAny* aDesPtr, DThread* aClientThread = NULL);
+	IMPORT_C void SetFromBuffer(TLinAddr aStartAddr, TInt aLength, TBool aWriteable);
+	IMPORT_C TBool IsSet() const;
+	IMPORT_C void Reset();
+	IMPORT_C TBool IsWriteable() const;
+	IMPORT_C TInt Length() const;
+	IMPORT_C TInt MaxLength() const;
+	IMPORT_C TInt UpdateDescriptorLength(DThread* aClientThread = NULL);
+public:
+	TAny* DesPtr() const;
+	TAny* DataPtr() const;
+private:
+	enum TFlags
+		{
+		EIsBuffer = 1
+		};
+private:
+	TUint32 iPtr;
+	TDesHeader iHeader;
+	friend class Kern;
+	};
+
+class TVirtualPinObject;
+class TPhysicalPinObject;
+class TShPool;
+class TShBuf;
+
+/**
+An object representing a device driver request that involves writing data to one or more user-side
+buffers.
+
+It handles pinning of the buffers when the request is set up, so that the memory can be accessed in
+kernel thread context.
+
+It can be queued for completion when the thread next returns to user-mode.  Any writeable
+descriptors have their lengths written back to the client at the same time as the completion value.
+
+The following operations can only be called from client thread context:
+
+  StartSetup
+  AddBuffer
+  EndSetup
+
+These operations can be called from any thread context:
+
+  Kern::QueueRequestComplete
+
+@publishedPartner
+@released
+*/
+class TClientBufferRequest : private TClientRequest
+	{
+public:
+	enum TFlags
+		{
+		/** A flag indicating that buffers should have their virtual memory pinned. */
+		EPinVirtual = 1
+		};
+	IMPORT_C TInt StartSetup(TRequestStatus* aStatus);
+	IMPORT_C TInt AddBuffer(TClientBuffer*& aBufOut, TAny* aDesPtr);
+	IMPORT_C TInt AddBuffer(TClientBuffer*& aBufOut, TLinAddr aStartAddr, TInt aLength, TBool aWriteable = EFalse);
+	IMPORT_C void EndSetup();
+	IMPORT_C void Reset();
+	inline TInt Setup(TClientBuffer*& aBufOut, TRequestStatus* aStatus, TAny* aDesPtr);
+	inline TInt Setup(TClientBuffer*& aBufOut, TRequestStatus* aStatus, TLinAddr aStartAddr, TInt aLength, TBool aWriteable = EFalse);
+	inline TBool IsReady();
+private:
+	struct SBufferData : public SDblQueLink
+		{
+		TClientBuffer iBuffer;
+		TVirtualPinObject* iPinObject;
+		};
+	TClientBufferRequest(TUint aFlags);
+	~TClientBufferRequest();	// call Close(), don't delete
+	TInt Construct(TInt aMaxBuffers);
+	void Close();
+	TInt AllocateBufferData();
+	SBufferData* StartAddBuffer();
+	TInt EndAddBuffer(TClientBuffer*& aBufOut, SBufferData* aBuf);
+	void QueueComplete(DThread* aThread, TInt aReason);
+	static void CallbackFunc(TAny* aData, TUserModeCallbackReason aReason);
+private:
+	TUint iFlags;
+	DThread* iSetupThread;
+	SDblQue iBufferList;
+	static NFastMutex Lock;
+	friend class Kern;
+	};
+
+inline TInt TClientBufferRequest::Setup(TClientBuffer*& aBufOut, TRequestStatus* aStatus, TAny* aDesPtr)
+	{
+	TInt r = StartSetup(aStatus);
+	if (r == KErrNone)
+		r = AddBuffer(aBufOut, aDesPtr);
+	if (r == KErrNone)
+		EndSetup();
+	return r;
+	}
+
+inline TInt TClientBufferRequest::Setup(TClientBuffer*& aBufOut, TRequestStatus* aStatus, TLinAddr aStartAddr, TInt aLength, TBool aWriteable)
+	{
+	TInt r = StartSetup(aStatus);
+	if (r == KErrNone)
+		r = AddBuffer(aBufOut, aStartAddr, aLength, aWriteable);
+	if (r == KErrNone)
+		EndSetup();
+	return r;
+	}
+
+inline TBool TClientBufferRequest::IsReady()
+	{
+	return TClientRequest::IsReady();
+	}
+
+class DPagingDevice;
+class DLogicalDevice;
+class DPhysicalDevice;
+class TShPoolCreateInfo;
+
+class Kern
+/**
+Kernel utility functions
+
+@publishedPartner
+@released
+*/
+	{
+public:
+	/**
+	Bit values to be used with the aMode parameter of Kern::SetSytemTime() to
+	specify the mode of operation of Kern::SetSytemTime().
+	*/
+	enum TTimeSetMode
+		{
+		ETimeSet_SetHwRtc = 1,		/**< Set HW as well as SW RTC */
+		ETimeSet_LocalTime = 2,		/**< The Kern::SetSytemTime() parameter aTime is specified in local time rather than UTC */
+		ETimeSet_SyncNotify = 4,	/**< Synchronously trigger change notifiers*/
+		ETimeSet_AsyncNotify = 8,	/**< Asynchronously trigger change notifiers*/
+		ETimeSet_Secure = 16		/**< Set the secure clock (implies ETimeSet_SetHwRtc)*/
+		};
+public:
+	IMPORT_C static void Printf(const char* aFmt, ...);
+	IMPORT_C static TInt AddHalEntry(TInt aId, THalFunc aFunc, TAny* aPtr);
+	IMPORT_C static TInt AddHalEntry(TInt aId, THalFunc aFunc, TAny* aPtr, TInt aDeviceNumber);
+	IMPORT_C static TInt RemoveHalEntry(TInt aId);
+	IMPORT_C static TInt RemoveHalEntry(TInt aId, TInt aDeviceNumber);
+	IMPORT_C static SHalEntry* FindHalEntry(TInt aId);
+	IMPORT_C static SHalEntry* FindHalEntry(TInt aId, TInt aDeviceNumber);
+	IMPORT_C static void SafeClose(DObject*& aObj, TAny* aPtr);
+	IMPORT_C static TInt ValidateName(const TDesC& aName);
+	IMPORT_C static TInt ValidateFullName(const TDesC& aName);
+	IMPORT_C static TBool PowerGood();
+	IMPORT_C static void NotifyChanges(TUint aChangesMask);
+	IMPORT_C static void NotifyThreadDeath(DThread* aDeadThread);	/**< @internalComponent */
+	IMPORT_C static void AsyncNotifyChanges(TUint aChangesMask);
+	IMPORT_C static void InfoCopy(TDes8& aDest, const TDesC8& aSrc);
+	IMPORT_C static void InfoCopy(TDes8& aDest, const TUint8* aPtr, TInt aLength);
+	IMPORT_C static void RequestComplete(DThread* aThread, TRequestStatus*& aStatus, TInt aReason);
+	IMPORT_C static void RequestComplete(TRequestStatus*& aStatus, TInt aReason);	
+	IMPORT_C static void QueueRequestComplete(DThread* aThread, TClientRequest* aRequest, TInt aReason);
+	IMPORT_C static TInt CreateClientRequest(TClientRequest*& aRequestPtr);
+	
+	template <class T> inline static TInt CreateClientDataRequest(TClientDataRequest<T>*& aRequestPtr)
+		{
+		TInt r = Kern::CreateClientDataRequestBase((TClientDataRequestBase*&)aRequestPtr, sizeof(T));
+		if (r == KErrNone)
+			new (aRequestPtr->Buffer()) T;
+		return r;
+		}
+
+	template <class T1, class T2> inline static TInt CreateClientDataRequest2(TClientDataRequest2<T1,T2>*& aRequestPtr)
+		{
+		TInt r = Kern::CreateClientDataRequestBase2((TClientDataRequestBase2*&)aRequestPtr, sizeof(T1), sizeof(T2));
+		if (r == KErrNone)
+			{
+			new (aRequestPtr->Buffer1()) T1;
+			new (aRequestPtr->Buffer2()) T2;
+			}
+		return r;
+		}
+	
+	IMPORT_C static void DestroyClientRequest(TClientRequest*& aRequestPtr);
+	template <class T> inline static void DestroyClientRequest(TClientDataRequest<T>*& aRequestPtr)
+		{ DestroyClientRequest((TClientRequest*&)aRequestPtr); } /**< @prototype */
+	template <class T, class T2> inline static void DestroyClientRequest(TClientDataRequest2<T,T2>*& aRequestPtr)
+		{ DestroyClientRequest((TClientRequest*&)aRequestPtr); } /**< @prototype */
+	IMPORT_C static TInt CreateClientBufferRequest(TClientBufferRequest*& aRequestPtr, TUint aInitialBuffers, TUint aFlags);
+	IMPORT_C static void DestroyClientBufferRequest(TClientBufferRequest*& aRequestPtr);
+	IMPORT_C static void QueueBufferRequestComplete(DThread* aThread, TClientBufferRequest* aRequest, TInt aReason);
+	IMPORT_C static TDfcQue* DfcQue0();
+	IMPORT_C static TDfcQue* DfcQue1();
+	IMPORT_C static TDfcQue* TimerDfcQ();
+	IMPORT_C static TDfcQue* SvMsgQue();
+	IMPORT_C static DObjectCon* const *Containers();	/**< @internalComponent */
+	IMPORT_C static SDblQue* CodeSegList();
+	IMPORT_C static DMutex* CodeSegLock();
+	IMPORT_C static DPowerModel* PowerModel();
+	IMPORT_C static TInt SetThreadPriority(TInt aPriority, DThread* aThread=NULL);
+	IMPORT_C static void SetRealtimeState(TThreadRealtimeState aNewState);
+	IMPORT_C static DObject* ObjectFromHandle(DThread* aThread, TInt aHandle, TInt aType);
+	IMPORT_C static DObject* ObjectFromHandle(DThread* aThread, TInt aHandle, TInt aType, TUint& aAttr);
+	IMPORT_C static DThread* ThreadFromId(TUint aId);
+	IMPORT_C static DProcess* ProcessFromId(TUint aId);
+	IMPORT_C static void ThreadSuspend(DThread& aThread, TInt aCount);
+	IMPORT_C static void ThreadResume(DThread& aThread);
+	IMPORT_C static TInt MutexWait(DMutex& aMutex);
+	IMPORT_C static void MutexSignal(DMutex& aMutex);
+	IMPORT_C static TInt MutexCreate(DMutex*& aMutex, const TDesC& aName, TUint aOrder);
+	IMPORT_C static TInt SemaphoreWait(DSemaphore& aSem, TInt aNTicks=0);
+	IMPORT_C static void SemaphoreSignal(DSemaphore& aSem);
+	IMPORT_C static TInt SemaphoreCreate(DSemaphore*& aSem, const TDesC& aName, TInt aInitialCount);
+	IMPORT_C static TInt ThreadCreate(SThreadCreateInfo& aInfo);
+	IMPORT_C static TInt DfcQInit(TDfcQue* aDfcQ, TInt aPriority, const TDesC* aName=NULL);
+	IMPORT_C static TInt DfcQCreate(TDfcQue*& aDfcQ, TInt aPriority, const TDesC* aName=NULL);
+	IMPORT_C static TInt DynamicDfcQCreate(TDynamicDfcQue*& aDfcQ, TInt aPriority, const TDesC& aBaseName);
+	IMPORT_C static TInt ProcessCreate(DProcess*& aProcess, TProcessCreateInfo& aInfo, HBuf*& aCommand, TInt* aHandle);	/**< @internalComponent */
+	IMPORT_C static TSupplyStatus MachinePowerStatus();
+	IMPORT_C static void AppendFormat(TDes8& aDes, const char* aFmt, VA_LIST aList);
+	IMPORT_C static TSuperPage& SuperPage();
+	IMPORT_C static TMachineConfig& MachineConfig();
+	IMPORT_C static TUint32 Random();
+	IMPORT_C static void RandomSalt(TUint32 aBit);
+    IMPORT_C static void WaitForRequest(TRequestStatus& aStatus);	/**< @internalTechnology */
+    IMPORT_C static TAny* Alloc(TInt aSize);
+    IMPORT_C static TAny* AllocZ(TInt aSize);
+    IMPORT_C static void Free(TAny* aPtr);
+    IMPORT_C static void AsyncFree(TAny* aPtr);
+    IMPORT_C static TAny* ReAlloc(TAny* aPtr, TInt aSize, TInt aMode=0); 
+	IMPORT_C static TInt SafeReAlloc(TAny*& aPtr, TInt aOldSize, TInt aNewSize);
+	IMPORT_C static void ValidateHeap();
+	IMPORT_C static void PanicCurrentThread(const TDesC& aCategory, TInt aReason);
+    IMPORT_C static TBool QueryVersionSupported(const TVersion& aCurrent,const TVersion& aRequested);
+	IMPORT_C static TTimeK SystemTimeSecure();
+	IMPORT_C static TTimeK SystemTime();
+	IMPORT_C static	TInt SetSystemTime(const TTimeK& aTime, TUint aMode);
+	IMPORT_C static TInt HalFunction(TInt aGroup, TInt aFunction, TAny* a1, TAny* a2);
+	IMPORT_C static TInt HalFunction(TInt aGroup, TInt aFunction, TAny* a1, TAny* a2, TInt aDeviceNumber);
+	IMPORT_C static TInt AddEvent(const TRawEvent& aEvent);
+	IMPORT_C static TInt AddEvent(const TRawEvent& aEvent, TBool aResetUserActivity);
+	IMPORT_C static void Exit(TInt aReason);
+	IMPORT_C static TInt TickPeriod();
+	IMPORT_C static void KUDesGet(TDes8& aDest, const TDesC8& aSrc);
+	IMPORT_C static void KUDesPut(TDes8& aDest, const TDesC8& aSrc);
+	IMPORT_C static const TUint8* KUDesInfo(const TDesC8& aSrc, TInt& aLength, TInt& aMaxLength);
+	IMPORT_C static void KUDesSetLength(TDes8& aDes, TInt aLength);
+	IMPORT_C static TInt ThreadDesRead(DThread* aThread, const TAny* aSrc, TDes8& aDest, TInt aOffset, TInt aMode);
+	IMPORT_C static TInt ThreadRawRead(DThread* aThread, const TAny* aSrc, TAny* aDest, TInt aSize);
+	IMPORT_C static TInt ThreadDesWrite(DThread* aThread, TAny* aDest, const TDesC8& aSrc, TInt aOffset, TInt aMode, DThread* aOrigThread);
+	IMPORT_C static TInt ThreadRawWrite(DThread* aThread, TAny* aDest, const TAny* aSrc, TInt aSize, DThread* aOrigThread=NULL);
+	inline static TInt ThreadDesRead(DThread* aThread, const TAny* aSrc, TDes8& aDest, TInt aOffset);
+	inline static TInt ThreadDesWrite(DThread* aThread, TAny* aDest, const TDesC8& aSrc, TInt aOffset, DThread* aOrigThread=NULL);
+	IMPORT_C static TInt ThreadBufRead(DThread* aThread, const TClientBuffer* aSrc, TDes8& aDest, TInt aOffset, TInt aMode);
+	IMPORT_C static TInt ThreadBufWrite(DThread* aThread, TClientBuffer* aDest, const TDesC8& aSrc, TInt aOffset, TInt aMode, DThread* aOrigThread);
+	IMPORT_C static TInt ThreadGetDesLength(DThread* aThread, const TAny* aDes);
+	IMPORT_C static TInt ThreadGetDesMaxLength(DThread* aThread, const TAny* aDes);
+	IMPORT_C static TInt ThreadGetDesInfo(DThread* aThread, const TAny* aDes, TInt& aLength, TInt& aMaxLength, TUint8*& aPtr, TBool aWriteable);
+	IMPORT_C static void ThreadKill(DThread* aThread, TExitType aType, TInt aReason, const TDesC& aCategory);
+	IMPORT_C static TAny* KUSafeRead(const TAny* aSrc, TAny* aDest, TInt aSize);	/**< @internalTechnology */
+	IMPORT_C static TAny* SafeRead(const TAny* aSrc, TAny* aDest, TInt aSize);		/**< @internalTechnology */
+	IMPORT_C static TAny* KUSafeWrite(TAny* aDest, const TAny* aSrc, TInt aSize);	/**< @internalTechnology */
+	IMPORT_C static TAny* SafeWrite(TAny* aDest, const TAny* aSrc, TInt aSize);		/**< @internalTechnology */
+	IMPORT_C static TInt KUSafeInc(TInt& aValue);		/**< @internalTechnology */
+	IMPORT_C static TInt KUSafeDec(TInt& aValue);		/**< @internalTechnology */
+	IMPORT_C static DThread& CurrentThread();
+	IMPORT_C static DProcess& CurrentProcess();
+	IMPORT_C static TThreadMessage& Message();
+	IMPORT_C static TInt FreeRamInBytes();
+	IMPORT_C static void Fault(const char* aCat, TInt aFault);
+	IMPORT_C static TBool ColdStart();
+	IMPORT_C static void NanoWait(TUint32 aInterval);
+	IMPORT_C static TUint32 TickCount();
+	IMPORT_C static TInt PollingWait(TPollFunction aFunction, TAny* aPtr, TInt aPollPeriodMs, TInt aMaxPoll);
+	IMPORT_C static TUint32 RoundToPageSize(TUint32 aSize);
+	IMPORT_C static TUint32 RoundToChunkSize(TUint32 aSize);
+	IMPORT_C static void Restart(TInt aMode);			/**< @internalTechnology */
+	IMPORT_C static void AccessCode();
+	IMPORT_C static void EndAccessCode();
+	IMPORT_C static	DThread* NThreadToDThread(NThread* aNThread);
+	IMPORT_C static	TInt PrepareMemoryForDMA(DThread* aThread, TAny* aAddress, TInt aSize, TPhysAddr* aPageList); /**< @internalComponent */
+	IMPORT_C static	TInt ReleaseMemoryFromDMA(DThread* aThread, TAny* aAddress, TInt aSize, TPhysAddr* aPageList);/**< @internalComponent */
+	
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	/**
+	Checks whether the process that owns the current thread has the specified capability.
+
+	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 True even though the
+	check failed.
+
+	@param aCapability The capability to be tested.
+	@param aDiagnosticText	A string that will be emitted along with any diagnostic message
+	                   		that may be issued if the test finds the capability is not present.
+					   		This string must be enclosed in the __PLATSEC_DIAGNOSTIC_STRING macro
+					   		which enables it to be easily removed from the system.
+
+	@return True if the current thread's process has the capability, False otherwise.
+	*/
+	inline static TBool CurrentThreadHasCapability(TCapability aCapability, const char* aDiagnosticText=0)
+		{ return DoCurrentThreadHasCapability(aCapability, aDiagnosticText); }
+#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	// Only available to NULL arguments
+	/**
+	Checks whether the process that owns the current thread has the specified capability.
+
+	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 True even though the
+	check failed.
+
+	@param aCapability The capability to be tested.
+
+	@return True if the current thread's process has the capability, False otherwise.
+	*/
+	inline static TBool CurrentThreadHasCapability(TCapability aCapability, OnlyCreateWithNull /*aDiagnosticText*/=NULL)
+		{ return DoCurrentThreadHasCapability(aCapability); }
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+
+	IMPORT_C static TVendorId ThreadVendorId(DThread* aThread);
+	IMPORT_C static TVendorId ProcessVendorId(DProcess* aProcess);
+	IMPORT_C static TSecureId ThreadSecureId(DThread* aThread);
+	IMPORT_C static TSecureId ProcessSecureId(DProcess* aProcess);
+
+	IMPORT_C static DCodeSeg* CodeSegFromAddress(TLinAddr aAddr, DProcess* aProcess);
+	IMPORT_C static void CodeSegGetMemoryInfo(DCodeSeg& aCodeSeg, TModuleMemoryInfo& aInfo, DProcess* aProcess);
+	IMPORT_C static TInt MakeHandleAndOpen(DThread* aThread, DObject* aObject);
+	IMPORT_C static TInt CloseHandle(DThread* aThread, TInt aHandle);
+	IMPORT_C static TInt ChunkCreate(const TChunkCreateInfo& aInfo, DChunk*& aChunk, TLinAddr& aKernAddr, TUint32& iMapAttr);
+	IMPORT_C static TInt ChunkCommit(DChunk* aChunk, TInt aOffset, TInt aSize);
+	IMPORT_C static TInt ChunkCommitContiguous(DChunk* aChunk, TInt aOffset, TInt aSize, TUint32& aPhysicalAddress);
+	IMPORT_C static TInt ChunkCommitPhysical(DChunk* aChunk, TInt aOffset, TInt aSize, TUint32 aPhysicalAddress);
+	IMPORT_C static TInt ChunkCommitPhysical(DChunk* aChunk, TInt aOffset, TInt aSize, const TUint32* aPhysicalAddressList);
+	IMPORT_C static TInt ChunkClose(DChunk* aChunk);
+	IMPORT_C static DChunk* OpenSharedChunk(DThread* aThread, const TAny* aAddress, TBool aWrite, TInt& aOffset);
+	IMPORT_C static DChunk* OpenSharedChunk(DThread* aThread, TInt aChunkHandle, TBool aWrite);
+	IMPORT_C static TInt ChunkAddress(DChunk* aChunk, TInt aOffset, TInt aSize, TLinAddr& aKernelAddress);
+	IMPORT_C static TInt ChunkPhysicalAddress(DChunk* aChunk, TInt aOffset, TInt aSize, TLinAddr& aKernelAddress, TUint32& aMapAttr, TUint32& aPhysicalAddress, TUint32* aPhysicalPageList=NULL);
+	IMPORT_C static TUint8* ChunkUserBase(DChunk* aChunk, DThread* aThread);
+
+	/**
+	Enumeration indicating the behaviour of text trace messages.
+	@publishedPartner
+	@released
+	*/
+	enum TTextTraceMode
+		{
+		/** Traces are sent to the serial port if not already handled by other means. */
+		ESerialOutDefault = 0, 
+		/** Traces are never sent to the serial port. */
+		ESerialOutNever = 1,
+		/** Traces are always sent to the serial port. */
+		ESerialOutAlways = 2,
+		/** Mask for serial port mode values. */
+		ESerialOutMask = 3
+		};
+	IMPORT_C static TUint SetTextTraceMode(TUint aMode, TUint aMask);
+	IMPORT_C static TTraceHandler SetTraceHandler(TTraceHandler aHandler);
+	inline static TNanoWaitHandler SetNanoWaitHandler(TNanoWaitHandler aHandler);
+	inline static TInitialTimeHandler SetInitialTimeHandler(TInitialTimeHandler aHandler);
+	
+	/**
+	Install the specified paging device.
+	@param aDevice The device.
+	@return KErrNone or standard error code.
+	@post The devices DPagingDevice::iDeviceId has been set.
+	@internalTechnology
+	*/
+	IMPORT_C static TInt InstallPagingDevice(DPagingDevice* aDevice);
+	IMPORT_C static TInt InstallLogicalDevice(DLogicalDevice* aDevice);		/**< @internalTechnology */
+	IMPORT_C static TInt InstallPhysicalDevice(DPhysicalDevice* aDevice);		/**< @internalTechnology */
+
+	IMPORT_C static TInt CreateVirtualPinObject(TVirtualPinObject*& aPinObject); // prototype
+	IMPORT_C static TInt PinVirtualMemory(TVirtualPinObject* aPinObject, TLinAddr aStart, TUint aSize, DThread* aThread=NULL); // prototype
+	IMPORT_C static TInt PinVirtualMemory(TVirtualPinObject* aPinObject, const TClientBuffer& aDes, DThread* aThread=NULL); // prototype
+	IMPORT_C static TInt CreateAndPinVirtualMemory(TVirtualPinObject*& aPinObject, TLinAddr aStart, TUint aSize); //prototype
+	IMPORT_C static void UnpinVirtualMemory(TVirtualPinObject* aPinObject); // prototype
+	IMPORT_C static void DestroyVirtualPinObject(TVirtualPinObject*& aPinObject); // prototype
+
+	IMPORT_C static TInt CreatePhysicalPinObject(TPhysicalPinObject*& aPinObject); // prototype
+	IMPORT_C static TInt PinPhysicalMemory(TPhysicalPinObject* aPinObject, TLinAddr aStart, TUint aSize, TBool aReadOnly, TPhysAddr& aAddress, TPhysAddr* aPages, TUint32& aMapAttr, TUint& aColour, DThread* aThread=NULL);
+	IMPORT_C static TInt UnpinPhysicalMemory(TPhysicalPinObject* aPinObject); // prototype
+	IMPORT_C static TInt DestroyPhysicalPinObject(TPhysicalPinObject*& aPinObject); // prototype
+	
+
+	IMPORT_C static TInt ShPoolCreate(TShPool*& aPool, TShPoolCreateInfo& aInfo, TBool aMap, TUint aFlags);
+	IMPORT_C static TInt ShPoolOpen(TShPool*& aPool, DThread* aThread, TInt aHandle, TBool aMap, TUint aFlags);
+	IMPORT_C static TInt ShPoolClose(TShPool* aPool);
+	IMPORT_C static TInt ShPoolMakeHandleAndOpen(TShPool* aPool, DThread* aThread, TUint aAttr);
+	IMPORT_C static TInt ShPoolSetBufferWindow(TShPool* aPool, TInt aWindowSize);
+	IMPORT_C static TInt ShPoolAlloc(TShPool* aPool, TShBuf*& aBuf, TUint aFlags);
+	IMPORT_C static void ShPoolGetInfo(TShPool* aPool, TShPoolInfo& aInfo);
+	IMPORT_C static TUint ShPoolBufSize(TShPool* aPool);
+	IMPORT_C static TUint ShPoolFreeCount(TShPool* aPool);
+	IMPORT_C static TInt ShBufOpen(TShBuf*& aBuf, DThread* aThread, TInt aHandle);
+	IMPORT_C static TInt ShBufClose(TShBuf* aBuf);
+	IMPORT_C static TInt ShBufMakeHandleAndOpen(TShBuf* aBuf, DThread* aThread);
+	IMPORT_C static void ShBufCopyFrom(TShBuf* aBuf, const TDesC8& aSrc, TUint aOffset);
+	IMPORT_C static TUint8* ShBufPtr(TShBuf* aBuf);
+	IMPORT_C static TUint ShBufSize(TShBuf* aBuf);
+	IMPORT_C static TInt ShBufPin(TShBuf* aBuf, TPhysicalPinObject* aPinObject, TBool aReadOnly, TPhysAddr& Address, TPhysAddr* aPages, TUint32& aMapAttr, TUint& aColour);
+
+
+private:
+	IMPORT_C static TBool DoCurrentThreadHasCapability(TCapability aCapability, const char* aDiagnosticText);
+	IMPORT_C static TBool DoCurrentThreadHasCapability(TCapability aCapability);
+	IMPORT_C static TKernelHookFn SetHook(TKernelHookType aType, TKernelHookFn aFunction, TBool aAllowOveride=EFalse);
+	IMPORT_C static TInt CreateClientDataRequestBase(TClientDataRequestBase*& aRequestPtr, TInt aSize);					/**< @internalTechnology */
+	IMPORT_C static TInt CreateClientDataRequestBase2(TClientDataRequestBase2*& aRequestPtr, TInt aSize1, TInt aSize2);	/**< @internalTechnology */
+	friend class DThread;
+	};
+
+
+
+/**
+Reads an 8-bit descriptor from the specified thread's address space, enforcing
+checks on validity of source and destination if necessary.
+	
+It is used especially by device drivers to transfer data from a user thread.
+aDes might be accessed with user permission validation.
+
+@param aThread The thread from whose address space data is to be read.
+@param aSrc Pointer to a source descriptor in the specified thread's address
+            space. This must not be NULL.
+@param aDest Target descriptor
+@param aOffset Offset in aSrc from where to start reading data.
+
+@return KErrNone, if sucessful; KErrBadDescriptor, if aPtr or aDes is an
+        invalid decriptor; KErrArgument if anOffset is negative; KErrDied if aThread
+        is dead.
+*/
+inline TInt Kern::ThreadDesRead(DThread* aThread, const TAny* aSrc, TDes8& aDest, TInt aOffset)
+	{ return ThreadDesRead(aThread,aSrc,aDest,aOffset,KChunkShiftBy0); }
+
+
+
+
+/**
+Writes an 8-bit descriptor to the specified thread's address space, enforcing
+checks on validity of source and destination if necessary.
+	
+It is used especially by device drivers to transfer data to a user thread.
+aDes might be accessed with user permission validation.
+	  
+@param aThread The thread into whose address space data is to be written.
+@param aDest Pointer to a target descriptor in the specified thread's address
+            space. It must not be NULL
+@param aSrc Source descriptor
+@param aOffset Offset in aDest to start writing data to.
+@param aOrigThread The thread on behalf of which this operation is performed (eg client of device driver).
+
+@return KErrNone, if sucessful; KErrBadDescriptor, if aPtr or aDes is an
+        invalid decriptor; KErrArgument if anOffset is negative; KErrDied if aThread
+        is dead.
+*/
+inline TInt Kern::ThreadDesWrite(DThread* aThread, TAny* aDest, const TDesC8& aSrc, TInt aOffset, DThread* aOrigThread)
+	{ return ThreadDesWrite(aThread,aDest,aSrc,aOffset,KChunkShiftBy0,aOrigThread); }
+
+
+/**
+Register the function used to implement Kern::NanoWait.
+
+This should be called from the variant to supply an accurate implementation for Kern::NanoWait.
+
+@return The previous implemention.
+
+@see Kern::NanoWait
+
+@publishedPartner
+@released
+*/
+inline TNanoWaitHandler Kern::SetNanoWaitHandler(TNanoWaitHandler aHandler)
+	{
+	return (TNanoWaitHandler) SetHook(EHookNanoWait, (TKernelHookFn)aHandler, ETrue);
+	}
+
+
+
+/**
+Register the function used to read the initial system time.
+
+This may be called from the variant to override the default behaviour.  If so it
+should be called in phase 1 of initialisation.
+
+@return The previous implemention.
+
+@publishedPartner
+@released
+*/
+inline TInitialTimeHandler Kern::SetInitialTimeHandler(TInitialTimeHandler aHandler)
+	{
+	return (TInitialTimeHandler) SetHook(EHookInitialTime, (TKernelHookFn)aHandler, ETrue);
+	}
+
+
+
+struct SMiscNotifierQ;
+class TMiscNotifierMgr;
+class DObject : public DBase
+/**
+Base class for reference-counted kernel side objects.
+
+@publishedPartner
+@released
+*/
+// NOTE: Any changes to the structure of this class should be duplicated in class DMonObject
+	{
+public:
+
+    /**
+    Defines a set of bit values that are returned from calls
+    to DObject::Close(), or by an overriding implementation of Close() provided
+    by a derived class.
+    
+    The values describe the state of the object on return from Close().
+    */
+	enum TCloseReturn
+		{
+		
+		/**
+		If set, indicates that the object has been deleted.  
+		*/
+		EObjectDeleted=1,
+		
+		/**
+		If set, indicates that the last reference
+		from a user process has been removed.
+		
+		Note that this only applies to DLibrary objects.
+		*/
+		EObjectUnmapped=2,
+		};
+		
+	/**	@internalComponent */
+	enum TObjectProtection
+		{
+		ELocal=0,		// Private
+		EProtected,
+		EGlobal,		// Public
+		};
+		
+	/**	@internalComponent */
+	enum TObjectFlags
+		{
+		EObjectExtraReference = (1<<0),
+		EObjectDeferKernelCodesegCleanup = (1<<1)
+		};
+		
+public:
+	/**	@internalComponent */
+	inline TInt Inc() { return __e32_atomic_tas_ord32(&iAccessCount, 1, 1, 0); }
+
+	/**	@internalComponent */
+	inline TInt Dec() { return __e32_atomic_tas_ord32(&iAccessCount, 1, -1, 0); }
+
+	IMPORT_C DObject();
+	IMPORT_C ~DObject();
+	
+	/**
+	Opens this kernel side reference-counted object.
+	
+	Opening a reference-counted object increments its reference count
+	by one. The increment operation is done atomically.
+	
+	@return KErrNone, if the increment operation succeeds;
+	        KErrGeneral, if the reference count value is either zero
+	        or negative before performing the increment operation;
+	        the reference count is initialised to 1 on construction
+	        of the object, and can never be less than 1.
+	*/
+	inline TInt Open() { return(Inc()?KErrNone:KErrGeneral); }
+	IMPORT_C void CheckedOpen();
+	IMPORT_C virtual TInt Close(TAny* aPtr);
+	IMPORT_C virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
+	IMPORT_C virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType, TUint aAttr);
+	IMPORT_C virtual TInt AddToProcess(DProcess* aProcess);
+	IMPORT_C virtual TInt AddToProcess(DProcess* aProcess, TUint aAttr);
+	IMPORT_C TInt AsyncClose();
+	IMPORT_C virtual void DoAppendName(TDes& aName);
+	IMPORT_C void DoAppendFullName(TDes& aFullName);
+	IMPORT_C void Name(TDes& aName);
+	IMPORT_C void AppendName(TDes& aName);
+	IMPORT_C void FullName(TDes& aFullName);
+	IMPORT_C void AppendFullName(TDes& aFullName);
+	IMPORT_C TInt SetName(const TDesC* aName);
+	IMPORT_C TInt SetOwner(DObject* aOwner);
+	IMPORT_C void TraceAppendName(TDes8& aName, TBool aLock);
+	IMPORT_C void TraceAppendFullName(TDes8& aFullName, TBool aLock);
+	inline DObject* Owner();
+	inline TInt AccessCount();
+	inline TInt UniqueID();
+	inline HBuf* NameBuf();
+	inline void SetProtection(TObjectProtection aProtection);
+	inline TUint Protection();
+	void BaseName(TDes& aName);
+	inline TUint64 ObjectId() const;		/**< @internalComponent */
+public:
+	/**	@internalComponent */
+	TInt iAccessCount;			// must be first
+
+	/**	@internalComponent */
+	DObject* iOwner;
+
+	/** A TObjectType value with one added
+		@internalComponent */
+	TUint8 iContainerID;
+
+	/** A TObjectProtection value
+		@internalComponent */
+	TUint8 iProtection;
+
+	/**	Bit field made of values from TObjectFlags
+		@internalComponent */
+	TUint8 iObjectFlags;
+
+	/**	@internalComponent */
+	TUint8 iNotQLow;
+
+	/**	@internalComponent */
+	HBuf* iName;
+
+	/** A unique ID.
+	    @internalComponent */
+	TUint64 iObjectId;
+
+	/**	@internalComponent */
+//	SMiscNotifierQ* iNotifierQ;
+
+public:
+	static NFastMutex Lock;
+private:
+	inline SMiscNotifierQ* NotifierQ() const;	/**< @internalComponent */
+	inline void SetNotifierQ(SMiscNotifierQ*);	/**< @internalComponent */
+	inline TBool HasNotifierQ() const;			/**< @internalComponent */
+private:
+	static TUint64 NextObjectId;
+
+	friend class DObjectCon;
+	friend class RObjectIx;
+	friend class Monitor;
+	friend class Debugger;
+	friend void Kern::AppendFormat(TDes8&, const char*, VA_LIST);
+	friend class K;
+	friend struct SMiscNotifierQ;
+	friend class TMiscNotifierMgr;
+	};
+
+/**
+Gets the number of open references to
+this reference-counted kernel side object.
+
+@return The number of open references.
+*/
+inline TInt DObject::AccessCount()
+	{ return iAccessCount; }
+	
+/**
+Gets a pointer to the kernel-side reference counted object
+that owns this kernel side reference-counted object.
+
+@return A pointer to the owning reference-counted object.
+        This is NULL, if there is no owner.
+*/	
+inline DObject* DObject::Owner()
+	{ return iOwner; }
+
+/** @internalComponent */
+inline HBuf* DObject::NameBuf()
+	{ return iName; }
+
+/** @internalComponent */
+inline TInt DObject::UniqueID()
+	{return(iContainerID);}
+
+/** @internalComponent */
+inline TUint DObject::Protection()
+	{return (TUint8)iProtection;}
+
+/** @internalComponent */
+inline void DObject::SetProtection(TObjectProtection aProtection)
+	{iProtection=(TUint8)aProtection;}
+
+/********************************************
+ * Device driver base classes
+ ********************************************/
+
+/**
+@publishedPartner
+@released
+
+If set, it indicates that the use of units is valid.
+
+@see DLogicalDevice::iParsemask
+*/
+const TUint KDeviceAllowUnit=0x01;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+If set, then an LDD requires a PDD.
+
+@see DLogicalDevice::iParsemask
+*/
+const TUint KDeviceAllowPhysicalDevice=0x02;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+If set, it indicates that the use of additional information is allowed.
+
+@see DLogicalDevice::iParsemask
+*/
+const TUint KDeviceAllowInfo=0x04;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Combines all of: KDeviceAllowUnit, KDeviceAllowPhysicalDevice and KDeviceAllowInfo.
+
+@see DLogicalDevice::iParsemask
+*/
+const TUint KDeviceAllowAll=(KDeviceAllowUnit|KDeviceAllowPhysicalDevice|KDeviceAllowInfo);
+
+
+
+
+/**
+@publishedPartner
+@released
+
+A flag bit that can set in the aMode parameter passed to the
+Kern::ThreadDesWrite(DThread* ,TAny*, const TDesC8&, TInt, TInt aMode, DThread*);
+variant.
+
+It ensures that the length of data copied to the target descriptor is
+truncated, if necesary, to prevent the maximum length of that target descriptor
+from being exceeded.
+
+@see Kern::ThreadDesWrite()
+*/
+const TInt KTruncateToMaxLength=(TInt)0x40000000;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Used internally by Symbian OS.
+*/
+const TInt KCheckLocalAddress=(TInt)0x20000000;
+
+
+
+
+/**
+@internalTechnology
+@prototype
+
+A flag bit that can set in the aMode parameter passed to the
+Kern::ThreadDesWrite(DThread* ,TAny*, const TDesC8&, TInt, TInt aMode, DThread*);
+variant.
+
+It indicates that the descriptor header should not be updated to reflect the new length.
+
+@see Kern::ThreadDesWrite()
+*/
+const TInt KDoNotUpdateDesLength=(TInt)0x10000000;
+
+class DLogicalDevice;
+class DPhysicalDevice;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+The abstract base class for a logical channel.
+*/
+class DLogicalChannelBase : public DObject
+	{
+public:
+	IMPORT_C virtual ~DLogicalChannelBase();
+public:
+    /**
+    Handles a client request in the client context.
+    
+    The function is called from within the kernel, but the implementation
+    must be provided by external code.
+    */
+	virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2)=0;
+	IMPORT_C virtual TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
+public:
+	DLogicalDevice* iDevice;
+	DPhysicalDevice* iPhysicalDevice;
+	DBase* iPdd;
+	};
+
+
+
+
+/**
+@publishedPartner
+@released
+
+The abstract base class for an LDD factory object.
+*/
+class DLogicalDevice : public DObject
+	{
+public:
+	IMPORT_C virtual ~DLogicalDevice();
+	IMPORT_C virtual TBool QueryVersionSupported(const TVersion& aVer) const;
+	IMPORT_C virtual TBool IsAvailable(TInt aUnit, const TDesC* aDriver, const TDesC8* aInfo) const;
+	TInt ChannelCreate(DLogicalChannelBase*& pC, TChannelCreateInfo& aInfo);
+	TInt FindPhysicalDevice(DLogicalChannelBase* aChannel, TChannelCreateInfo& aInfo);
+
+
+	/**
+	Second stage constructor for derived objects.
+	This must at least set a name for the driver object.
+
+	@return KErrNone or standard error code.
+	*/
+	virtual TInt Install()=0;
+
+
+	/**
+	Gets the driver's capabilities.
+	
+	This is called in the response to an RDevice::GetCaps() request.
+
+	@param aDes A user-side descriptor into which capabilities information is to be wriiten.
+	*/
+	virtual void GetCaps(TDes8& aDes) const =0;
+
+
+	/**
+	Called by the kernel's device driver framework to create a Logical Channel.
+	This is called in the context of the user thread (client) which requested the creation of a Logical Channel
+	(e.g. through a call to RBusLogicalChannel::DoCreate).
+	The thread is in a critical section.
+
+	@param aChannel Set to point to the created Logical Channel
+
+	@return KErrNone or standard error code.
+	*/
+	virtual TInt Create(DLogicalChannelBase*& aChannel)=0;
+
+
+public:
+    /**
+    The version of this factory object.
+
+    This is used to check that an LDD and PDD are compatible.
+    Typically, this is set by the constructor of a derived class.
+    */
+	TVersion iVersion;
+	
+	
+	/**
+	A bitmask that indicates device properties.
+
+    This can take the following values:
+    KDeviceAllowUnit
+    KDeviceAllowPhysicalDevice
+    KDeviceAllowInfo
+    KDeviceAllowAll
+    
+    Typically, this is set by the constructor of a derived class.
+
+    @see RBusLogicalChannel::DoCreate()
+    @see KDeviceAllowUnit
+    @see KDeviceAllowPhysicalDevice
+    @see KDeviceAllowInfo
+    @see KDeviceAllowAll
+	*/
+	TUint iParseMask;
+	
+	
+	/**
+	Indicates which units are valid.
+
+    If units are allowed, i.e. the KDeviceAllowUnit bit is set in iParseMask,
+    then this mask indicates which of the units (from 0 to 31) are valid.
+
+    The DPhysicalDevice object associated with the PDD has a similar mask,
+    and both masks are used to indicate which units the LDD-PDD pair
+    can handle.
+
+    Typically, this is set by the constructor of a derived class.
+    
+    @see KDeviceAllowUnit
+	*/
+	TUint iUnitsMask;
+	
+	
+	/**
+	Pointer to the DCodeSeg object which contains the executable code
+	for this LDD.
+	*/
+	DCodeSeg* iCodeSeg;
+	
+	
+	/**
+	Number of DLogicalChannelBase objects currently in existence which
+	have been created from this LDD.
+	*/
+	TInt iOpenChannels;
+	};
+
+/** @internalComponent */
+typedef DLogicalDevice* (*TLogicalDeviceNew)();
+
+
+
+
+/**
+@publishedPartner
+@released
+
+The abstract base class for a PDD factory object.
+*/
+class DPhysicalDevice : public DObject
+	{
+public:
+	enum TInfoFunction
+		{
+		EPriority=0,
+		
+		/** if implemented (i.e. Info(EMediaDriverPersistent) returns KErrNone) implies the media driver 
+		created by this DPhysicalDevice will not be unloaded when the peripheral bus is powered down */
+		EMediaDriverPersistent=1,
+		};
+public:
+	IMPORT_C virtual ~DPhysicalDevice();
+	IMPORT_C virtual TBool QueryVersionSupported(const TVersion& aVer) const;
+	IMPORT_C virtual TBool IsAvailable(TInt aUnit, const TDesC8* aInfo) const;
+
+	/**
+	Second stage constructor for derived objects.
+	This must at least set a name for the driver object.
+
+	@return KErrNone or standard error code.
+	*/
+	virtual TInt Install() =0;
+
+	/**
+	Returns the drivers capabilities. This is not used by the Symbian OS device driver framework
+	but may be useful for the LDD to use.
+
+	@param aDes Descriptor to write capabilities information into
+	*/
+	virtual void GetCaps(TDes8& aDes) const =0;
+
+	/**
+	Called by the kernel's device driver framework to create a Physical Channel.
+	This is called in the context of the user thread (client) which requested the creation of a Logical Channel
+	(E.g. through a call to RBusLogicalChannel::DoCreate)
+	The thread is in a critical section.
+
+	@param aChannel Set to point to the created Physical Channel
+	@param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
+	@param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
+	@param aVer The version number of the Logical Channel which will use this Physical Channel 
+
+	@return KErrNone or standard error code.
+	*/
+	virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) =0;
+
+	/**
+	Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.
+	This is called in the context of the user thread (client) which requested the creation of a Logical Channel
+	(E.g. through a call to RBusLogicalChannel::DoCreate)
+	The thread is in a critical section.
+
+	@param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
+	@param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
+	@param aVer The version number of the Logical Channel which will use this Physical Channel 
+
+	@return KErrNone or standard error code.
+	*/
+	virtual TInt Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) =0;
+	IMPORT_C virtual TInt Info(TInt aFunction, TAny* a1);
+public:
+	TVersion iVersion;
+	TUint iUnitsMask;
+	DCodeSeg* iCodeSeg;
+	};
+
+
+
+
+/** @internalComponent */
+typedef DPhysicalDevice* (*TPhysicalDeviceNew)();
+
+// Utility stuff for PDD finding
+
+/** @internalTechnology */
+struct SPhysicalDeviceEntry
+	{
+	TInt iPriority;
+	DPhysicalDevice* iPhysicalDevice;
+	};
+
+/** @internalTechnology */
+class RPhysicalDeviceArray : public RArray<SPhysicalDeviceEntry>
+	{
+public:
+	IMPORT_C RPhysicalDeviceArray();
+	IMPORT_C void Close();
+	IMPORT_C TInt GetDriverList(const TDesC& aMatch, TInt aUnit, const TDesC8* aInfo, const TVersion& aVersion);
+	};
+
+/********************************************
+ * Kernel-side messages and message queues.
+ ********************************************/
+class TMessageQue;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+The base class for a kernel side message.
+
+This is a means of communication between Symbian OS threads
+executing kernel-side code.
+*/
+class TMessageBase : public SDblQueLink
+	{
+public:
+	/** @internalComponent */
+	enum TState {EFree,EDelivered,EAccepted};
+public:
+	TMessageBase() : iState(EFree), iQueue(NULL) {}
+	IMPORT_C void Send(TMessageQue* aQ);
+	IMPORT_C TInt SendReceive(TMessageQue* aQ);
+	IMPORT_C void Forward(TMessageQue* aQ, TBool aReceiveNext);
+	IMPORT_C void Complete(TInt aResult, TBool aReceiveNext);
+	IMPORT_C void Cancel();			/**< @internalComponent */
+	IMPORT_C void PanicClient(const TDesC& aCategory, TInt aReason);
+public:
+	IMPORT_C DThread* Client();
+public:
+	TUint8 iState;					/**< @internalComponent */
+	TMessageQue* iQueue;			/**< @internalComponent */
+	NFastSemaphore iSem;			/**< @internalComponent */
+	TInt iValue;					/**< @internalComponent */ // msg id/return code
+	};
+
+
+
+
+/**
+@publishedPartner
+@released
+
+A queue for kernel-side messages.
+
+Objects of this type consist of a DFC plus a doubly-linked list
+of received messages.
+*/
+class TMessageQue : private TDfc
+	{
+public:
+	IMPORT_C TMessageQue(TDfcFn aFunction, TAny* aPtr, TDfcQue* aDfcQ, TInt aPriority);
+	IMPORT_C void Receive();
+	IMPORT_C TMessageBase* Poll();
+	IMPORT_C TMessageBase* Last();
+	IMPORT_C void CompleteAll(TInt aResult);
+	using TDfc::SetDfcQ;
+public:
+	inline static void Lock() {NKern::FMWait(&MsgLock);}			/**< @internalComponent */
+	inline static void Unlock() {NKern::FMSignal(&MsgLock);}		/**< @internalComponent */
+	inline void UnlockAndKick() {Enque(&MsgLock);}					/**< @internalComponent */
+public:
+	SDblQue iQ;						/**< @internalComponent */
+	TBool iReady;					/**< @internalComponent */
+	TMessageBase* iMessage;			/**< @internalComponent */
+	static NFastMutex MsgLock;		/**< @internalComponent */
+	friend class TMessageBase;
+	};
+
+
+
+
+/**
+@publishedPartner
+@released
+	
+Synchronous kernel-side messages.
+	
+There is one per thread, and the thread always blocks while the message is outstanding.
+The iPtr field of a DFC points to the message.
+*/
+class TThreadMessage : public TMessageBase
+	{
+public:
+    /**
+    Returns argument 0 as an integer.
+    */
+	inline TInt Int0() const {return (TInt)iArg[0];}
+	
+    /**
+    Returns argument 1 as an integer.
+    */
+	inline TInt Int1() const {return (TInt)iArg[1];}
+	
+    /**
+    Returns argument 2 as an integer.
+    */
+	inline TInt Int2() const {return (TInt)iArg[2];}
+	
+    /**
+    Returns argument 3 as an integer.
+    */
+	inline TInt Int3() const {return (TInt)iArg[3];}
+	
+    /**
+    Returns argument 0 as a pointer type.
+    */
+	inline TAny* Ptr0() const {return iArg[0];}
+	
+    /**
+    Returns argument 1 as a pointer type.
+    */
+	inline TAny* Ptr1() const {return iArg[1];}
+	
+    /**
+    Returns argument 2 as a pointer type.
+    */
+	inline TAny* Ptr2() const {return iArg[2];}
+	
+    /**
+    Returns argument 3 as a pointer type.
+    */
+	inline TAny* Ptr3() const {return iArg[3];}
+public:
+    /**
+    Message arguments.
+    */
+	TAny* iArg[10];				// message arguments
+	};
+
+
+
+
+/**
+@publishedPartner
+@released
+	
+An abstract class for a logical channel that provides a framework in which
+user-side client requests are executed in the context of
+a single kernel-side thread.
+*/
+class DLogicalChannel : public DLogicalChannelBase
+	{
+public:
+	enum {
+	      /**
+	      Defines the smallest request number that Request() accepts.
+	      Smaller request numbers will raise a panic.
+	      */
+	      EMinRequestId=(TInt)0xc0000000,
+	      
+	      /**
+	      The value of the close message sent to the device driver thread
+	      by Close().
+	      */
+	      ECloseMsg=(TInt)0x80000000};
+public:
+	IMPORT_C DLogicalChannel();
+	IMPORT_C virtual ~DLogicalChannel();
+	IMPORT_C virtual TInt Close(TAny*);
+	IMPORT_C virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
+ 	IMPORT_C virtual TInt SendMsg(TMessageBase* aMsg);
+
+	/**
+	Processes a message for this logical channel.
+	This function is called in the context of a DFC thread.
+
+	@param aMsg     The message to process.
+	                The iValue member of this distinguishes the message type:
+	                iValue==ECloseMsg, channel close message
+	                iValue==KMaxTInt, a 'DoCancel' message
+	                iValue>=0, a 'DoControl' message with function number equal to iValue
+	                iValue<0, a 'DoRequest' message with function number equal to ~iValue
+	*/
+	IMPORT_C virtual void HandleMsg(TMessageBase* aMsg)=0;
+	IMPORT_C void SetDfcQ(TDfcQue* aDfcQ);
+public:
+	static void MsgQFunc(TAny* aPtr);
+public:
+	TDfcQue* iDfcQ;
+	TMessageQue iMsgQ;
+	};
+
+
+
+
+/********************************************
+ * Timers based on the system tick
+ ********************************************/
+
+/**
+@publishedPartner
+@released
+
+Defines the signature for a tick timer callback function.
+*/
+typedef void (*TTickCallBack)(TAny* aPtr);
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Relative timer with the resolution of one Symbian OS tick (generally 1/64 second).
+
+Tick timers are general purpose interval timers which are used where there
+is no need for high resolution or great accuracy. They correspond to the
+timing functions available to user side code on EKA1 (User::After,
+RTimer::After, RTimer::Lock).
+
+@see User::After()
+@see RTimer::After()
+@see RTimer::Lock()
+*/
+class TTickLink : public SDeltaQueLink
+	{
+public:
+	IMPORT_C TTickLink();
+	IMPORT_C void Periodic(TInt aPeriod, TTickCallBack aCallBack, TAny* aPtr);
+	IMPORT_C void OneShot(TInt aTime, TTickCallBack aCallBack, TAny* aPtr);
+	IMPORT_C void Lock(TInt aTicks, TTickCallBack aCallBack, TAny* aPtr);
+	IMPORT_C void Cancel();
+	void DoCancel();
+	TInt GetNextLock(TTimerLockSpec aMark, TInt &aTickCount) const;
+public:
+	TInt iPeriod;				/**< @internalComponent */
+	TAny *iPtr;					/**< @internalComponent */
+	TTickCallBack iCallBack;	/**< @internalComponent */
+	Int64 iLastLock;			/**< @internalComponent */
+	};
+
+
+
+
+/**
+@publishedPartner
+@released
+	
+Defines the signature for a second timer callback function.
+
+@see TSecondLink
+*/
+typedef void (*TSecondCallBack)(TAny* aPtr);
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Absolute timer with a resolution of 1 second.
+
+Second timers are used when an event needs to occur at a specific date and
+time of day, rather than after a specified interval. They have a resolution of
+1 second.
+
+They are typically used for user alarms, and, if necessary, will power up
+the system at the expiry time.
+*/
+class TSecondLink : public SDblQueLink
+	{
+public:
+	IMPORT_C TSecondLink();
+	IMPORT_C TInt At(const TTimeK& aUTCTime, TSecondCallBack aCallBack, TAny* aPtr);
+	IMPORT_C void Cancel();
+public:
+	Int64 iTime;				/**< @internalComponent */
+	TAny* iPtr;					/**< @internalComponent */
+	TSecondCallBack iCallBack;	/**< @internalComponent */
+	};
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Defines the signature for an inactivity timer callback function.
+
+@see TInactivityLink
+*/
+typedef void (*TInactivityCallBack)(TAny*);
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Inactivity timer.
+
+Inactivity timers are used to detect a specified period of user inactivity,
+for example to enable device auto power down or screen saver functionality.
+*/
+class TInactivityLink : public SDblQueLink
+	{
+public:
+	IMPORT_C TInactivityLink();
+	IMPORT_C TInt Start(TInt aSeconds, TInactivityCallBack aCallBack, TAny* aPtr);
+	IMPORT_C void Cancel();
+public:
+	TUint32 iTime;					/**< @internalComponent */ // expiry time in ticks
+	TAny* iPtr;						/**< @internalComponent */
+	TInactivityCallBack iCallBack;	/**< @internalComponent */
+	};
+
+/********************************************
+ * Internal RAM drive
+ ********************************************/
+
+/**
+	@internalTechnology
+*/
+class TInternalRamDrive
+	{
+public:
+	static TInt Create();
+	IMPORT_C static TLinAddr Base();
+	IMPORT_C static TInt Size();
+	IMPORT_C static TInt MaxSize();
+	IMPORT_C static TInt Adjust(TInt aNewSize);
+	IMPORT_C static void Lock();
+	IMPORT_C static void Unlock();
+	IMPORT_C static void Wait();
+	IMPORT_C static void Signal();
+public:
+	static DMutex* Mutex;
+	friend class Monitor;
+	};
+
+/********************************************/
+
+/** List of all supported events.
+
+	By default, all events, except the explicitly mentioned ones, are sent only
+	if the kernel is built with __DEBUGGER_SUPPORT__ defined.
+
+	This event set may be extended in the future, so clients should handle
+	unknown events gracefully.
+
+	@see DKernelEventHandler
+	@publishedPartner
+	@released
+*/
+enum TKernelEvent
+	{
+	/**
+	Event delivered when a user-side software exception occurs.
+	This event is always sent.
+	The following conditions are true:
+		- a1 contains a TExcType instance.
+		- The current thread is the thread taking the exception.
+	*/
+	EEventSwExc,
+
+	/**
+	Event delivered when a hardware exception occurs.
+	This event is always sent.
+	The following conditions are true:
+		- a1 points to the CPU-specific structure stored on the 
+		  stack where the processor state has been saved.  For ARM, 
+		  the structure is TArmExcInfo.
+		- The current thread is the thread taking the exception.
+	On exit, use DKernelEventHandler::EExcHandled to indicate event
+	handled.
+	*/
+	EEventHwExc,
+
+	/**
+	Event delivered when a process is created (i.e. during a call to 
+	RProcess::Create or Kern::ProcessCreate()).
+	The following conditions are true:
+		- a1 points to the process being created.
+		- a2 points to the creator thread (which may not be the current thread).
+		  In some case the creator thread can not be reliably determined and a2
+		  will be set to NULL.
+		- The process being created is partly constructed (no threads and no chunks yet).
+	*/
+	EEventAddProcess,
+
+	/**
+	Event delivered after a process attribute change.  Currently this applies
+	only to process renaming and address space change (chunk addition/removal)
+	but may be extended in the future.
+	The following conditions are true:
+		- a1 points to the process being modified.
+		- The process lock may be held
+	*/
+	EEventUpdateProcess,
+
+	/**
+	Event delivered when a process terminates.
+	The following conditions are true:
+		- a1 points to the process being terminated.
+		- The current thread is the kernel server thread.
+		- The process is partly destructed so its resources should be accessed
+		  only after checking they still exist.
+	*/
+	EEventRemoveProcess,
+
+	/**
+	Event delivered when a user or kernel thread is created (i.e. during a call
+	to RProcess::Create(), RThread::Create() or Kern::ThreadCreate()).  
+	The following conditions are true:
+		- a1 points to the thread being created.
+		- a2 points to the creator thread (which may not be the current thread).
+		- The thread being created is fully constructed but has not executed any code yet.
+	*/
+	EEventAddThread,
+
+	/**
+	Event delivered when a user or kernel thread is scheduled for the first time.
+	The following conditions are true:
+		- a1 points to the thread being scheduled.
+		- The current thread is the thread being scheduled.
+		- The thread has not executed any code yet.
+	*/
+	EEventStartThread,
+
+	/**
+	Event delivered after a thread attribute change.  Currently this applies
+	only to thread renaming but may be extended in the future.
+	a1 points to the thread being modified.
+	*/
+	EEventUpdateThread,
+
+	/**
+	Event delivered when a user or kernel thread terminates.
+	This event is always sent.
+	The following conditions are true:
+		- a1 points to the thread being terminated.
+		- The current thread is the thread being terminated.
+		- The current thread is in the ECSExitInProgress state, 
+		  and so can not be suspended.
+		- The thread's address space can be inspected.
+	*/
+	EEventKillThread,
+
+	/**
+	Event delivered when a user or kernel thread is about to be closed.
+	The following conditions are true:
+		- a1 points to the thread being terminated.
+		- The current thread is the supervisor thread.
+		- The thread is partly destructed so its resources should be accessed
+		  only after checking if they still exist.
+	 */
+	EEventRemoveThread,
+
+	/**
+	Event delivered when a chunk is created.
+	The following conditions are true:
+		- a1 points to the chunk being created.
+	*/
+	EEventNewChunk,
+
+	/**
+	Event delivered when physical memory is committed to/decommitted from a
+	chunk.
+	The following conditions are true:
+		- a1 points to the chunk being modified.
+	*/
+	EEventUpdateChunk,
+
+	/**
+	Event delivered when a chunk is deleted.
+	The following conditions are true:
+		- a1 points to the chunk being deleted.
+	*/
+	EEventDeleteChunk,
+
+	/**
+	Event delivered when a user-side DLL is explicitly loaded.
+	The following conditions are true:
+		- a1 points to the DLibrary instance being loaded.
+		- a2 points to the creator thread.
+		- DLibrary::iMapCount is equals to 1 if the DLL is loaded for the first 
+		  time into the creator thread's address space.
+		- If the DLL is loaded for the first time, its global c'tors (if any) 
+		  haven't been called yet.
+		- The DLL and all its dependencies have been mapped.
+		- The system-wide mutex DCodeSeg::CodeSegLock is held.
+	*/
+	EEventAddLibrary,
+
+	/**
+	Event delivered when a previously explicitly loaded user-side DLL is 
+	closed or unloaded (i.e. call to RLibrary::Close()).
+	The following conditions are true:
+		- a1 points to the DLibrary instance being unloaded.
+		- DLibrary::iMapCount is equals to 0 if the DLL is about to be unloaded.
+		- If the DLL is about to be unloaded, its global d'tors have been called
+		  but it is still mapped (and so are its dependencies).
+		- The current thread may be the kernel server.
+		- The system-wide mutex DCodeSeg::CodeSegLock is held.
+	*/
+	EEventRemoveLibrary,
+
+	/**
+	Event delivered when a LDD is loaded.  
+	The following conditions are true:
+		- a1 points to the LDD's code segment (DCodeSeg instance).
+		- The current thread is the loader thread.
+		- The LDD factory function has not been called yet.
+	*/
+	EEventLoadLdd,
+
+	/** 
+	Event delivered when a LDD is unloaded.
+	The following conditions are true:
+		- a1 points to the LDD's code segment (DCodeSeg instance).
+		- The current thread is the loader thread.
+	*/
+	EEventUnloadLdd,
+
+	/**
+	Event delivered when a PDD is loaded.
+	The following conditions are true:
+		- a1 points to the PDD's code segment (DCodeSeg instance).
+		- The current thread is the loader thread.
+		- The PDD factory function has not been called yet.
+	*/
+	EEventLoadPdd,
+
+	/** 
+	Event delivered when a PDD is unloaded.
+	The following conditions are true:
+		- a1 points to the PDD's code segment (DCodeSeg instance).
+		- The current thread is the loader thread.
+	*/
+	EEventUnloadPdd,
+
+	/** 
+	Event delivered when RDebug::Print is called in user-side code.
+	The following conditions are true:
+		- a1 points to the user-side buffer containing the unicode string 
+		  for printing.  The characters can not be accessed directly. The
+		  string must copied instead using kumemget() and, as the event
+		  is delivered in thread critical section, the call to kumemget()
+		  must be protected with XTRAP.
+		- a2 is a TInt which holds the length in characters of the string 
+		  for printing.  As this is a unicode string, the size of the 
+		  user-side buffer is twice the length.
+		- The current thread is the user-side client.
+	On exit use DKernelEventHandler::ETraceHandled to indicate event handled.
+	*/
+	EEventUserTrace,
+	
+	/**
+	Event delivered when a code segment is mapped into a process.
+	The following conditions are true:
+		- a1 points to the code segment.
+		- a2 points to the process.
+		- The system-wide mutex DCodeSeg::CodeSegLock is held.
+	*/
+	EEventAddCodeSeg,
+
+	/**
+	Event delivered when a code segment is unmapped from a process.
+	The following conditions are true:
+		- a1 points to the code segment.
+		- a2 points to the process.
+		- The system-wide mutex DCodeSeg::CodeSegLock is held.
+	*/
+	EEventRemoveCodeSeg,
+	
+	/**
+	Event delivered when a process is created (i.e. during a call to 
+	RProcess::Create or Kern::ProcessCreate()).
+	The following conditions are true:
+		- a1 points to the process.
+		- The process being created is fully constructed.
+	*/
+	EEventLoadedProcess,
+
+	/**
+	Event delivered when a process is being released, before its code segment,
+	stack chunk, etc. are unmapped.
+	The following conditions are true:
+		- a1 points to the process.
+		- The process being released is fully constructed.
+	*/
+	EEventUnloadingProcess,
+
+	/**
+	Must be last
+	*/
+	EEventLimit
+	};
+
+/** Access-counted event handler callback.
+
+	The kernel maintains a queue of event handlers which are called in turn 
+	when various events (thread creation, hardware exception, ...) occur.
+
+	Typical clients would be drivers or kernel extensions implementing kernel
+	debug agents or profilers.  This class could also be used to extend the
+	instruction set (by trapping undefined instructions).
+
+	An access count needs to be maintained because handlers can not be dequeued
+	and destructed while one or more threads are executing some code inside the
+	callback.  The access count, initially set to 1, is incremented every time
+	a thread enters the callback and decremented every time a thread exits the
+	callback.  
+	
+	Consequently: 
+
+	- Client code should use Close() instead the operator delete to destroy the
+	  event handler.  
+
+	- If the client is a LDD, the lifetime of the event handler may exceed that
+	of the logical channel and its user-side client thread.  Therefore, the
+	callback should not refer to data stored in the channel and any
+	asynchronous request to be completed in the callback should be cancelled by
+	the channel destructor.
+
+	If the client is a RAM-loaded LDD (or PDD), it is possible for the DLL to
+	be unloaded while the handler is still in use.  This would result in an
+	exception.  To avoid this, the handler must open a reference to the
+	DLogicalDevice (or DPhysicalDevice) and close it in its d'tor.
+
+	@publishedPartner
+	@released
+*/
+class DKernelEventHandler : public DBase
+	{
+public:
+	/** Values used to select where to insert the handler in the queue */
+	enum TAddPolicy
+		{
+		EAppend, /**< Append at end of queue */
+		};
+
+	/** Bitmask returned by callback function */
+	enum TReturnCode
+		{
+		/** Run next handler if set, ignore remaining handlers if cleared */
+		ERunNext = 1,
+		/** Available for EEventUserTrace only.  Ignore trace statement if set. */
+		ETraceHandled = 0x40000000,
+		/** Available for hardware exceptions only.  Do not panic thread if set. */
+		EExcHandled = (TInt)0x80000000,
+		};
+
+	/** Pointer to C callback function called when an event occurs.
+		aEvent designates what event is dispatched.  a1 and a2 are event-specific.  
+		aPrivateData is specified when the handler is created, typically a pointer
+		to the event handler.  
+		The function is always called in thread critical section. 
+		@see TReturnCode
+	 */
+	typedef TUint (*TCallback)(TKernelEvent aEvent, TAny* a1, TAny* a2, TAny* aPrivateData);
+public:
+	// external interface
+	IMPORT_C static TBool DebugSupportEnabled();
+	IMPORT_C DKernelEventHandler(TCallback aCb, TAny* aPrivateData);
+	IMPORT_C TInt Add(TAddPolicy aPolicy = EAppend);
+	IMPORT_C TInt Close();
+	inline TBool IsQueued() const;
+public:
+	// kernel internal interface
+	static TUint Dispatch(TKernelEvent aEvent, TAny* a1, TAny* a2);
+private:
+	static SDblQue HandlersQ;
+private:
+	TInt iAccessCount;
+	SDblQueLink iLink;
+	TCallback iCb;
+	TAny* iPrivateData;
+	};
+
+/** Returns whether or not the handler has been queued. */
+inline TBool DKernelEventHandler::IsQueued() const
+	{
+	return iLink.iNext != NULL;
+	}
+
+
+/********************************************
+ * Persistent Machine Configuration
+ ********************************************/
+
+/**
+	@internalTechnology
+*/
+class TMachineConfig
+	{
+public:
+	TInt iLogSize;
+	TInt iLogMaxSize;
+	SLocaleData iLocale;
+	TInt iXtalError;
+
+	/** The last time set by the user */
+	TTimeK LastSetTime;
+
+	/** The accumulated RTC correction due to crystal errors */
+	TInt TheRTCCorrection;
+	};
+
+/******************************************************************************
+ * Macros for typical extensions/device drivers/ASSPs
+ ******************************************************************************/
+#ifndef __WINS__
+/**
+@internalComponent
+@prototype 9.5
+	
+Defines the entry point for an extension that specifies a priority
+Priorities are used to sequence calls to the entry point (KModuleEntryReasonExtensionInit1)
+and may be used to ensure that extensions with higher priority are started before
+ones with lower priority. When the priority of 2 extensions is the same, the order
+they are started is the order they appear in the ROM header extension list.
+The maximum priority is 255. Priority 0 is the lowest priority (standard extension).
+@note This feature is not available for the emulator.
+*/
+#define	DECLARE_EXTENSION_WITH_PRIORITY(priority)							\
+	GLREF_C TInt InitExtension();											\
+	TInt KernelModuleEntry(TInt aReason)									\
+		{																	\
+		if (aReason==KModuleEntryReasonExtensionInit0)						\
+			return priority;												\
+		if (aReason!=KModuleEntryReasonExtensionInit1)						\
+			return KErrArgument;											\
+		return InitExtension();												\
+		}																	\
+	GLDEF_C TInt InitExtension()
+
+
+/**
+@publishedPartner
+@released
+	
+Defines the entry point for a standard extension	
+*/
+#define	DECLARE_STANDARD_EXTENSION() DECLARE_EXTENSION_WITH_PRIORITY(KExtensionStandardPriority)
+
+#else 
+/**
+@publishedPartner
+@released
+	
+Defines the entry point for a standard extension	
+*/
+#define	DECLARE_STANDARD_EXTENSION()										\
+	GLREF_C TInt InitExtension();											\
+	TInt KernelModuleEntry(TInt aReason)									\
+		{																	\
+		if (aReason==KModuleEntryReasonExtensionInit0)						\
+			return KErrNone;												\
+		if (aReason!=KModuleEntryReasonExtensionInit1)						\
+			return KErrArgument;											\
+		return InitExtension();												\
+		}																	\
+	GLDEF_C TInt InitExtension()
+
+#endif
+
+/**
+@publishedPartner
+@released
+
+Defines the entry point for a standard logical device driver (LDD),
+and declares the ordinal 1 export function for creating the LDD factory object	
+*/
+#define	DECLARE_STANDARD_LDD()												\
+	TInt KernelModuleEntry(TInt)											\
+		{ return KErrNone; }												\
+	EXPORT_C DLogicalDevice* CreateLogicalDevice()
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Defines the entry point for a standard physical device driver (PDD),
+and declares the ordinal 1 export function for creating the PDD factory object.
+*/
+#define	DECLARE_STANDARD_PDD()												\
+	TInt KernelModuleEntry(TInt)											\
+		{ return KErrNone; }												\
+	EXPORT_C DPhysicalDevice* CreatePhysicalDevice()
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Defines the entry point for a standard logical device driver (LDD)
+that is also an extension, and declares the ordinal 1 export function
+for creating the LDD factory object	
+*/
+#define	DECLARE_EXTENSION_LDD()												\
+	EXPORT_C DLogicalDevice* CreateLogicalDevice()
+
+
+
+
+/**
+@publishedPartner
+@released
+	
+Defines the entry point for a standard physical device driver (PDD)
+that is also an extension, and declares the ordinal 1 export function
+for creating the PDD factory object	
+*/
+#define	DECLARE_EXTENSION_PDD()												\
+	EXPORT_C DPhysicalDevice* CreatePhysicalDevice()
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Generates a stub entry point function and the AsicInitialise() function that 
+causes static constructors to be called.
+
+ASSP DLLs require static constructors to be called at the same time as
+the variant is initialised.
+*/
+#define	DECLARE_STANDARD_ASSP()												\
+	extern "C" { GLREF_C TInt _E32Dll(TInt); }								\
+	GLDEF_C TInt KernelModuleEntry(TInt aReason)							\
+		{ return (aReason==KModuleEntryReasonExtensionInit1)				\
+						?KErrNone:KErrGeneral; }							\
+	EXPORT_C void AsicInitialise()											\
+		{ _E32Dll(KModuleEntryReasonExtensionInit1); }
+
+
+/**
+@internalComponent
+*/
+#define	__VARIANT_SUPPORTS_ADDITIONAL_INTERFACE_BLOCK__(x)					\
+	__Variant_Flags__ |= (x)
+
+/**
+@internalTechnology
+@prototype
+Used to indicate that a variant supports the nanokernel interface block
+*/
+#define	__VARIANT_SUPPORTS_NANOKERNEL_INTERFACE_BLOCK__()					\
+			__VARIANT_SUPPORTS_ADDITIONAL_INTERFACE_BLOCK__(1)
+
+
+class DemandPaging;
+
+/**
+Memory locking on demand paging systems.
+
+This class is not thread safe. I.e. Only one method should be executed at any time
+for a given instance of an object.
+
+@internalTechnology
+@prototype
+*/
+class DDemandPagingLock : public DBase
+	{
+public:
+	IMPORT_C DDemandPagingLock();
+
+	/**
+	Unlock and Free the memory associated with this object
+	*/
+	inline ~DDemandPagingLock() { Free(); }
+
+	/**
+	Reserve memory so that this object can be used for locking up to
+	the specified number of bytes.
+
+	@param aSize Maximum number of bytes to be locked.
+
+	@return KErrNone or standard error code.
+	*/
+	IMPORT_C TInt Alloc(TInt aSize);
+
+	/**
+	Unlock any memory locked by this object, then free the memory reserved with 
+	Alloc(). This returns the object to the same state it was at immediately after 
+	construction.
+	*/
+	IMPORT_C void Free();
+
+	/**
+	Ensure all pages in the given region are present and lock them so that they will 
+	not be paged out. If the region contained no demand paged memory, then no action 
+	is performed.
+
+	This function may not be called again until the previous memory has been 
+	unlocked.
+
+	@param aThread The thread in whoes process the memory lies.
+	@param aStart The address of the first byte of memory to be locked.
+	@param aSize The number of bytes to lock.
+
+	@return 1 (one) if any memory was locked. 0 (KErrNone) if memory
+			did not need locking because it is not demand paged. Otherwise
+			KErrBadDescriptor to indicate that the memory region was not
+			valid.
+
+	@pre Alloc must have been used to reserve sufficient RAM.
+	*/
+	IMPORT_C TInt Lock(DThread* aThread, TLinAddr aStart, TInt aSize);
+
+	/**
+	Unlock the memory region which was previousely locked with Lock.
+	This may be called even if memory wasn't previousely locked.
+	*/
+	inline void Unlock() { if(iLockedPageCount) DoUnlock(); }
+
+private:
+	IMPORT_C void DoUnlock();
+private:
+	DemandPaging* iThePager;
+	TInt iReservedPageCount;
+	TInt iLockedPageCount;
+	TLinAddr iLockedStart;
+	DProcess* iProcess;
+	TPhysAddr* iPages;
+	TAny* iPinMapping;
+	TInt iMaxPageCount;
+
+	friend class DemandPaging;
+	};
+
+
+
+class DPagingRequestPool;
+
+/**
+Base class for Paging Devices.
+A Paging Device provides the paging system with access to storage media which holds
+data being demand paged.
+@internalTechnology
+@prototype
+*/
+class DPagingDevice : public DBase
+	{
+public:
+	/** The type of device this represents. */
+	enum TType
+		{
+		ERom  = 1<<0,	/**< Paged ROM device type. */
+		ECode = 1<<1,	/**< Code paging device type. */
+		EData = 1<<2	/**< Data paging device type. */
+		};
+
+	enum TSpecialDrives
+		{
+		EDriveRomPaging = -1,	/**< Special drive number to indicate rom paging. */
+		EDriveDataPaging = -2,	/**< Special drive number to indicate data paging. */
+		};
+
+	/**
+	Called by the paging system to read data from the media represented by this
+	device.
+
+	@param aBuffer The location where the read data should be stored.
+	@param aOffset The offset from the media start, in read units, from where
+				   data should be read.
+	@param aSize   The number of read units to be read.
+	
+	@param aDrvNumber The drive number for code paging or a member of TSpecialDrives for rom or data
+	paging.
+
+	@return KErrNone or standard error code.
+	*/
+	virtual TInt Read(TThreadMessage* aReq,TLinAddr aBuffer,TUint aOffset,TUint aSize, TInt aDrvNumber) = 0;
+
+	/**
+	Called by the paging system to write data to the media represented by this device.
+
+	This is only used in the implementation of data paging to write to the swap partition.
+
+	@param aBuffer The location of the data to write.
+	@param aOffset The offset from the media start, in read units, to where data should be written.
+	@param aSize   The number of read units to write.
+	@param aBackground  If set, this indicates that the request should not count as making the device busy.
+
+	@return KErrNone or standard error code.
+	*/
+	inline virtual TInt Write(TThreadMessage* aReq,TLinAddr aBuffer,TUint aOffset,TUint aSize,TBool aBackground);
+
+	/**
+	Called by the paging system to notify the media driver that data that was previously written is
+	now no longer needed.
+
+	This is only used in the implementation of data paging when data in the swap partition is no
+	longer needed.
+
+	@param aOffset The offset from the media start, in read units, to where data was written.
+	@param aSize   The size in read units.
+
+	@return KErrNone or standard error code.
+	*/
+	inline virtual TInt DeleteNotify(TThreadMessage* aReq,TUint aOffset,TUint aSize);
+
+	/**
+	Called by the paging device to notify the kernel that the device has just become idle and is not
+	currently processing any requests.
+
+	This is used by the kernel to work out when to clean pages in the background.
+
+	Note that write requests made by calling the DPagingDevice::Write() with the aBackground flag
+	set do not count towards the device being busy.
+	*/
+	IMPORT_C void NotifyIdle();
+
+	/**
+	Called by the paging device to notify the kernel that the device has just become busy and is
+	currently processing requests.
+
+	This is used by the kernel to work out when to clean pages in the background.
+
+	Note that write requests made by calling the DPagingDevice::Write() with the aBackground flag
+	set do not count towards the device being busy.
+	*/
+	IMPORT_C void NotifyBusy();
+	
+public:
+	/** The type of device this represents. */
+	TUint32 iType;
+
+	/** The local drives supported for code paging.
+	    This is a bitmask containing one bit set for each local drive supported, where the bit set
+	    is 1 << the local drive number.  If this device does not support code paging, this should be
+	    zero. */
+	TUint32 iDrivesSupported;
+
+	/** Zero terminated string representing the name of the device.
+		(Only used for debug tracing purposes.) */
+	const char* iName;
+
+	/** Log2 of the read unit size. A read unit is the number of bytes which
+		the device can optimally read from the underlying media.
+		E.g. for small block NAND, a read unit would be equal to the page size,
+		512 bytes, therefore iReadUnitShift would be set to 9. */
+	TInt iReadUnitShift;
+
+	/** The value the device should use to identify itself.
+		This value is set by Kern::InstallPagingDevice().
+		The purpose of this Id is to distinguish multiple Code Paging devices. */
+	TInt iDeviceId;
+
+	/** For data paging only, the size of the swap partition supported by this device, in read units.
+		
+		If data paging is not supported, or has been disabled by the media driver, this should be
+		zero.
+	*/
+	TInt iSwapSize;
+
+	/** The pool of DPagingRequest objects used to issue requests for this device.
+		This is setup and used internally by the kernel.
+	*/
+	DPagingRequestPool* iRequestPool;
+
+	/** Reserved for future use.
+	*/
+	TInt iSpare[4];
+	};
+
+inline TInt DPagingDevice::Write(TThreadMessage*,TLinAddr,TUint,TUint,TBool)
+	{
+	// Default implementation, may be overriden by dervied classes
+	return KErrNotSupported;
+	}
+
+inline TInt DPagingDevice::DeleteNotify(TThreadMessage*,TUint,TUint)
+	{
+	// Default implementation, may be overriden by dervied classes
+	return KErrNotSupported;
+	}
+
+extern "C" { extern TInt __Variant_Flags__; }
+
+/********************************************
+ * Shareable Data Buffers
+ ********************************************/
+/**
+   Pool create info
+
+   @publishedPartner
+   @prototype
+*/
+class TMappingAttributes2;
+
+#include <e32shbufcmn.h>
+
+class TShPoolCreateInfo
+	{
+public:
+	/**
+	Enumeration type to say that the shared pool is to be backed with memory supplied by the kernel.
+	*/
+	enum TShPoolPageAlignedBuffers
+		{
+		EPageAlignedBuffer = EShPoolPageAlignedBuffer,
+		};
+
+	/**
+	Enumeration type to say that the shared pool is to be backed with memory supplied by the kernel.
+	*/
+	enum TShPoolNonPageAlignedBuffers
+		{
+		ENonPageAlignedBuffer = EShPoolNonPageAlignedBuffer,
+		};
+
+	/**
+	Enumeration type to say that the shared pool is to be mapped onto device memory.
+	*/
+	enum TShPoolMemoryDevice
+		{
+		EDevice = EShPoolPhysicalMemoryPool,
+		};
+
+	IMPORT_C TShPoolCreateInfo(TShPoolPageAlignedBuffers aFlag, TUint aBufSize, TUint aInitialBufs);
+	IMPORT_C TShPoolCreateInfo(TShPoolNonPageAlignedBuffers aFlag, TUint aBufSize, TUint aInitialBufs, TUint aAlignment);
+
+	IMPORT_C TShPoolCreateInfo(TShPoolMemoryDevice aFlag, TUint aBufSize, TUint aInitialBufs, TUint aAlignment, TUint aPages, TPhysAddr* aPhysicalAddressList);
+
+	IMPORT_C TShPoolCreateInfo(TShPoolMemoryDevice aFlag, TUint aBufSize, TUint aInitialBufs, TUint aAlignment, TUint aPages, TPhysAddr aPhysicalAddress);
+
+	IMPORT_C TInt SetSizingAttributes(TUint aMaxBufs, TUint aMinFreeBufs, TUint aGrowByBufs, TUint aShrinkByBufs);
+	IMPORT_C TInt SetExclusive();
+	IMPORT_C TInt SetContiguous();
+	IMPORT_C TInt SetGuardPages();
+
+private:
+	friend class ExecHandler;
+	friend class DShPool;
+	friend class DMemModelShPool;
+	friend class DMemModelAlignedShPool;
+	friend class DMemModelNonAlignedShPool;
+	friend class DMemModelProcess;
+	friend class DWin32ShPool;
+	friend class DWin32AlignedShPool;
+	friend class DWin32NonAlignedShPool;
+	friend class DWin32Process;
+	friend class DShBufTestDrvChannel;
+
+	inline TShPoolCreateInfo()	///< default constructor
+		{
+		memclr(this, sizeof(TShPoolCreateInfo));
+		};
+
+	TShPoolInfo iInfo;
+
+	union PhysAddr
+		{
+		TPhysAddr* iPhysAddrList;	///< physical addresses for hardware
+		TPhysAddr  iPhysAddr;		///< physical address for hardware
+		} iPhysAddr;
+
+	TUint iPages;				///< number of pages to commit
+};
+
+#endif //__K32STD_H__