--- /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 <e32svr.h>
+#include <bautils.h>
+
+// --------------------------------------------------------------------------------------------
+
+//***********************************
+//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<TFileOpArgs> 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<TFileOpArgs> 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<TFileOpArgs> 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<TFileOpArgs> 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<TFileOpArgs> 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<TFileOpArgs> pckgBuf;
+ aMessage.ReadL(0, pckgBuf, 0);
+ TFileOpArgs argsStruct = pckgBuf();
+
+ User::LeaveIfError(iFs.MkDirAll(argsStruct.iBuf1));
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CFBFileOpServerSession::CreateEmptyFileL(const RMessage2& aMessage)
+ {
+ TPckgBuf<TFileOpArgs> 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<TFileOpArgs> 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<TFileOpArgs> 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;
+ }
+
+// --------------------------------------------------------------------------------------------