diff -r 000000000000 -r a03f92240627 memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanThreadAndProcess.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanThreadAndProcess.cpp Tue Feb 02 01:57:15 2010 +0200 @@ -0,0 +1,511 @@ +/* +* 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 "MemSpyDriverLogChanThreadAndProcess.h" + +// System includes +#include +#include +#include + +// Shared includes +#include "MemSpyDriverOpCodes.h" +#include "MemSpyDriverObjectsInternal.h" + +// User includes +#include "MemSpyDriverUtils.h" +#include "MemSpyDriverOSAdaption.h" +#include "MemSpyDriverSuspensionManager.h" + +// Constants +const TBool KMemSpyDriverAllowDeadOpenRequests = ETrue; +const TInt KMemSpyDriverLogChanThreadAndProcessXferBufferSize = 512; + + +DMemSpyDriverLogChanThreadAndProcess::DMemSpyDriverLogChanThreadAndProcess( DMemSpyDriverDevice& aDevice, DThread& aThread ) +: DMemSpyDriverLogChanBase( aDevice, aThread ) + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::DMemSpyDriverLogChanThreadAndProcess() - this: 0x%08x", this )); + } + + +DMemSpyDriverLogChanThreadAndProcess::~DMemSpyDriverLogChanThreadAndProcess() + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::~DMemSpyDriverLogChanThreadAndProcess() - START - this: 0x%08x", this )); + + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::~DMemSpyDriverLogChanThreadAndProcess() - END - this: 0x%08x", this )); + } + + +TInt DMemSpyDriverLogChanThreadAndProcess::Construct() + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::Construct() - START - this: 0x%08x", this )); + + const TInt ret = BaseConstruct( KMemSpyDriverLogChanThreadAndProcessXferBufferSize ); + + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::Construct() - END - this: 0x%08x, err: %d", this, ret )); + return ret; + } + + +TInt DMemSpyDriverLogChanThreadAndProcess::Request( TInt aFunction, TAny* a1, TAny* a2 ) + { + TInt r = DMemSpyDriverLogChanBase::Request( aFunction, a1, a2 ); + if ( r == KErrNone ) + { + switch( aFunction ) + { + case EMemSpyDriverOpCodeThreadAndProcessGetInfoThread: + r = GetInfoThread( (TUint)a1, (TMemSpyDriverInternalThreadInfoParams*) a2); + break; + case EMemSpyDriverOpCodeThreadAndProcessGetInfoProcess: + r = GetInfoProcess( (TUint)a1, (TMemSpyDriverProcessInfo*) a2); + break; + case EMemSpyDriverOpCodeThreadAndProcessEndThread: + r = EndThread( (TUint) a1, (TExitType) ((TUint) a2) ); + break; + case EMemSpyDriverOpCodeThreadAndProcessOpenThread: + r = OpenThread( (TUint) a1 ); + break; + case EMemSpyDriverOpCodeThreadAndProcessOpenProcess: + r = OpenProcess( (TUint) a1 ); + break; + case EMemSpyDriverOpCodeThreadAndProcessSuspendAllThreads: + r = SuspendAllThreadsInProcess( (TUint) a1 ); + break; + case EMemSpyDriverOpCodeThreadAndProcessResumeAllThreads: + r = ResumeAllThreadsInProcess( (TUint) a1 ); + break; + case EMemSpyDriverOpCodeThreadAndProcessGetThreads: + r = GetThreadsForProcess( (TUint) a1, (TDes8*) a2 ); + break; + case EMemSpyDriverOpCodeThreadAndProcessSetPriorityThread: + r = SetPriority( (TUint) a1, (TThreadPriority) ((TUint) a2) ); + break; + + default: + r = KErrNotSupported; + break; + } + } + // + return r; + } + + +TBool DMemSpyDriverLogChanThreadAndProcess::IsHandler( TInt aFunction ) const + { + return ( aFunction > EMemSpyDriverOpCodeThreadAndProcessBase && aFunction < EMemSpyDriverOpCodeThreadAndProcessEnd ); + } + + + + + + +TInt DMemSpyDriverLogChanThreadAndProcess::GetInfoThread( TUint aTid, TMemSpyDriverInternalThreadInfoParams* aParams ) + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - START")); + + TMemSpyDriverInternalThreadInfoParams params; + TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalThreadInfoParams) ); + if ( r != KErrNone ) + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - END - params read error: %d", r)); + return r; + } + + r = OpenTempObject( aTid, EThread ); + if ( r == KErrNone ) + { + DThread* dThread = (DThread*) TempObject(); + NKern::ThreadEnterCS(); + + // Get DThread adaptor. This is a means of querying DThread internals + // without accessing them directly. Takes into account possible differences + // between compile time and run time + DMemSpyDriverOSAdaptionDThread& dThreadAdaptor = OSAdaption().DThread(); + + // Saved CPU registers for thread. Need to get NThread to do this. + NThread* nThread = dThreadAdaptor.GetNThread( *dThread ); + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting regs..." )); + MemSpyDriverUtils::GetThreadRegisters( nThread, params.iCpu ); + + // Name + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting full name..." )); + dThread->FullName( params.iFullName ); + + // User framework + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting allocator..." )); + params.iAllocator = dThreadAdaptor.GetAllocator( *dThread ); + + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting scheduler..." )); + params.iScheduler = dThreadAdaptor.GetActiveScheduler( *dThread ); + + // User stack information - rest comes from user side API calls + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting user stack pointer..." )); + params.iStackInfo.iUserStackPointer = params.iCpu.iRn[ 12 ]; + + // Supervisor stack information + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - getting supervisor stack..." )); + params.iStackInfo.iSupervisorStackPointer = 0; + params.iStackInfo.iSupervisorStackHighWatermark = 0; + params.iStackInfo.iSupervisorStackBase = dThreadAdaptor.GetSupervisorStackBase( *dThread ); + params.iStackInfo.iSupervisorStackSize = dThreadAdaptor.GetSupervisorStackSize( *dThread ); + + // Write back to user-side + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - writing to user side..." )); + r = Kern::ThreadRawWrite( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalThreadInfoParams) ); + NKern::ThreadLeaveCS(); + CloseTempObject(); + } + + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoThread() - END - ret: %d", r)); + return r; + } + + +TInt DMemSpyDriverLogChanThreadAndProcess::GetInfoProcess( TUint aPid, TMemSpyDriverProcessInfo* aParams ) + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoProcess() - START")); + + TMemSpyDriverProcessInfo params; + TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverProcessInfo) ); + if ( r != KErrNone ) + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoProcess() - END - params read error: %d", r)); + return r; + } + + r = OpenTempObject( aPid, EProcess ); + if ( r == KErrNone ) + { + DMemSpyDriverOSAdaptionDProcess& processAdaptor = OSAdaption().DProcess(); + + DProcess* process = (DProcess*) TempObject(); + NKern::ThreadEnterCS(); + // + params.iFlags = processAdaptor.GetFlags( *process ); + params.iGeneration = processAdaptor.GetGeneration( *process ); + params.iSecurityInfo = processAdaptor.GetSecurityInfo( *process ); + + // Write back to user-side + r = Kern::ThreadRawWrite( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverProcessInfo) ); + NKern::ThreadLeaveCS(); + CloseTempObject(); + } + + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::GetInfoProcess() - END - ret: %d", r)); + return r; + } + + + + + + + + + +TInt DMemSpyDriverLogChanThreadAndProcess::EndThread( TUint aId, TExitType aType ) + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::EndThread() - START - aId: %d, aType: %d", aId, aType )); + + TInt r = OpenTempObject( aId, EThread ); + if ( r == KErrNone ) + { + DThread* thread = (DThread*) TempObject(); + // + const TInt reason = MapToMemSpyExitReason( aType ); + Kern::ThreadKill( thread, aType, reason, KMemSpyClientPanic ); + // + CloseTempObject(); + } + else + { + r = KErrNotFound; + } + + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::EndThread() - END - r: %d", r)); + return r; + } + + + + + + + + + + + + + + + + + + + + + + +TInt DMemSpyDriverLogChanThreadAndProcess::OpenThread( TUint aId ) + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - START - aId: %d", aId)); + + TInt r = OpenTempObject( aId, EThread, KMemSpyDriverAllowDeadOpenRequests ); + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - done open temp object, r: %d", r )); + if ( r == KErrNone ) + { + NKern::ThreadEnterCS(); + DThread* threadToOpen = (DThread*) TempObject(); + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - thread exit type: %d", threadToOpen->iExitType )); + + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - making handle..." )); + r = Kern::MakeHandleAndOpen( &ClientThread(), threadToOpen ); + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - handle: %d",r )); + NKern::ThreadLeaveCS(); + + // Balance reference count, handle is still open and mapped into our process since we opened + // it above via MakeHandleAndOpen + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - closing temp object..." )); + CloseTempObject(); + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - closed temp object" )); + } + else + { + r = KErrNotFound; + } + + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenThread() - END - r: %d", r)); + return r; + } + + +TInt DMemSpyDriverLogChanThreadAndProcess::OpenProcess( TUint aId ) + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenProcess() - START - aId: %d", aId)); + + TInt r = OpenTempObject( aId, EProcess, KMemSpyDriverAllowDeadOpenRequests ); + if ( r == KErrNone ) + { + NKern::ThreadEnterCS(); + DProcess* processToOpen = (DProcess*) TempObject(); + r = Kern::MakeHandleAndOpen( &ClientThread(), processToOpen ); + NKern::ThreadLeaveCS(); + + // Balance reference count, handle is still open and mapped into our process since we opened + // it above via MakeHandleAndOpen + CloseTempObject(); + } + else + { + r = KErrNotFound; + } + + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::OpenProcess() - END - r: %d", r)); + return r; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +TInt DMemSpyDriverLogChanThreadAndProcess::SuspendAllThreadsInProcess( TUint aPid ) + { + TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::SuspendAllThreadsInProcess() - START - aPid: %d", aPid )); + + DMemSpySuspensionManager& susMan = SuspensionManager(); + const TInt err = susMan.SuspendAllThreadsInProcess( aPid, ClientThread() ); + + TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::SuspendAllThreadsInProcess() - END - aPid: %d, err: %d", aPid, err )); + return err; + } + + +TInt DMemSpyDriverLogChanThreadAndProcess::ResumeAllThreadsInProcess( TUint aPid ) + { + TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::ResumeAllThreadsInProcess() - START - aPid: %d", aPid )); + + DMemSpySuspensionManager& susMan = SuspensionManager(); + const TInt err = susMan.ResumeAllThreadsInProcess( aPid, ClientThread() ); + + TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::ResumeAllThreadsInProcess() - END - aPid: %d, err: %d", aPid, err )); + return err; + } + + +TInt DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess( TUint aPid, TDes8* aBufferSink ) + { + TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - START - aPid: %d", aPid ) ); + + // We open the source thread or process, just to ensure it doesn't die underneath us... + TInt r = OpenTempObject( aPid, EProcess ); + if ( r == KErrNone ) + { + DProcess& process = TempObjectAsProcess(); + + // Open stream + RMemSpyMemStreamWriter stream = OpenXferStream(); + TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - stream remaining: %d", stream.Remaining() ) ); + + // Save marker pos for the thread count - we'll update it after the loop + TInt count = 0; + TInt32* pCountMarkerThread = stream.WriteInt32( 0 ); + + DMemSpyDriverOSAdaptionDProcess& processAdaptor = OSAdaption().DProcess(); + SDblQue& threadQueue = processAdaptor.GetThreadQueue( process ); + SDblQueLink* pLink = threadQueue.First(); + while( pLink != & threadQueue.iA && !stream.IsFull() ) + { + DThread* pT = processAdaptor.GetThread( pLink ); + // + if ( pT ) + { + const TUint tid = OSAdaption().DThread().GetId( *pT ); + TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - id: %d (0x%04x)", tid, tid ) ); + stream.WriteUint32( tid ); + } + + pLink = pLink->iNext; + ++count; + } + + if ( stream.IsFull() ) + { + Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - STREAM FULL - id: %d (0x%04x), thread: %O", process.iId, process.iId, &process ); + } + + // Now write the count + *pCountMarkerThread = count; + + // Tidy up + r = stream.WriteAndClose( aBufferSink ); + TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - r: %d, count: %d", r, count )); + + CloseTempObject(); + } + + TRACE( Kern::Printf( "DMemSpyDriverLogChanThreadAndProcess::GetThreadsForProcess() - END - aPid: %d, err: %d", aPid, r )); + return r; + } + + +TInt DMemSpyDriverLogChanThreadAndProcess::SetPriority( TUint aId, TThreadPriority aPriority ) + { + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::SetPriority(T) - START - aId: %d, aPriority: %d", aId, aPriority )); + + TInt r = OpenTempObject( aId, EThread ); + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::SetPriority(T) - done open temp object, r: %d", r )); + if ( r == KErrNone ) + { + // Map user side thread priority to kernel-side absolute thread priority (typically 0-63) + const TInt kernelThreadPri = MemSpyDriverUtils::MapToAbsoluteThreadPriority( aPriority ); + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::SetPriority(T) - user: %d, kernel absolute: %d", aPriority, kernelThreadPri )); + + if ( kernelThreadPri > 0 && kernelThreadPri < KNumPriorities ) + { + NKern::ThreadEnterCS(); + DThread& thread = TempObjectAsThread(); + r = Kern::SetThreadPriority( kernelThreadPri, &thread ); + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::SetPriority(T) - Kern::SetThreadPriority() returned: %d", r )); + NKern::ThreadLeaveCS(); + } + else + { + // Error + r = kernelThreadPri; + } + + CloseTempObject(); + } + + TRACE( Kern::Printf("DMemSpyDriverLogChanThreadAndProcess::SetPriority(T) - END - r: %d", r)); + return r; + } + + + + + + +TInt DMemSpyDriverLogChanThreadAndProcess::MapToMemSpyExitReason( TExitType aType ) + { + TInt ret = 0; + // + switch( aType ) + { + default: + case EExitKill: + ret = EPanicForcedKill; + break; + case EExitTerminate: + ret = EPanicForcedTerminate; + break; + case EExitPanic: + ret = EPanicForcedPanic; + break; + } + // + return ret; + } + + + + + + + + + + + + + + + + + + + +