memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainerBase.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 16:45:49 +0300
branchRCL_3
changeset 20 ca8a1b6995f6
parent 0 a03f92240627
child 21 52e343bb8f80
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* 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::CheckedOpen(TMemSpyDriverContainerType aContainerType, DObject* aObject, TBool aQuick)
	{
	__ASSERT_CRITICAL;
	__ASSERT_DEBUG(aObject != NULL, MemSpyDriverUtils::Fault( __LINE__ ));
    const TObjectType expectedType = ObjectTypeFromMemSpyContainerType(aContainerType);

    // Quick mode means we just check container ids and we trust that the object will exist.
	// [TomS: not entirely convinced we can ever be certain of that]
    TInt err = KErrNotFound;
    if (aQuick)
        {
		LOG("quick CheckedOpen of %08x", aObject);
        const TObjectType objectType = OSAdaption().DThread().GetObjectType(*aObject);
        if (objectType == expectedType)
            {
            err = aObject->Open();
            }
        }
	else
		{
        DObjectCon* container = Kern::Containers()[expectedType];
        container->Wait();
        const TInt count = container->Count();
        for (TInt i = 0; i < count; i++)
            {
            DObject* object = (*container)[i];
            if (object == aObject)
                {
                err = aObject->Open();
				break;
				}
			}
		container->Signal();
		}

	LOG("CheckedOpen(%d, 0x%08x, quick=%d) returned error %d", aContainerType, aObject, aQuick, err);
	return (err == KErrNone) ? aObject : NULL;
	}



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;
    }