TInt DKdaChannel::OpenTempObject(TUint aId, TObjectType aType) { __ASSERT_DEBUG(aType == EProcess || aType == EThread, Kern::Fault(KFault, __LINE__)); __ASSERT_DEBUG(! iTempObj, Kern::Fault(KFault, __LINE__)); DObjectCon* pC = Kern::Containers()[aType]; NKern::ThreadEnterCS(); pC->Wait(); DObject* tempObj = (aType == EProcess) ? (DObject*)Kern::ProcessFromId(aId) : (DObject*)Kern::ThreadFromId(aId); NKern::LockSystem(); iTempObj = tempObj; TInt r = KErrNotFound; if (iTempObj) r = iTempObj->Open(); NKern::UnlockSystem(); pC->Signal(); NKern::ThreadLeaveCS(); return r; }
TInt DMemSpyDriverLogChanChunks::GetChunkHandles( TMemSpyDriverInternalChunkHandleParams* aParams ) { TMemSpyDriverInternalChunkHandleParams params; TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalChunkHandleParams) ); if ( r != KErrNone ) { TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - END - params read error: %d", r)); return r; } const TInt maxCount = params.iMaxCount; TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - START - id: %d, maxCount: %d, type: %d", params.iId, maxCount, params.iType)); DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread(); DMemSpyDriverOSAdaptionDProcess& processAdaption = OSAdaption().DProcess(); // This variable holds the number of handles that we have already // written to the client-side. TInt currentWriteIndex = 0; if ( params.iType == EMemSpyDriverPrivateObjectTypeProcess || params.iType == EMemSpyDriverPrivateObjectTypeThread ) { if ( params.iType == EMemSpyDriverPrivateObjectTypeThread ) { r = OpenTempObject( params.iId, EThread ); if ( r == KErrNone ) { // Open the owning process instead, so that we can see which chunks are mapped // into the thread. DThread* thread = (DThread*) TempObject(); DProcess* process = threadAdaption.GetOwningProcess( *thread ); if ( process ) { const TUint parentProcessId = processAdaption.GetId( *process ); CloseTempObject(); r = OpenTempObject( parentProcessId, EProcess ); } else { CloseTempObject(); r = KErrNotFound; } } } else { r = OpenTempObject( params.iId, EProcess ); } // Handle error opening correct process if (r != KErrNone) { Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - END - parent process not found"); return r; } DProcess* process = (DProcess*) TempObject(); NKern::ThreadEnterCS(); // Iterate through each handle in the process MemSpyObjectIx* processHandles = processAdaption.GetHandles( *process ); MemSpyObjectIx_HandleLookupLock(); const TInt processHandleCount = processHandles->Count(); MemSpyObjectIx_HandleLookupUnlock(); for( TInt processHandleIndex = 0; processHandleIndex<processHandleCount && r == KErrNone && currentWriteIndex < maxCount; processHandleIndex++ ) { // Get a handle from the process container... MemSpyObjectIx_HandleLookupLock(); if (processHandleIndex >= processHandles->Count()) break; // Count may have changed in the meantime DObject* object = (*processHandles)[ processHandleIndex ]; if (object && object->Open() != KErrNone) object = NULL; MemSpyObjectIx_HandleLookupUnlock(); if ( object ) { const TObjectType objectType = processAdaption.GetObjectType( *object ); if ( objectType == EChunk ) { DChunk* chunk = (DChunk*) object; TAny* handle = (TAny*) chunk; r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + currentWriteIndex, &handle, sizeof(TAny*) ); if ( r == KErrNone ) { ++currentWriteIndex; } } object->Close(NULL); } } // If we were asked for process-related chunks, also check the chunk container // for entries which we don't have handles to, but do refer to our process // Need a listing of all chunks in the system. Let client filter duplicates. DObjectCon* container = Kern::Containers()[ EChunk ]; container->Wait(); // const TInt count = container->Count(); for( TInt i=0; i<count && r == KErrNone && currentWriteIndex < maxCount; i++ ) { DChunk* chunk= (DChunk*) (*container)[ i ]; // const TBool isRelated = DoesChunkRelateToProcess( *chunk, TempObjectAsProcess() ); if ( isRelated ) { r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + currentWriteIndex, &chunk, sizeof(TAny*) ); if ( r == KErrNone ) { ++currentWriteIndex; } } } // container->Signal(); NKern::ThreadLeaveCS(); CloseTempObject(); } else { // Need a listing of all chunks in the system. Let client filter duplicates. DObjectCon* container = Kern::Containers()[ EChunk ]; NKern::ThreadEnterCS(); container->Wait(); // const TInt count = container->Count(); for( TInt i=0; i<count && r == KErrNone && currentWriteIndex < maxCount; i++ ) { DChunk* chunk= (DChunk*) (*container)[ i ]; // r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + currentWriteIndex, &chunk, sizeof(TAny*) ); if (r == KErrNone) { ++currentWriteIndex; } } // container->Signal(); NKern::ThreadLeaveCS(); } if ( r == KErrBadDescriptor ) { MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor ); } else { const TInt finalWrite = Kern::ThreadRawWrite( &ClientThread(), params.iCountPtr, ¤tWriteIndex, sizeof(TInt) ); if ( r == KErrNone ) { r = finalWrite; } } TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkHandles() - END - number of handles written to client: %d, ret: %d", currentWriteIndex, r)); return r; }