omadrm/drmengine/dcfrepository/server/src/FileScan.cpp
author hgs
Thu, 14 Oct 2010 13:45:23 +0300
changeset 84 b09186059647
parent 23 493788a4a8a4
permissions -rw-r--r--
201039_02

/*
* Copyright (c) 2002-2010 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;
    CActiveScheduler::Add( this );

    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()
    {
    Deque();
    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 (iStatus.Int());
    if ( !err && iSearching && iServer->State()!=EStateIdle )
        {
        err = SearchNext();
        if ( err == KErrCancel )
            {
            err = KErrNone;
            }
        if ( !err )
            {
            if (iServer->State() != EStateIdle)
                {
                if (iSearching)
                    {
                    SetActive();
                    TRequestStatus* status = &iStatus;
                    User::RequestComplete(status, err);
                    }
                else
                    {
                    iServer->CompleteScanning(err);
                    }
                }
            else
                {
                CleanInternal();
                }
            }
        }
    if ( err )
        {
        CleanInternal();
        iServer->CompleteScanning(err);
        }
    }



// -----------------------------------------------------------------------------
// 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;

    if ( IsActive() )
        {
        err=KErrServerBusy;
        }

    if ( !err )
        {
        iServer = aServer;
        iSearching = ETrue;
        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