--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverOSAdaption.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,1482 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:
+*
+*/
+#include "MemSpyDriverOSAdaption.h"
+
+// System includes
+#include <kern_priv.h>
+#include <nkern.h>
+#include <nk_plat.h>
+
+#ifdef __MARM__
+
+#include <arm.h>
+// Necessary when accessing data members by steam via offsets in order
+// to prevent potential unaligned data aborts
+
+#ifdef __CC_ARM
+#define UNALIGNED_DATA_MEMBER __packed
+#endif /* __CC_ARM */
+
+#endif /* __MARM__ */
+
+#ifndef UNALIGNED_DATA_MEMBER
+#define UNALIGNED_DATA_MEMBER
+#endif
+
+// User includes
+#include "MemSpyDriverLog.h"
+#include "MemSpyDriverPAndS.h"
+#include "MemSpyDriverDevice.h"
+
+// Internal constants
+const TInt KMemSpyLocalThreadDataSizeEstimate = 0x80; // The amount of user stack that MemSpy attempts to scan for the RHeaep vTable
+
+
+
+DMemSpyDriverOSAdaptionDObject::DMemSpyDriverOSAdaptionDObject( DMemSpyDriverOSAdaption& aOSAdaption )
+: iOSAdaption( aOSAdaption )
+ {
+ }
+
+
+TUint8 DMemSpyDriverOSAdaptionDObject::GetContainerID( DObject& aObject ) const
+ {
+ return aObject.iContainerID;
+ }
+
+
+TObjectType DMemSpyDriverOSAdaptionDObject::GetObjectType( DObject& aObject ) const
+ {
+ const TUint8 containerId = GetContainerID( aObject );
+ const TObjectType ret = static_cast< TObjectType >( containerId - 1 );
+ return ret;
+ }
+
+
+DObject* DMemSpyDriverOSAdaptionDObject::GetOwner( DObject& aObject ) const
+ {
+ return aObject.iOwner;
+ }
+
+
+DObject* DMemSpyDriverOSAdaptionDObject::GetOwner( DObject& aObject, TUint8 aExpectedContainerId ) const
+ {
+ DObject* owner = GetOwner( aObject );
+ //
+ const TUint8 containerId = GetContainerID( aObject ) - 1;
+ if ( containerId != aExpectedContainerId )
+ {
+ owner = NULL;
+ }
+ //
+ return owner;
+ }
+
+TInt DMemSpyDriverOSAdaptionDObject::GetAccessCount( DObject& aObject ) const
+ {
+ return aObject.AccessCount();
+ }
+
+TInt DMemSpyDriverOSAdaptionDObject::GetUniqueID( DObject& aObject ) const
+ {
+ return aObject.UniqueID();
+ }
+
+TUint DMemSpyDriverOSAdaptionDObject::GetProtection( DObject& aObject ) const
+ {
+ return aObject.Protection();
+ }
+
+TUint8* DMemSpyDriverOSAdaptionDObject::GetAddressOfKernelOwner( DObject& aObject ) const
+ {
+ return (TUint8*)aObject.Owner();
+ }
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDThread::DMemSpyDriverOSAdaptionDThread( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ // Get current NThread and map it on to DThread
+ NThread* nThread = NKern::CurrentThread();
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::Construct() - nThread: 0x%08x", nThread ) );
+ DThread* dThread = Kern::NThreadToDThread( nThread );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::Construct() - dThread: 0x%08x", dThread ) );
+
+ // At this point, it should be possible to work out the offset of the NThread within DThread.
+ iOffset_NThread = reinterpret_cast<TUint32>( nThread ) - reinterpret_cast<TUint32>( dThread );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::Construct() - difference: 0x%08x", iOffset_NThread ) );
+
+ // Work out the delta between compile time and run time
+ TInt delta = iOffset_NThread - _FOFF( DThread, iNThread );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::Construct() - compile time vs run time offset delta: %d", delta ));
+
+ // iNThread
+ TRACE( Kern::Printf( "OSA - [DThread::iNThread] compile time offset: 0x%08x, run time offset: 0x%08x", _FOFF(DThread,iNThread), iOffset_NThread ));
+
+ // iExitType
+ iOffset_ExitType = _FOFF( DThread, iExitType ) + delta;
+ TRACE( Kern::Printf( "OSA - [DThread::iExitType] compile time offset: 0x%08x, run time offset: 0x%08x", _FOFF(DThread,iExitType), iOffset_ExitType ));
+
+ // iSupervisorStack
+ iOffset_SupervisorStackBase = _FOFF( DThread, iSupervisorStack ) + delta;
+ TRACE( Kern::Printf( "OSA - [DThread::iSupervisorStack] compile time offset: 0x%08x, run time offset: 0x%08x", _FOFF(DThread,iSupervisorStack), iOffset_SupervisorStackBase ));
+
+ // iSupervisorStackSize
+ iOffset_SupervisorStackSize = _FOFF( DThread, iSupervisorStackSize ) + delta;
+ TRACE( Kern::Printf( "OSA - [DThread::iSupervisorStackSize] compile time offset: 0x%08x, run time offset: 0x%08x", _FOFF(DThread,iSupervisorStackSize), iOffset_SupervisorStackSize ));
+ }
+
+
+NThread* DMemSpyDriverOSAdaptionDThread::GetNThread( DThread& aObject ) const
+ {
+ DThread* dThread = &aObject;
+ TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_NThread;
+ NThread* pRet = reinterpret_cast< NThread* >( pTarget );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetNThread() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
+ return pRet;
+ }
+
+
+TExitType DMemSpyDriverOSAdaptionDThread::GetExitType( DThread& aObject ) const
+ {
+ DThread* dThread = &aObject;
+ TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_ExitType;
+ UNALIGNED_DATA_MEMBER TExitType* pRet = reinterpret_cast< TExitType* >( pTarget );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - value: %d", *pRet ) );
+ return *pRet;
+ }
+
+
+TUint32 DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase( DThread& aObject ) const
+ {
+ DThread* dThread = &aObject;
+ TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_SupervisorStackBase;
+ UNALIGNED_DATA_MEMBER TUint32* pRet = reinterpret_cast< TUint32* >( pTarget );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - 0x%08x: %d", *pRet ) );
+ return *pRet;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize( DThread& aObject ) const
+ {
+ DThread* dThread = &aObject;
+ TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_SupervisorStackSize;
+ UNALIGNED_DATA_MEMBER TInt* pRet = reinterpret_cast< TInt* >( pTarget );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - value: %d", *pRet ) );
+ return *pRet;
+ }
+
+
+RAllocator* DMemSpyDriverOSAdaptionDThread::GetAllocator( DThread& aObject ) const
+ {
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocator() - START" ) );
+ //
+ RAllocator* ret = aObject.iAllocator;
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocator() - allocator: 0x%08x", ret ) );
+ //
+ if ( ret == NULL )
+ {
+ TUint32 stackAddress = 0;
+ ret = GetAllocatorAndStackAddress( aObject, stackAddress );
+ }
+ //
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocator() - END - ret: 0x%08x", ret ) );
+ return ret;
+ }
+
+
+CActiveScheduler* DMemSpyDriverOSAdaptionDThread::GetActiveScheduler( DThread& aObject ) const
+ {
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetActiveScheduler() - START" ) );
+ CActiveScheduler* ret = aObject.iScheduler;
+ //
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetActiveScheduler() - scheduler: 0x%08x", ret ) );
+ if ( ret == NULL )
+ {
+ // We need the stack address of the heap in order to locate the active scheduler.
+ // Implicitly this means that MemSpy can only list active scheduler contents for threads
+ // that use a default RHeap. This has always been the case, so this is not a functional break.
+ //
+ // Assumed stack layout is something like this:
+ //
+ // stack[0x00403ffc] 0x00000000, vTable: 0x00000000 (offset: 0004)
+ // stack[0x00403ff8] 0x00000000, vTable: 0x00000000 (offset: 0008)
+ // stack[0x00403ff4] 0x00000002, vTable: 0x00000000 (offset: 0012)
+ // stack[0x00403ff0] 0x00000002, vTable: 0x00000000 (offset: 0016)
+ // stack[0x00403fec] 0x00000000, vTable: 0x00000000 (offset: 0020)
+ // stack[0x00403fe8] 0x0000000c, vTable: 0x00000000 (offset: 0024)
+ // stack[0x00403fe4] 0x00600078, vTable: 0x80228938 (offset: 0028)
+ // stack[0x00403fe0] 0x00000001, vTable: 0x00000000 (offset: 0032)
+ // stack[0x00403fdc] 0x00600000, vTable: 0x80268430 (offset: 0036) TLocalThreadData::iTlsHeap RAllocator* 80268428 0034 vtable for RHeap
+ // stack[0x00403fd8] 0x0060009c, vTable: 0x80268394 (offset: 0040) TLocalThreadData::iTrapHandler TTrapHandler 8026838c 0014 vtable for TCleanupTrapHandler
+ // stack[0x00403fd4] 0x00600110, vTable: 0x802682ec (offset: 0044) TLocalThreadData::iScheduler CActiveScheduler* 802682e4 002c vtable for CActiveScheduler
+ // stack[0x00403fd0] 0x00600000, vTable: 0x80268430 (offset: 0048) TLocalThreadData::iHeap RAllocator* 80268428 0034 vtable for RHeap
+ // stack[0x00403fcc] 0x00000000, vTable: 0x00000000 (offset: 0052)
+ // stack[0x00403fc8] 0x00100000, vTable: 0x00000000 (offset: 0056)
+ //
+ // GetAllocatorAndStackAddress() will return the first RHeap* it finds, so this will be iTlsHeap, which
+ // is actually no bad thing as it will hopefully be initialised using an RHeap pointer.
+ // CActiveScheduler* is 8 bytes further on from that.
+ //
+ const TUint32 KOffsetToCActiveScheduler = 8;
+ //
+ TUint32 stackAddress = 0;
+ RAllocator* allocator = GetAllocatorAndStackAddress( aObject, stackAddress );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetActiveScheduler() - allocator: 0x%08x, stackAddress: 0x%08x", allocator, stackAddress ) );
+
+ // This assumes the layout of the thread local data structure, i.e. that the four bytes that follow the
+ // allocator pointer are always the active scheduler pointer.
+ if ( allocator != NULL && stackAddress > 0 )
+ {
+ TUint32* ptr = reinterpret_cast< TUint32* >( stackAddress - KOffsetToCActiveScheduler );
+ const TInt r = Kern::ThreadRawRead( &aObject, ptr, &ret, sizeof( ret ) );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetActiveScheduler() - stack address containing scheduler pointer: 0x%08x, read result: %d, CActiveScheduler*: 0x%08x", ptr, r, ret ) );
+ if ( r != KErrNone )
+ {
+ ret = NULL;
+ }
+ }
+ }
+ //
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetActiveScheduler() - END - ret: 0x%08x", ret ) );
+ return ret;
+ }
+
+
+TUint32 DMemSpyDriverOSAdaptionDThread::GetUserStackBase( DThread& aObject ) const
+ {
+ return aObject.iUserStackRunAddress;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDThread::GetUserStackSize( DThread& aObject ) const
+ {
+ return aObject.iUserStackSize;
+ }
+
+
+DProcess* DMemSpyDriverOSAdaptionDThread::GetOwningProcess( DThread& aObject ) const
+ {
+ return aObject.iOwningProcess;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDThread::GetId( DThread& aObject ) const
+ {
+ return aObject.iId;
+ }
+
+
+MemSpyObjectIx* DMemSpyDriverOSAdaptionDThread::GetHandles( DThread& aObject ) const
+ {
+ MemSpyObjectIx* handles = MemSpyObjectIx_GetHandlePointer_Thread( aObject );
+ return handles;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDThread::GetOwningProcessId( DThread& aObject ) const
+ {
+ DProcess* process = GetOwningProcess( aObject );
+ TUint ret = 0;
+ //
+ if ( process )
+ {
+ ret = OSAdaption().DProcess().GetId( *process );
+ }
+ //
+ return ret;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDThread::GetPriority( DThread& aObject ) const
+ {
+ return aObject.iThreadPriority;
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDThread::GetAddressOfOwningProcess( DThread& aObject ) const
+ {
+ return (TUint8*)aObject.iOwningProcess;
+ }
+
+
+void DMemSpyDriverOSAdaptionDThread::GetNameOfOwningProcess( DThread& aObject, TDes& aName ) const
+ {
+ if ( aObject.iOwningProcess )
+ {
+ aObject.iOwningProcess->FullName( aName );
+ }
+ }
+
+
+RAllocator* DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress( DThread& aObject, TUint32& aStackAddress ) const
+ {
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - START" ) );
+ //
+ aStackAddress = 0;
+ RAllocator* ret = NULL;
+
+ // We will assume the thread is running and that the user-side stack has been set up
+ // accordingly.
+ const TUint32 base = GetUserStackBase( aObject );
+ const TInt size = GetUserStackSize( aObject );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - base: 0x%08x, size: %d, KMemSpyLocalThreadDataSizeEstimate: %d", base, size, KMemSpyLocalThreadDataSizeEstimate ) );
+ const TUint32 top = base + size;
+
+ // This is the RHeap vtable we are looking for
+ const TUint32 rHeapVTable = OSAdaption().Device().RHeapVTable();
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - rHeapVTable: 0x%08x", rHeapVTable ) );
+ //
+ TInt r = KErrNone;
+
+#ifdef TRACE_TYPE_GENERAL
+ for( TUint32 addr = top - 4; addr >= top - KMemSpyLocalThreadDataSizeEstimate; addr -= 4 )
+ {
+ TUint32 value = 0;
+ TUint32 possibleVTable = 0;
+ //
+ TUint32* ptr = reinterpret_cast< TUint32* >( addr );
+ //
+ r = Kern::ThreadRawRead( &aObject, ptr, &value, sizeof( value ) );
+ if ( r == KErrNone )
+ {
+ Kern::ThreadRawRead( &aObject, reinterpret_cast< const TAny* >( value ), &possibleVTable, sizeof( possibleVTable ) );
+ }
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - stack[0x%08x] 0x%08x, vTable: 0x%08x (offset: %04d)", addr, value, possibleVTable, top - addr ) );
+ }
+#endif
+
+ for( TUint32 addr = top - 4; addr >= top - KMemSpyLocalThreadDataSizeEstimate; addr -= 4 )
+ {
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - addr to read from: 0x%08x", addr ) );
+ TUint32 value = 0;
+ //
+ TUint32* ptr = reinterpret_cast< TUint32* >( addr );
+ //
+ r = Kern::ThreadRawRead( &aObject, ptr, &value, sizeof( value ) );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - read from: 0x%08x, result: %d, value: 0x%08x", addr, r, value ) );
+ //
+ if ( r == KErrNone )
+ {
+ // Try and read from the address which is now stored within 'value'. We must do this because
+ // the TLD class holds an RAllocator* and we need to ascertain the vTable of the RAllocator* matches the
+ // only supported vTable that MemSpy understands (RHeap*).
+ TUint32 possibleVTable = 0;
+ r = Kern::ThreadRawRead( &aObject, reinterpret_cast< const TAny* >( value ), &possibleVTable, sizeof( possibleVTable ) );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - possible vtable read from: 0x%08x, result: %d, possibleVTable: 0x%08x", value, r, possibleVTable ) );
+ if ( r == KErrNone && possibleVTable == rHeapVTable )
+ {
+ aStackAddress = addr;
+ ret = reinterpret_cast< RAllocator* >( value );
+ break;
+ }
+ }
+ }
+ //
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - END - ret: 0x%08x, aStackAddress: 0x%08x", ret, aStackAddress ) );
+ return ret;
+ }
+
+
+TBool DMemSpyDriverOSAdaptionDThread::IsHandleIndexValid( DThread& aObject ) const
+ {
+ MemSpyObjectIx* handles = MemSpyObjectIx_GetHandlePointer_Thread( aObject );
+ return ( handles != NULL );
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDProcess::DMemSpyDriverOSAdaptionDProcess( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDProcess::GetId( DProcess& aObject ) const
+ {
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDProcess::GetId() - value: %d", aObject.iId ) );
+ return aObject.iId;
+ }
+
+
+MemSpyObjectIx* DMemSpyDriverOSAdaptionDProcess::GetHandles( DProcess& aObject ) const
+ {
+ MemSpyObjectIx* handles = MemSpyObjectIx_GetHandlePointer_Process( aObject );
+ return handles;
+ }
+
+
+TExitType DMemSpyDriverOSAdaptionDProcess::GetExitType( DProcess& aObject ) const
+ {
+ return static_cast< TExitType >( aObject.iExitType );
+ }
+
+
+DThread* DMemSpyDriverOSAdaptionDProcess::GetFirstThread( DProcess& aObject ) const
+ {
+ return aObject.FirstThread();
+ }
+
+
+TUint32 DMemSpyDriverOSAdaptionDProcess::GetSID( DProcess& aObject ) const
+ {
+ return GetSecurityInfo( aObject ).iSecureId;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDProcess::GetSecurityZone( DProcess& aObject ) const
+ {
+ return aObject.iSecurityZone;
+ }
+
+
+SSecurityInfo& DMemSpyDriverOSAdaptionDProcess::GetSecurityInfo( DProcess& aObject ) const
+ {
+ return aObject.iS;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDProcess::GetFlags( DProcess& aObject ) const
+ {
+ return aObject.iFlags;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDProcess::GetGeneration( DProcess& aObject ) const
+ {
+ return aObject.iGeneration;
+ }
+
+
+SDblQue& DMemSpyDriverOSAdaptionDProcess::GetThreadQueue( DProcess& aObject ) const
+ {
+ return aObject.iThreadQ;
+ }
+
+
+DThread* DMemSpyDriverOSAdaptionDProcess::GetThread( SDblQueLink* aLink ) const
+ {
+ DThread* ret = _LOFF( aLink, DThread, iProcessLink );
+ return ret;
+ }
+
+
+void DMemSpyDriverOSAdaptionDProcess::SetSID( DProcess& aObject, TUint32 aSID ) const
+ {
+ GetSecurityInfo( aObject ).iSecureId = aSID;
+ }
+
+
+void DMemSpyDriverOSAdaptionDProcess::SetSecurityZone( DProcess& aObject, TUint aSecurityZone ) const
+ {
+ aObject.iSecurityZone = aSecurityZone;
+ }
+
+
+TBool DMemSpyDriverOSAdaptionDProcess::IsHandleIndexValid( DProcess& aObject ) const
+ {
+ MemSpyObjectIx* handles = MemSpyObjectIx_GetHandlePointer_Process( aObject );
+ return ( handles != NULL );
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDProcess::GetCreatorId( DProcess& aObject ) const
+ {
+ return aObject.iCreatorId;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDProcess::GetAttributes( DProcess& aObject ) const
+ {
+ return aObject.iAttributes;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDProcess::GetPriority( DProcess& aObject ) const
+ {
+ return aObject.iPriority;
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDProcess::GetAddressOfOwningProcess( DProcess& aObject ) const
+ {
+ return (TUint8*)aObject.iOwningProcess;
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDProcess::GetAddressOfDataBssStackChunk( DProcess& aObject ) const
+ {
+ return (TUint8*)aObject.iDataBssStackChunk;
+ }
+
+
+
+
+DMemSpyDriverOSAdaptionDChunk::DMemSpyDriverOSAdaptionDChunk( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDChunk::GetSize( DChunk& aObject ) const
+ {
+ return aObject.Size();
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDChunk::GetMaxSize( DChunk& aObject ) const
+ {
+ return aObject.MaxSize();
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aObject ) const
+ {
+ return aObject.Base();
+ }
+
+
+DProcess* DMemSpyDriverOSAdaptionDChunk::GetOwningProcess( DChunk& aObject ) const
+ {
+ return aObject.OwningProcess();
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDChunk::GetOwningProcessId( DChunk& aObject ) const
+ {
+ TUint ret = 0;
+ //
+ DProcess* process = GetOwningProcess( aObject );
+ if ( process )
+ {
+ ret = OSAdaption().DProcess().GetId( *process );
+ }
+ //
+ return ret;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDChunk::GetControllingOwnerId( DChunk& aObject ) const
+ {
+ return aObject.iControllingOwner;
+ }
+
+
+TChunkType DMemSpyDriverOSAdaptionDChunk::GetType( DChunk& aObject ) const
+ {
+ return aObject.iChunkType;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDChunk::GetAttributes( DChunk& aObject ) const
+ {
+ return aObject.iAttributes;
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDChunk::GetAddressOfOwningProcess( DChunk& aObject ) const
+ {
+ return (TUint8*)aObject.iOwningProcess;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDChunk::GetBottom( DChunk& aObject ) const
+ {
+ return aObject.Bottom();
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDChunk::GetTop( DChunk& aObject ) const
+ {
+ return aObject.Top();
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDChunk::GetStartPos( DChunk& aObject ) const
+ {
+ return aObject.iStartPos;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDChunk::GetRestrictions( DChunk& aObject ) const
+ {
+ return aObject.iRestrictions;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDChunk::GetMapAttr( DChunk& aObject ) const
+ {
+ return aObject.iMapAttr;
+ }
+
+
+void DMemSpyDriverOSAdaptionDChunk::GetNameOfOwningProcess( DChunk& aObject, TDes& aName ) const
+ {
+ if ( aObject.OwningProcess() )
+ {
+ aObject.OwningProcess()->FullName( aName );
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDServer::DMemSpyDriverOSAdaptionDServer( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+SDblQue& DMemSpyDriverOSAdaptionDServer::GetSessionQueue( DServer& aObject ) const
+ {
+ return aObject.iSessionQ;
+ }
+
+
+DSession* DMemSpyDriverOSAdaptionDServer::GetSession( SDblQueLink* aLink ) const
+ {
+ DSession* session = _LOFF( aLink, DSession, iServerLink );
+ return session;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDServer::GetSessionCount( DServer& aObject ) const
+ {
+ TInt ret = 0;
+ //
+ SDblQueLink* anchor = &aObject.iSessionQ.iA;
+ SDblQueLink* link = aObject.iSessionQ.First();
+ //
+ while( link != anchor)
+ {
+ ++ret;
+ link = link->iNext;
+ }
+ //
+ return ret;
+ }
+
+
+DThread* DMemSpyDriverOSAdaptionDServer::GetOwningThread( DServer& aObject ) const
+ {
+ return aObject.iOwningThread;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDServer::GetOwningThreadId( DServer& aObject ) const
+ {
+ TUint ret = 0;
+ //
+ DThread* thread = GetOwningThread( aObject );
+ if ( thread )
+ {
+ ret = OSAdaption().DThread().GetId( *thread );
+ }
+ //
+ return ret;
+ }
+
+
+TIpcSessionType DMemSpyDriverOSAdaptionDServer::GetSessionType( DServer& aObject ) const
+ {
+ return static_cast< TIpcSessionType >( aObject.iSessionType );
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDServer::GetAddressOfOwningThread( DServer& aObject ) const
+ {
+ return (TUint8*)aObject.iOwningThread;
+ }
+
+
+void DMemSpyDriverOSAdaptionDServer::GetNameOfOwningThread( DServer& aObject, TDes& aName ) const
+ {
+ if ( aObject.iOwningThread )
+ {
+ aObject.iOwningThread->FullName( aName );
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDSession::DMemSpyDriverOSAdaptionDSession( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TIpcSessionType DMemSpyDriverOSAdaptionDSession::GetSessionType( DSession& aObject ) const
+ {
+ return static_cast< TIpcSessionType >( aObject.iSessionType );
+ }
+
+
+DServer* DMemSpyDriverOSAdaptionDSession::GetServer( DSession& aObject ) const
+ {
+ return aObject.iServer;
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDSession::GetAddressOfServer( DSession& aObject ) const
+ {
+ return (TUint8*)aObject.iServer;
+ }
+
+
+TUint16 DMemSpyDriverOSAdaptionDSession::GetTotalAccessCount( DSession& aObject ) const
+ {
+ return aObject.iTotalAccessCount;
+ }
+
+
+TUint8 DMemSpyDriverOSAdaptionDSession::GetSrvSessionType( DSession& aObject ) const
+ {
+ return aObject.iSvrSessionType;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDSession::GetMsgCount( DSession& aObject ) const
+ {
+ return aObject.iMsgCount;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDSession::GetMsgLimit( DSession& aObject ) const
+ {
+ return aObject.iMsgLimit;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDCodeSeg::DMemSpyDriverOSAdaptionDCodeSeg( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+DCodeSeg* DMemSpyDriverOSAdaptionDCodeSeg::GetCodeSeg( SDblQueLink* aLink ) const
+ {
+ DCodeSeg* ret = _LOFF( aLink, DCodeSeg, iTempLink );
+ return ret;
+ }
+
+
+DCodeSeg* DMemSpyDriverOSAdaptionDCodeSeg::GetCodeSeg( DLibrary& aLibrary ) const
+ {
+ return aLibrary.iCodeSeg;
+ }
+
+
+DCodeSeg* DMemSpyDriverOSAdaptionDCodeSeg::GetCodeSegFromHandle( TAny* aHandle ) const
+ {
+ DCodeSeg* ret = DCodeSeg::VerifyHandle( aHandle );
+ return ret;
+ }
+
+
+TBool DMemSpyDriverOSAdaptionDCodeSeg::GetIsXIP( DCodeSeg& aCodeSeg ) const
+ {
+ TBool ret = ETrue;
+ //
+#ifdef __WINS__
+ (void) aCodeSeg;
+#else
+ DEpocCodeSeg& epocCodeSegment = static_cast< DEpocCodeSeg& >( aCodeSeg );
+ ret = ( epocCodeSegment.iXIP != 0 );
+#endif
+ //
+ return ret;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDCodeSeg::GetCodeSegQueue( DProcess& aObject, SDblQue& aQueue ) const
+ {
+ const TInt count = aObject.TraverseCodeSegs( &aQueue, NULL, DCodeSeg::EMarkDebug, DProcess::ETraverseFlagAdd );
+ return count;
+ }
+
+
+void DMemSpyDriverOSAdaptionDCodeSeg::EmptyCodeSegQueue( SDblQue& aQueue ) const
+ {
+ DCodeSeg::EmptyQueue( aQueue, DCodeSeg::EMarkDebug );
+ }
+
+
+TUint32 DMemSpyDriverOSAdaptionDCodeSeg::GetSize( DCodeSeg& aCodeSeg ) const
+ {
+ return aCodeSeg.iSize;
+ }
+
+
+void DMemSpyDriverOSAdaptionDCodeSeg::GetCreateInfo( DCodeSeg& aCodeSeg, TCodeSegCreateInfo& aInfo ) const
+ {
+ aCodeSeg.Info( aInfo );
+ }
+
+
+TUint8 DMemSpyDriverOSAdaptionDCodeSeg::GetState( DLibrary& aLibrary ) const
+ {
+ return aLibrary.iState;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDCodeSeg::GetMapCount( DLibrary& aLibrary ) const
+ {
+ return aLibrary.iMapCount;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDSemaphore::DMemSpyDriverOSAdaptionDSemaphore( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDSemaphore::GetCount( DSemaphore& aObject ) const
+ {
+ return aObject.iCount;
+ }
+
+
+TUint8 DMemSpyDriverOSAdaptionDSemaphore::GetResetting( DSemaphore& aObject ) const
+ {
+ return aObject.iResetting;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDMutex::DMemSpyDriverOSAdaptionDMutex( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDMutex::GetHoldCount( DMutex& aObject ) const
+ {
+ return aObject.iHoldCount;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDMutex::GetWaitCount( DMutex& aObject ) const
+ {
+ return aObject.iWaitCount;
+ }
+
+
+TUint8 DMemSpyDriverOSAdaptionDMutex::GetResetting( DMutex& aObject ) const
+ {
+ return aObject.iResetting;
+ }
+
+
+TUint8 DMemSpyDriverOSAdaptionDMutex::GetOrder( DMutex& aObject ) const
+ {
+ return aObject.iOrder;
+ }
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDLogicalDevice::DMemSpyDriverOSAdaptionDLogicalDevice( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDLogicalDevice::GetOpenChannels( DLogicalDevice& aObject ) const
+ {
+ return aObject.iOpenChannels;
+ }
+
+
+TVersion DMemSpyDriverOSAdaptionDLogicalDevice::GetVersion( DLogicalDevice& aObject ) const
+ {
+ return aObject.iVersion;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDLogicalDevice::GetParseMask( DLogicalDevice& aObject ) const
+ {
+ return aObject.iParseMask;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDLogicalDevice::GetUnitsMask( DLogicalDevice& aObject ) const
+ {
+ return aObject.iUnitsMask;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDPhysicalDevice::DMemSpyDriverOSAdaptionDPhysicalDevice( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TVersion DMemSpyDriverOSAdaptionDPhysicalDevice::GetVersion( DPhysicalDevice& aObject ) const
+ {
+ return aObject.iVersion;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDPhysicalDevice::GetUnitsMask( DPhysicalDevice& aObject ) const
+ {
+ return aObject.iUnitsMask;
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDPhysicalDevice::GetAddressOfCodeSeg( DPhysicalDevice& aObject ) const
+ {
+ return (TUint8*)aObject.iCodeSeg;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDChangeNotifier::DMemSpyDriverOSAdaptionDChangeNotifier( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDChangeNotifier::GetChanges( DChangeNotifier& aObject ) const
+ {
+ return aObject.iChanges;
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDChangeNotifier::GetAddressOfOwningThread( DChangeNotifier& aObject ) const
+ {
+ return (TUint8*)aObject.iThread;
+ }
+
+
+void DMemSpyDriverOSAdaptionDChangeNotifier::GetNameOfOwningThread( DChangeNotifier& aObject, TDes& aName ) const
+ {
+ if ( aObject.iThread )
+ {
+ aObject.iThread->FullName( aName );
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDUndertaker::DMemSpyDriverOSAdaptionDUndertaker( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDUndertaker::GetAddressOfOwningThread( DUndertaker& aObject ) const
+ {
+ return (TUint8*)aObject.iOwningThread;
+ }
+
+
+void DMemSpyDriverOSAdaptionDUndertaker::GetNameOfOwningThread( DUndertaker& aObject, TDes& aName ) const
+ {
+ if ( aObject.iOwningThread )
+ {
+ aObject.iOwningThread->FullName( aName );
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDCondVar::DMemSpyDriverOSAdaptionDCondVar( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TUint8 DMemSpyDriverOSAdaptionDCondVar::GetResetting( DCondVar& aObject ) const
+ {
+ return aObject.iResetting;
+ }
+
+
+TUint8* DMemSpyDriverOSAdaptionDCondVar::GetAddressOfMutex( DCondVar& aObject ) const
+ {
+ return (TUint8*)aObject.iMutex;
+ }
+
+
+void DMemSpyDriverOSAdaptionDCondVar::GetNameOfMutex( DCondVar& aObject, TDes& aName ) const
+ {
+ if ( aObject.iMutex )
+ {
+ aObject.iMutex->FullName( aName );
+ }
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDCondVar::GetWaitCount( DCondVar& aObject ) const
+ {
+ return aObject.iWaitCount;
+ }
+
+
+SDblQue& DMemSpyDriverOSAdaptionDCondVar::GetSuspendedQ( DCondVar& aObject ) const
+ {
+ return aObject.iSuspendedQ;
+ }
+
+
+DThread* DMemSpyDriverOSAdaptionDCondVar::GetThread( SDblQueLink* aLink ) const
+ {
+ DThread* thread = _LOFF( aLink, DThread, iWaitLink );
+ return thread;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDTimer::DMemSpyDriverOSAdaptionDTimer( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TTimer::TTimerType DMemSpyDriverOSAdaptionDTimer::GetType( DTimer& aObject ) const
+ {
+ const TTimer::TTimerType ret = aObject.iTimer.Type();
+ return ret;
+ }
+
+
+TTimer::TTimerState DMemSpyDriverOSAdaptionDTimer::GetState( DTimer& aObject ) const
+ {
+ const TTimer::TTimerState ret = static_cast<TTimer::TTimerState>( aObject.iTimer.iState );
+ return ret;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaptionDPropertyRef::DMemSpyDriverOSAdaptionDPropertyRef( DMemSpyDriverOSAdaption& aOSAdaption )
+: DMemSpyDriverOSAdaptionDObject( aOSAdaption )
+ {
+ }
+
+
+TBool DMemSpyDriverOSAdaptionDPropertyRef::GetIsReady( DObject& aObject ) const
+ {
+ DMemSpyPropertyRef* prop = GetPropertyRef( aObject );
+ return ( prop != NULL );
+ }
+
+
+RProperty::TType DMemSpyDriverOSAdaptionDPropertyRef::GetType( DObject& aObject ) const
+ {
+ RProperty::TType ret = RProperty::EInt;
+ //
+ DMemSpyPropertyRef* prop = GetPropertyRef( aObject );
+ if ( prop )
+ {
+ ret = (RProperty::TType) prop->iProp->iType;
+ }
+ //
+ return ret;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDPropertyRef::GetCategory( DObject& aObject ) const
+ {
+ TUint ret = 0;
+ //
+ DMemSpyPropertyRef* prop = GetPropertyRef( aObject );
+ if ( prop )
+ {
+ ret = prop->iProp->iCategory;
+ }
+ //
+ return ret;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDPropertyRef::GetKey( DObject& aObject ) const
+ {
+ TUint ret = 0;
+ //
+ DMemSpyPropertyRef* prop = GetPropertyRef( aObject );
+ if ( prop )
+ {
+ ret = prop->iProp->iKey;
+ }
+ //
+ return ret;
+ }
+
+
+TInt DMemSpyDriverOSAdaptionDPropertyRef::GetRefCount( DObject& aObject ) const
+ {
+ TInt ret = 0;
+ //
+ DMemSpyPropertyRef* prop = GetPropertyRef( aObject );
+ if ( prop )
+ {
+ ret = prop->iProp->iRefCount;
+ }
+ //
+ return ret;
+ }
+
+
+TUint DMemSpyDriverOSAdaptionDPropertyRef::GetThreadId( DObject& aObject ) const
+ {
+ TUint ret = 0;
+ //
+ DMemSpyPropertyRef* prop = GetPropertyRef( aObject );
+ if ( prop )
+ {
+ DThread* thread = prop->iClient;
+ if ( thread )
+ {
+ ret = OSAdaption().DThread().GetId( *thread );
+ }
+ }
+ //
+ return ret;
+ }
+
+
+TUint32 DMemSpyDriverOSAdaptionDPropertyRef::GetCreatorSID( DObject& aObject ) const
+ {
+ TUint32 ret = 0;
+ //
+ DMemSpyPropertyRef* prop = GetPropertyRef( aObject );
+ if ( prop )
+ {
+ ret = prop->iProp->iOwner;
+ }
+ //
+ return ret;
+ }
+
+
+DMemSpyPropertyRef* DMemSpyDriverOSAdaptionDPropertyRef::GetPropertyRef( DObject& aObject ) const
+ {
+ DMemSpyPropertyRef* ret = NULL;
+ //
+ const TUint8 containerId = GetContainerID( aObject ) - 1;
+ if ( containerId == EPropertyRef )
+ {
+ DMemSpyPropertyRef* prop = reinterpret_cast< DMemSpyPropertyRef* >( &aObject );
+ if ( prop->iProp && prop->iClient )
+ {
+ ret = prop;
+ }
+ }
+ //
+ return ret;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+DMemSpyDriverOSAdaption::DMemSpyDriverOSAdaption( DMemSpyDriverDevice& aDevice )
+: iDevice( aDevice )
+ {
+ }
+
+
+DMemSpyDriverOSAdaption::~DMemSpyDriverOSAdaption()
+ {
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaption::~DMemSpyDriverOSAdaption() - START"));
+ NKern::ThreadEnterCS();
+ //
+ delete iDThread;
+ delete iDProcess;
+ delete iDChunk;
+ delete iDServer;
+ delete iDSession;
+ delete iDCodeSeg;
+ delete iDSemaphore;
+ delete iDMutex;
+ delete iDLogicalDevice;
+ delete iDPhysicalDevice;
+ delete iDChangeNotifier;
+ delete iDUndertaker;
+ delete iDCondVar;
+ delete iDTimer;
+ delete iDPropertyRef;
+ //
+ NKern::ThreadLeaveCS();
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaption::~DMemSpyDriverOSAdaption() - END"));
+ }
+
+
+TInt DMemSpyDriverOSAdaption::Construct()
+ {
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaption::Construct() - START" ) );
+ //
+ NKern::ThreadEnterCS();
+ //
+ TInt error = KErrNoMemory;
+ //
+ iDThread = new DMemSpyDriverOSAdaptionDThread( *this );
+ if ( iDThread )
+ {
+ iDProcess = new DMemSpyDriverOSAdaptionDProcess( *this );
+ if ( iDProcess )
+ {
+ iDChunk = new DMemSpyDriverOSAdaptionDChunk( *this );
+ if ( iDChunk )
+ {
+ iDServer = new DMemSpyDriverOSAdaptionDServer( *this );
+ if ( iDServer )
+ {
+ iDSession = new DMemSpyDriverOSAdaptionDSession( *this );
+ if ( iDSession )
+ {
+ iDCodeSeg = new DMemSpyDriverOSAdaptionDCodeSeg( *this );
+ if ( iDCodeSeg )
+ {
+ iDSemaphore = new DMemSpyDriverOSAdaptionDSemaphore( *this );
+ if ( iDSemaphore )
+ {
+ iDMutex = new DMemSpyDriverOSAdaptionDMutex( *this );
+ if ( iDMutex )
+ {
+ iDLogicalDevice = new DMemSpyDriverOSAdaptionDLogicalDevice( *this );
+ if ( iDLogicalDevice )
+ {
+ iDPhysicalDevice = new DMemSpyDriverOSAdaptionDPhysicalDevice( *this );
+ if ( iDPhysicalDevice )
+ {
+ iDChangeNotifier = new DMemSpyDriverOSAdaptionDChangeNotifier( *this );
+ if ( iDChangeNotifier )
+ {
+ iDUndertaker = new DMemSpyDriverOSAdaptionDUndertaker( *this );
+ if ( iDUndertaker )
+ {
+ iDCondVar = new DMemSpyDriverOSAdaptionDCondVar( *this );
+ if ( iDCondVar )
+ {
+ iDTimer = new DMemSpyDriverOSAdaptionDTimer( *this );
+ if ( iDTimer )
+ {
+ iDPropertyRef = new DMemSpyDriverOSAdaptionDPropertyRef( *this );
+ if ( iDPropertyRef )
+ {
+ error = KErrNone;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ //
+ NKern::ThreadLeaveCS();
+
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaption::Construct() - END - error: %d", error ) );
+ return error;
+ }
+
+
+
+
+