dosservices/dosserver/src/dosshareddatabase.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dosservices/dosserver/src/dosshareddatabase.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,373 @@
+/*
+* Copyright (c) 2002 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: 
+*    Implementation for the CDosharedDataBase class
+*
+*/
+
+
+#include "dosshareddatabase.h"
+#include "dosclientserver.h"
+#include "dosserver.h"
+#include "shareddatafilesystemnotifier.h"
+#include "dosclishareddata.h"
+#include "dos_debug.h"
+#include <e32svr.h>
+
+// CONSTANTS
+_LIT( KSDReserveFileName, "C:\\Private\\101f6efa\\reserve.bin" );
+_LIT(KSDPath, "C:\\Private\\101f6efa\\");
+
+// Definitions for reserve file system
+const TInt KSDLotsOfFreeDiskSpace = 1000000;
+const TInt KSDFreeDiskSpaceOverhead = 1024;
+const TInt KSDReserveFileLoopMaxCount = 5;
+
+// -----------------------------------------------------------------------------
+// CDosSharedDataBase::CDosSharedDataBase* NewL()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CDosSharedDataBase* CDosSharedDataBase::NewL(CSharedDataFileSystemNotifier* fileSystemNotifier)
+    {
+    COM_TRACE_1( "[DOSSERVER]\t CDosSharedDataBase* CDosSharedDataBase::NewL(0x%x)", fileSystemNotifier );		
+    CDosSharedDataBase* self = NewLC(fileSystemNotifier);
+    CleanupStack::Pop();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CDosSharedDataBase::CDosSharedDataBase* NewLC()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CDosSharedDataBase* CDosSharedDataBase::NewLC(CSharedDataFileSystemNotifier* fileSystemNotifier)
+    {
+    COM_TRACE_1( "[DOSSERVER]\t CDosSharedDataBase* CDosSharedDataBase::NewL(0x%x)", fileSystemNotifier );
+    CDosSharedDataBase* self = new( ELeave ) CDosSharedDataBase();
+    CleanupStack::PushL( self );
+    self->ConstructL( fileSystemNotifier );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CDosSharedDataBase::void ConstructL()
+// -----------------------------------------------------------------------------
+//
+void CDosSharedDataBase::ConstructL(CSharedDataFileSystemNotifier* fileSystemNotifier)
+    {
+    COM_TRACE_1( "[DOSSERVER]\t CDosSharedDataBase::ConstructL(0x%x)", fileSystemNotifier );	
+    iFileSystemNotifier = fileSystemNotifier;
+    iFreeDiskSpaceRequest = 0;
+
+	TInt err( iFs.Connect() );
+	if ( err < 0 )
+	    {
+		User::LeaveIfError( err );
+	    }
+	User::LeaveIfError(iFs.ShareProtected());
+    }
+
+// Destructor
+CDosSharedDataBase::~CDosSharedDataBase()    
+    {
+    COM_TRACE_( "[DOSSERVER]\t CDosSharedDataBase::~CDosSharedDataBase()" );	
+    if ( iFileSystemNotifier )
+        {
+        iFileSystemNotifier->Cancel();
+        }
+    iFs.Close();    
+    }
+    
+//
+// ---------------------------------------------------------
+// CDosSharedDataBase::ExecuteMessageL
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDosSharedDataBase::ExecuteMessageL(const RMessage2& aMessage)
+{
+	COM_TRACE_( "[DOSSERVER]\t CDosSharedDataBase::ExecuteMessageL(...)" );    
+	switch (aMessage.Function())
+	{       
+		case ERequestFreeDiskSpace:
+            {
+            
+            TInt amount( aMessage.Int0() );
+            COM_TRACE_2( "CDosSharedDataBase::ExecuteMessageL() case ERequestFreeDiskSpace, amount = %d iFreeDiskSpaceRequest = %d", amount, iFreeDiskSpaceRequest );
+            
+            if ( amount > iFreeDiskSpaceRequest )
+                {
+                if ( amount > KSDReserveFileMaxSize )
+                    {
+                    amount = KSDReserveFileMaxSize;
+                    }
+                
+                COM_TRACE_2( "CDosSharedDataBase::ExecuteMessageL() case ERequestFreeDiskSpace, amount = %d iFreeDiskSpaceRequest = %d", amount, iFreeDiskSpaceRequest );
+                
+                iFreeDiskSpaceRequest = amount;
+                RequestFreeDiskSpace( &iFreeDiskSpaceRequest );
+                }  
+            
+            TInt err(KErrNone);
+			return err;
+            }
+
+		case ERequestFreeDiskSpaceCancel:
+			{
+			COM_TRACE_1( "CDosSharedDataBase::ExecuteMessageL() case ERequestFreeDiskSpaceCancel iFreeDiskSpaceRequest = %d", iFreeDiskSpaceRequest );
+            
+			if ( iFreeDiskSpaceRequest > 0 )
+                {
+                // iFreeDiskSpaceRequest = 0;
+                RequestFreeDiskSpaceCancel(&iFreeDiskSpaceRequest);
+                }
+                		    
+            TInt err(KErrNone);
+			return err;
+            }
+
+		default:
+			COM_TRACE_( "[DOSSERVER]\t Panic: Illegal function!" );
+			PanicClient(aMessage,EPanicIllegalFunction);
+			return KErrNone;
+	}
+}
+
+//
+// ---------------------------------------------------------
+// CDosSharedDataBase::RequestFreeDiskSpace
+// ---------------------------------------------------------
+//
+void CDosSharedDataBase::RequestFreeDiskSpace( TInt* aRequest )
+    {
+    __ASSERT_DEBUG( aRequest, User::Invariant() );
+    
+    COM_TRACE_( "[DOSSERVER]\t CDosSharedDataBase::RequestFreeDiskSpace" );
+            
+    TInt* currentFreeDiskSpaceRequest = iFileSystemNotifier->iServer.CurrentFreeDiskSpaceRequest();
+    if ( !currentFreeDiskSpaceRequest || // no request earlier
+         aRequest == currentFreeDiskSpaceRequest || // current request updated
+         *aRequest > *currentFreeDiskSpaceRequest ) // new higher request
+        {
+        COM_TRACE_( "CDosSharedDataBase::RequestFreeDiskSpace - no request earlier,..." );
+        iFileSystemNotifier->Cancel();        
+        iFileSystemNotifier->iServer.SetCurrentFreeDiskSpaceRequest(aRequest);
+        SetReserveFileSize( *aRequest );
+        }
+    COM_TRACE_( "[DOSSERVER]\t CDosSharedDataBase::RequestFreeDiskSpace - return" );
+    }
+    
+// -----------------------------------------------------------------------------
+// CDosSharedDataBase::RequestFreeDiskSpaceCancel()
+// -----------------------------------------------------------------------------
+void CDosSharedDataBase::RequestFreeDiskSpaceCancel( TInt* aRequest )
+    {
+    __ASSERT_DEBUG( aRequest, User::Invariant() );
+    
+    COM_TRACE_( "[DOSSERVER]\t CDosSharedDataBase::RequestFreeDiskSpaceCancel" );
+    
+    TInt* currentFreeDiskSpaceRequest = iFileSystemNotifier->iServer.CurrentFreeDiskSpaceRequest();
+    if ( currentFreeDiskSpaceRequest == aRequest )
+        {
+        
+        //*currentFreeDiskSpaceRequest = KSDReserveFileMaxSize;
+        *currentFreeDiskSpaceRequest = 0;
+        
+        iFileSystemNotifier->iServer.SetCurrentFreeDiskSpaceRequest( currentFreeDiskSpaceRequest );
+        
+        // Adjust the size of the reserve file to the maximum size
+
+        // SetReserveFileSize( KSDReserveFileMaxSize);
+        SetReserveFileSize( 0 );
+        }
+    COM_TRACE_( "[DOSSERVER]\t CDosSharedDataBase::RequestFreeDiskSpaceCancel - return" );
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CDosSharedDataBase::SetReserveFileSize()
+// -----------------------------------------------------------------------------
+
+void CDosSharedDataBase::SetReserveFileSize( const TInt aRequiredFreeDiskSpace )
+    {    	
+    COM_TRACE_( "[DOSSERVER]\t CDosSharedDataBase::SetReserveFileSize" );    
+    
+    TInt newSize( 0 );
+    TInt currentSize( 0 );
+    TInt freeSpace( KSDLotsOfFreeDiskSpace );
+
+	TVolumeInfo info;
+	TInt ret = iFs.Volume( info, EDriveC );
+
+    if ( ret == KErrNone )
+        {
+        RFile file;
+        ret = file.Open( iFs, KSDReserveFileName, EFileShareAny | EFileWrite );
+
+        switch ( ret )
+            {
+            case KErrPathNotFound:
+                iFs.MkDirAll( KSDPath );    // no break here 
+            case KErrNotFound:
+                ret = file.Create( iFs, KSDReserveFileName, 
+                                   EFileShareAny | EFileWrite );      
+            default: {}
+            }
+
+        if ( ret == KErrNone )
+            {
+            ret = file.Size( currentSize );
+
+            COM_TRACE_( "SharedData: SetReserveFileSize() start" );
+            COM_TRACE_1( "SharedData: Free disk space: %d", TInt(info.iFree) );    
+            COM_TRACE_1( "SharedData: Reserve file size: %d", currentSize );                
+
+            if ( ret == KErrNone )
+                {
+                if ( info.iFree < freeSpace )
+                    {
+                    freeSpace = I64INT(info.iFree);
+                    }
+
+                // to make sure infinite loop can never happen
+                TInt loopCounter( 0 );
+
+                // *** START of reserve file size altering section ***
+
+                do  {
+                    loopCounter++;
+
+                    newSize = freeSpace + currentSize - aRequiredFreeDiskSpace;
+
+                    if ( aRequiredFreeDiskSpace > 0 )
+                        {
+                        newSize -= KSDFreeDiskSpaceOverhead;
+                        }
+
+                    if ( newSize < 0 )
+                        {
+                        newSize = 0;
+                        }
+
+                    else if ( newSize > KSDReserveFileMaxSize )
+                        {
+                        newSize = KSDReserveFileMaxSize;
+                        }
+
+                    // set the file size to 'newSize' here
+
+                    TInt position( 0 );
+                    ret = file.Seek( ESeekEnd, position );
+
+                    if ( ret == KErrNone )
+                        {
+                        if ( position > newSize )
+                            {
+                            ret = file.SetSize( newSize );
+                            
+                            COM_TRACE_1( "SharedData: SetSize returned: %d", ret );
+
+                            file.Flush();
+                            }
+
+                        else if ( position < newSize )
+                            {
+                            TInt toBeWritten( newSize - position );
+
+                            HBufC8* buffer = HBufC8::New( toBeWritten );
+
+                            // Write the new data in cycles,
+                            // halving the total amount to be written in
+                            // every cycle until we get below 1024 bytes.
+                            // This leads to max 6 cycles and ensures that
+                            // as much as possible gets reserved back.
+
+                            if ( buffer )
+                                {
+                                while ( ret != KErrDiskFull &&
+                                        toBeWritten > 1024 )
+                                    {
+                                    buffer->Des().SetLength( toBeWritten >> 1 );
+
+                                    ret = file.Write( *buffer );
+
+                                    if ( ret == KErrNone )
+                                        {
+                                        ret = file.Flush();
+                                        }
+
+                                    toBeWritten -= ( toBeWritten >> 1 );
+                                    }
+                            
+                                buffer->Des().SetLength( toBeWritten );
+                                ret = file.Write( *buffer );
+
+                                if ( ret == KErrNone )
+                                    {
+                                    ret = file.Flush();
+                                    }
+
+                                delete buffer;
+                                }
+                            }
+                        }
+
+                    // update reserve file size info
+                    file.Size( currentSize );
+
+                    // update free disk space info
+                    ret = iFs.Volume( info, EDriveC );
+
+                    if ( ret == KErrNone )
+                        {
+                        freeSpace = KSDLotsOfFreeDiskSpace;
+
+                        if ( info.iFree < freeSpace )
+                            {
+                            freeSpace = I64INT(info.iFree);
+                            }
+                        }
+
+                    COM_TRACE_( "SharedData: SetReserveFileSize() loop" );
+                    COM_TRACE_1( "SharedData: Free disk space: %d", (TInt) info.iFree );
+                    COM_TRACE_1( "SharedData: Expected reserve file size: %d", newSize );
+                    COM_TRACE_1( "SharedData: Reserve file size: %d", currentSize );                    
+                    }
+
+                while ( loopCounter < KSDReserveFileLoopMaxCount &&
+                        aRequiredFreeDiskSpace > 0 &&
+                        currentSize > 0 &&
+                        freeSpace < aRequiredFreeDiskSpace );
+
+                // *** END of reserve file size altering section ***
+
+                // If there are no more free disk space requests but we didn't
+                // manage to increase the reserve file size back to max, get
+                // notification from file server when there is more disk space.
+
+                if ( aRequiredFreeDiskSpace == 0 &&
+                     currentSize < KSDReserveFileMaxSize )
+                    {
+                    iFileSystemNotifier->Start( freeSpace + 2500, iFs, this );
+                    }
+                }
+                
+            file.Close();
+            }
+        }
+
+    COM_TRACE_1( "SharedData: Free disk space: %d", (TInt) info.iFree );
+    COM_TRACE_1( "SharedData: Expected reserve file size: %d", newSize );
+    COM_TRACE_1( "SharedData: Reserve file size:  %d", currentSize );
+    
+    COM_TRACE_( "[DOSSERVER]\t CDosSharedDataBase::SetReserveFileSize - return" );    
+    }