omadrm/drmengine/dcfrepository/server/src/FileScan.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omadrm/drmengine/dcfrepository/server/src/FileScan.cpp	Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,526 @@
+/*
+* Copyright (c) 2002-2004 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:  server implementation
+*
+*/
+
+
+// INCLUDE FILES
+#include	<e32std.h>
+#include	<e32base.h>
+#include	<f32file.h>
+#include    <drmcommon.h>
+
+#ifdef RD_MULTIPLE_DRIVE
+#include    <DriveInfo.h>
+#endif
+
+#include    "DcfRepSrv.h"
+#include    "SearchLeaf.h"
+#include	"FileScan.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES  
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+_LIT( KWma, ".wma" );
+_LIT( KWmv, ".wmv" );
+_LIT( KAsf, ".asf" );
+
+#ifdef RD_MULTIPLE_DRIVE
+_LIT( KIgnoreDir1, "%c:\\sys" );
+_LIT( KIgnoreDir2, "%c:\\private\\101F51F2" );
+#else
+_LIT( KIgnoreDir1, "c:\\sys" );
+_LIT( KIgnoreDir2, "c:\\private\\101F51F2" );
+#endif
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+#ifndef RD_MULTIPLE_DRIVE
+LOCAL_C TBool IgnoreDir( TFileName& aDir );
+#else // RD_MULTIPLE_DRIVE
+LOCAL_C TBool IgnoreDir( RFs& aFs, TFileName& aDir );
+#endif
+// FORWARD DECLARATIONS
+
+// ============================ LOCAL FUNCTIONS =================================
+
+// ------------------------------------------------------------------------------
+// Returns whether directory should be ignored or not
+// ------------------------------------------------------------------------------
+ #ifndef RD_MULTIPLE_DRIVE
+LOCAL_C TBool IgnoreDir( TFileName& aDir )
+    {
+    if ( !aDir.CompareF( KIgnoreDir1 ) || 
+         !aDir.CompareF( KIgnoreDir2 ) )
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+#else // RD_MULTIPLE_DRIVE
+LOCAL_C TBool IgnoreDir( RFs& aFs, TFileName& aDir )
+    {
+    TInt driveNumber( -1 );
+    TChar driveLetter;
+    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+	aFs.DriveToChar( driveNumber, driveLetter );
+	
+	TFileName ignore1;
+	TFileName ignore2;
+	
+	ignore1.Format( KIgnoreDir1, (TUint)driveLetter );
+    ignore2.Format( KIgnoreDir2, (TUint)driveLetter );
+    
+    if ( !aDir.CompareF( ignore1 ) || 
+         !aDir.CompareF( ignore2 ) )
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+#endif
+    
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CFileScan::CFileScan
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CFileScan::CFileScan( RFs& aFs ) : 
+CActive( CActive::EPriorityStandard ),iServer(NULL),iFs(&aFs),iCurrentLeaf(NULL)
+	{
+	CleanInternal();
+    }
+
+// -----------------------------------------------------------------------------
+// CFileScan::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CFileScan::ConstructL()
+    {
+	TInt err = 0;
+	if ( !iFs )
+		{
+		err = KErrArgument;
+		}
+	else
+		{
+		err = KErrNone;
+		}
+	User::LeaveIfError( err );
+	}
+
+// -----------------------------------------------------------------------------
+// CFileScan::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CFileScan* CFileScan::NewL( RFs& aFs )
+    {
+    CFileScan* self = new( ELeave ) CFileScan( aFs ); 
+	CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+    
+// Destructor
+CFileScan::~CFileScan()
+    {
+	CleanInternal();
+	iServer = NULL;
+	iFs = NULL;
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CFileScan::DoCancel
+// Function is called when the request is completed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CFileScan::DoCancel()
+	{
+	CleanInternal();
+	}
+
+
+// -----------------------------------------------------------------------------
+// CFileScan::IsProtected
+// Function returns whether the specific file is protected or not 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CFileScan::IsProtected( const TDesC& aFileName , TBool& aIsDCF )
+	{
+	TInt err = KErrNone;
+	aIsDCF = EFalse;
+	err = iServer->ProcessFile( aFileName , aIsDCF );
+	if ( err && err != KErrNoMemory )
+		{
+		err = KErrNone;
+		}
+	return err;
+	}
+
+
+// -----------------------------------------------------------------------------
+// CFileScan::RunL
+// Function is called when the request is completed
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CFileScan::RunL()
+	{
+	TInt err = KErrNone;
+	if ( iSearching && iServer->State()!=EStateIdle )
+		{
+		err = SearchNext();
+		if ( err == KErrCancel )
+			{
+			err = KErrNone;
+			}
+		if ( !err )
+			{
+			SetActive();			
+			TRequestStatus* status = &iStatus;
+			User::RequestComplete( status , err );			
+			}
+		}
+	else 
+		{
+		CleanInternal();
+		iServer->CompleteScanning(err);
+		Deque();
+		}
+	if ( err )
+		{
+		CleanInternal();
+		iServer->CompleteScanning(err);
+		Deque();
+		}
+	}
+
+
+
+// -----------------------------------------------------------------------------
+// CFileScan::SearchContent
+// Function starts the active objects to search protected file through whole file system 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CFileScan::SearchContent( CDcfRepSrv* aServer )
+	{
+    TInt err = KErrNone;
+	
+	iServer = aServer;
+	CActiveScheduler::Add( this );
+	
+	iSearching = ETrue;
+	err = SearchNext();
+	if ( err )
+		{
+		return err;
+		}
+	SetActive();
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete( status , KErrNone );
+	return err;
+	}
+
+// -----------------------------------------------------------------------------
+// CFileScan::SearchDrive
+// This function searches for the DCF files on target device
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CFileScan::SearchDrive()
+	{
+	_LIT( KDrive, "%c:");
+	TDriveList drivelist;
+	TChar driveLetter;
+	TInt driveNumber = EDriveA - 1;
+	TInt err = KErrNone;
+
+#ifdef RD_MULTIPLE_DRIVE
+	
+	TInt ramDrive( -1 );
+    TInt romDrive( -1 );
+
+    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRam, ramDrive );
+    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRom, romDrive );
+
+#endif
+
+	err = iFs->DriveList( drivelist ); 
+
+	if ( iLastPosition != KNullDesC )
+		{
+		driveLetter = iLastPosition[0];
+		err = iFs->CharToDrive( driveLetter, driveNumber );
+		}
+	
+	driveNumber++;
+	
+    for ( ; driveNumber < KMaxDrives ; driveNumber++ )
+        {
+        
+#ifndef RD_MULTIPLE_DRIVE
+	    
+	    if ( driveNumber == EDriveD || driveNumber == EDriveZ )
+		    {
+		    }
+	    		
+#else // RD_MULTIPLE_DRIVE
+
+		if ( driveNumber == ramDrive || driveNumber == romDrive )
+		    {
+			}
+
+#endif
+		
+		else if ( drivelist[driveNumber] ) 
+				{
+				err = iFs->DriveToChar( driveNumber, driveLetter );
+				iLastPosition.Format( KDrive, (TUint)driveLetter );
+				iDeeper = ETrue;
+				return err;
+				}
+        }
+	CleanInternal();
+	return err;
+	}
+
+
+
+// -----------------------------------------------------------------------------
+// CFileScan::SearchFolder
+// This function create Leaves for the current leaf
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CFileScan::SearchFolder( CDir*& aFolderList )
+	{
+	TInt err = KErrNone;
+	TRAP( err , iCurrentLeaf->SetLeafL( aFolderList ) );
+	return err;
+	}
+
+// -----------------------------------------------------------------------------
+// CFileScan::SearchFile
+// This function searches for the DCF files under specific folder 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CFileScan::SearchFile( CDir*& aFileList )
+	{
+	TInt err = KErrNone;
+	TInt i = 0;
+	TBool isDCF;
+	_LIT ( KFullFileName , "%S\\%S");
+	TFileName fileName;
+
+	for ( ; i < aFileList->Count() && !err ; i++ )
+		{
+		if (!( *aFileList )[i].IsDir())
+		    {
+    		TPtrC extension = (*aFileList)[i].iName.Right( 4 );
+    		if( !extension.CompareF( KWma ) || 
+    		    !extension.CompareF( KWmv ) ||
+    		    !extension.CompareF( KAsf ) )
+    		    {
+    		    
+    		    }
+    		else
+    		    {
+    		    fileName.Format( KFullFileName , &iLastPosition , &( *aFileList )[i].iName );
+    		    err = IsProtected( fileName , isDCF );
+		        }
+    		}
+		}
+	return err;
+	}
+
+// -----------------------------------------------------------------------------
+// CFileScan::SearchNext
+// This function searches for the DCF files under specific folder or drive
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CFileScan::SearchNext()
+	{
+	TInt err = KErrNone;
+
+	err = CheckDrive();
+	if ( !err && iSearching )
+		{
+		if ( iDeeper )
+			{
+			err = CheckFolder();
+			}
+		if ( !err && iSearching )
+			{
+			err = ToNextLeaf();
+			}
+		}
+	return err;
+	}
+
+TInt CFileScan::CheckDrive()
+	{
+	// check if current drive is end of searching
+	TInt err = KErrNone;
+
+	if( !iCurrentLeaf )
+		{
+		err = SearchDrive();
+		if ( err || !iSearching )
+			{
+			return err;
+			}
+		CSearchLeaf* root = NULL;
+		TRAP( err , iCurrentLeaf = CSearchLeaf::NewL( root , iLastPosition ) );
+		}	
+	return err;
+	}
+
+TInt CFileScan::CheckFolder()	
+	{
+	// check current folder
+	_LIT ( KSearchDir , "%S\\*");
+
+	TInt err = KErrNone;
+	CDir* fileList = NULL;
+	CDir* dirList = NULL;
+	TFileName temp;
+    
+#ifndef RD_MULTIPLE_DRIVE
+    if ( IgnoreDir( iLastPosition ) )
+#else // RD_MULTIPLE_DRIVE
+    if ( IgnoreDir( *iFs, iLastPosition ) )    
+#endif
+        {
+        return err;
+        }
+    
+    if( iLastPosition.Length() + KSearchDir().Length() < iLastPosition.MaxLength() )
+        {
+	    temp.Format( KSearchDir , &iLastPosition );
+	    err = iFs->GetDir( temp  
+		    , KEntryAttMaskSupported
+		    , ESortByName 
+		    , fileList , dirList );
+	
+	    if ( !err )
+		    {
+		    err = SearchFolder( dirList );
+		    if ( !err )
+			    {
+			    err = SearchFile( fileList );
+			    }
+		    }
+	    delete fileList;
+	    fileList = NULL;
+	    delete dirList;
+	    dirList = NULL;        
+        }
+	return err;
+	}
+
+TInt CFileScan::ToNextLeaf()
+	{
+	_LIT ( KChildDir , "%S\\%S");
+	TInt err = KErrNone;
+	TFileName file;
+	CSearchLeaf* temp = NULL;
+
+	file.Format( iLastPosition );
+
+	if ( iCurrentLeaf->LeafList().Count() > 0 )
+		{
+		iDeeper = ETrue;
+		iCurrentLeaf = iCurrentLeaf->LeafList()[0];
+		iLastPosition.Format( KChildDir , &file , &iCurrentLeaf->FolderName() );
+		}
+	else
+		{
+		iDeeper = EFalse;
+		temp = iCurrentLeaf;
+		iCurrentLeaf = iCurrentLeaf->Root();
+		if ( iCurrentLeaf )
+			{
+			iCurrentLeaf->RemoveLeaf( temp );			
+			}
+		delete temp;
+		temp = NULL;
+		err = UpFolder();
+		}
+	return err;
+	}
+
+TInt CFileScan::UpFolder()
+	{
+	TInt err = KErrNone;
+	TParse file;
+	if ( iLastPosition.Length()<3 )
+		{
+		return err;
+		}
+	err = file.Set( iLastPosition , NULL , NULL );
+	iLastPosition.Format( file.DriveAndPath() );
+	iLastPosition.SetLength( iLastPosition.Length() - 1 );
+	return err;
+	}
+
+
+void CFileScan::CleanInternal()
+	{
+	CSearchLeaf* root = iCurrentLeaf;
+	iLastPosition = KNullDesC;
+	iSearching = EFalse;
+	root = GetRootLeaf();
+	delete root;
+	root = NULL;
+	iCurrentLeaf = NULL;
+	iDeeper = ETrue;
+	}
+
+CSearchLeaf* CFileScan::GetRootLeaf()
+	{
+	CSearchLeaf* root = iCurrentLeaf;
+	if ( iCurrentLeaf )
+		{
+		while ( root->Root() )
+			{
+			root = root->Root();
+			}	
+		}
+	return root;
+	}
+
+// End of File
+