terminalsecurity/server/src/TcFileScan.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 09:07:52 +0200
changeset 0 b497e44ab2fc
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2000 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 of terminalsecurity components
*
*/


// INCLUDES
#include <e32base.h>
#include "TcFileScan.h"
#include "TerminalControlClient.h" // For TFileName8
#include "debug.h"

// MACROS
_LIT8(KFormatFolderEmpty, "<folder name=\"%S\"/>\r\n");
_LIT8(KFormatFolderOpen,  "<folder name=\"%S\">\r\n");
_LIT8(KFormatFolderClose, "</folder>\r\n");
_LIT8(KFormatFileOpen,    "<file name=\"%S\"/>\r\n");
_LIT8(KFormatDriveName,   "<drive name=\"%S\"/>\r\n");
_LIT8(KFormatListingOpen, "<folder-listing version=\"1.1\">\r\n");
_LIT8(KFormatListingClose,"</folder-listing>\r\n");

// METHODS


CTcFileScan* CTcFileScan::NewL()
	{
	return new (ELeave) CTcFileScan();	
	}


// ----------------------------------------------------------------------------------------
// CTcFileScan::CTcFileScan
// ----------------------------------------------------------------------------------------
CTcFileScan::CTcFileScan()
: iFileScanResults(0)
    {
	RDEBUG("CTcFileScan::CTcFileScan");

    }

// ----------------------------------------------------------------------------------------
// CTcFileScan::~CTcFileScan
// ----------------------------------------------------------------------------------------
CTcFileScan::~CTcFileScan()
    {
	RDEBUG("CTcFileScan::~CTcFileScan");

    delete iFileScanResults;
    }    

// ----------------------------------------------------------------------------------------
// CTcFileScan::FileScanL
// ----------------------------------------------------------------------------------------
void CTcFileScan::FileScanL( const TDesC8 &aFileName, TBool aRecursive )
    {
		RDEBUG_2( "CTcFileScan::FileScanL: %S", &aFileName );
		RDEBUG_2( "CTcFileScan::FileScanL: Recursive: %d", aRecursive );

    RFs fileSession;
    User::LeaveIfError(fileSession.Connect());
    CleanupClosePushL(fileSession);

    TBuf<sizeof(TFileName8)+2> startDirBuf;
    startDirBuf.Copy(aFileName.Left(sizeof(TFileName8)));
    startDirBuf.TrimAll();

    //
    // Add asterisk if path is specified
    //
    if(startDirBuf.Length() > 0)
        {
        if(startDirBuf.Right(1) != _L("\\"))
            {
            startDirBuf.Append(TChar('\\'));
            }
            
        startDirBuf.Append(TChar('*'));
        }        
    
    if( iFileScanResults != 0 )
        {
        delete iFileScanResults;
        iFileScanResults = 0;
        }

    iFileScanResults = CBufFlat::NewL(128);

    // Every scan result begins with <folder-listing>
    //
    iFileScanResults->InsertL(0, KFormatListingOpen);
    iRecurseLevel = 0;
    
    if( startDirBuf.Length() > 0 )
        {        
        ScanDirectoryL( fileSession, startDirBuf, aRecursive );
        }
    else
        {
        GetDriveListL();
        }

    // Every scan result ends with </folder-listing>
    //
    iFileScanResults->InsertL(iFileScanResults->Size(), KFormatListingClose);

    CleanupStack::PopAndDestroy( &fileSession );
    }

// ----------------------------------------------------------------------------------------
// CTcFileScan::ScanDirectoryL
// ----------------------------------------------------------------------------------------
void CTcFileScan::ScanDirectoryL( RFs& aFileSession,
                                  const TDesC &aDirectory,
                                  TBool aRecursive )
    {
		RDEBUG_2( "CTcFileScan::ScanDirectoryL: %S", &aDirectory);

    // Note: this function is used recursively
    // Stack use is minimized to avoid overflow as long as possible
    //
    iRecurseLevel ++;
    TFindFile* fileFinder1 = new (ELeave) TFindFile( aFileSession );
    CDir*      fileList1;

    TInt err = fileFinder1->FindWildByPath(aDirectory, &KNullDesC(), fileList1);

    while( err == KErrNone )
        {
        TInt i;

        for (i=0; i<fileList1->Count(); i++)
            {
            const TEntry & entry = (*fileList1)[i];
            TInt iFilesInDirectory = 0;

            //
            // Is there any files in directory?
            //
            if(aRecursive && entry.IsDir())
                {
                HBufC *fullPathName1 = CreateScanPathNameL(aDirectory, entry.iName, _L("*"));
                CleanupStack::PushL( fullPathName1 );
                
                iFilesInDirectory = FilesInDirectoryL( aFileSession, *fullPathName1 );
                
                CleanupStack::PopAndDestroy( fullPathName1 );    
                }

            //
            // Add file information into result buffer
            //
            BeginAddFileToResultsL( TPtrC ( entry.iName ), entry.IsDir(), iFilesInDirectory );

            //
            // Scan subdirectory
            //
            if(aRecursive && entry.IsDir() && (iRecurseLevel < 200))
                {
                HBufC *fullPathName2 = CreateScanPathNameL(aDirectory, entry.iName, _L("*"));                
                CleanupStack::PushL( fullPathName2 );
                
                ScanDirectoryL( aFileSession, fullPathName2->Des(), ETrue );
                                
                CleanupStack::PopAndDestroy( fullPathName2 );
                }
            
            //
            // More file information into result buffer
            //
            EndAddFileToResultsL( entry.IsDir(), iFilesInDirectory );
            }

        delete fileList1;

        err = fileFinder1->FindWild( fileList1 );
        }

    delete fileFinder1;
    
    iRecurseLevel --;
    }

