diff -r 819e59dfc032 -r 2d9cac8919d3 utilityapps/filebrowser/fileopserver/src/FBFileOpServer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilityapps/filebrowser/fileopserver/src/FBFileOpServer.cpp Mon Oct 18 16:30:05 2010 +0300 @@ -0,0 +1,474 @@ +/* +* 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 "FBFileOpServer.h" +#include "FBDrivePartitioner.h" + +#include +#include + +// -------------------------------------------------------------------------------------------- + +//*********************************** +//CFBFileOpServer - implementations +//*********************************** + +CServer2* CFBFileOpServer::NewLC() + { + CFBFileOpServer* self = new(ELeave) CFBFileOpServer; + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +// -------------------------------------------------------------------------------------------- + +// +// 2nd phase construction - ensure the timer and server objects are running +// +void CFBFileOpServer::ConstructL() + { + StartL(KMyServerName); + iShutdown.ConstructL(); + // ensure that the server still exits even if the 1st client fails to connect + iShutdown.Start(); + } + +// -------------------------------------------------------------------------------------------- + +// +// Cretae a new client session. This should really check the version number. +// +CSession2* CFBFileOpServer::NewSessionL(const TVersion&,const RMessage2&) const + { + return new(ELeave) CFBFileOpServerSession(); + } + +// -------------------------------------------------------------------------------------------- + +// +// A new session is being created +// Cancel the shutdown timer if it was running +// +void CFBFileOpServer::AddSession() + { + ++iSessionCount; + iShutdown.Cancel(); + } + +// -------------------------------------------------------------------------------------------- + +// +// A session is being destroyed +// Start the shutdown timer if it is the last session. +// +void CFBFileOpServer::DropSession() + { + if (--iSessionCount==0) + iShutdown.Start(); + } + +// -------------------------------------------------------------------------------------------- + +CRequestObserver::CRequestObserver( TInt aPriority ) : CActive( aPriority ) + { + CActiveScheduler::Add( this ); + } + +CRequestObserver::~CRequestObserver() + { + Cancel(); + } + +void CRequestObserver::StartWaiting( const RMessage2& aMsg ) + { + iMsg = aMsg; + SetActive(); + } + +void CRequestObserver::RunL() + { + iMsg.Complete( iStatus.Int() ); + } + +void CRequestObserver::DoCancel() + { + iMsg.Complete( KErrCancel ); + } + +// -------------------------------------------------------------------------------------------- + +//*********************************** +//CFBFileOpServerSession - implementations +//*********************************** + +// +// 2nd phase construct for sessions - called by the CServer framework +// +void CFBFileOpServerSession::CreateL() + { + User::LeaveIfError(iFs.Connect()); + iFileMan = CFileMan::NewL( iFs, this ); + iReqObserver = new (ELeave) CRequestObserver( CActive::EPriorityStandard ); + Server().AddSession(); + } + +// -------------------------------------------------------------------------------------------- + +CFBFileOpServerSession::~CFBFileOpServerSession() + { + if (iFileMan) + { + delete iFileMan; + iFileMan = NULL; + } + iFs.Close(); + delete iReqObserver; + Server().DropSession(); + } + +// -------------------------------------------------------------------------------------------- + +/** +Services a client request. +*/ +void CFBFileOpServerSession::ServiceL(const RMessage2& aMessage) + { + TBool completeImmediately( ETrue ); + TRAPD( err,DispatchMessageL( aMessage, completeImmediately ) ); + if ( completeImmediately ) aMessage.Complete( err ); + } + +// -------------------------------------------------------------------------------------------- + +/** +Called by ServiceL() + +It tests the function code and then delegates to +the appropriate function. +*/ +void CFBFileOpServerSession::DispatchMessageL(const RMessage2& aMessage, TBool& aComplete) + { + switch (aMessage.Function()) + { + case EFileOpCopy: + CopyL(aMessage); + aComplete = EFalse; + return; + + case EFileOpRename: + RenameL(aMessage); + return; + + case EFileOpAttribs: + AttribsL(aMessage); + return; + + case EFileOpRmDir: + RmDirL(aMessage, aComplete); + return; + + case EFileOpDelete: + DeleteL(aMessage); + aComplete = EFalse; + return; + + case EFileOpMkDirAll: + MkDirAllL(aMessage); + return; + + case EFileOpCreateEmptyFile: + CreateEmptyFileL(aMessage); + return; + + case EFileOpEraseMBR: + EraseMBRL(aMessage); + return; + + case EFileOpPartitionDrive: + PartitionDriveL(aMessage); + return; + + case EFileOpCancel: + CancelOp(); + return; + + default: + PanicClient(aMessage, EPanicIllegalFunction); + return; + } + } + +// -------------------------------------------------------------------------------------------- + +void CFBFileOpServerSession::CopyL( const RMessage2& aMessage ) + { + __ASSERT_ALWAYS( iReqObserver && !iReqObserver->IsActive(), User::Leave( KErrServerBusy ) ); + TPckgBuf pckgBuf; + aMessage.ReadL( 0, pckgBuf, 0 ); + TFileOpArgs argsStruct = pckgBuf(); + + TInt err = iFileMan->Copy( argsStruct.iBuf1, argsStruct.iBuf2, argsStruct.iUint1, iReqObserver->iStatus ); + User::LeaveIfError( err ); + iFileManObserverResult = MFileManObserver::EContinue; + iReqObserver->StartWaiting( aMessage ); // start asynchronous waiting + } + +// -------------------------------------------------------------------------------------------- + +void CFBFileOpServerSession::RenameL(const RMessage2& aMessage) + { + TPckgBuf pckgBuf; + aMessage.ReadL(0, pckgBuf, 0); + TFileOpArgs argsStruct = pckgBuf(); + + iFileManObserverResult = MFileManObserver::EContinue; + User::LeaveIfError(iFileMan->Rename(argsStruct.iBuf1, argsStruct.iBuf2, argsStruct.iUint1)); + } + +// -------------------------------------------------------------------------------------------- + +void CFBFileOpServerSession::AttribsL(const RMessage2& aMessage) + { + TPckgBuf pckgBuf; + aMessage.ReadL(0, pckgBuf, 0); + TFileOpArgs argsStruct = pckgBuf(); + + iFileManObserverResult = MFileManObserver::EContinue; + User::LeaveIfError(iFileMan->Attribs(argsStruct.iBuf1, argsStruct.iUint1, argsStruct.iUint2, argsStruct.iTime1, argsStruct.iUint3)); + } + +// -------------------------------------------------------------------------------------------- + +void CFBFileOpServerSession::RmDirL( const RMessage2& aMessage, TBool& aComplete ) + { + TPckgBuf pckgBuf; + aMessage.ReadL( 0, pckgBuf, 0 ); + TFileOpArgs argsStruct = pckgBuf(); + + if ( argsStruct.iUint1 & CFileMan::ERecurse ) + { + __ASSERT_ALWAYS( iReqObserver && !iReqObserver->IsActive(), User::Leave( KErrServerBusy ) ); + User::LeaveIfError( iFileMan->RmDir( argsStruct.iBuf1, iReqObserver->iStatus ) ); + iFileManObserverResult = MFileManObserver::EContinue; + aComplete = EFalse; + iReqObserver->StartWaiting( aMessage ); // start asynchronous waiting + } + else + { + iFileManObserverResult = MFileManObserver::EContinue; + User::LeaveIfError( iFs.RmDir( argsStruct.iBuf1 ) ); + } + } + +// -------------------------------------------------------------------------------------------- + +void CFBFileOpServerSession::DeleteL( const RMessage2& aMessage ) + { + __ASSERT_ALWAYS( iReqObserver && !iReqObserver->IsActive(), User::Leave( KErrServerBusy ) ); + TPckgBuf pckgBuf; + aMessage.ReadL( 0, pckgBuf, 0 ); + TFileOpArgs argsStruct = pckgBuf(); + + User::LeaveIfError( iFileMan->Delete(argsStruct.iBuf1, argsStruct.iUint1, iReqObserver->iStatus ) ); + iFileManObserverResult = MFileManObserver::EContinue; + iReqObserver->StartWaiting( aMessage ); // start asynchronous waiting + } + +// -------------------------------------------------------------------------------------------- + +void CFBFileOpServerSession::MkDirAllL(const RMessage2& aMessage) + { + TPckgBuf pckgBuf; + aMessage.ReadL(0, pckgBuf, 0); + TFileOpArgs argsStruct = pckgBuf(); + + User::LeaveIfError(iFs.MkDirAll(argsStruct.iBuf1)); + } + +// -------------------------------------------------------------------------------------------- + +void CFBFileOpServerSession::CreateEmptyFileL(const RMessage2& aMessage) + { + TPckgBuf pckgBuf; + aMessage.ReadL(0, pckgBuf, 0); + TFileOpArgs argsStruct = pckgBuf(); + + TInt err(KErrNone); + RFile newFile; + err = newFile.Create(iFs, argsStruct.iBuf1, EFileShareExclusive); + if (err == KErrNone) + err = newFile.Flush(); + newFile.Close(); + + User::LeaveIfError(err); + } + +// -------------------------------------------------------------------------------------------- + +void CFBFileOpServerSession::EraseMBRL(const RMessage2& aMessage) + { + TPckgBuf pckgBuf; + aMessage.ReadL(0, pckgBuf, 0); + TFileOpArgs argsStruct = pckgBuf(); + + RFs fs; + CleanupClosePushL(fs); + User::LeaveIfError(fs.Connect()); + + User::LeaveIfError(FBDrivePartioner::EraseMBR(fs, argsStruct.iUint1)); + + CleanupStack::PopAndDestroy(); //fs + } + +// -------------------------------------------------------------------------------------------- + +void CFBFileOpServerSession::PartitionDriveL(const RMessage2& aMessage) + { + TPckgBuf pckgBuf; + aMessage.ReadL(0, pckgBuf, 0); + TFileOpArgs argsStruct = pckgBuf(); + + RFs fs; + CleanupClosePushL(fs); + User::LeaveIfError(fs.Connect()); + + FBDrivePartioner::CreatePartitions(fs, argsStruct.iUint1, argsStruct.iUint2); + User::LeaveIfError(FBDrivePartioner::FormatPartitions(fs, argsStruct.iUint1, argsStruct.iUint2)); + + CleanupStack::PopAndDestroy(); //fs + } + +// -------------------------------------------------------------------------------------------- + +// +// Panics the client +// +void CFBFileOpServerSession::PanicClient(const RMessage2& aMessage, TInt aPanic) const + { + _LIT(KTxtServer,"FBFileOpServer"); + aMessage.Panic(KTxtServer, aPanic); + } + +// -------------------------------------------------------------------------------------------- + +// +// Handle an error from CFBFileOpServerSession::ServiceL() +// A bad descriptor error implies a badly programmed client, so panic it; +// otherwise use the default handling (report the error to the client) +// +void CFBFileOpServerSession::ServiceError(const RMessage2& aMessage, TInt aError) + { + if (aError==KErrBadDescriptor) + PanicClient(aMessage,EPanicBadDescriptor); + CSession2::ServiceError(aMessage,aError); + } + +// -------------------------------------------------------------------------------------------- + +MFileManObserver::TControl CFBFileOpServerSession::NotifyFileManStarted() + { + return iFileManObserverResult; + } + +// -------------------------------------------------------------------------------------------- + +MFileManObserver::TControl CFBFileOpServerSession::NotifyFileManOperation() + { + return iFileManObserverResult; + } +// -------------------------------------------------------------------------------------------- + +MFileManObserver::TControl CFBFileOpServerSession::NotifyFileManEnded() + { + return iFileManObserverResult; + } + +// -------------------------------------------------------------------------------------------- + +void CFBFileOpServerSession::CancelOp() + { + iFileManObserverResult = MFileManObserver::ECancel; + iReqObserver->Cancel(); + } + +// -------------------------------------------------------------------------------------------- + +//********************************** +//Global functions +//********************************** + +// +// Initiate server exit when the timer expires +// +void CShutdown::RunL() + { + CActiveScheduler::Stop(); + } + +// -------------------------------------------------------------------------------------------- + +// +// 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(RThread::RenameMe(KMyServerName)); + // + // create and install the active scheduler we need + CActiveScheduler* s=new(ELeave) CActiveScheduler; + CleanupStack::PushL(s); + CActiveScheduler::Install(s); + // + // create the server (leave it on the cleanup stack) + CFBFileOpServer::NewLC(); + // + // Initialisation complete, now signal the client + RProcess::Rendezvous(KErrNone); + // + // Ready to run + CActiveScheduler::Start(); + // + // Cleanup the server and scheduler + CleanupStack::PopAndDestroy(2); + } + +// -------------------------------------------------------------------------------------------- + +// +// Server process entry-point +// +TInt E32Main() + { + __UHEAP_MARK; + // + CTrapCleanup* cleanup=CTrapCleanup::New(); + TInt r=KErrNoMemory; + if (cleanup) + { + TRAP(r,RunServerL()); + delete cleanup; + } + // + __UHEAP_MARKEND; + return r; + } + +// --------------------------------------------------------------------------------------------