connectivitymodules/SeCon/servers/pcconn/src/sconfolderlister.cpp
branchRCL_3
changeset 20 4a793f564d72
parent 18 453dfc402455
equal deleted inserted replaced
19:0aa8cc770c8a 20:4a793f564d72
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  CSconFolderLister implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "sconfolderlister.h"
       
    20 
       
    21 #include <driveinfo.h>
       
    22 #include <centralrepository.h>
       
    23 #include <sysutildomaincrkeys.h>
       
    24 #include <CDirectoryLocalizer.h>
       
    25 #include <stringresourcereader.h>
       
    26 #include <sconftp.rsg>
       
    27 #include <bautils.h>
       
    28 
       
    29 #include "debug.h"
       
    30 
       
    31 const TUint16 KFormatVersion( 1 );
       
    32 
       
    33 // Obex package size
       
    34 const TInt KPackageSize = 65536;
       
    35 
       
    36 const TInt KMaxLevelsToSearch = 80;
       
    37 
       
    38 _LIT( KSConResourceName, "z:\\Resource\\sconftp.rsc" );
       
    39 
       
    40 CSconFolderEntry* CSconFolderEntry::NewLC()
       
    41     {
       
    42     CSconFolderEntry* self = new (ELeave) CSconFolderEntry();
       
    43     CleanupStack::PushL( self );
       
    44     return self;
       
    45     }
       
    46 CSconFolderEntry* CSconFolderEntry::NewLC( const TEntry& aEntry )
       
    47     {
       
    48     CSconFolderEntry* self = new (ELeave) CSconFolderEntry();
       
    49     CleanupStack::PushL( self );
       
    50     self->ConstructL( aEntry );
       
    51     return self;
       
    52     }
       
    53 CSconFolderEntry::CSconFolderEntry()
       
    54     {
       
    55     }
       
    56 CSconFolderEntry::~CSconFolderEntry()
       
    57     {
       
    58     delete iName;
       
    59     delete iLabel;
       
    60     }
       
    61 
       
    62 
       
    63 void CSconFolderEntry::ConstructL( const TEntry& aEntry )
       
    64     {
       
    65     iAtt = aEntry.iAtt;
       
    66     iModified = aEntry.iModified.Int64();
       
    67     iName = aEntry.iName.AllocL();
       
    68     }
       
    69 
       
    70 CSconFolderLister::CSconFolderLister( RFs& aFs ) : iFs(aFs)
       
    71     {
       
    72     // No implementation required
       
    73     }
       
    74 
       
    75 CSconFolderLister::~CSconFolderLister()
       
    76     {
       
    77     TRACE_FUNC;
       
    78     delete iLocalizer;
       
    79     }
       
    80 
       
    81 CSconFolderLister* CSconFolderLister::NewL( RFs& aFs )
       
    82     {
       
    83     TRACE_FUNC_ENTRY;
       
    84     CSconFolderLister* self = new (ELeave) CSconFolderLister( aFs );
       
    85     CleanupStack::PushL( self );
       
    86     self->ConstructL();
       
    87     CleanupStack::Pop( self );
       
    88     TRACE_FUNC_EXIT;
       
    89     return self;
       
    90     }
       
    91 
       
    92 void CSconFolderLister::ConstructL()
       
    93     {
       
    94     TRACE_FUNC_ENTRY;
       
    95     
       
    96     iLocalizer = CDirectoryLocalizer::NewL();
       
    97     
       
    98     // set free memory up to critical level for all drives
       
    99     CRepository* repository = CRepository::NewLC( KCRUidDiskLevel );
       
   100     TInt iCriticalLevel(0);
       
   101     User::LeaveIfError( repository->Get( KDiskCriticalThreshold, iCriticalLevel ) );
       
   102     CleanupStack::PopAndDestroy( repository );
       
   103     iCriticalLevel += KPackageSize; // add obex package size to critical level
       
   104     TRACE_FUNC_EXIT;
       
   105     }
       
   106 
       
   107 
       
   108 void CSconFolderLister::GenerateFolderListL( RBufWriteStream& aStream, const TDesC& aStartPath, 
       
   109         const TInt aLevelsToSearch )
       
   110     {
       
   111     TRACE_FUNC_ENTRY;
       
   112     LOGGER_WRITE_1("aStartPath: %S", &aStartPath );
       
   113     LOGGER_WRITE_1("aLevelsToSearch: %d", aLevelsToSearch );
       
   114     TInt levelsToSearch = aLevelsToSearch;
       
   115     if ( levelsToSearch > KMaxLevelsToSearch || levelsToSearch == KErrNotFound )
       
   116         levelsToSearch = KMaxLevelsToSearch;
       
   117     iFolders = 0;
       
   118     iFiles = 0;
       
   119     const TInt KDriveNameLength( 3 );
       
   120     
       
   121     if ( aStartPath.CompareF( _L("\\") ) == 0 )
       
   122         {
       
   123         LOGGER_WRITE("List all drives");
       
   124         aStream.WriteUint16L( KFormatVersion );
       
   125         ListAllDrivesL( aStream, levelsToSearch );
       
   126         }
       
   127     else if ( aStartPath.Length() >= KDriveNameLength )
       
   128         {
       
   129         if ( aStartPath.Length() > KDriveNameLength )
       
   130             {
       
   131             // check root path permissions, is listing allowed
       
   132             TPtrC path = aStartPath.Mid(KDriveNameLength);
       
   133             LOGGER_WRITE_1("pathFromRoot: %S", &path);
       
   134             TInt pathEndMark = path.Locate(TChar('\\'));
       
   135             if ( pathEndMark == KErrNotFound )
       
   136                 {
       
   137                 User::Leave( KErrArgument );
       
   138                 }
       
   139             //"private\" locate = 7"
       
   140             TPtrC pathName = aStartPath.Left( KDriveNameLength+pathEndMark );
       
   141             LOGGER_WRITE_1("pathName: %S", &path);
       
   142             TEntry pathEntry;
       
   143             User::LeaveIfError( iFs.Entry(pathName, pathEntry) );
       
   144             
       
   145             TBool printable = IsDirectoryPrintable( aStartPath.Left(3), pathEntry );
       
   146             if ( !printable )
       
   147                 {
       
   148                 // access denied
       
   149                 LOGGER_WRITE("Access denied!");
       
   150                 User::Leave( KErrAccessDenied );
       
   151                 }
       
   152             User::LeaveIfError( iFs.Entry(aStartPath, pathEntry) );
       
   153             if ( pathEntry.IsSystem() )
       
   154                 {
       
   155                 // access denied
       
   156                 LOGGER_WRITE("System folder, Access denied!");
       
   157                 User::Leave( KErrAccessDenied );
       
   158                 }
       
   159             }
       
   160         
       
   161         
       
   162         aStream.WriteUint16L( KFormatVersion );
       
   163         
       
   164         TInt drive;
       
   165         User::LeaveIfError( iFs.CharToDrive( aStartPath[0], drive) );
       
   166         ListDriveAndPathL( aStream, drive, aStartPath, levelsToSearch);
       
   167 
       
   168         }
       
   169     else
       
   170         {
       
   171         LOGGER_WRITE("aStartPath KErrArgument");
       
   172         User::Leave( KErrArgument );
       
   173         }
       
   174     
       
   175     
       
   176     LOGGER_WRITE_1("iFolders: %d", iFolders);
       
   177     LOGGER_WRITE_1("iFiles: %d", iFiles);
       
   178     TRACE_FUNC_EXIT;
       
   179     }
       
   180 
       
   181 void CSconFolderLister::ListAllDrivesL( RBufWriteStream& aStream, const TInt aLevelsToSearch )
       
   182     {
       
   183     TRACE_FUNC_ENTRY;
       
   184     TInt devDriveCount = 0;
       
   185     TInt mmcDriveCount = 0;
       
   186     TChar driveLetter;
       
   187     TBuf8<1> driveBuf;
       
   188     RArray<TSconDriveInfo>  sconDriveInfo(5);
       
   189     
       
   190     // Write all drives to folderlisting object
       
   191     TDriveList driveList;
       
   192     // Get all drives that are visible to the user.
       
   193     TInt driveCount;
       
   194     User::LeaveIfError( DriveInfo::GetUserVisibleDrives( iFs, driveList, driveCount ) );
       
   195     
       
   196     for( TInt i = EDriveA; i < KMaxDrives; i++ )
       
   197         {
       
   198         if( driveList[i] )
       
   199             {
       
   200             TUint driveStatus;
       
   201             User::LeaveIfError( DriveInfo::GetDriveStatus( iFs, i, driveStatus ) );
       
   202             //LOGGER_WRITE_1( "DriveInfo for drive: %d", i);
       
   203 
       
   204             if( !(driveStatus & DriveInfo::EDrivePresent )
       
   205                 || driveStatus & DriveInfo::EDriveCorrupt
       
   206                 || (driveStatus & DriveInfo::EDriveRemote) )
       
   207                 {
       
   208                 //LOGGER_WRITE_1( "skip drive %d", i);
       
   209                 continue;
       
   210                 }
       
   211             
       
   212             User::LeaveIfError( iFs.DriveToChar( i, driveLetter ) );
       
   213             //Letter to uppercase form.
       
   214             driveLetter.UpperCase();
       
   215             
       
   216             TSconDriveInfo info;
       
   217             info.iDriveStatus = driveStatus;
       
   218             info.iDriveLetter.Zero();
       
   219             info.iDriveLetter.Append( driveLetter );
       
   220             info.iDriveLetter.Append( _L(":") );
       
   221             
       
   222             
       
   223             info.iDriveAttr = KEntryAttNormal; // ReadWrite
       
   224             
       
   225             if( driveStatus & DriveInfo::EDriveInternal && devDriveCount==0 )
       
   226                 {
       
   227                 //permission always R for first internal drive
       
   228                 info.iDriveAttr = KEntryAttReadOnly;
       
   229                 }
       
   230             
       
   231             //memory type
       
   232             if( driveStatus & DriveInfo::EDriveInternal )
       
   233                 {
       
   234                 LOGGER_WRITE( "DriveInfo::EDriveInternal" );
       
   235                 devDriveCount++;
       
   236                 info.iDriveType = DriveInfo::EDriveInternal; // =1
       
   237                 info.iDriveTypeCount = devDriveCount;
       
   238                 
       
   239                 }
       
   240             else if( driveStatus & DriveInfo::EDriveRemovable )
       
   241                 {
       
   242                 LOGGER_WRITE( "DriveInfo::EDriveRemovable" );
       
   243                 mmcDriveCount++;
       
   244                 info.iDriveType = DriveInfo::EDriveRemovable;; // =2
       
   245                 info.iDriveTypeCount = mmcDriveCount;
       
   246                 }
       
   247             
       
   248             TVolumeInfo volumeInfo;
       
   249             User::LeaveIfError( iFs.Volume( volumeInfo, i) );
       
   250             
       
   251             info.iVolumeName = volumeInfo.iName;
       
   252             if ( volumeInfo.iFree > iCriticalLevel )
       
   253                 {
       
   254                 volumeInfo.iFree = volumeInfo.iFree - iCriticalLevel;
       
   255                 }       
       
   256             else
       
   257                 {
       
   258                 volumeInfo.iFree = 0;
       
   259                 }
       
   260             
       
   261             info.iFree = volumeInfo.iFree;
       
   262             info.iSize = volumeInfo.iSize;
       
   263             
       
   264             
       
   265             sconDriveInfo.AppendL( info );
       
   266             
       
   267             }
       
   268         }
       
   269     
       
   270     LOGGER_WRITE_1("Drives: %d", sconDriveInfo.Count());
       
   271     aStream.WriteUint8L( sconDriveInfo.Count() );
       
   272     for ( TInt i=0; i < sconDriveInfo.Count(); i++ )
       
   273         {
       
   274         
       
   275         TBuf<3> path(KNullDesC);
       
   276         path.Copy(sconDriveInfo[i].iDriveLetter);
       
   277         path.Append(_L("\\"));
       
   278         
       
   279         ExportDriveL( aStream, sconDriveInfo[i], path, aLevelsToSearch);
       
   280         }
       
   281     sconDriveInfo.Close();
       
   282     TRACE_FUNC_EXIT;
       
   283     }
       
   284 
       
   285 void CSconFolderLister::ListDriveAndPathL( RBufWriteStream& aStream, TInt aDrive, const TDesC& aStartPath, const TInt aLevelsToSearch )
       
   286     {
       
   287     TRACE_FUNC_ENTRY;
       
   288     TVolumeInfo volumeInfo;
       
   289     User::LeaveIfError( iFs.Volume(volumeInfo, aDrive) );
       
   290     TInt driveCount(0);
       
   291     TUint driveStatus;
       
   292     User::LeaveIfError( DriveInfo::GetDriveStatus( iFs, aDrive, driveStatus ) );
       
   293     GetDriveTypeNumberL( aDrive, driveStatus, driveCount );
       
   294     
       
   295     
       
   296     TSconDriveInfo info;
       
   297     info.iDriveLetter.Copy( aStartPath.Left(2) );
       
   298     info.iVolumeName = volumeInfo.iName;
       
   299     
       
   300     info.iDriveAttr = KEntryAttNormal; // ReadWrite   
       
   301     if( driveStatus & DriveInfo::EDriveInternal && driveCount==0 )
       
   302         {
       
   303         //permission always R for first internal drive
       
   304         info.iDriveAttr = KEntryAttReadOnly;
       
   305         }
       
   306     info.iDriveType = 0;
       
   307     if( driveStatus & DriveInfo::EDriveInternal )
       
   308         {
       
   309         info.iDriveType = DriveInfo::EDriveInternal; // =1
       
   310         }
       
   311     else if( driveStatus & DriveInfo::EDriveRemovable )
       
   312         {
       
   313         info.iDriveType = DriveInfo::EDriveRemovable;; // =2
       
   314         }
       
   315     
       
   316     if ( volumeInfo.iFree > iCriticalLevel )
       
   317         {
       
   318         volumeInfo.iFree = volumeInfo.iFree - iCriticalLevel;
       
   319         }       
       
   320     else
       
   321         {
       
   322         volumeInfo.iFree = 0;
       
   323         }
       
   324     
       
   325     info.iFree = volumeInfo.iFree;
       
   326     info.iSize = volumeInfo.iSize;
       
   327     
       
   328     aStream.WriteUint8L( 1 );
       
   329     ExportDriveL( aStream, info, aStartPath, aLevelsToSearch);
       
   330     
       
   331     TRACE_FUNC_EXIT;
       
   332     }
       
   333 
       
   334 void CSconFolderLister::ExportDriveL( RBufWriteStream& aStream, const TSconDriveInfo& aDriveInfo,
       
   335         const TDesC& aPathName, const TInt aLevelsToSearch )
       
   336     {
       
   337     TRACE_FUNC_ENTRY;
       
   338     LOGGER_WRITE_1("Drive: %S", &aDriveInfo.iDriveLetter);
       
   339     LOGGER_WRITE_1("aLevelsToSearch: %d", aLevelsToSearch );
       
   340     
       
   341     CSconFolderEntry* driveEntry = CSconFolderEntry::NewLC();
       
   342     driveEntry->iName = aDriveInfo.iDriveLetter.AllocL();
       
   343     
       
   344     if ( driveEntry->iLabel )
       
   345         {
       
   346         LOGGER_WRITE_1("Label: %S", &driveEntry->iLabel->Des());
       
   347         }
       
   348     driveEntry->iAtt = aDriveInfo.iDriveAttr;
       
   349 
       
   350     driveEntry->iDriveInfoEntryExists = ETrue;
       
   351     driveEntry->iDriveInfoEntry.iDriveType = aDriveInfo.iDriveType;
       
   352     driveEntry->iDriveInfoEntry.iDriveTypeCount = aDriveInfo.iDriveTypeCount;
       
   353              
       
   354     driveEntry->iDriveInfoEntry.iFree = aDriveInfo.iFree;
       
   355     driveEntry->iDriveInfoEntry.iSize = aDriveInfo.iSize;
       
   356     
       
   357     driveEntry->iLabel = aDriveInfo.iVolumeName.AllocL();
       
   358     GetLocalizedVolumeNameL( *driveEntry );
       
   359     
       
   360     ExportPathL( aStream, aPathName, *driveEntry, ETrue, aLevelsToSearch );
       
   361     CleanupStack::PopAndDestroy( driveEntry );
       
   362     TRACE_FUNC_EXIT;
       
   363     }
       
   364 
       
   365 void CSconFolderLister::GetLocalizedVolumeNameL( CSconFolderEntry& aDriveEntry )
       
   366     {
       
   367     TRACE_FUNC_ENTRY;
       
   368     // Get localized names
       
   369     if ( aDriveEntry.iDriveInfoEntry.iDriveType == DriveInfo::EDriveInternal 
       
   370             && aDriveEntry.iDriveInfoEntry.iDriveTypeCount > 1 )
       
   371         {
       
   372         LOGGER_WRITE("Internal mass memory");
       
   373         // internal second memory (Mass memory)
       
   374         TFileName file( KSConResourceName );
       
   375         BaflUtils::NearestLanguageFile( iFs, file );
       
   376         
       
   377         CStringResourceReader* reader = CStringResourceReader::NewL( file );
       
   378         if ( aDriveEntry.iLabel )
       
   379             {
       
   380             delete aDriveEntry.iLabel;
       
   381             aDriveEntry.iLabel = NULL;
       
   382             }
       
   383         aDriveEntry.iLabel = reader->ReadResourceString( R_SECON_VALUE_MASS_STORAGE ).AllocL();
       
   384         delete reader;
       
   385         }
       
   386     else if ( aDriveEntry.iLabel && aDriveEntry.iLabel->Length()>0 )
       
   387         {
       
   388         LOGGER_WRITE("Use normal volume label");
       
   389         
       
   390         }
       
   391     else
       
   392         {
       
   393         TFileName file( KSConResourceName );
       
   394         BaflUtils::NearestLanguageFile( iFs, file );
       
   395         CStringResourceReader* reader = CStringResourceReader::NewL( file );
       
   396         if (aDriveEntry.iLabel)
       
   397             {
       
   398             delete aDriveEntry.iLabel;
       
   399             aDriveEntry.iLabel = NULL;
       
   400             }
       
   401         if ( aDriveEntry.iDriveInfoEntry.iDriveType == DriveInfo::EDriveRemovable )
       
   402             {
       
   403             LOGGER_WRITE("EDriveRemovable");
       
   404             // read default MMC name
       
   405             aDriveEntry.iLabel = reader->ReadResourceString( R_SECON_VALUE_MMC ).AllocL();
       
   406             }
       
   407         else
       
   408             {
       
   409             LOGGER_WRITE("EDriveInternal");
       
   410             // read default DEV name
       
   411             aDriveEntry.iLabel = reader->ReadResourceString( R_SECON_VALUE_DEVICE ).AllocL();
       
   412             }
       
   413         delete reader;
       
   414         }
       
   415     TRACE_FUNC_EXIT;
       
   416     }
       
   417 
       
   418 // -----------------------------------------------------------------------------
       
   419 // CSconFolderLister::GetDriveTypeNumberL()
       
   420 // 
       
   421 // -----------------------------------------------------------------------------
       
   422 //  
       
   423 void CSconFolderLister::GetDriveTypeNumberL( TInt aDrive, TUint aDriveStatus , TInt& aTypeNumber)
       
   424     {
       
   425     TRACE_FUNC_ENTRY;
       
   426     aTypeNumber = 0;
       
   427     
       
   428     //TUint driveStatus;
       
   429     //
       
   430     // if true, search internal drives, else search removable drives
       
   431     TBool searchInternalDrives = (aDriveStatus & DriveInfo::EDriveInternal);
       
   432     
       
   433     TInt driveCount;
       
   434     TDriveList driveList;
       
   435     
       
   436     User::LeaveIfError( DriveInfo::GetUserVisibleDrives( iFs, driveList, driveCount ) );
       
   437     
       
   438     for( TInt i = EDriveA; i <= aDrive; i++ )
       
   439         {
       
   440         if( driveList[i] )
       
   441             {
       
   442             TUint driveStatus;
       
   443             User::LeaveIfError( DriveInfo::GetDriveStatus( iFs, i, driveStatus ) );
       
   444 
       
   445             if( !(driveStatus & DriveInfo::EDrivePresent )
       
   446                 || driveStatus & DriveInfo::EDriveCorrupt )
       
   447                 {
       
   448                 LOGGER_WRITE( "not present or corrupted" );
       
   449                 continue;
       
   450                 }
       
   451             
       
   452             if( driveStatus & DriveInfo::EDriveInternal )
       
   453                 {
       
   454                 if( searchInternalDrives )
       
   455                     {
       
   456                     aTypeNumber++;
       
   457                     }
       
   458                 }
       
   459             else if( driveStatus & DriveInfo::EDriveRemovable )
       
   460                 {
       
   461                 if( !searchInternalDrives )
       
   462                     {
       
   463                     aTypeNumber++;
       
   464                     }
       
   465                 }
       
   466             }
       
   467         }
       
   468     TRACE_FUNC_EXIT;
       
   469     }
       
   470 
       
   471 
       
   472 void CSconFolderLister::ExportPathL( RBufWriteStream& aStream, const TDesC& aPathName,
       
   473         const CSconFolderEntry& aEntry, const TBool aLocalize, const TInt aLevelsToSearch )
       
   474     {
       
   475     TRACE_FUNC_ENTRY;
       
   476     LOGGER_WRITE_1("aPathName: %S", &aPathName );
       
   477     LOGGER_WRITE_1("aLevelsToSearch: %d", aLevelsToSearch );
       
   478     
       
   479     LOGGER_WRITE_1("aEntry.iName: %S", &aEntry.iName->Des() );
       
   480     
       
   481     TBool localized(EFalse); 
       
   482     
       
   483     // foldername length + name
       
   484     aStream.WriteUint8L( aEntry.iName->Length() );
       
   485     aStream.WriteL( aEntry.iName->Des() );
       
   486     
       
   487     TUint att = aEntry.iAtt;
       
   488     
       
   489     if ( aEntry.iLabel && aEntry.iLabel->Length() > 0 )
       
   490         {
       
   491         aStream.WriteUint8L( aEntry.iLabel->Length() );
       
   492         aStream.WriteL( aEntry.iLabel->Des() );
       
   493         }
       
   494     else
       
   495         {
       
   496         if ( aLocalize )
       
   497             {
       
   498             // initialize Localizer
       
   499             iLocalizer->SetFullPath( aPathName );
       
   500             localized = iLocalizer->IsLocalized();
       
   501             }
       
   502         
       
   503         if( localized )
       
   504             {
       
   505             const TDesC& localizedName = iLocalizer->LocalizedName();
       
   506             aStream.WriteUint8L( localizedName.Length() );
       
   507             aStream.WriteL( localizedName );
       
   508             LOGGER_WRITE_1("LocalizedName: %S", &localizedName );
       
   509             }
       
   510         else if ( aPathName.CompareF(_L("C:\\Data\\")) == 0 )
       
   511             {
       
   512             TFileName file( KSConResourceName );
       
   513             
       
   514             BaflUtils::NearestLanguageFile( iFs, file );
       
   515                
       
   516             CStringResourceReader* reader = CStringResourceReader::NewL( file );
       
   517             CleanupStack::PushL( reader );
       
   518             
       
   519             const TDesC& localizedName = reader->ReadResourceString( R_SECON_DATA_FOLDER );
       
   520             aStream.WriteUint8L( localizedName.Length() );
       
   521             aStream.WriteL( localizedName );
       
   522             LOGGER_WRITE_1("LocalizedName: %S", &localizedName );
       
   523             
       
   524             CleanupStack::PopAndDestroy( reader );
       
   525             localized = ETrue;
       
   526             }
       
   527         else
       
   528             {
       
   529             aStream.WriteUint8L( 0 );
       
   530             }
       
   531         // attributes
       
   532         if ( localized )
       
   533             {
       
   534             // localized folder, set readonly flag
       
   535             att = att | KEntryAttReadOnly;
       
   536             }
       
   537         }
       
   538     
       
   539     if ( aPathName.Length() == 3 && aLocalize )
       
   540         {
       
   541         // enable subfolder localization, even when root cannot be localized
       
   542         localized = ETrue;
       
   543         }
       
   544     
       
   545     // DriveInfoEntry
       
   546     if ( aEntry.iDriveInfoEntryExists )
       
   547         {
       
   548         aStream.WriteUint8L( 1 );
       
   549         aStream.WriteUint8L( aEntry.iDriveInfoEntry.iDriveType );
       
   550         aStream.WriteUint8L( aEntry.iDriveInfoEntry.iDriveTypeCount );
       
   551         aStream << aEntry.iDriveInfoEntry.iFree;
       
   552         aStream << aEntry.iDriveInfoEntry.iSize;
       
   553         }
       
   554     else
       
   555         {
       
   556         aStream.WriteUint8L( 0 );
       
   557         }
       
   558     
       
   559     
       
   560     // modified time
       
   561     TDateTime time = aEntry.iModified.DateTime();
       
   562     aStream.WriteInt16L( time.Year() );
       
   563     aStream.WriteInt8L( time.Month()+1 ); // range 1...12
       
   564     aStream.WriteInt8L( time.Day()+1 );
       
   565     aStream.WriteInt8L( time.Hour() );
       
   566     aStream.WriteInt8L( time.Minute() );
       
   567     aStream.WriteInt8L( time.Second() );
       
   568     
       
   569     // write attribute
       
   570     aStream.WriteUint32L( att );
       
   571     
       
   572     
       
   573     if ( aLevelsToSearch == 0 )
       
   574         {
       
   575         // don't list directory content
       
   576         LOGGER_WRITE("Not listing directory content");
       
   577         aStream.WriteInt16L( 0 ); // files count
       
   578         aStream.WriteInt16L( 0 ); // directory count
       
   579         return;
       
   580         }
       
   581     
       
   582     CDir *fileList = 0;
       
   583     CDir *dirList = 0;
       
   584     
       
   585     // show normal and hidden files and folders
       
   586     TUint entryAttMask = KEntryAttNormal | KEntryAttHidden;
       
   587     
       
   588     // get folders and files
       
   589     TInt err = iFs.GetDir( aPathName, entryAttMask, ESortByName, 
       
   590             fileList, dirList );
       
   591     
       
   592     if ( err )
       
   593         {
       
   594         LOGGER_WRITE_1( "ParseFolderListL GetDir returned: %d", err );
       
   595         User::Leave( err );
       
   596         }
       
   597     
       
   598     CleanupStack::PushL( dirList );
       
   599     CleanupStack::PushL( fileList );
       
   600     
       
   601     
       
   602     LOGGER_WRITE_1("files: %d", fileList->Count());
       
   603     aStream.WriteUint16L( fileList->Count() );
       
   604     
       
   605     // Print files to folder listing object
       
   606     for( TInt i = 0; i < fileList->Count(); i++ )
       
   607         {
       
   608         const TEntry& fileEntry = ( *fileList )[i];
       
   609         iFiles++;
       
   610         LOGGER_WRITE_1("fileEntry.iName: %S", &fileEntry.iName);
       
   611         // filename length + name
       
   612         aStream.WriteUint8L( fileEntry.iName.Length() );
       
   613         aStream.WriteL( fileEntry.iName );
       
   614         
       
   615         // modified time
       
   616         TDateTime time = fileEntry.iModified.DateTime();
       
   617         aStream.WriteInt16L( time.Year() );
       
   618         aStream.WriteInt8L( time.Month()+1 ); // range 1...12
       
   619         aStream.WriteInt8L( time.Day()+1 );
       
   620         aStream.WriteInt8L( time.Hour() );
       
   621         aStream.WriteInt8L( time.Minute() );
       
   622         aStream.WriteInt8L( time.Second() );
       
   623         
       
   624         // attributes
       
   625         aStream.WriteUint32L( fileEntry.iAtt );
       
   626         
       
   627         // file size
       
   628         aStream.WriteUint32L( fileEntry.iSize );
       
   629         }
       
   630     CleanupStack::PopAndDestroy( fileList );
       
   631     
       
   632     
       
   633     // calculate ow many directories we are going to list
       
   634     TInt directoryCount(0);
       
   635     for( TInt i = 0; i < dirList->Count(); i++ )
       
   636         {
       
   637         if ( IsDirectoryPrintable(aPathName, ( *dirList )[i] ) )
       
   638             {
       
   639             directoryCount++;
       
   640             }
       
   641         }
       
   642     LOGGER_WRITE_1("directories: %d", directoryCount);
       
   643     aStream.WriteUint16L( directoryCount );
       
   644     
       
   645     HBufC* fullpath = HBufC::NewL( KMaxPath );
       
   646     TPtr fullpathPtr = fullpath->Des();
       
   647     CleanupStack::PushL( fullpath );
       
   648     
       
   649     // Print folders to folder listing object
       
   650     for( TInt i = 0; i < dirList->Count(); i++ )
       
   651         {
       
   652         const TEntry& folderEntry = ( *dirList )[i];
       
   653         if ( !IsDirectoryPrintable(aPathName, folderEntry) )
       
   654             {
       
   655             continue;
       
   656             }
       
   657         iFolders++;
       
   658         
       
   659         fullpathPtr.Copy( aPathName );
       
   660         fullpathPtr.Append( folderEntry.iName );
       
   661         fullpathPtr.Append( _L("\\") );
       
   662         CSconFolderEntry* subFolderEntry = CSconFolderEntry::NewLC( folderEntry );
       
   663         if ( aLevelsToSearch == KErrNotFound )
       
   664             {
       
   665             ExportPathL( aStream, fullpathPtr, *subFolderEntry, localized, aLevelsToSearch);
       
   666             }
       
   667         else
       
   668             {
       
   669             ExportPathL( aStream, fullpathPtr, *subFolderEntry, localized, aLevelsToSearch-1);
       
   670             }
       
   671         CleanupStack::PopAndDestroy( subFolderEntry );
       
   672         }
       
   673     CleanupStack::PopAndDestroy( fullpath );
       
   674     CleanupStack::PopAndDestroy( dirList );
       
   675     
       
   676     TRACE_FUNC_EXIT;
       
   677     }
       
   678 TBool CSconFolderLister::IsDirectoryPrintable( const TDesC& aParentPath, const TEntry& aFolderEntry )
       
   679     {
       
   680     if ( aFolderEntry.IsSystem() )
       
   681         {
       
   682         LOGGER_WRITE_1("folder '%S' was system folder", &aFolderEntry.iName);
       
   683         return EFalse;
       
   684         }
       
   685     if ( aParentPath.Length() == 3 )
       
   686         {
       
   687         if ( aParentPath.FindF(_L("C:\\")) == 0 && aFolderEntry.iName.CompareF(_L("data")) != 0 )
       
   688             {
       
   689             // C root not visible, exept Data folder
       
   690             LOGGER_WRITE_1("folder '%S' not visible to user in c-root", &aFolderEntry.iName);
       
   691             return EFalse;
       
   692             }
       
   693         
       
   694         if ( aFolderEntry.iName.CompareF(_L("private")) == 0 )
       
   695             {
       
   696             LOGGER_WRITE_1("folder '%S' not visible to user", &aFolderEntry.iName);
       
   697             return EFalse;
       
   698             }
       
   699         else if ( aFolderEntry.iName.CompareF(_L("sys")) == 0 )
       
   700             {
       
   701             LOGGER_WRITE_1("folder '%S' not visible to user", &aFolderEntry.iName);
       
   702             return EFalse;
       
   703             }
       
   704         else if ( aFolderEntry.iName.CompareF(_L("system")) == 0 )
       
   705             {
       
   706             LOGGER_WRITE_1("folder '%S' not visible to user", &aFolderEntry.iName);
       
   707             return EFalse;
       
   708             }
       
   709         else if ( aFolderEntry.iName.CompareF(_L("resource")) == 0 )
       
   710             {
       
   711             LOGGER_WRITE_1("folder '%S' not visible to user", &aFolderEntry.iName);
       
   712             return EFalse;
       
   713             }
       
   714         }
       
   715     return ETrue;
       
   716     }
       
   717