// ----------------------------------------------------------------------------------------
// CTcFileScan::BeginAddFileToResults
// ----------------------------------------------------------------------------------------
void CTcFileScan::BeginAddFileToResultsL( const TDesC &aFileName,
                                         TBool aIsDir,
                                         TInt aFiles )
    {    
	RDEBUG("CTcFileScan::BeginAddFileToResultsL");

    iTabString.Zero();
    if( iRecurseLevel > 0)
        {
        TInt max = (iRecurseLevel>sizeof(iTabString)?sizeof(iTabString):iRecurseLevel);
        for(TInt i=0; i<max; i++)
            {
            iTabString.Append(TChar('\t'));
            }
        }
        
    TFileName8 filename; filename.Copy( aFileName.Left( sizeof( TFileName8 ) ) );
    
    if(aIsDir)
        {
        if(aFiles == 0)
            {
            TInt appendPosition = iFileScanResults->Size();
            TInt appendSize = filename.Length() + KFormatFolderEmpty().Length() + iTabString.Length();

            HBufC8* appendString = HBufC8::NewLC(appendSize);
            appendString->Des().Format(KFormatFolderEmpty, &filename);
            appendString->Des().Insert(0, iTabString);

            iFileScanResults->InsertL(appendPosition, *appendString);
            CleanupStack::PopAndDestroy(appendString);
            }
        else
            {
            TInt appendPosition = iFileScanResults->Size();
            TInt appendSize = filename.Length() + KFormatFolderOpen().Length() + iTabString.Length();
            
            HBufC8* appendString = HBufC8::NewLC(appendSize);
            appendString->Des().Format(KFormatFolderOpen, &filename);
            appendString->Des().Insert(0, iTabString);

            iFileScanResults->InsertL(appendPosition, *appendString);
            CleanupStack::PopAndDestroy(appendString);            
            }
        }
    else
        {
        TInt appendPosition = iFileScanResults->Size();
        TInt appendSize = filename.Length() + KFormatFileOpen().Length() + iTabString.Length();
        
        HBufC8* appendString = HBufC8::NewLC(appendSize);
        appendString->Des().Format(KFormatFileOpen, &filename);
        appendString->Des().Insert(0, iTabString);

        iFileScanResults->InsertL(appendPosition, *appendString);
        CleanupStack::PopAndDestroy(appendString);                        
        }
    }

// ----------------------------------------------------------------------------------------
// CTcFileScan::EndAddFileToResults
// ----------------------------------------------------------------------------------------
void CTcFileScan::EndAddFileToResultsL( TBool aIsDir,
                                        TInt aFiles )
    {   
	RDEBUG("CTcFileScan::EndAddFileToResultsL");

    iTabString.Zero();
    if( iRecurseLevel > 0)
        {
        TInt max = (iRecurseLevel>sizeof(iTabString)?sizeof(iTabString):iRecurseLevel);
        for(TInt i=0; i<max; i++)
            {
            iTabString.Append(TChar('\t'));
            }
        }

    if(aIsDir)
        {
        if(aFiles > 0)
            {
            TInt appendPosition = iFileScanResults->Size();
            TInt appendSize = KFormatFolderClose().Length() + iTabString.Length();
            
            HBufC8* appendString = HBufC8::NewLC(appendSize);
            appendString->Des().Copy(KFormatFolderClose);
            appendString->Des().Insert(0, iTabString);

            iFileScanResults->InsertL(appendPosition, *appendString);
            CleanupStack::PopAndDestroy(appendString);
            }
        }
    }

