remotestoragefw/remotefileengine/src/rsfwrfeasyncoperation.cpp
changeset 0 3ad9d5175a89
--- /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);
+        }
+    }
+