filesystemuis/memscaneng/serversrc/memscanserv.cpp
changeset 14 1957042d8c7e
parent 1 d1daf54a55b5
child 16 ada7962b4308
--- a/filesystemuis/memscaneng/serversrc/memscanserv.cpp	Tue Feb 02 00:03:31 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,621 +0,0 @@
-/*
-* Copyright (c) 2006-2006 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:  Memory Scan Server
-*
-*/
-
-
-
-// SYSTEM INCLUDES
-#include <e32svr.h>
-#include <s32mem.h> // RBufWriteStream
-
-// USER INCLUDES
-#include "memscanserv.h"
-#include "memscanutils.h" // traces
-
-    
-// ---------------------------------------------------------------------------
-// Server startup code
-// ---------------------------------------------------------------------------
-
-// Perform all server initialisation, in particular creation of the
-// scheduler and server and then run the scheduler
-// 
-static void RunServerL()
-    {
-    // naming the server thread after the server helps to debug panics
-    User::LeaveIfError(User::RenameThread(KMemScanServName));
-
-    // create and install the active scheduler we need
-    CActiveScheduler* scheduler=new(ELeave) CActiveScheduler;
-    CleanupStack::PushL(scheduler);
-    CActiveScheduler::Install(scheduler);
-    // create the server (leave it on the cleanup stack)
-    CMemScanServ::NewLC();
-    // Initialisation complete, now signal the client
-
-    RProcess::Rendezvous(KErrNone);
-
-    // Ready to run
-    TRACES( RDebug::Print(_L("MemScanServ: server fully running")) );
-    CActiveScheduler::Start();
-    // Cleanup the server and scheduler
-    CleanupStack::PopAndDestroy(2, scheduler);
-    }
-
-// Server process entry-point
-TInt E32Main()
-    {
-    __UHEAP_MARK;
-    TRACES( RDebug::Print(_L("MemScanServ: E32Main")) ); 
-    CTrapCleanup* cleanup=CTrapCleanup::New();
-    TInt r=KErrNoMemory;
-    if (cleanup)
-        {
-        TRAP(r,RunServerL());
-        delete cleanup;
-        }
-    __UHEAP_MARKEND;
-    return r;
-    }
-    
-// RMessagePtr2::Panic() also completes the message. This is:
-// (a) important for efficient cleanup within the kernel
-// (b) a problem if the message is completed a second time
-void PanicClient(const RMessagePtr2& aMessage,TMemScanServPanic aPanic)
-    {
-    _LIT(KPanic,"MemScanServ");
-    aMessage.Panic(KPanic,aPanic);
-    }
-
-    
-// ---------------------------------------------------------------------------
-// CShutDown
-// ---------------------------------------------------------------------------
-inline CShutdown::CShutdown()
-    :CTimer(-1)
-    {
-    CActiveScheduler::Add(this);
-    }
-    
-inline void CShutdown::ConstructL()
-    {
-    CTimer::ConstructL();
-    }
-
-inline void CShutdown::Start()
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: starting shutdown timeout")) );
-    After(EMemScanServShutdownDelay);
-    }
-
-void CShutdown::RunL()
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: server timeout ... closing")) );
-    CActiveScheduler::Stop();
-    }
-
-// ---------------------------------------------------------------------------
-// CMemScanServ
-// ---------------------------------------------------------------------------
-inline CMemScanServ::CMemScanServ()
-    :CPolicyServer(0, KMemScanServPolicy, ESharableSessions)
-    {
-    }
-    
-CServer2* CMemScanServ::NewLC()
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: CMemScanServ::NewLC")) );
-    CMemScanServ* self=new(ELeave) CMemScanServ;
-    CleanupStack::PushL(self);
-    self->ConstructL();
-    return self;
-    }
-
-// 2nd phase construction - ensure the timer and server objects are running
-void CMemScanServ::ConstructL()
-    {
-    StartL(KMemScanServName);
-    iShutdown.ConstructL();
-    // ensure the server still exits even if the 1st client fails to connect
-    if( !iShutdown.IsActive() )
-        {
-        iShutdown.Start();
-        }
-    }
-
-
-// Create a new client session.
-CSession2* CMemScanServ::NewSessionL(const TVersion& aVersion, const RMessage2&) const
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: CMemScanServ::NewSessionL")) );
-
-    // Client-Server version check
-	TVersion version(KMemScanServMajor, KMemScanServMinor, KMemScanServBuild);
-	if( !User::QueryVersionSupported( version, aVersion ) )
-	    {
-	    User::Leave( KErrNotSupported );
-	    }
-
-    return new (ELeave) CMemScanServSession();
-    }
-
-// A new session is being created
-// Cancel the shutdown timer if it was running
-void CMemScanServ::AddSession()
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: CMemScanServ::AddSession")) );
-    ++iSessionCount;
-    iShutdown.Cancel();
-    }
-
-// A session is being destroyed
-// Start the shutdown timer if it is the last session.
-void CMemScanServ::DropSession()
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: CMemScanServ::DropSession")) );
-    if (--iSessionCount==0)
-        {
-        if( !iShutdown.IsActive() )
-            {
-            iShutdown.Start();
-            }
-        }
-    }
-
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession
-// ---------------------------------------------------------------------------
-inline CMemScanServSession::CMemScanServSession()
-    {
-    TRACES( RDebug::Print(_L("MemScanServer: CMemScanServSession::CMemScanServSession")); )
-    }
-    
-inline CMemScanServ& CMemScanServSession::Server()
-    {
-    return *static_cast<CMemScanServ*>(const_cast<CServer2*>(CSession2::Server()));
-    }
-
-// 2nd phase construct for sessions - called by the CServer framework
-void CMemScanServSession::CreateL()
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: CMemScanServSession::CreateL")); )
-    Server().AddSession();
-        
-    // Create a transfer buffer
-    iTransferBuffer = CBufFlat::NewL(KMemScanServTransferBufferExpandSize);
-    }
-
-CMemScanServSession::~CMemScanServSession()
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: CMemScanServSession::~CMemScanServSession")); )
-    
-    
-    delete iTransferBuffer;
-    delete iMseng;
-    
-    
-    iEventBuffer.Close();
-    Server().DropSession();
-    }
-
-
-// Handle a client request.
-// Leaving is handled by CMemScanServSession::ServiceError() which reports
-// the error code to the client
-void CMemScanServSession::ServiceL(const RMessage2& aMessage)
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: CMemScanServSession::ServiceL; %d"),aMessage.Function()); )
-    switch (aMessage.Function())
-        {
-        case EMemScanPrepareDataGroups:
-            {
-            PrepareDataGroupsL( aMessage );
-            break;
-            }
-        case EMemScanGetDataGroups:
-            {
-            GetDataGroupsL( aMessage );
-            break;
-            }            
-        case EMemScanStartScan:
-            {
-            MemScanL( aMessage );
-            break;
-            }
-        case EMemScanPrepareScanResults:
-            {
-            PrepareScanResultsL( aMessage );
-            break;
-            }
-        case EMemScanGetScanResults:
-            {
-            GetScanResultsL( aMessage );
-            break;
-            }                       
-        case EMemScanRequestScanEvents:
-            {
-            RequestScanEventsL( aMessage );
-            break;
-            }
-        case EMemScanRequestScanEventsCancel:
-            {
-            RequestScanEventsCancel( aMessage );
-            break;
-            }
-        case EMemScanInProgress:
-            {
-            ScanInProgress( aMessage );
-            break;
-            }
-
-        default:
-            {
-            TRACES( RDebug::Print(_L("MemScanServ: CMemScanServSession::ServiceL; %d"),aMessage.Function()); )
-            PanicClient(aMessage,EPanicIllegalFunction);
-            break;
-            }
-            
-        }
-    }
-
-// Handle an error from CMemScanServSession::ServiceL()
-void CMemScanServSession::ServiceError(const RMessage2& aMessage,TInt aError)
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: CMemScanServSession::ServiceError %d"),aError); )
-    CSession2::ServiceError(aMessage,aError);
-    }
-
-
-// ***************************************************************************
-// Internal utility functions
-// ***************************************************************************
-
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::PrepareDataGroupsL()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::PrepareDataGroupsL(const RMessage2& aMessage)
-    {
-    // Create scan engine if it does not exist
-    if(!iMseng)
-        {
-        iMseng = CMseng::NewL(*this);
-        }
-    
-    // Get data group name array
-    CDesCArray* dataGroupArray = iMseng->DataGroupsL();
-    CleanupStack::PushL(dataGroupArray);
-   
-   
-    // *** Start externalizing the data group array to transfer buffer
-
-    // Clear the buffer
-    iTransferBuffer->Reset();
-
-    // Set buffer for the stream
-    RBufWriteStream stream(*iTransferBuffer);
-    CleanupClosePushL(stream);
-    
-    // Write number of fields in array to stream 
-    TInt count = dataGroupArray->MdcaCount();
-    stream.WriteInt32L(count);
-    
-    // Write each field in array to stream
-    for(TInt i=0; i<count; i++)
-        {
-        TInt length = dataGroupArray->MdcaPoint(i).Length();
-        stream.WriteInt32L(length); // writes datagroup name length to stream
-        const TPtrC group = dataGroupArray->MdcaPoint(i);
-        stream << group; // writes one datagroup to stream
-        }
-    
-    stream.CommitL();
-    CleanupStack::PopAndDestroy(&stream);
-    CleanupStack::PopAndDestroy(dataGroupArray);
-    
-    // *** externalizing done
-    
-    
-    // Write the size of transfer buffer back to client
-    TPckgBuf<TInt> size(iTransferBuffer->Size());
-    aMessage.WriteL(0, size);
-    
-    // complete the message
-    aMessage.Complete( KErrNone );
-    }
-
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::GetDataGroupsL()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::GetDataGroupsL(const RMessage2& aMessage)
-    {
-    // Get the prepared data groups
-    aMessage.WriteL( KMesArg0, iTransferBuffer->Ptr(0)); 
-        
-    aMessage.Complete( KErrNone );
-    }
-    
-// ---------------------------------------------------------------------------
-// CMemScanServSession::PrepareScanResultsL()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::PrepareScanResultsL(const RMessage2& aMessage)
-    {
-    // Get scan results from server
-    CArrayFix<TInt64>* resultArray = iMseng->ScanResultL();
-    CleanupStack::PushL(resultArray);
-
-    // *** Start externalizing the result array to transfer buffer
-    
-    // Clear the buffer
-    iTransferBuffer->Reset();
-        
-    // Set buffer for the stream
-    RBufWriteStream stream(*iTransferBuffer);
-    CleanupClosePushL(stream);
-    
-    // Write number of fields in array to stream 
-    TInt count = resultArray->Count();
-    stream.WriteInt32L(count);    
-    
-    // Write each field in array to stream
-    for(TInt i=0; i<count; i++)
-        {
-        const TInt64 result = resultArray->At(i);
-        stream << result; // writes one data result to stream
-        }
-    
-    stream.CommitL();
-    CleanupStack::PopAndDestroy(&stream);
-    CleanupStack::PopAndDestroy(resultArray);
-    
-    // *** externalizing done
-    
-    
-    // Write the size of transfer buffer back to client
-    TPckgBuf<TInt> size(iTransferBuffer->Size());
-    aMessage.WriteL(0, size);    
-    
-    
-    aMessage.Complete( KErrNone );    
-    }
-
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::GetScanResultsL()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::GetScanResultsL(const RMessage2& aMessage)
-    {
-    // Get the prepared scan results
-    aMessage.WriteL( KMesArg0, iTransferBuffer->Ptr(0));    
-    
-    aMessage.Complete( KErrNone ); 
-    }
-
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::MemScanL()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::MemScanL(const RMessage2& aMessage)
-    {
-    TRACES( RDebug::Print(_L("MemScanServ: CMemScanServSession::ScanL")); )
-    
-     // Get the first integer parameter of message     
-    TDriveNumber drive = TDriveNumber(aMessage.Int0()); 
-        
-    iMseng->ScanL( drive );
-    aMessage.Complete( KErrNone );
-    }
-
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::RequestScanEventsL()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::RequestScanEventsL(const RMessage2& aMessage)
-    {
-    if  ( iScanEventMessage.IsNull() ) 
-        {
-        // We want check that the client hasn't requested scan events
-        // twice in a row. The client is only allowed to have one 
-        // scan event request outstanding at any given time.
-        //
-        // Since the iScanEventMessage was null (i.e. its not been
-        // initialised) then its safe to store the client's message
-        // for completion later on when the scan engine has a real event.
-        
-        // Save the clients message for later until we receive an
-        // event callback from the scan engine.
-        iScanEventMessage = aMessage;
-
-        // If we have at least one event ready to send to the client, then
-        // we deliver it to the client immediately. This could be possible
-        // if the client is slow to process an earlier event.
-        const TBool haveAtLeastOneEventPending = IsEventReady();
-        if  ( haveAtLeastOneEventPending )
-            {
-            // We must deliver the oldest event to the client.
-            DeliverOldestEventToClientL(); // this will complete aMessage immediately.
-            }
-        }
-    else
-        {
-        // The client has already asked for scan events as we still
-        // have an existing (valid) iScanEventMessage object.
-        //
-        // This would imply a programming error in the client code
-        // so we punish the client by panicking it.
-        aMessage.Panic( KMemScanServerPanicCategory, EMemScanServerPanicRequestedScanEventsTwice );
-        }
-    }
-
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::RequestScanEventsCancel()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::RequestScanEventsCancel(const RMessage2& aMessage)
-    {
-    // We only are able to cancel a client request if the client actually
-    // requested something.
-    // We can check whether a request is pending by using the IsNull method
-    // on our outstanding request object ("iScanEventMessage").
-    if  ( iScanEventMessage.IsNull() == EFalse ) 
-        {
-        // The client has made a request, and we need to cancel it.
-        iScanEventMessage.Complete( KErrCancel );
-        }
-        
-        
-    // If the client wants to cancel events, we should also empty
-    // the event buffer.
-    iEventBuffer.Reset();
-    
-    aMessage.Complete( KErrNone );
-    }
-
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::ScanInProgress()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::ScanInProgress(const RMessage2& aMessage)
-    {
-    TBool scanInProgress = iMseng->ScanInProgress();
-    aMessage.Complete(static_cast<TInt> (scanInProgress));
-    }
-
-
-
-// From MMsengUIHandler:
-// ===========================================================================
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::StartL()
-// ---------------------------------------------------------------------------
-void CMemScanServSession::StartL()
-    {
-    SendEventToClientL( EMemScanEventScanningStarted );
-    }
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::QuitL()
-// ---------------------------------------------------------------------------
-void CMemScanServSession::QuitL(TInt aReason)
-    {
-    SendEventToClientL( EMemScanEventScanningFinished, aReason );
-    }
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::Error()
-// ---------------------------------------------------------------------------
-void CMemScanServSession::ErrorL(TInt aError)
-    {
-    SendEventToClientL( EMemScanEventScanningError, aError );
-    }
-
-// ===========================================================================
-
-
-
-    
-// ---------------------------------------------------------------------------
-// CMemScanServSession::SendEventToClientL()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::SendEventToClientL( TMemScanEvent aEventType,
-                                              TInt aError )
-    {
-    // We need to tell the client about the event that has taken place. 
-    // The client event API expects to receive the event type, i.e. what 
-    // kind of "thing" just happened, and also any associated error value 
-    // (e.g. "Nothing went wrong" or, "we ran out of memory").
-    
-    AddNewEventToBufferL( aEventType, aError );
-    DeliverOldestEventToClientL();
-    }
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::AddNewEventToBufferL()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::AddNewEventToBufferL( TMemScanEvent aEventType,
-                                                TInt aError )
-    {
-    TMemScanEventPackage event;
-    event.iEvent = aEventType;
-    event.iError = aError;
-    
-    // Add the event to the event buffer. We will send this event to the 
-    // client when the client is ready to accept it.
-    iEventBuffer.AppendL( event );
-    }
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::IsEventReady()
-//
-// ---------------------------------------------------------------------------
-TBool CMemScanServSession::IsEventReady() const
-    {
-    // Returns whether we have at least one event in the buffer ready to send
-    // to the client.
-    const TInt count = iEventBuffer.Count();
-    return ( count > 0 );
-    }
-
-
-// ---------------------------------------------------------------------------
-// CMemScanServSession::DeliverOldestEventToClientL()
-//
-// ---------------------------------------------------------------------------
-void CMemScanServSession::DeliverOldestEventToClientL()
-    {
-    // Fetch the oldest event from the buffer and deliver it
-    // to the client.
-    if  ( iScanEventMessage.IsNull() == EFalse && IsEventReady() )
-        {
-        // This next block of code converts the error number to look like
-        // a descriptor, since this is the only way of writing to the
-        // client's address space. 
-        //
-        // We check that the client actually requested scan events before
-        // we try and write to its address space. If we don't do this
-        // then the kernel will panic our code with KERN-SVR 0
-        // ("you're trying to use a null message object")
-        const TMemScanEventPackage& event = iEventBuffer[ 0 ];
-        
-        TPckgC<TInt> associatedErrorAsDescriptor( event.iError );
-        iScanEventMessage.WriteL( 0, associatedErrorAsDescriptor );
-        
-        // Now that we have written the error value, its safe to complete
-        // the clients asynchronous request which will end up calling
-        // the client's RunL method.
-        iScanEventMessage.Complete( event.iEvent );
-
-        // We've delivered the oldest event to the client, so now 
-        // its safe to discard it.
-        iEventBuffer.Remove( 0 );
-        }
-    }
- 
-
-// End of File