예제 #1
0
void DKdaChannel::CloseTempObject()
	{
	__ASSERT_DEBUG(iTempObj, Kern::Fault(KFault, __LINE__));
	NKern::ThreadEnterCS();
	iTempObj->Close(NULL);
	iTempObj = NULL;
	NKern::ThreadLeaveCS();
	}
TInt DMemSpyDriverLogChanChunks::GetChunkHandles( TMemSpyDriverInternalChunkHandleParams* aParams )
    {
	TMemSpyDriverInternalChunkHandleParams params;
    TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &params, 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, &currentWriteIndex, 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;
    }