memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanBase.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:37:10 +0100
branchRCL_3
changeset 21 52e343bb8f80
parent 20 ca8a1b6995f6
permissions -rw-r--r--
Revert incorrect RCL_3 drop: 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 "MemSpyDriverLogChanBase.h"

// System includes
#include <u32hal.h>
#include <kernel.h>
#include <memspy/driver/memspydriverobjectsshared.h>

// Shared includes
#include "MemSpyDriverOpCodes.h"
#include "MemSpyDriverObjectsInternal.h"

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



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


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

    NKern::ThreadEnterCS();

    if  ( iTempObj != NULL )
        {
    	Kern::SafeClose( iTempObj, NULL );
        }

    delete iXferBuffer;
	
    NKern::ThreadLeaveCS();

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


TInt DMemSpyDriverLogChanBase::BaseConstruct( TInt aTransferBufferSize )
    {
    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::BaseConstruct() - START - this: 0x%08x, aTransferBufferSize: %d", this, aTransferBufferSize ));
    TInt ret = KErrNone;
    //
    if  ( aTransferBufferSize != 0 )
        {
        iXferBuffer = new DMemSpyDriverXferBuffer( iDevice, iClientThread );
        if  ( !iXferBuffer )
            {
            ret = KErrNoMemory;
            }
        else
            {
            ret = iXferBuffer->Construct( aTransferBufferSize );
            if  ( ret != KErrNone )
                {
                delete iXferBuffer;
                iXferBuffer = NULL;
                }
            }
        }
    //
    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::BaseConstruct() - END - this: 0x%08x, aTransferBufferSize: %d, size: %d", this, aTransferBufferSize, iXferBuffer ? iXferBuffer->Size() : 0 ));
    return ret;
    }


TInt DMemSpyDriverLogChanBase::Construct()
    {
    const TInt baseErr = BaseConstruct();
    return baseErr;
    }


TInt DMemSpyDriverLogChanBase::Request( TInt /*aFunction*/, TAny* /*a1*/, TAny* /*a2*/ )
    {
    return KErrNone;
    }







DMemSpyDriverDevice& DMemSpyDriverLogChanBase::MemSpyDevice()
    {
    return iDevice;
    }


DMemSpySuspensionManager& DMemSpyDriverLogChanBase::SuspensionManager()
    {
    return MemSpyDevice().SuspensionManager();
    }










TInt DMemSpyDriverLogChanBase::OpenTempObject( TUint aId, TObjectType aType, TBool aAllowDeadObjects )
	{
	__ASSERT_DEBUG( aType == EProcess || aType == EThread, MemSpyDriverUtils::Fault( __LINE__ ) );
	__ASSERT_DEBUG( !iTempObj, MemSpyDriverUtils::Fault( __LINE__ ) );

	TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - START - aId: %d, aType: %d, aAllowDeadObjects: %d", aId, aType, aAllowDeadObjects ));
	DObjectCon* pC = Kern::Containers()[ aType ];
	NKern::ThreadEnterCS();
	pC->Wait();
	iTempObj = (aType == EProcess) ? (DObject*) Kern::ProcessFromId( aId ) : (DObject*) Kern::ThreadFromId( aId );
	TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - kernel obj from id returned: 0x%08x %O", iTempObj, iTempObj ));
    //
    TBool openedOkay = EFalse;
    TInt r = KErrNone;
    //
	if ( iTempObj )
        {
		NKern::LockSystem();
		r = iTempObj->Open();
	    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - open returned: %d", r ));
		NKern::UnlockSystem();
		//
        if  ( r == KErrNone )
            {
            openedOkay = ETrue;
            if  ( aType == EProcess )
                {
                // Check the process is still alive
                DProcess* process = (DProcess*) iTempObj;
                const TExitType exitType = OSAdaption().DProcess().GetExitType( *process );
                TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - process exitType: %d", exitType ));

                if  ( !aAllowDeadObjects && exitType != EExitPending )
					{
                    r = KErrDied;
                    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - PROCESS IS DEAD!" ));
					}
                }
            else if ( aType == EThread )
                {
                // Check the thread is still alive
                DThread* thread = (DThread*) iTempObj;
                const TExitType exitType = OSAdaption().DThread().GetExitType( *thread );
                TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - thread exitType: %d", exitType ));

                if  ( !aAllowDeadObjects && exitType != EExitPending )
                    {
                    r = KErrDied;
                    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - THREAD IS DEAD!" ));
                    }
                }
            }

        }
    else if ( !iTempObj )
        {
        r = KErrNotFound;
	    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - ENTITY NOT FOUND!" ));
        }
    //
	pC->Signal();
	TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - signalled container..." ));
	NKern::ThreadLeaveCS();
	TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - left CS..." ));
    //
    if  ( r != KErrNone && iTempObj )
        {
	    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - ERROR CASE - closing temp object (r: %d, openedOkay: %d)...", r, openedOkay ));
        //
        if ( openedOkay )
            {
            CloseTempObject();
            }
        else
            {
            NKern::SafeSwap( NULL, (TAny*&) iTempObj );
            }
        //
	    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - ERROR CASE - closed temp object" ));
        }
    //
	TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - END - r: %d", r ));
	return r;
	}


