remotestoragefw/remotefileengine/src/rsfwrfeserver.cpp
branchRCL_3
changeset 20 1aa8c82cb4cb
parent 0 3ad9d5175a89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/remotestoragefw/remotefileengine/src/rsfwrfeserver.cpp	Wed Sep 01 12:15:08 2010 +0100
@@ -0,0 +1,498 @@
+/*
+* Copyright (c) 2003-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:  Remote File Engine server
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <e32svr.h>
+#include <e32math.h>
+#include <e32cons.h>
+
+#include <bacline.h>
+
+#include "rsfwvolumetable.h"
+#include "rsfwcommon.h"
+#include "rsfwinterface.h"
+#include "rsfwrfesession.h"
+#include "rsfwrfeserver.h"
+#include "mdebug.h"
+#include "ecom.h"
+#include "rsfwmountstore.h"
+
+#include "rsfwconfig.h"
+
+
+// ----------------------------------------------------------------------------------------
+// Server's policy here
+// ----------------------------------------------------------------------------------------
+
+//Total number of ranges
+const TUint remoteFileEngineRangeCount = 3;
+
+//Definition of the ranges of IPC numbers
+const TInt remoteFileEngineRanges[remoteFileEngineRangeCount] = 
+        {
+        0, // 0 & 1 ; ERfeRequest, EAsynchRequest
+        2, // 2 ; The Control API starts from EMount
+        12 // 12 ; The Access API starts from ERenameReplace
+        }; 
+
+//Policy to implement for each of the above ranges        
+const TUint8 remoteFileEngineElementsIndex[remoteFileEngineRangeCount] = 
+        {
+        CPolicyServer::EAlwaysPass,	//applies to 0th range
+        0,  //applies to 1st range
+        1  //applies to 2nd range
+        };
+
+//Specific capability checks
+const static CPolicyServer::TPolicyElement remoteFileEngineElements[] = 
+        {
+        // action = -1 ===> failing calls happens via CustomFailureActionL
+        // File Server is always allowed based on its SID from that function
+        //policy "0" for the Control API; fail call if NetworkServices and ReadDeviceData not present
+        {_INIT_SECURITY_POLICY_C2(ECapabilityNetworkServices, ECapabilityReadDeviceData), -1},  
+        //policy "1"; for the Access API, fail call if Network Services and AllFiles not prosent
+        {_INIT_SECURITY_POLICY_C2(ECapabilityNetworkServices, ECapabilityAllFiles), -1} 
+        };
+
+//Package all the above together into a policy
+const CPolicyServer::TPolicy remoteFileEnginePolicy =
+        {
+        CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass
+        remoteFileEngineRangeCount,	//number of ranges                                   
+        remoteFileEngineRanges,	//ranges array
+        remoteFileEngineElementsIndex,	//elements<->ranges index
+        remoteFileEngineElements,		//array of elements
+        };
+
+
+// DATA STRUCTURES
+TRfeEnv* CRsfwRfeServer::iEnvp;
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::CRsfwRfeServer
+// ----------------------------------------------------------------------------
+// 
+inline CRsfwRfeServer::CRsfwRfeServer(TInt aPriority, TServerType aType)
+    :CPolicyServer(aPriority, remoteFileEnginePolicy, aType)
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::NewL
+// ----------------------------------------------------------------------------
+// 
+
+CRsfwRfeServer* CRsfwRfeServer::NewL()
+    {
+    CRsfwRfeServer* self = CRsfwRfeServer::NewLC();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::NewLC
+// ----------------------------------------------------------------------------
+// 
+
+CRsfwRfeServer* CRsfwRfeServer::NewLC()
+    {
+    CRsfwRfeServer* self = new (ELeave) CRsfwRfeServer(EPriorityNormal,
+                                               ESharableSessions);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::ConstructL
+// ----------------------------------------------------------------------------
+// 
+
+void CRsfwRfeServer::ConstructL()
+    {
+    StartL(KRemoteFEName);
+    DEBUGSTRING(("registered RFE name 0x%x", this));
+
+    // Prepare the environment
+    iEnvp = &iEnv;
+    iDelayedShutdownTimer = CPeriodic::NewL(CActive::EPriorityLow);
+    User::LeaveIfError(iEnvp->iFs.Connect());
+    iEnvp->iRsfwConfig = CRsfwConfig::NewL(KCRUidRsfwCtrl);  
+    
+	// Make cache root directory
+   	PrepareCacheRootL();
+   	// Load configuration
+   	// Create volume table
+   	iVolumes = CRsfwVolumeTable::NewL(this, iEnvp->iRsfwConfig);
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::ThreadFunction
+// ----------------------------------------------------------------------------
+//
+TInt CRsfwRfeServer::ThreadFunction(TAny* /*aNone*/)
+    {
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+    if (!cleanupStack)
+        {
+        PanicServer(ECreateTrapCleanup);
+        }
+
+//  __UHEAP_MARK;
+    TRAPD(err, ThreadFunctionL());
+//  __UHEAP_MARKENDC(0);
+    if (err != KErrNone)
+        {
+        PanicServer(ESrvCreateServer);
+        }
+
+    delete cleanupStack;
+    cleanupStack = NULL;
+
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::IncrementSessions
+// ----------------------------------------------------------------------------
+//
+void CRsfwRfeServer::IncrementSessions()
+    {
+    StopDelayedShutdownTimer();
+    iSessionCount++;
+    DEBUGSTRING(("+session count = %d", iSessionCount));
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::DecrementSessions
+// ----------------------------------------------------------------------------
+//
+void CRsfwRfeServer::DecrementSessions()
+    {
+    iSessionCount--;
+    // this debug output crashes the server for some reason
+//    DEBUGSTRING(("-session count = %d", iSessionCount));
+    // Note that the event causing server to shut down
+    // is not session count going to zero, as 
+    // there are "permanent" session(s) from the File Server plugin.
+    // (they would be closed when remote drives are unmounted, which never happens)
+    // Instead, server shutdown is triggered by last connected volume
+    // going to disconnect state, or inactivity timeout expires and
+    // there are no open files.
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::AllEnginesIdling
+// ----------------------------------------------------------------------------
+//
+void CRsfwRfeServer::AllEnginesIdling(TInt aTimeout)
+    {
+    if (!iShuttingDown)
+        {
+        DEBUGSTRING(("starting to shut down after %d seconds", aTimeout));
+        if (aTimeout)
+            {
+            StartDelayedShutdownTimer(aTimeout);
+            }
+        else
+            {
+            ShutDown();
+            }
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::ServiceRequested
+// ----------------------------------------------------------------------------
+//
+void CRsfwRfeServer::ServiceRequested()
+    {
+    StopDelayedShutdownTimer();
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::RunError
+// ----------------------------------------------------------------------------
+//
+TInt CRsfwRfeServer::RunError(TInt aError)
+    {
+    if (aError == KErrBadDescriptor)
+        {
+        // A bad descriptor error implies a badly programmed client,
+        // so panic it;
+        // otherwise report the error to the client
+        PanicClient(Message(), EBadDescriptor);
+        }
+    else
+        {
+        Message().Complete(aError);
+        }
+
+    // The leave will result in an early return from CServer::RunL(), skipping
+    // the call to request another message. So do that now in order to keep the
+    // server running.
+    ReStart();
+
+    return KErrNone;    // handled the error fully
+    }
+
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::CustomFailureActionL
+// ----------------------------------------------------------------------------
+//
+CPolicyServer::TCustomResult CRsfwRfeServer::CustomFailureActionL(const RMessage2& aMsg, 
+                                                   TInt /* aAction */, 
+                                                   const TSecurityInfo& /*aMissing */)
+    {
+    TCustomResult result = EFail;
+    TSecureId secId = aMsg.SecureId();
+    if (secId = KFileServerSecureUid) 
+        {
+        result = EPass;
+        }
+    return result;
+    }
+
+
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::PanicClient
+// ----------------------------------------------------------------------------
+//
+void CRsfwRfeServer::PanicClient(const RMessage2& aMessage, TRfePanic aPanic)
+    {
+    aMessage.Panic(KRfeServer, aPanic);
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::PanicServer
+// ----------------------------------------------------------------------------
+//
+void CRsfwRfeServer::PanicServer(TRfePanic aPanic)
+    {
+    User::Panic(KRfeServer, aPanic);
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::ThreadFunctionL
+// ----------------------------------------------------------------------------
+//
+void CRsfwRfeServer::ThreadFunctionL()
+    {
+
+    // Construct active scheduler
+    CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
+    CleanupStack::PushL(activeScheduler);
+
+    // Install active scheduler.
+    // We don't need to check whether an active scheduler is already installed
+    // as this is a new thread, so there won't be one
+    CActiveScheduler::Install(activeScheduler);
+
+    // Change the name of the thread, so it is easier to recognize
+    User::RenameThread(KRfeMain);
+    // Construct our server
+    CRsfwRfeServer::NewLC();    // anonymous
+
+    RSemaphore semaphore;
+    TInt err;
+    err = semaphore.OpenGlobal(KRfeSemaphoreName);
+    if (err == KErrNotFound)
+        {
+        err = semaphore.CreateGlobal(KRfeSemaphoreName, 0);
+        }
+    User::LeaveIfError(err);
+
+    // Semaphore opened ok
+    semaphore.Signal();
+    semaphore.Close();
+
+#ifdef _DEBUG
+    {
+    TInt8* p = (TInt8*)User::Alloc(1);
+    DEBUGSTRING(("Test alloc addr=0x%x", p));
+    delete p;
+    DEBUGSTRING(("Enter alloc count=%d", User::CountAllocCells()));
+    TInt b;
+    TInt a = User::Available(b);
+    DEBUGSTRING(("Enter alloc avail=%d, biggest=%d", a, b));
+    }
+#endif
+
+    // Start handling requests
+    CActiveScheduler::Start();
+#ifdef _DEBUG
+    {
+    DEBUGSTRING(("Exit alloc count=%d", User::CountAllocCells()));
+    TInt b;
+    TInt a = User::Available(b);
+    DEBUGSTRING(("Exit alloc avail=%d, biggest=%d", a, b));
+    }
+#endif
+    CleanupStack::PopAndDestroy(2, activeScheduler);
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::NewSessionL
+// ----------------------------------------------------------------------------
+//     
+CSession2* CRsfwRfeServer::NewSessionL(const TVersion &aVersion,
+                                   const RMessage2&) const
+    {
+    // Check we're the right version
+    if (!User::QueryVersionSupported(TVersion(KRfeMajorVersionNumber,
+                                              KRfeMinorVersionNumber,
+                                              KRfeBuildVersionNumber),
+                                     aVersion))
+        {
+        User::Leave(KErrNotSupported);
+        }
+    // Make new session
+    return CRsfwRfeSession::NewL(*const_cast<CRsfwRfeServer*> (this));
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::PrepareCacheRootL
+// Get the cache path and create the directory if it does not exist
+// ----------------------------------------------------------------------------
+//   
+void CRsfwRfeServer::PrepareCacheRootL()
+    {
+    TInt err;
+    err = iEnvp->iRsfwConfig->Get(RsfwConfigKeys::KCacheDirectoryPath,
+                                  iEnvp->iCacheRoot);
+    if (err == KErrNone)
+        {
+        TBuf<KMaxRsfwConfItemLength> driveString;
+        if ((iEnvp->iCacheRoot.Length() < 2) || (iEnvp->iCacheRoot[1] != ':'))
+            {
+            err = iEnvp->iRsfwConfig->Get(RsfwConfigKeys::KRsfwDefaultDrive,
+                                          driveString);
+            if (err != KErrNone)
+                {
+                driveString.Copy(KRSFWDefaultDrive);
+                }
+            }
+        if (driveString.Length() < 2)
+            {
+            driveString.Append(':');
+            }
+        iEnvp->iCacheRoot.Insert(0, driveString);
+        }
+    else
+        {
+        HBufC* defaultcacheRoot = HBufC::NewL(KMaxPath);
+        TPtr defaultCache(defaultcacheRoot->Des());
+        defaultCache.Append(KRSFWDefaultDrive);
+        defaultCache.Append(KCacheRootDefault);
+        iEnvp->iCacheRoot.Copy(defaultCache);
+        delete defaultcacheRoot;
+        }
+    RFs& fs = iEnvp->iFs;
+    TUint att;
+    TChar cacheDriveChar = iEnvp->iCacheRoot[0];
+    User::LeaveIfError(fs.CharToDrive(cacheDriveChar, iEnvp->iCacheDrive));
+    err = fs.Att(iEnvp->iCacheRoot, att);
+    if (err != KErrNone)
+        {
+        // There was no prior cache root
+        err = fs.MkDirAll(iEnvp->iCacheRoot);
+        DEBUGSTRING(("Cache root creation failed with err=%d", err));
+        User::LeaveIfError(err);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::ShutDown
+// ----------------------------------------------------------------------------
+//
+void CRsfwRfeServer::ShutDown()
+    {
+    DEBUGSTRING(("shutting down"));
+    iShuttingDown = ETrue;
+    CActiveScheduler::Stop();
+    delete iVolumes;
+    iVolumes = NULL;
+    delete iEnvp->iRsfwConfig;
+    iEnvp->iRsfwConfig = NULL;
+    iEnvp->iFs.Close();
+    delete iDelayedShutdownTimer;
+    iDelayedShutdownTimer = NULL;
+    // REComSession::FinalClose must be called when everything else
+    // related to ECom use has been deleted
+    REComSession::FinalClose(); 
+    DEBUGSTRING(("shut down"));
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::StartDelayedShutdownTimer
+// ----------------------------------------------------------------------------
+//
+void CRsfwRfeServer::StartDelayedShutdownTimer(TInt aTimeout)
+    {
+    if (!iShuttingDown)
+        {
+        iDelayedShutdownTimer->Cancel();
+        DEBUGSTRING(("shutting down in %d seconds",
+                     aTimeout));
+        TCallBack callBack(CRsfwRfeServer::DelayedShutdownTimerExpired, this);
+        iDelayedShutdownTimer->Start(aTimeout * 1000000,
+                                     aTimeout * 1000000,
+                                     callBack);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::StopDelayedShutdownTimer
+// ----------------------------------------------------------------------------
+//
+void CRsfwRfeServer::StopDelayedShutdownTimer()
+    {
+    if (iDelayedShutdownTimer)
+        {
+        iDelayedShutdownTimer->Cancel();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CRsfwRfeServer::DelayedShutdownTimerExpired
+// ----------------------------------------------------------------------------
+//
+TInt CRsfwRfeServer::DelayedShutdownTimerExpired(TAny* aArg)
+    {   
+    CRsfwRfeServer* rfeServer = static_cast<CRsfwRfeServer*>(aArg);
+    rfeServer->ShutDown();
+    return 0;
+    }
+
+// ----------------------------------------------------------------------------
+// E32Main
+// ----------------------------------------------------------------------------
+//
+TInt E32Main()
+    {
+    return CRsfwRfeServer::ThreadFunction(NULL);
+    }
+
+
+// End of File