diff -r 000000000000 -r 4e1aa6a622a0 dosservices/dosserver/src/dosshareddatabase.cpp --- /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 + +// 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" ); + }