void DMemSpyDriverLogChanBase::CloseTempObject()
	{
	TRACE( Kern::Printf("DMemSpyDriverLogChanBase::CloseTempObject() - START - iTempObj: 0x%08x %O", iTempObj, iTempObj ));

	__ASSERT_DEBUG( iTempObj, MemSpyDriverUtils::Fault( __LINE__ ) );
    if  ( iTempObj )
        {
	    NKern::ThreadEnterCS();
        TRACE( Kern::Printf("DMemSpyDriverLogChanBase::CloseTempObject() - in CS..." ));
        //
	    Kern::SafeClose( iTempObj, NULL );
        TRACE( Kern::Printf("DMemSpyDriverLogChanBase::CloseTempObject() - done safe close..." ));
        //
	    NKern::ThreadLeaveCS();
        TRACE( Kern::Printf("DMemSpyDriverLogChanBase::CloseTempObject() - left CS" ));
        }

    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::CloseTempObject() - END" ));
	}


DThread& DMemSpyDriverLogChanBase::TempObjectAsThread()
    {
	__ASSERT_DEBUG( iTempObj, MemSpyDriverUtils::Fault( __LINE__ ) );
    DThread* ret = (DThread*) iTempObj;
    return *ret;
    }


DProcess& DMemSpyDriverLogChanBase::TempObjectAsProcess()
    {
	__ASSERT_DEBUG( iTempObj, MemSpyDriverUtils::Fault( __LINE__ ) );
    DProcess* ret = (DProcess*) iTempObj;
    return *ret;
    }
















RMemSpyMemStreamWriter DMemSpyDriverLogChanBase::OpenXferStream()
    {
	__ASSERT_ALWAYS( iXferBuffer, MemSpyDriverUtils::Fault( __LINE__ ) );
    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenXferStream() - this: 0x%08x, xferSize: %d", this, iXferBuffer->Size() ) );
    RMemSpyMemStreamWriter ret( *iXferBuffer );
    return ret;
    }


TInt DMemSpyDriverLogChanBase::OpenXferStream( RMemSpyMemStreamWriter& aWriter, TInt aRequiredSize )
    {
    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenXferStream() - START - this: 0x%08x, xferSize: %d, aRequiredSize: %d", this, iXferBuffer->Size(), aRequiredSize ) );
    __ASSERT_ALWAYS( iXferBuffer, MemSpyDriverUtils::Fault( __LINE__ ) );
    
    TInt err = KErrNone;
    
    // Never make the buffer smaller - but we will make it bigger if needs be.
    if  ( aRequiredSize > iXferBuffer->Size() )
        {
        TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenXferStream() - Need to grow Xfer buffer..." ));
        err = iXferBuffer->EnsureCapacity( aRequiredSize );
        TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenXferStream() - grow result: %d", err ));
        }
    //
    if  ( err == KErrNone )
        {
        TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenXferStream() - creating writer... with xfer buffer size: %d", iXferBuffer->Size() ));
        aWriter = RMemSpyMemStreamWriter( *iXferBuffer );
        }
    //
    TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenXferStream() - END - this: 0x%08x, xferSize: %d, aRequiredSize: %d", this, iXferBuffer->Size(), aRequiredSize ) );
    return err;
    }





DMemSpyDriverOSAdaption& DMemSpyDriverLogChanBase::OSAdaption()
    {
    return iDevice.OSAdaption();
    }