diff -r 88ee4cf65e19 -r 1aa8c82cb4cb remotestoragefw/remotefileengine/src/rsfwrfeasyncoperation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/remotestoragefw/remotefileengine/src/rsfwrfeasyncoperation.cpp Wed Sep 01 12:15:08 2010 +0100 @@ -0,0 +1,378 @@ +/* +* Copyright (c) 2005-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: Encapsulates an asynchronous operation +* +*/ + + +#include "rsfwrfeasyncoperation.h" +#include "rsfwrfemessagerequest.h" +#include "rsfwrfestatemachine.h" +#include "rsfwmountstatemachine.h" +#include "rsfwmountconnectionstatemachine.h" +#include "rsfwopenbypathstatemachine.h" +#include "rsfwgetattributesstatemachine.h" +#include "rsfwattributerefreshingstatemachine.h" +#include "rsfwfetchandcachestatemachine.h" +#include "rsfwfetchdatastatemachine.h" +#include "rsfwlookupstatemachine.h" +#include "rsfwclosestatemachine.h" +#include "rsfwflushstatemachine.h" +#include "rsfwmkdirstatemachine.h" +#include "rsfwdeletestatemachine.h" +#include "rsfwcreatefilestatemachine.h" +#include "rsfwrenamefilestatemachine.h" +#include "rsfwvolumetable.h" +#include "mdebug.h" +#include "rsfwcommon.h" +#include "rsfwrfeserver.h" +#include "rsfwinterface.h" + + +// ---------------------------------------------------------------------------- +// CRsfwRfeAsyncOperation::~CRsfwRfeAsyncOperation +// ---------------------------------------------------------------------------- +// +CRsfwRfeAsyncOperation::~CRsfwRfeAsyncOperation() + { + delete iImplementation; + iImplementation = NULL; + } + +// ---------------------------------------------------------------------------- +// CRsfwRfeAsyncOperation::Implementation +// ---------------------------------------------------------------------------- +// +CRsfwRfeStateMachine* CRsfwRfeAsyncOperation::Implementation() + { + return iImplementation; + } + +// ---------------------------------------------------------------------------- +// CRsfwRfeAsyncOperation::SetImplementation +// ---------------------------------------------------------------------------- +// +void CRsfwRfeAsyncOperation::SetImplementation(CRsfwRfeStateMachine* aImpl) + { + iImplementation = aImpl; + } + +// ---------------------------------------------------------------------------- +// CRsfwRfeAsyncOperation::SetL +// Set asynchronous operation and its parameters +// Leave if OOM etc. +// ---------------------------------------------------------------------------- +// +void CRsfwRfeAsyncOperation::SetL(CRsfwRfeRequest* aRequest, TInt aOpCode) + { + CRsfwRfeMessageRequest* request = (CRsfwRfeMessageRequest*)aRequest; + CRsfwRfeStateMachine::TState* initialState = NULL; + CRsfwRfeStateMachine* operation = NULL; + + if (aRequest->iVolume) + { + DEBUGSTRING(("<<< Dispatch enter (operation=%d, volume=%d)", + aOpCode, + aRequest->iVolume->iMountInfo.iMountStatus.iVolumeId)); + } + else + { + DEBUGSTRING(("<<< Dispatch enter (operation=%d)", aOpCode)); + } + + switch (aOpCode) + { + case EMount: + case EMountByDriveLetter: + { + DEBUGSTRING(("EMount / EMountByDriveLetter")); + TRsfwMountConfig* mountConfig = new (ELeave) TRsfwMountConfig; + CleanupStack::PushL(mountConfig); + TPckg mountConfigPackage(*mountConfig); + if (aOpCode == EMount) + { + request->Message().ReadL(0, mountConfigPackage); + // this is to satisfy IPC fuzz testing + VerifyMountConfigL(*mountConfig); + } + else + { + // EMountByDriveLetter - create a stub TRsfwMountConfig + TInt driveNumber = request->Message().Int0(); + RFs fs = CRsfwRfeServer::Env()->iFs; + fs.DriveToChar(driveNumber, mountConfig->iDriveLetter); + mountConfig->iUri.SetLength(0); + } + + // fetch mountconfig from mountStore + if (!mountConfig->iUri.Length() || aOpCode == EMountByDriveLetter) + { + // the drive letter must be set + User::LeaveIfError(aRequest->iVolumeTable->GetMountConfigL( + *mountConfig)); + } + + // If there is an existing mount, the configurations must match. + // Otherwise we unmount the already existing mount. + CRsfwVolume* volume = + aRequest-> + iVolumeTable-> + VolumeByDriveLetter(mountConfig->iDriveLetter); + if (volume) + { + if (volume->iMountInfo.iMountConfig.iUri.CompareF( + mountConfig->iUri) != 0) + { + // We have a mismatch + DEBUGSTRING16(("Dismounting an obsolete mount %S", + &volume->iMountInfo.iMountConfig.iUri)); + aRequest-> + iVolumeTable-> + DismountByDriveLetterL(mountConfig->iDriveLetter, + ETrue); + } + } + TInt mountState = + aRequest->iVolumeTable->MountState(mountConfig->iDriveLetter); + operation = CRsfwMountStateMachine::NewL(*mountConfig, + mountState, + aRequest->iVolumeTable); + CleanupStack::PushL(operation); + ((CRsfwWaitNoteStateMachine *) operation)->BaseConstructL(); + initialState = + new (ELeave) CRsfwMountStateMachine::TRequestConnectionState( + (CRsfwMountStateMachine *)operation); + + CleanupStack::Pop(operation); + DEBUGSTRING16(("EMount: name '%S' with URI='%S' as '%c' (state=%d)", + &mountConfig->iName, + &mountConfig->iUri, + TUint(mountConfig->iDriveLetter), + mountState)); + CleanupStack::PopAndDestroy(mountConfig); + } + break; + + case ESetMountConnectionState: + { + DEBUGSTRING(("ESetMountConnectionState")); + // Set the connection state of the mount + TChar driveLetter = reinterpret_cast(request->Message().Ptr0()); + TUint state = reinterpret_cast(request->Message().Ptr1()); + DEBUGSTRING(("EMountConnectionState: drive '%c', state=%d", + TUint(driveLetter), + state)); + + operation = new(ELeave) CRsfwMountConnectionStateMachine(driveLetter, + state); + CleanupStack::PushL(operation); + ((CRsfwWaitNoteStateMachine *) operation)->BaseConstructL(); + initialState = + new (ELeave) CRsfwMountConnectionStateMachine::TChangeConnectionState( + (CRsfwMountConnectionStateMachine *)operation); + CleanupStack::Pop(operation); + } + + break; + + case EOpenByPath: + { + DEBUGSTRING(("OPENBYPATH")); + operation = new (ELeave) CRsfwOpenByPathStateMachine(); + CleanupStack::PushL(operation); + operation->BaseConstructL(); + // we need to refresh attributes first + initialState = + new (ELeave) CRsfwGetAttributesStateMachine::TRefreshAttributesState( + (CRsfwAttributeRefreshingStateMachine *)operation); + CleanupStack::Pop(operation); + break; + } + + case EFetch: + { + DEBUGSTRING(("FETCH")); + operation = new (ELeave) CRsfwFetchAndCacheStateMachine(); + CleanupStack::PushL(operation); + ((CRsfwWaitNoteStateMachine *) operation)->BaseConstructL(); + initialState = + new (ELeave) CRsfwFetchAndCacheStateMachine::TFetchDataState( + (CRsfwFetchAndCacheStateMachine *)operation); + CleanupStack::Pop(operation); + break; + } + + case EFetchData: + { + DEBUGSTRING(("FETCHDATA")); + operation = new (ELeave) CRsfwFetchDataStateMachine(); + CleanupStack::PushL(operation); + ((CRsfwWaitNoteStateMachine *) operation)->BaseConstructL(); + initialState = new (ELeave) CRsfwFetchDataStateMachine::TFetchDataState( + (CRsfwFetchDataStateMachine *)operation); + CleanupStack::Pop(operation); + break; + } + + case ELookUp: + { + DEBUGSTRING(("LOOKUP")); + operation = new (ELeave) CRsfwLookupStateMachine(); + CleanupStack::PushL(operation); + operation->BaseConstructL(); + initialState = new (ELeave) + CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState( + (CRsfwLookupStateMachine *)operation); + CleanupStack::Pop(operation); + break; + } + + case EGetAttr: + { + DEBUGSTRING(("GETATTR")); + operation = new (ELeave) CRsfwGetAttributesStateMachine(); + CleanupStack::PushL(operation); + operation->BaseConstructL(); + initialState = + new (ELeave) CRsfwGetAttributesStateMachine::TRefreshAttributesState( + (CRsfwGetAttributesStateMachine *)operation); + CleanupStack::Pop(operation); + break; + } + + case EClose: + { + DEBUGSTRING(("CLOSE")); + operation = new (ELeave) CRsfwCloseStateMachine(); + CleanupStack::PushL(operation); + ((CRsfwWaitNoteStateMachine *) operation)->BaseConstructL(); + initialState = + new (ELeave) CRsfwCloseStateMachine::TReleaseLockState( + (CRsfwCloseStateMachine *) operation); + CleanupStack::Pop(operation); + break; + } + case EFlush: + { + DEBUGSTRING(("FLUSH")); + operation = new (ELeave) CRsfwFlushStateMachine(); + CleanupStack::PushL(operation); + ((CRsfwFlushStateMachine *) operation)->BaseConstructL(); + initialState = + new (ELeave) CRsfwFlushStateMachine::TFlushDataToServerState( + (CRsfwFlushStateMachine *) operation); + CleanupStack::Pop(operation); + break; + } + + case EMkDir: + { + DEBUGSTRING(("MKDIR")); + operation = new (ELeave) CRsfwMkDirStateMachine(); + CleanupStack::PushL(operation); + operation->BaseConstructL(); + initialState = new (ELeave) CRsfwMkDirStateMachine::TCheckIfExistsState( + (CRsfwMkDirStateMachine *) operation); + CleanupStack::Pop(operation); + break; + } + + case ERemoveDir: + { + DEBUGSTRING(("RMDIR")); + operation = new (ELeave) CRsfwDeleteStateMachine(KNodeTypeDir); + CleanupStack::PushL(operation); + operation->BaseConstructL(); + initialState = new (ELeave) CRsfwDeleteStateMachine::TCheckIfCanBeDeleted( + (CRsfwDeleteStateMachine *) operation); + CleanupStack::Pop(operation); + break; + } + + case ERemove: + DEBUGSTRING(("REMOVE")); + operation = new (ELeave) CRsfwDeleteStateMachine(KNodeTypeFile); + CleanupStack::PushL(operation); + operation->BaseConstructL(); + initialState = new (ELeave) CRsfwDeleteStateMachine::TCheckIfCanBeDeleted( + (CRsfwDeleteStateMachine *) operation); + CleanupStack::Pop(operation); + break; + + case ECreateFile: + DEBUGSTRING(("CREATE")); + operation = new (ELeave) CRsfwCreateFileStateMachine(); + CleanupStack::PushL(operation); + operation->BaseConstructL(); + initialState = + new (ELeave) CRsfwCreateFileStateMachine::TCheckIfExistsState( + (CRsfwCreateFileStateMachine *) operation); + CleanupStack::Pop(operation); + break; + + case ERenameReplace: + DEBUGSTRING(("RENAME")); + operation = new (ELeave) CRsfwRenameFileStateMachine(); + CleanupStack::PushL(operation); + operation->BaseConstructL(); + initialState = new (ELeave) CRsfwRenameFileStateMachine::TRenameFileState( + (CRsfwRenameFileStateMachine *) operation); + CleanupStack::Pop(operation); + break; + + default: + // request handler function not set, + // would lead to accessing a NULL pointer + User::Panic(KRfeServer, ENullRequestHandler); + } + + SetImplementation(operation); + Implementation()->SetNextState(initialState); + + // Set parameters + iImplementation->SetVolumes(aRequest->iVolumeTable); + + if (aRequest->iVolume) + { + iImplementation->SetFileEngine(aRequest->iVolume->iFileEngine); + } + + iImplementation->SetArguments(aRequest->iInArgs, aRequest->iOutArgs); + + // Set backpointer to the request we are running, + // so that the state machine can easily complete it + iImplementation->SetRequest(aRequest); + + iIsSync = EFalse; + CRsfwRfeOperation::Set(aOpCode); + } + +// ---------------------------------------------------------------------------- +// CRsfwRfeAsyncOperation::VerifyMountConfigL +// Checks whether mount config data is correct +// ---------------------------------------------------------------------------- +// +void CRsfwRfeAsyncOperation::VerifyMountConfigL(TRsfwMountConfig& aMountConfig) + { + if (aMountConfig.iName.Length() > KMaxMountNameLength || + aMountConfig.iUri.Length() > KMaxMountUriLength || + aMountConfig.iUserName.Length() > KMaxMountUserNameLength || + aMountConfig.iPassword.Length() > KMaxMountPasswordLength || + aMountConfig.iAuxData.Length() > KMaxMountAuxDataLength) + { + DEBUGSTRING16(("CRsfwRfeAsyncOperation::VerifyMountConfigL bad aMountConfig argument")); + User::Leave(KErrArgument); + } + } +