--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/remotestoragefw/remotefileengine/src/rsfwrfeasyncoperation.cpp Thu Dec 17 09:07:59 2009 +0200
@@ -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<TRsfwMountConfig> 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<TInt>(request->Message().Ptr0());
+ TUint state = reinterpret_cast<TUint>(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);
+ }
+ }
+