memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainerBase.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 16:17:58 +0300
branchRCL_3
changeset 59 8ad140f3dd41
parent 49 7fdc9a71d314
permissions -rw-r--r--
Revision: 201039 Kit: 201041

/*
* 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 "MemSpyDriverLogChanContainerBase.h"

// Shared includes
#include "MemSpyDriverOpCodes.h"
#include <memspy/driver/memspydriverobjectsshared.h>
#include "MemSpyDriverObjectsInternal.h"

// User includes
#include "MemSpyDriverUtils.h"
#include "MemSpyDriverDevice.h"
#include "MemSpyDriverOSAdaption.h"


DMemSpyDriverLogChanContainerBase::DMemSpyDriverLogChanContainerBase( DMemSpyDriverDevice& aDevice, DThread& aThread )
:   DMemSpyDriverLogChanBase( aDevice, aThread )
    {
	TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::DMemSpyDriverLogChanContainerBase() - this: 0x%08x", this ));
    }


DMemSpyDriverLogChanContainerBase::~DMemSpyDriverLogChanContainerBase()
	{
	TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::~DMemSpyDriverLogChanContainerBase() - START - this: 0x%08x", this ));

    ResetTempHandles();

	TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::~DMemSpyDriverLogChanContainerBase() - END - this: 0x%08x", this ));
	}









DObject* DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer( TMemSpyDriverContainerType aContainerType, DObject* aSearchFor, TBool aQuick )
    {
	__ASSERT_DEBUG( aSearchFor != NULL, MemSpyDriverUtils::Fault( __LINE__ ) );
    const TObjectType expectedType = ObjectTypeFromMemSpyContainerType( aContainerType );
    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer - START - aSearchFor: 0x%08x, expectedType: %d", aSearchFor, expectedType ));

    DObject* ret = NULL;
    
    // Quick mode means we just check container ids and we trust that the object
    // will exist.
    if ( aQuick )
        {
        const TObjectType objectType = OSAdaption().DThread().GetObjectType( *aSearchFor );
        TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer - aSearchFor.iContainerID: %d", objectType ) );
        if  ( objectType == expectedType )
            {
            ret = aSearchFor;
            }
        }
    else
        {
        // Full check to see if the specified object is part of the container
        DObjectCon* container = Kern::Containers()[ expectedType ];
        container->Wait();
        NKern::LockSystem();

        const TInt count = container->Count();
        for(TInt i=0; i<count; i++)
            {
            DObject* object = (*container)[ i ];

            // Do the two match?
            if  ( object == aSearchFor )
                {
                TRACE( Kern::Printf("    found match: %O", object));

                ret = object;
                break;
                }
            }

        NKern::UnlockSystem();
        container->Signal();
        }

    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer - END - ret: 0x%08x", ret ));
    TRACE( Kern::Printf(" ") );
    return ret;
    }



TObjectType DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType( TMemSpyDriverContainerType aType )
    {
    // Map type
    TObjectType type = EObjectTypeAny;
    switch( aType )
        {
    case EMemSpyDriverContainerTypeThread:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeThread" ));
        type = EThread;
        break;
    case EMemSpyDriverContainerTypeProcess:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeProcess" ));
        type = EProcess;
        break;
    case EMemSpyDriverContainerTypeChunk:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeChunk" ));
        type = EChunk;
        break;
    case EMemSpyDriverContainerTypeLibrary:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeLibrary" ));
        type = ELibrary;
        break;
    case EMemSpyDriverContainerTypeSemaphore:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeSemaphore" ));
        type = ESemaphore;
        break;
    case EMemSpyDriverContainerTypeMutex:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeMutex" ));
        type = EMutex;
        break;
    case EMemSpyDriverContainerTypeTimer:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeTimer" ));
        type = ETimer;
        break;
    case EMemSpyDriverContainerTypeServer:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeServer" ));
        type = EServer;
        break;
    case EMemSpyDriverContainerTypeSession:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeSession" ));
        type = ESession;
        break;
    case EMemSpyDriverContainerTypeLogicalDevice:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeLogicalDevice" ));
        type = ELogicalDevice;
        break;
    case EMemSpyDriverContainerTypePhysicalDevice:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypePhysicalDevice" ));
        type = EPhysicalDevice;
        break;
    case EMemSpyDriverContainerTypeLogicalChannel:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeLogicalChannel" ));
        type = ELogicalChannel;
        break;
    case EMemSpyDriverContainerTypeChangeNotifier:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeChangeNotifier" ));
        type = EChangeNotifier;
        break;
    case EMemSpyDriverContainerTypeUndertaker:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeUndertaker" ));
        type = EUndertaker;
        break;
    case EMemSpyDriverContainerTypeMsgQueue:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeMsgQueue" ));
        type = EMsgQueue;
        break;
    case EMemSpyDriverContainerTypePropertyRef:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypePropertyRef" ));
        type = EPropertyRef;
        break;
    case EMemSpyDriverContainerTypeCondVar:
 	    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType() - EMemSpyDriverContainerTypeCondVar" ));
        type = ECondVar;
        break;
    default:
        Kern::Printf("DMemSpyDriverLogChanContainerBase::ObjectTypeFromMemSpyContainerType - unsupported container type: %d", aType);
        break;
        }
    //
    return type;
    }




























    

void DMemSpyDriverLogChanContainerBase::ResetTempHandles()
    {
    iTempHandleCount = 0;
    }


void DMemSpyDriverLogChanContainerBase::AddTempHandle( TAny* aHandle )
    {
    __ASSERT_ALWAYS( iTempHandleCount >= 0, MemSpyDriverUtils::Fault( __LINE__) );
    if  ( iTempHandleCount < KMemSpyDriverMaxHandles )
        {
        iTempHandles[ iTempHandleCount++ ] = aHandle;
        }
    }


TAny* DMemSpyDriverLogChanContainerBase::TempHandleAt( TInt aIndex ) const
    {
    __ASSERT_ALWAYS( aIndex >= 0 && aIndex < KMemSpyDriverMaxHandles, MemSpyDriverUtils::Fault(__LINE__) );
    __ASSERT_ALWAYS( aIndex < iTempHandleCount, MemSpyDriverUtils::Fault(__LINE__) );
    return iTempHandles[ aIndex ];
    }


TInt DMemSpyDriverLogChanContainerBase::TempHandleCount() const
    {
    TRACE( Kern::Printf( "DMemSpyDriverLogChanContainerBase::TempHandleCount() - END - count is: %d", iTempHandleCount ));
    return iTempHandleCount;
    }


TInt DMemSpyDriverLogChanContainerBase::WriteToClient( TAny** aHandlePtr, TInt* aCountPtr, TInt aMaxCount )
    {
	TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::WriteToClient() - START - iTempHandleCount: %d", iTempHandleCount ));

    TInt r = KErrNone;

    // This variable holds the number of handles that we have already
	// written to the client-side.
	TInt currentWriteIndex = 0;

    // If the client passed a bad descriptor then we panic it. Otherwise, we always update the amount
    // of handles we have found (even if there was an error - i.e. we set the value to zero) or else
    // the client will attempt to index through its huge stack-based handle array.
	NKern::ThreadEnterCS();
    TInt tempHandleCount = TempHandleCount();
    TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::GetContainerHandles - trying to write %d handles to client...", tempHandleCount ));

    for( ; currentWriteIndex<tempHandleCount && r == KErrNone && currentWriteIndex < aMaxCount; )
        {
        TAny* handle = TempHandleAt( currentWriteIndex );
        r = Kern::ThreadRawWrite( &ClientThread(), aHandlePtr + currentWriteIndex, &handle, sizeof(TAny*) );
        if  (r == KErrNone)
            {
            ++currentWriteIndex;
            }
        }

	if  ( r == KErrBadDescriptor )
        {
        MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor );
        }
    else
        {
        const TInt finalWrite = Kern::ThreadRawWrite( &ClientThread(), aCountPtr, &currentWriteIndex, sizeof(TInt) );
        if  ( r == KErrNone )
            {
            r = finalWrite;
            }
        }
	NKern::ThreadLeaveCS();

	TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::GetContainerHandles() - END - r: %d", r));
	return r;
    }