// ----------------------------------------------------------------------------------------
// CTcFileScan::AddDriveToResults
// ----------------------------------------------------------------------------------------
void CTcFileScan::AddDriveToResultsL( const TDesC& aDriveName )
    {
	RDEBUG("CTcFileScan::AddDriveToResultsL");

    iTabString.Zero();
    if( iRecurseLevel > 0)
        {
        TInt max = (iRecurseLevel>sizeof(iTabString)?sizeof(iTabString):iRecurseLevel);
        for(TInt i=0; i<max; i++)
            {
            iTabString.Append(TChar('\t'));
            }
        }

    TFileName8 filename; filename.Copy( aDriveName.Left( sizeof( TFileName8 ) ) );

    TInt appendPosition = iFileScanResults->Size();
    TInt appendSize = filename.Length() + KFormatDriveName().Length() + iTabString.Length();

    HBufC8* appendString = HBufC8::NewLC(appendSize);
    appendString->Des().Format(KFormatDriveName, &filename);
    appendString->Des().Insert(0, iTabString);

    iFileScanResults->InsertL(appendPosition, *appendString);
    CleanupStack::PopAndDestroy(appendString);
    }

// ----------------------------------------------------------------------------------------
// CTcFileScan::FilesInDirectoryL
// ----------------------------------------------------------------------------------------
TInt CTcFileScan::FilesInDirectoryL(RFs& aFs, TDesC &aDirectory)
    {
	RDEBUG("CTcFileScan::FilesInDirectoryL");

    TInt retVal = 0;

    TFindFile* fileFinder = new (ELeave) TFindFile( aFs );

    CDir* fileList = NULL;
    if(KErrNone == fileFinder->FindWildByPath(aDirectory, &KNullDesC(), fileList))
        {
            retVal = fileList->Count();
            delete fileList;
        }

    delete fileFinder;
    
    return retVal;
    }

// ----------------------------------------------------------------------------------------
// CTcFileScan::CreateScanPathNameL
// @return String "aDirectory\aSubDirectory\*"
// @note aDirectory may contain one extra '*' in the end
// ----------------------------------------------------------------------------------------
HBufC* CTcFileScan::CreateScanPathNameL ( const TDesC &aDirectory, const TDesC &aSubDirectory, const TDesC& aAsterisk )
    {
	RDEBUG("CTcFileScan::CreateScanPathNameL");

    TInt fullLength = aDirectory.Length() + aSubDirectory.Length() + aAsterisk.Length() + 2;

    HBufC *fullPathName = HBufC::NewL(fullLength);

    fullPathName->Des().Append(aDirectory);

    // Remove last star character '*'
    if(( fullPathName->Des().Length() > 0 ) && ( fullPathName->Des().Right(1) == _L("*") ))
        {
        fullPathName->Des().SetLength(fullPathName->Des().Length()-1);
        }

    // Add last backslash character '\'
    if(( fullPathName->Des().Length() > 0 ) && ( fullPathName->Des().Right(1) != _L("\\") ))
        {
        fullPathName->Des().Append(TChar('\\'));
        }

    fullPathName->Des().Append(aSubDirectory);

    // Add last backslash character '\'
    if(( fullPathName->Des().Length() > 0 ) && ( fullPathName->Des().Right(1) != _L("\\") ))
        {
        fullPathName->Des().Append(TChar('\\'));
        }

    fullPathName->Des().Append(aAsterisk);

    return fullPathName;
    }

// ----------------------------------------------------------------------------------------
// CTcFileScan::GetCopyOfResults
// ----------------------------------------------------------------------------------------
HBufC8* CTcFileScan::GetCopyOfResultsL()
    {
	RDEBUG("CTcFileScan::GetCopyOfResultsL");

    if(iFileScanResults == 0)
        return 0;
    
    HBufC8* results = HBufC8::NewL( iFileScanResults->Size() );
    results->Des().Append(iFileScanResults->Ptr(0));
    return results;
    }

// ----------------------------------------------------------------------------------------
// CTcFileScan::GetDriveListL
// This method will list available local drives (letters from 'a' to 'i', including 'z')
// Drive letters from 'j' to 'y' are substed or redirected and NOT included in results
// ----------------------------------------------------------------------------------------
void CTcFileScan::GetDriveListL()
    {
	RDEBUG("CTcFileScan::GetDriveListL");

    RFs fs;
    User::LeaveIfError( fs.Connect() );
    CleanupClosePushL( fs );
    
    TDriveList list;
    fs.DriveList( list );

    iRecurseLevel = 0;
    TInt   i;
    TUint8 c = 'a';
        
    for(i= 0; i<sizeof(TDriveList) && c<'i'; i++, c++)
        {
        if( list[i] != 0 )
            {
            TBuf<10> driveName;
            driveName.Append(TChar(c));
            AddDriveToResultsL( driveName );
            }
        }
        
    // Look for drive 'z'
    if( list['z' - 'a'] != 0 )
        {
        TBuf<10> driveName;
        driveName.Append(TChar('z'));
        AddDriveToResultsL( driveName );
        }
        
    CleanupStack::PopAndDestroy( &fs );       
    }

// ----------------------------------------------------------------------------------------
// End of file