hti/HtiServicePlugins/HtiFtpServicePlugin/src/HtiFtpServicePlugin.cpp
branchRCL_3
changeset 59 8ad140f3dd41
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
       
     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:  HtiFtpServicePlugin implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "HtiFtpServicePlugin.h"
       
    21 #include <HtiFtpBackupFakeBase.h>
       
    22 #include <HtiDispatcherInterface.h>
       
    23 #include <HtiLogging.h>
       
    24 
       
    25 #include <e32property.h>
       
    26 #include <hash.h>
       
    27 
       
    28 // CONSTANTS
       
    29 static const TUid KFtpServiceUid = { 0x1020DEC5 };
       
    30 _LIT( KBackslash, "\\" );
       
    31 _LIT( KRootPathFormat, "%c:\\" );
       
    32 _LIT( KHtiFtpBackupFakeDllName, "HtiFtpBackupFake.dll" );
       
    33 const static TInt KMinBufferSize = 1024;
       
    34 const static TUint8 KUnicodeMask = 0x1;
       
    35 const static TInt KFileSizeMsgSize = 5;
       
    36 
       
    37 //error description
       
    38 _LIT8( KErrDescrUnknownCmd, "unknown command" );
       
    39 _LIT8( KErrDescrNoSpace, "no disk space" );
       
    40 _LIT8( KErrDescrFailedRead, "failed read file" );
       
    41 _LIT8( KErrDescrFailedWrite, "failed write file" );
       
    42 _LIT8( KErrDescrFailedGetDir, "failed to read directory" );
       
    43 _LIT8( KErrDescrEmptyDirname, "directory name empty" );
       
    44 _LIT8( KErrDescrInvalidDirnameLength, "invalid directory name length" );
       
    45 _LIT8( KErrDescrEmptyFilename, "file name empty" );
       
    46 _LIT8( KErrDescrInvalidFilenameLength, "invalid file name length" );
       
    47 _LIT8( KErrDescrFailedMkDir, "failed create directory" );
       
    48 _LIT8( KErrDescrFailedRmDir, "failed remove directory" );
       
    49 _LIT8( KErrDescrFailedDeleFile, "failed delete file" );
       
    50 _LIT8( KErrDescrFailedRenameFile, "failed rename file" );
       
    51 _LIT8( KErrDescrFailedCopyFile, "failed copy file" );
       
    52 _LIT8( KErrDescrFailedMoveFile, "failed move file" );
       
    53 _LIT8( KErrDescrInvalidStorArgument, "invalid arguments" );
       
    54 _LIT8( KErrDescrFailedCreateFile, "invalid create file" );
       
    55 _LIT8( KErrDescrFailedOpenFile, "failed open file" );
       
    56 _LIT8( KErrDescrFailedCloseFile, "failed close file" );
       
    57 _LIT8( KErrDescrInvalidDataMessage, "invalid data message" );
       
    58 _LIT8( KErrDescrNoMemory, "no memory to send file" );
       
    59 _LIT8( KErrDescrNoCancel, "nothing to cancel" );
       
    60 _LIT8( KErrDescrBusy, "Busy" );
       
    61 _LIT8( KErrDescrFailedCopyTcb, "Failed to copy to Tcb directories" );
       
    62 _LIT8( KErrDescrInvalidForceArgs, "invalid arguments for setforce" );
       
    63 _LIT8( KErrDescrInvalidChecksumArgs, "invalid arguments for checksum" );
       
    64 _LIT8( KErrDescrInvalidFormatArgs, "invalid arguments for format" );
       
    65 _LIT8( KErrDescrInvalidDriveListArgs, "invalid arguments for drive list" );
       
    66 _LIT8( KErrDescrFailedFormat, "failed to format" );
       
    67 _LIT8( KErrDescrNotSupported, "command not supported" );
       
    68 
       
    69 // MACROS
       
    70 
       
    71 // LOCAL CONSTANTS AND MACROS
       
    72 
       
    73 // MODULE DATA STRUCTURES
       
    74 
       
    75 // LOCAL FUNCTION PROTOTYPES
       
    76 
       
    77 // FORWARD DECLARATIONS
       
    78 
       
    79 // ============================ MEMBER FUNCTIONS ===============================
       
    80 
       
    81 /**
       
    82 * CFtpHandlerAO implementation
       
    83 */
       
    84 CFtpHandlerAO::CFtpHandlerAO( MFtpObserverAO* anObserver ):
       
    85     CActive( EPriorityStandard ),
       
    86     iObserver( anObserver ),
       
    87     iCancelFileMan( EFalse )
       
    88     {
       
    89     CActiveScheduler::Add( this );
       
    90     }
       
    91 
       
    92 CFtpHandlerAO::~CFtpHandlerAO()
       
    93     {
       
    94     }
       
    95 
       
    96 void CFtpHandlerAO::Start()
       
    97     {
       
    98     SetActive();
       
    99     }
       
   100 
       
   101 MFileManObserver::TControl CFtpHandlerAO::NotifyFileManStarted()
       
   102     {
       
   103     return iCancelFileMan?
       
   104                 MFileManObserver::EAbort :
       
   105                 MFileManObserver::EContinue;
       
   106     }
       
   107 
       
   108 MFileManObserver::TControl CFtpHandlerAO::NotifyFileManOperation()
       
   109     {
       
   110     return iCancelFileMan?
       
   111                 MFileManObserver::ECancel :
       
   112                 MFileManObserver::EContinue;
       
   113     }
       
   114 
       
   115 MFileManObserver::TControl CFtpHandlerAO::NotifyFileManEnded()
       
   116     {
       
   117     return iCancelFileMan?
       
   118                 MFileManObserver::EAbort :
       
   119                 MFileManObserver::EContinue;
       
   120     }
       
   121 
       
   122 void CFtpHandlerAO::RunL()
       
   123     {
       
   124     iObserver->FtpComplete( iStatus.Int() );
       
   125     }
       
   126 
       
   127 void CFtpHandlerAO::DoCancel()
       
   128     {
       
   129     iCancelFileMan = ETrue;
       
   130     }
       
   131 
       
   132 CProcessLogonAO::CProcessLogonAO( MFtpObserverAO* anObserver ):
       
   133     CActive( EPriorityStandard ),
       
   134     iObserver( anObserver )
       
   135     {
       
   136     CActiveScheduler::Add( this );
       
   137     }
       
   138 
       
   139 CProcessLogonAO::~CProcessLogonAO()
       
   140     {
       
   141     Cancel();
       
   142     iProcess.Close();
       
   143     }
       
   144 
       
   145 void CProcessLogonAO::Start( const TDesC& aCmdLine )
       
   146     {
       
   147     TInt err = iProcess.Create( KHtiFileHlp, aCmdLine );
       
   148 
       
   149     if ( err == KErrNone )
       
   150         {
       
   151         iProcess.Logon( iStatus );
       
   152         //start HtiFileHlp.exe
       
   153         iProcess.Resume();
       
   154         }
       
   155     else
       
   156         {
       
   157         TRequestStatus* pS = &iStatus;
       
   158         User::RequestComplete( pS, err );
       
   159         }
       
   160     SetActive();
       
   161     }
       
   162 
       
   163 void CProcessLogonAO::RunL()
       
   164     {
       
   165     iObserver->FtpComplete( iStatus.Int() );
       
   166     }
       
   167 
       
   168 void CProcessLogonAO::DoCancel()
       
   169     {
       
   170     iProcess.LogonCancel( iStatus );
       
   171     }
       
   172 
       
   173 // Create instance of concrete ECOM interface implementation
       
   174 CHtiFtpServicePlugin* CHtiFtpServicePlugin::NewL()
       
   175     {
       
   176     CHtiFtpServicePlugin* self = new (ELeave) CHtiFtpServicePlugin;
       
   177     CleanupStack::PushL (self);
       
   178     self->ConstructL();
       
   179     CleanupStack::Pop();
       
   180     return self;
       
   181     }
       
   182 
       
   183 // Constructor
       
   184 CHtiFtpServicePlugin::CHtiFtpServicePlugin():
       
   185     iState( EIdle ),
       
   186     iSendBuffer( NULL ),
       
   187     iSendBufferDes( NULL, 0 ),
       
   188     iHandlerAO( NULL ),
       
   189     iProcessLogonAO( NULL )
       
   190     {
       
   191     }
       
   192 
       
   193 CHtiFtpServicePlugin::~CHtiFtpServicePlugin()
       
   194     {
       
   195     HTI_LOG_FUNC_IN("~CHtiFtpServicePlugin");
       
   196     delete iSendBuffer;
       
   197     delete iHandlerAO;
       
   198     delete iProcessLogonAO;
       
   199     delete iFileMan;
       
   200     delete iBackupFake;
       
   201     iBackupFakeLib.Close();
       
   202     iFs.Close();
       
   203     HTI_LOG_FUNC_OUT("~CHtiFtpServicePlugin");
       
   204     }
       
   205 
       
   206 // Second phase construction.
       
   207 void CHtiFtpServicePlugin::ConstructL()
       
   208     {
       
   209     HTI_LOG_FUNC_IN("CHtiFtpServicePlugin::ConstructL");
       
   210 
       
   211     User::LeaveIfError( iFs.Connect() );
       
   212     iFileMan = CFileMan::NewL( iFs );
       
   213 
       
   214     HTI_LOG_FUNC_OUT("CHtiFtpServicePlugin::ConstructL");
       
   215     }
       
   216 
       
   217 void CHtiFtpServicePlugin::InitL()
       
   218     {
       
   219     if ( iDispatcher->GetFreeMemory() < KMinBufferSize )
       
   220         {
       
   221         User::Leave( KErrNoMemory );
       
   222         }
       
   223     // just guess
       
   224 
       
   225     iBufferSize = iDispatcher->GetFreeMemory()/10;
       
   226     iBufferSize = iBufferSize < KMinBufferSize ?
       
   227                     KMinBufferSize :
       
   228                     iBufferSize;
       
   229     //test
       
   230     iBufferSize = 3*KMinBufferSize;
       
   231     }
       
   232 
       
   233 TInt CHtiFtpServicePlugin::SendControlMsg( TFtpCommand aCmd,
       
   234                                            const TDesC8& aMsg  )
       
   235     {
       
   236     TInt err = KErrNone;
       
   237     HBufC8* temp = NULL;
       
   238     TRAP( err, temp = HBufC8::NewL( 1 + aMsg.Size() ) );
       
   239     if ( err == KErrNone )
       
   240         {
       
   241         temp->Des().Append( aCmd );
       
   242         temp->Des().Append( aMsg );
       
   243         err = iDispatcher->DispatchOutgoingMessage( temp,
       
   244                         KFtpServiceUid,
       
   245                         EFalse,
       
   246                         EHtiPriorityControl );
       
   247         if ( err != KErrNone )
       
   248             {
       
   249             delete temp;
       
   250             }
       
   251         }
       
   252     return err;
       
   253     }
       
   254 
       
   255 inline TInt CHtiFtpServicePlugin::SendErrorMsg( TInt anError,
       
   256                                                 const TDesC8& aMsg )
       
   257     {
       
   258     SetBURFakeState( EFalse ); // errors ignored
       
   259     return iDispatcher->DispatchOutgoingErrorMessage( anError,
       
   260                                                aMsg,
       
   261                                                KFtpServiceUid);
       
   262     }
       
   263 
       
   264 TBool CHtiFtpServicePlugin::IsBusy()
       
   265     {
       
   266     return !( iState == EIdle || iState == EStorWait || iState == ERetrWait );
       
   267     }
       
   268 
       
   269 void CHtiFtpServicePlugin::ProcessMessageL(const TDesC8& aMessage,
       
   270                 THtiMessagePriority aPriority)
       
   271     {
       
   272     HTI_LOG_FUNC_IN("CHtiFtpServicePlugin::ProcessMessage");
       
   273 
       
   274     if ( IsBusy() )
       
   275         {
       
   276         //should not happend - service busy,deny request
       
   277         User::Leave( KErrInUse );
       
   278         }
       
   279 
       
   280     switch ( aPriority )
       
   281         {
       
   282         case EHtiPriorityData:
       
   283             {
       
   284             HandleDataMessageL( aMessage );
       
   285             }
       
   286             break;
       
   287         case EHtiPriorityControl:
       
   288             {
       
   289             if ( iState == EStorWait || iState == ERetrWait )
       
   290                 {
       
   291                 HandleCancelL( aMessage );
       
   292                 }
       
   293             else
       
   294                 {
       
   295                 HandleControlMessageL( aMessage );
       
   296                 }
       
   297             }
       
   298             break;
       
   299         default:
       
   300             HTI_LOG_TEXT("Unknown priority");
       
   301         }
       
   302 
       
   303     HTI_LOG_FUNC_OUT("CHtiFtpServicePlugin::ProcessMessage");
       
   304     }
       
   305 
       
   306 void CHtiFtpServicePlugin::HandleControlMessageL(const TDesC8& aMessage)
       
   307     {
       
   308     TInt err = KErrNone;
       
   309 
       
   310     if ( aMessage.Length() > 0 )
       
   311         {
       
   312         TBool unicode = aMessage[0]&KUnicodeMask;
       
   313         HTI_LOG_FORMAT("cmd %d", aMessage[0] );
       
   314 
       
   315         switch ( aMessage[0] )
       
   316             {
       
   317             case EFtpSTOR:
       
   318             case EFtpSTOR_u:
       
   319                 {
       
   320                 //receive file
       
   321                 //get filesize
       
   322                 if ( aMessage.Length() > 5 )
       
   323                     {
       
   324                     iFileSize = aMessage[1] +
       
   325                                 ( aMessage[2] << 8  ) +
       
   326                                 ( aMessage[3] << 16 ) +
       
   327                                 ( aMessage[4] << 24 );
       
   328 
       
   329                     HTI_LOG_FORMAT( "Filesize %d", iFileSize );
       
   330                     //get fileName
       
   331                     if ( GetFileNameL( aMessage.Mid( 5 ),
       
   332                                       unicode ) )
       
   333                         {
       
   334                         HandleReceiveFileL();
       
   335                         }
       
   336                     }
       
   337                 else
       
   338                     {
       
   339                     HTI_LOG_TEXT("no file size or file name");
       
   340                     User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   341                                             KErrDescrInvalidStorArgument) );
       
   342 
       
   343                     }
       
   344                 }
       
   345                 break;
       
   346             case EFtpRETR:
       
   347             case EFtpRETR_u:
       
   348                 {
       
   349                 //send file
       
   350                 //get fileName and size
       
   351                 if ( GetFileNameL( aMessage.Mid(1),
       
   352                                    unicode ) )
       
   353                     {
       
   354                     HandleSendFileL();
       
   355                     }
       
   356                 }
       
   357                 break;
       
   358             case EFtpLIST:
       
   359             case EFtpLIST_u:
       
   360             case EFtpLISTSIZES:
       
   361             case EFtpLISTSIZES_u:
       
   362                 {
       
   363                 if ( GetDirectoryL( aMessage.Mid( 1 ),
       
   364                                    unicode ) )
       
   365                     {
       
   366                     HandleListL( unicode,
       
   367                         ( KEntryAttHidden| KEntryAttSystem|KEntryAttNormal ),
       
   368                         ( aMessage[0] == EFtpLISTSIZES ||
       
   369                           aMessage[0] == EFtpLISTSIZES_u ) );
       
   370                     }
       
   371                 }
       
   372                 break;
       
   373             case EFtpListDetail:
       
   374             case EFtpListDetail_u:
       
   375                 {
       
   376                 if ( GetDirectoryL( aMessage.Mid( 1 ),
       
   377                                    unicode ) )
       
   378                     {
       
   379                     HandleListDetailL( unicode,
       
   380                         KEntryAttHidden| KEntryAttSystem|KEntryAttNormal);
       
   381                     }
       
   382                 }
       
   383                 break;
       
   384             case EFtpLISTDIR:
       
   385             case EFtpLISTDIR_u:
       
   386                 {
       
   387                 if ( GetDirectoryL( aMessage.Mid( 1 ),
       
   388                                    unicode ) )
       
   389                     {
       
   390                     HandleListL( unicode,
       
   391                                 (KEntryAttMatchExclusive|
       
   392                                 KEntryAttHidden|KEntryAttSystem|
       
   393                                 KEntryAttDir), EFalse );
       
   394                     }
       
   395                 }
       
   396                 break;
       
   397             case EFtpListDirDetail:
       
   398             case EFtpListDirDetail_u:
       
   399                 {
       
   400                 if ( GetDirectoryL( aMessage.Mid( 1 ),
       
   401                                    unicode ) )
       
   402                     {
       
   403                     HandleListDetailL( unicode,
       
   404                             KEntryAttMatchExclusive|KEntryAttHidden|
       
   405                             KEntryAttSystem|KEntryAttDir);
       
   406                     }
       
   407                 }
       
   408                 break;
       
   409             case EFtpMKD:
       
   410             case EFtpMKD_u:
       
   411                 {
       
   412                 if ( GetDirectoryL( aMessage.Mid( 1 ),
       
   413                                    unicode ) )
       
   414                     {
       
   415                     if ( IsFileTcb( iFileName ) )
       
   416                         {
       
   417                         HandleTcbMkdL( iFileName );
       
   418                         }
       
   419                     else
       
   420                         {
       
   421                         err = iFs.MkDirAll( iFileName );
       
   422                         if ( err == KErrNone || err == KErrAlreadyExists )
       
   423                             {
       
   424                             User::LeaveIfError( SendControlMsg( EFtpOK,
       
   425                                                                 KNullDesC8) );
       
   426                             }
       
   427                         else
       
   428                             {
       
   429                             User::LeaveIfError( SendErrorMsg( err,
       
   430                                                         KErrDescrFailedMkDir ) );
       
   431 
       
   432                             }
       
   433                         }
       
   434                     }
       
   435                 }
       
   436                 break;
       
   437             case EFtpRMD:
       
   438             case EFtpRMD_u:
       
   439                 {
       
   440                 if ( GetDirectoryL( aMessage.Mid( 1 ),
       
   441                                    unicode ) )
       
   442                     {
       
   443                     if ( IsFileTcb( iFileName ) )
       
   444                         {
       
   445                         HandleTcbRmdL( iFileName );
       
   446                         }
       
   447                     else
       
   448                         {
       
   449                         delete iHandlerAO;
       
   450                         iHandlerAO = NULL;
       
   451 
       
   452                         iHandlerAO = new(ELeave) CFtpHandlerAO( this );
       
   453                         err = iFileMan->RmDir( iFileName, iHandlerAO->iStatus );
       
   454                         if ( err == KErrNone)
       
   455                             {
       
   456                             iState = ERmdBusy;
       
   457                             iHandlerAO->Start();
       
   458                             }
       
   459                         else
       
   460                             {
       
   461                             delete iHandlerAO;
       
   462                             iHandlerAO = NULL;
       
   463                             User::LeaveIfError( SendErrorMsg( err,
       
   464                                                         KErrDescrFailedRmDir ) );
       
   465                             }
       
   466                         }
       
   467                     }
       
   468                 }
       
   469                 break;
       
   470             case EFtpDELE:
       
   471             case EFtpDELE_u:
       
   472                 {
       
   473                 if ( GetFileNameL( aMessage.Mid( 1 ),
       
   474                                    unicode ) )
       
   475                     {
       
   476                     if ( IsFileTcb( iFileName ) )
       
   477                         {
       
   478                         HandleTcbDeleteL( iFileName );
       
   479                         }
       
   480                     else
       
   481                         {
       
   482                         HandleDeleteL( iFileName );
       
   483                         }
       
   484                     }
       
   485                 }
       
   486                 break;
       
   487             case EFtpCANCEL:
       
   488                 {
       
   489                 User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   490                                                 KErrDescrNoCancel ) );
       
   491                 }
       
   492                 break;
       
   493             case EFtpSETFORCE:
       
   494                 {
       
   495                 if ( aMessage.Length() != 2 )
       
   496                     {
       
   497                     User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   498                                                 KErrDescrInvalidForceArgs ) );
       
   499                     }
       
   500                 else
       
   501                     {
       
   502                     if ( aMessage[1] )
       
   503                         {
       
   504                         // Setting forced operations on
       
   505                         err = iBackupFakeLib.Load( KHtiFtpBackupFakeDllName );
       
   506                         HTI_LOG_FORMAT( "BackupFake DLL load returned %d", err );
       
   507                         if ( err == KErrNone && iBackupFakeLib.Type()[1] ==
       
   508                                 KHtiFtpBackupFakeInterfaceUid )
       
   509                             {
       
   510                             HTI_LOG_TEXT( "BackupFake DLL found" );
       
   511                             TLibraryFunction entry = iBackupFakeLib.Lookup( 1 );
       
   512                             if ( entry != NULL )
       
   513                                 {
       
   514                                 iBackupFake = ( CHtiFtpBackupFakeBase* ) entry();
       
   515                                 TRAP( err, iBackupFake->ConstructL( &iFs ) );
       
   516                                 }
       
   517                             }
       
   518                         if ( err == KErrNone )
       
   519                             {
       
   520                             SendControlMsg( EFtpOK, KNullDesC8 );
       
   521                             }
       
   522                         else
       
   523                             {
       
   524                             User::LeaveIfError( SendErrorMsg( KErrNotSupported,
       
   525                                 KErrDescrNotSupported ) );
       
   526                             }
       
   527                         }
       
   528                     else
       
   529                         {
       
   530                         // Setting forced operations off
       
   531                         delete iBackupFake;
       
   532                         iBackupFake = NULL;
       
   533                         iBackupFakeLib.Close();
       
   534                         SendControlMsg( EFtpOK, KNullDesC8 );
       
   535                         }
       
   536                     }
       
   537                 }
       
   538                 break;
       
   539             case EFtpCHECKSUM:
       
   540             case EFtpCHECKSUM_u:
       
   541                 {
       
   542                 if ( aMessage.Length() < 3 )
       
   543                     {
       
   544                     User::LeaveIfError(
       
   545                         SendErrorMsg( KErrArgument,
       
   546                                       KErrDescrInvalidChecksumArgs ) );
       
   547                     }
       
   548                 else if ( GetFileNameL( aMessage.Mid( 2 ), unicode ) )
       
   549                     {
       
   550                     HandleCheckSumCalcL( (TAlgorithm)aMessage[1], iFileName );
       
   551                     }
       
   552                 }
       
   553                 break;
       
   554             case EFtpFORMAT:
       
   555                 {
       
   556                 if ( aMessage.Length() != 3 )
       
   557                     {
       
   558                     User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   559                             KErrDescrInvalidFormatArgs ) );
       
   560                     }
       
   561                 else
       
   562                     {
       
   563                     HandleFormat( aMessage[1], aMessage[2] );
       
   564                     }
       
   565                 }
       
   566                 break;
       
   567             case EFtpLISTDRIVES:
       
   568             case EFtpLISTDRIVES_u:
       
   569                 {
       
   570                 if ( aMessage.Length() != 1 )
       
   571                     {
       
   572                     User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   573                         KErrDescrInvalidDriveListArgs ) );
       
   574                     }
       
   575                 else
       
   576                     {
       
   577                     HandleListDrivesL( unicode );
       
   578                     }
       
   579                 }
       
   580                 break;
       
   581             case EFtpRENAME:
       
   582             case EFtpRENAME_u:
       
   583                 {
       
   584                 HandleRenameL( aMessage, unicode );
       
   585                 }
       
   586                 break;
       
   587             case EFtpCOPY:
       
   588             case EFtpCOPY_u:
       
   589                 {
       
   590                 HandleCopyL( aMessage, unicode );
       
   591                 }
       
   592                 break;
       
   593             case EFtpMOVE:
       
   594             case EFtpMOVE_u:
       
   595                 {
       
   596                 HandleMoveL( aMessage, unicode );
       
   597                 }
       
   598                 break;
       
   599             default:
       
   600                 {
       
   601                 //Error: unknown command
       
   602                 User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   603                                                 KErrDescrUnknownCmd ) );
       
   604                 }
       
   605             }
       
   606         }
       
   607     else
       
   608         {
       
   609         //error: empty request
       
   610         User::LeaveIfError( SendErrorMsg( KErrArgument, KErrDescrUnknownCmd ) );
       
   611         }
       
   612     }
       
   613 
       
   614 void CHtiFtpServicePlugin::HandleDeleteL( const TDesC& aFilename )
       
   615     {
       
   616     HTI_LOG_FUNC_IN( "CHtiFtpServicePlugin::HandleDeleteL" );
       
   617     delete iHandlerAO;
       
   618     iHandlerAO = NULL;
       
   619 
       
   620     iHandlerAO = new(ELeave) CFtpHandlerAO( this );
       
   621     TInt err = iFileMan->Delete( aFilename, 0, iHandlerAO->iStatus );
       
   622     if ( err == KErrNone)
       
   623         {
       
   624         iState = EDeleBusy;
       
   625         iHandlerAO->Start();
       
   626         }
       
   627     else
       
   628         {
       
   629         HTI_LOG_FORMAT( "Delete failed %d", err );
       
   630         delete iHandlerAO;
       
   631         iHandlerAO = NULL;
       
   632         User::LeaveIfError( SendErrorMsg( err,
       
   633                                     KErrDescrFailedDeleFile ) );
       
   634         }
       
   635     HTI_LOG_FUNC_OUT( "CHtiFtpServicePlugin::HandleDeleteL" );
       
   636     }
       
   637 
       
   638 void CHtiFtpServicePlugin::HandleRenameL( const TDesC8& aMessage, TBool aUnicode )
       
   639     {
       
   640     delete iHandlerAO;
       
   641     iHandlerAO = NULL;
       
   642 
       
   643     TInt originalLenngth = aMessage[1];
       
   644 
       
   645     GetFileNameL( aMessage.Mid( 1, originalLenngth + 1 ), aUnicode );
       
   646 
       
   647     //If last character is back slash remove it
       
   648     RemoveEndBackslash(iFileName);
       
   649 
       
   650     TFileName origName = iFileName;
       
   651 
       
   652     TInt newNamePos = originalLenngth + 2 ;
       
   653     TInt newNameLength = aMessage[newNamePos];
       
   654     GetFileNameL( aMessage.Mid( newNamePos, newNameLength + 1 ), aUnicode );
       
   655 
       
   656     RemoveEndBackslash( iFileName );
       
   657 
       
   658     if ( IsFileTcb( origName ) || IsFileTcb( iFileName ) )
       
   659         {
       
   660         HandleTcbRenameL( origName, iFileName );
       
   661         }
       
   662     else
       
   663         {
       
   664         iHandlerAO = new ( ELeave ) CFtpHandlerAO( this );
       
   665         TInt err = iFileMan->Rename( origName, iFileName,
       
   666                     CFileMan::EOverWrite, iHandlerAO->iStatus );
       
   667 
       
   668         if ( err == KErrNone )
       
   669             {
       
   670             iState = ERenameBusy;
       
   671             iHandlerAO->Start();
       
   672             }
       
   673         else
       
   674             {
       
   675             HTI_LOG_FORMAT( "Rename failed %d", err );
       
   676             delete iHandlerAO;
       
   677             iHandlerAO = NULL;
       
   678             User::LeaveIfError( SendErrorMsg(
       
   679                     err, KErrDescrFailedRenameFile ) );
       
   680             }
       
   681         }
       
   682 
       
   683     }
       
   684 
       
   685 void CHtiFtpServicePlugin::RemoveEndBackslash( TFileName& aFileName  )
       
   686     {
       
   687     //If last character is back slash remove it
       
   688     if ( aFileName.Right( 1 ) == KBackslash )
       
   689         {
       
   690         aFileName.Delete( aFileName.Length() - 1, 1 );
       
   691         }
       
   692     }
       
   693 
       
   694 void CHtiFtpServicePlugin::HandleCopyL( const TDesC8& aMessage, TBool aUnicode )
       
   695     {
       
   696     delete iHandlerAO;
       
   697     iHandlerAO = NULL;
       
   698 
       
   699     TInt originalLenngth = aMessage[1];
       
   700 
       
   701     GetFileNameL( aMessage.Mid( 1, originalLenngth + 1 ), aUnicode );
       
   702     TFileName origName = iFileName;
       
   703 
       
   704     TInt newNamePos = originalLenngth + 2 ;
       
   705     TInt newNameLength = aMessage[newNamePos];
       
   706     GetFileNameL( aMessage.Mid( newNamePos, newNameLength + 1 ), aUnicode );
       
   707 
       
   708     TInt msglen = aMessage.Length();
       
   709     TInt recurse = 1;
       
   710     if(msglen>originalLenngth+newNameLength+3)        
       
   711         {
       
   712         recurse = aMessage[newNamePos+1+newNameLength];
       
   713         }
       
   714     
       
   715     TInt err=0;
       
   716     if ( IsFileTcb( origName ) || IsFileTcb( iFileName ) )
       
   717         {
       
   718         HandleTcbCopyL( origName, iFileName );
       
   719         }
       
   720     else{
       
   721         iHandlerAO = new ( ELeave ) CFtpHandlerAO( this );
       
   722         
       
   723         if (recurse)
       
   724             {
       
   725             err = iFileMan->Copy( origName, iFileName,
       
   726                 ( CFileMan::EOverWrite | CFileMan::ERecurse ),
       
   727                 iHandlerAO->iStatus );
       
   728             }
       
   729         else
       
   730             {
       
   731             err = iFileMan->Copy( origName, iFileName,
       
   732                 ( CFileMan::EOverWrite ),
       
   733                 iHandlerAO->iStatus );
       
   734             }
       
   735 
       
   736         if ( err == KErrNone)
       
   737             {
       
   738             iState = ECopyBusy;
       
   739             iHandlerAO->Start();
       
   740             }
       
   741         else
       
   742             {
       
   743             HTI_LOG_FORMAT( "Rename failed %d", err );
       
   744             delete iHandlerAO;
       
   745             iHandlerAO = NULL;
       
   746             User::LeaveIfError( SendErrorMsg( err,
       
   747                                         KErrDescrFailedCopyFile ) );
       
   748             }
       
   749         }
       
   750     }
       
   751 
       
   752 void CHtiFtpServicePlugin::HandleMoveL( const TDesC8& aMessage, TBool aUnicode )
       
   753     {
       
   754     delete iHandlerAO;
       
   755     iHandlerAO = NULL;
       
   756 
       
   757     TInt originalLenngth = aMessage[1];
       
   758 
       
   759     GetFileNameL( aMessage.Mid( 1, originalLenngth + 1 ), aUnicode );
       
   760 
       
   761     RemoveEndBackslash( iFileName );
       
   762 
       
   763     TFileName origName = iFileName;
       
   764 
       
   765     TInt newNamePos = originalLenngth + 2 ;
       
   766     TInt newNameLength = aMessage[newNamePos];
       
   767     GetFileNameL( aMessage.Mid( newNamePos, newNameLength + 1 ), aUnicode );
       
   768     // make sure destination ends with backslash - destination always directory
       
   769     if ( iFileName.Right( 1 ) != KBackslash )
       
   770         {
       
   771         iFileName.Append( KBackslash );
       
   772         }
       
   773 
       
   774     if ( IsFileTcb( origName ) || IsFileTcb( iFileName ) )
       
   775         {
       
   776         HandleTcbMoveL( origName, iFileName );
       
   777         }
       
   778     else
       
   779         {
       
   780         iHandlerAO = new ( ELeave ) CFtpHandlerAO( this );
       
   781         TInt err = iFileMan->Move( origName, iFileName,
       
   782                 ( CFileMan::EOverWrite | CFileMan::ERecurse ),
       
   783                 iHandlerAO->iStatus );
       
   784 
       
   785         if ( err == KErrNone )
       
   786             {
       
   787             iState = EMoveBusy;
       
   788             iHandlerAO->Start();
       
   789             }
       
   790         else
       
   791             {
       
   792             HTI_LOG_FORMAT( "Move failed %d", err );
       
   793             delete iHandlerAO;
       
   794             iHandlerAO = NULL;
       
   795             User::LeaveIfError( SendErrorMsg( err,
       
   796                                         KErrDescrFailedMoveFile ) );
       
   797             }
       
   798         }
       
   799     }
       
   800 
       
   801 void CHtiFtpServicePlugin::HandleCancelL(const TDesC8& aMessage)
       
   802     {
       
   803 
       
   804     if ( aMessage.Length()>0 )
       
   805         {
       
   806         HTI_LOG_FORMAT("cmd %d", aMessage[0]);
       
   807 
       
   808         if ( aMessage[0] == EFtpCANCEL )
       
   809             {
       
   810             //handle cancel
       
   811             iFile.Close();
       
   812 
       
   813             if ( iState == EStorWait )
       
   814                 {
       
   815                 iFs.Delete(iFileName);
       
   816                 }
       
   817             else if ( iState == ERetrWait )
       
   818                 {
       
   819                 iDispatcher->RemoveMemoryObserver(this);
       
   820 
       
   821                 delete iSendBuffer;
       
   822                 iSendBuffer = NULL;
       
   823                 }
       
   824             //other states filtered out before
       
   825 
       
   826             delete iHandlerAO;
       
   827             iHandlerAO = NULL;
       
   828 
       
   829             iState = EIdle;
       
   830 
       
   831             User::LeaveIfError( SendControlMsg( EFtpOK, KNullDesC8) );
       
   832             }
       
   833         else
       
   834             {
       
   835             User::LeaveIfError( SendErrorMsg( KErrServerBusy,
       
   836                             KErrDescrBusy) );
       
   837             }
       
   838         }
       
   839     else
       
   840         {
       
   841         //send err
       
   842         User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   843                             KErrDescrUnknownCmd ) );
       
   844         }
       
   845     }
       
   846 
       
   847 void CHtiFtpServicePlugin::CopyUnicode( TDes& aTo, const TDesC8& aFrom )
       
   848 {
       
   849     HTI_LOG_FUNC_IN("CHtiFtpServicePlugin::CopyUnicode");
       
   850     TInt len = aFrom.Length()>>1;
       
   851     aTo.SetLength( len );
       
   852     for ( TInt i = 0; i < len; ++i )
       
   853     {
       
   854         aTo[i] = (TUint16)aFrom[i<<1] + (((TUint16)aFrom[(i<<1)+1])<<8);
       
   855     }
       
   856     HTI_LOG_FUNC_OUT("CHtiFtpServicePlugin::CopyUnicode");
       
   857 }
       
   858 
       
   859 TBool CHtiFtpServicePlugin::GetFileNameL( const TDesC8& aFilename,
       
   860                                           TBool aToUnicode )
       
   861     {
       
   862     HTI_LOG_FUNC_IN("CHtiFtpServicePlugin::GetFileNameL");
       
   863     if ( aFilename.Length() > 1 )
       
   864         {
       
   865         TInt length = aFilename[0];
       
   866         TInt size = aToUnicode ? ( length * 2 ) : length;
       
   867 
       
   868         if ( ( size + 1 ) == aFilename.Size() )
       
   869             {
       
   870             if ( aToUnicode )
       
   871                 {
       
   872                 //const TPtrC8 ptr = aFilename.Mid(1).Ptr();
       
   873                 //iFileName.Copy( (TUint16*)ptr, len );
       
   874                 CopyUnicode( iFileName, aFilename.Mid( 1 ) );
       
   875                 }
       
   876             else
       
   877                 {
       
   878                 iFileName.Copy( aFilename.Mid( 1, length ) );
       
   879                 }
       
   880 
       
   881             HTI_LOG_TEXT( "filename:" );
       
   882             HTI_LOG_DES( iFileName );
       
   883             return ETrue;
       
   884             }
       
   885         else
       
   886             {
       
   887             User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   888                                               KErrDescrInvalidFilenameLength ) );
       
   889             }
       
   890         }
       
   891     else
       
   892         {
       
   893         User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   894                                           KErrDescrEmptyFilename ) );
       
   895         }
       
   896 
       
   897     HTI_LOG_FUNC_OUT("CHtiFtpServicePlugin::GetFileNameL");
       
   898     return EFalse;
       
   899     }
       
   900 
       
   901 TBool CHtiFtpServicePlugin::GetDirectoryL( const TDesC8& aDirname,
       
   902                                            TBool aToUnicode )
       
   903     {
       
   904     HTI_LOG_FUNC_IN("CHtiFtpServicePlugin::GetDirectoryL");
       
   905     if ( aDirname.Length() > 1 )
       
   906         {
       
   907         TInt len = aDirname[0];
       
   908         TInt size = aToUnicode ? ( len * 2 ) : len;
       
   909         if ( ( size + 1 ) == aDirname.Size() )
       
   910             {
       
   911             if ( aToUnicode )
       
   912                 {
       
   913                 //const TUint8* ptr = aDirname.Mid(1).Ptr();
       
   914                 //iFileName.Copy( (TUint16*)ptr, len );
       
   915                 CopyUnicode( iFileName, aDirname.Mid(1) );
       
   916                 }
       
   917             else
       
   918                 {
       
   919                 iFileName.Copy( aDirname.Mid( 1, len ) );
       
   920                 }
       
   921 
       
   922             HTI_LOG_TEXT( "dir:" );
       
   923             HTI_LOG_DES( iFileName );
       
   924             if ( iFileName.Right( 1 ) != KBackslash )
       
   925                 {
       
   926                 iFileName.Append( KBackslash );
       
   927                 }
       
   928             HTI_LOG_FUNC_OUT("CHtiFtpServicePlugin::GetDirectoryL");
       
   929             return ETrue;
       
   930             }
       
   931         else
       
   932             {
       
   933             User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   934                                               KErrDescrInvalidDirnameLength ) );
       
   935             }
       
   936         }
       
   937     else
       
   938         {
       
   939         User::LeaveIfError( SendErrorMsg( KErrArgument,
       
   940                                           KErrDescrEmptyDirname ) );
       
   941         }
       
   942 
       
   943     HTI_LOG_FUNC_OUT("CHtiFtpServicePlugin::GetDirectoryL");
       
   944     return EFalse;
       
   945     }
       
   946 
       
   947 void CHtiFtpServicePlugin::HandleListL( TBool aUnicodText,
       
   948                                         TUint aReadingAtt, TBool aSizes )
       
   949     {
       
   950     HTI_LOG_FUNC_IN("HandleListL");
       
   951     CDir* dir;
       
   952     TInt err = iFs.GetDir( iFileName, aReadingAtt, ESortNone, dir );
       
   953     if ( err != KErrNone )
       
   954         {
       
   955         User::LeaveIfError( SendErrorMsg( err, KErrDescrFailedGetDir ) );
       
   956         return;
       
   957         }
       
   958 
       
   959     CleanupStack::PushL( dir );
       
   960     //build list
       
   961     delete iSendBuffer;
       
   962     iSendBuffer = NULL;
       
   963     TInt bufferLen = dir->Count()*KMaxFileName;
       
   964     if ( aUnicodText )
       
   965         {
       
   966         bufferLen *= 2;
       
   967         }
       
   968     bufferLen += dir->Count();
       
   969     if ( aSizes )
       
   970         {
       
   971         bufferLen += 4 * dir->Count();
       
   972         }
       
   973 
       
   974     iSendBuffer = HBufC8::NewL( bufferLen );
       
   975     TInt dirNameLen = 0;
       
   976     for ( TInt i = 0; i < dir->Count(); ++i)
       
   977         {
       
   978         dirNameLen = (*dir)[i].iName.Length();
       
   979         iSendBuffer->Des().Append( dirNameLen );
       
   980         if ( aUnicodText )
       
   981             {
       
   982             iSendBuffer->Des().Append( (TUint8*)((*dir)[i].iName.Ptr()),
       
   983                                        dirNameLen*2 );
       
   984             }
       
   985         else
       
   986             {
       
   987             iSendBuffer->Des().Append( (*dir)[i].iName );
       
   988             }
       
   989         if ( aSizes )
       
   990             {
       
   991             TInt size = (*dir)[i].iSize;
       
   992             iSendBuffer->Des().Append( (TUint8*)(&size), 4 );
       
   993             }
       
   994         }
       
   995 
       
   996     err = iDispatcher->DispatchOutgoingMessage(iSendBuffer,
       
   997                         KFtpServiceUid,
       
   998                         EFalse,
       
   999                         EHtiPriorityControl);
       
  1000 
       
  1001     if (  err != KErrNone )
       
  1002         {
       
  1003         //wait for a memory
       
  1004         iState = EListBusy;
       
  1005         iDispatcher->AddMemoryObserver( this );
       
  1006         }
       
  1007     else
       
  1008         {
       
  1009         iSendBuffer = NULL;
       
  1010         }
       
  1011 
       
  1012     CleanupStack::PopAndDestroy();//dir
       
  1013     HTI_LOG_FUNC_OUT("HandleListL");
       
  1014     }
       
  1015 
       
  1016 void CHtiFtpServicePlugin::HandleListDetailL( TBool aUnicodText, TUint aReadingAtt)
       
  1017     {
       
  1018     HTI_LOG_FUNC_IN("HandleListDetailL");
       
  1019     CDir* dir;
       
  1020     TInt err = iFs.GetDir( iFileName, aReadingAtt, ESortNone, dir );
       
  1021     if ( err != KErrNone )
       
  1022         {
       
  1023         User::LeaveIfError( SendErrorMsg( err, KErrDescrFailedGetDir ) );
       
  1024         return;
       
  1025         }
       
  1026 
       
  1027     CleanupStack::PushL( dir );
       
  1028     //build list
       
  1029     delete iSendBuffer;
       
  1030     iSendBuffer = NULL;
       
  1031     TInt bufferLen = dir->Count()*KMaxFileName;
       
  1032     if ( aUnicodText )
       
  1033         {
       
  1034         bufferLen *= 2;
       
  1035         }
       
  1036     // 1 bytes for name length, 4 bytes for file size, 
       
  1037     // 6 bytes for date time, 3 bytes for attributes(hide, readonly and system)
       
  1038     bufferLen += (1 + 4 + 6 + 3) * dir->Count();
       
  1039 
       
  1040     iSendBuffer = HBufC8::NewL( bufferLen );
       
  1041     TInt dirNameLen = 0;
       
  1042     for ( TInt i = 0; i < dir->Count(); ++i)
       
  1043         {
       
  1044         dirNameLen = (*dir)[i].iName.Length();
       
  1045         iSendBuffer->Des().Append( dirNameLen );
       
  1046         if ( aUnicodText )
       
  1047             {
       
  1048             iSendBuffer->Des().Append( (TUint8*)((*dir)[i].iName.Ptr()),
       
  1049                                        dirNameLen*2 );
       
  1050             }
       
  1051         else
       
  1052             {
       
  1053             iSendBuffer->Des().Append( (*dir)[i].iName );
       
  1054             }
       
  1055         TInt year = (*dir)[i].iModified.DateTime().Year();
       
  1056         iSendBuffer->Des().Append((TUint8*)(&year), 2 );
       
  1057         iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Month()+1);
       
  1058         iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Day()+1);
       
  1059         iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Hour());
       
  1060         iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Minute());
       
  1061         iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Second());
       
  1062         iSendBuffer->Des().Append( (*dir)[i].IsHidden());
       
  1063         iSendBuffer->Des().Append( (*dir)[i].IsReadOnly());
       
  1064         iSendBuffer->Des().Append( (*dir)[i].IsSystem());
       
  1065         if((*dir)[i].IsDir() == EFalse)
       
  1066             {
       
  1067             TInt size = (*dir)[i].iSize;
       
  1068             iSendBuffer->Des().Append( (TUint8*)(&size), 4 );
       
  1069             }
       
  1070         }
       
  1071 
       
  1072     err = iDispatcher->DispatchOutgoingMessage(iSendBuffer,
       
  1073                         KFtpServiceUid,
       
  1074                         EFalse,
       
  1075                         EHtiPriorityControl);
       
  1076 
       
  1077     if (  err != KErrNone )
       
  1078         {
       
  1079         //wait for a memory
       
  1080         iState = EListBusy;
       
  1081         iDispatcher->AddMemoryObserver( this );
       
  1082         }
       
  1083     else
       
  1084         {
       
  1085         iSendBuffer = NULL;
       
  1086         }
       
  1087 
       
  1088     CleanupStack::PopAndDestroy();//dir
       
  1089     HTI_LOG_FUNC_OUT("HandleListDetailL");
       
  1090     }
       
  1091 
       
  1092 void CHtiFtpServicePlugin::HandleDataMessageL( const TDesC8& aMessage )
       
  1093     {
       
  1094     switch ( iState )
       
  1095         {
       
  1096         case EStorWait:
       
  1097             {
       
  1098             iState = EStorBusy;
       
  1099             iCurrentOffset += aMessage.Size();
       
  1100 
       
  1101             TInt anError = iFile.Write( aMessage );
       
  1102             if ( anError == KErrNone  )
       
  1103                 {
       
  1104                 HTI_LOG_FORMAT("received %d", iCurrentOffset);
       
  1105                 if ( iCurrentOffset == iFileSize )
       
  1106                     {
       
  1107                     HTI_LOG_TEXT("receiving is over");
       
  1108                     //receiving is over
       
  1109                     TInt err = iFile.Flush();
       
  1110                     iFile.Close();
       
  1111                     iState = EIdle;
       
  1112                     if ( err != KErrNone )
       
  1113                         {
       
  1114                         //err
       
  1115                         HTI_LOG_TEXT("failed to close file");
       
  1116                         iFs.Delete(iFileName);
       
  1117                         SendErrorMsg( err, KErrDescrFailedCloseFile );
       
  1118                         }
       
  1119                     else
       
  1120                         {
       
  1121                         //if file should be copied to TCB
       
  1122                         //copy it to to TCB from temp location
       
  1123                         if ( IsFileTcb( iFileName ) )
       
  1124                             {
       
  1125                             HandleTcbCopyL( KTmpFileName, iFileName );
       
  1126                             }
       
  1127                         else
       
  1128                             {
       
  1129                             SetBURFakeState( EFalse );
       
  1130                             SendControlMsg( EFtpOK, KNullDesC8 );
       
  1131                             }
       
  1132                         }
       
  1133                     }
       
  1134                 else
       
  1135                     {
       
  1136                     iState = EStorWait;
       
  1137                     }
       
  1138                 }
       
  1139             else
       
  1140                 {
       
  1141                 HTI_LOG_FORMAT("error writing file %d", anError);
       
  1142                 //abort operation and send err msg
       
  1143 
       
  1144                 iFile.Close();
       
  1145                 iFs.Delete(iFileName);
       
  1146                 iState = EIdle;
       
  1147                 SendErrorMsg( anError, KErrDescrFailedWrite );
       
  1148                 }
       
  1149             }
       
  1150             break;
       
  1151         default:
       
  1152             //do nothing
       
  1153             User::LeaveIfError( SendErrorMsg( KErrArgument,
       
  1154                                               KErrDescrInvalidDataMessage ) );
       
  1155             break;
       
  1156         }
       
  1157     }
       
  1158 
       
  1159 void CHtiFtpServicePlugin::HandleReceiveFileL()
       
  1160     {
       
  1161     HTI_LOG_FUNC_IN("HandleReceiveFileL");
       
  1162 
       
  1163     // create file
       
  1164     TInt err = KErrNone;
       
  1165 
       
  1166     //if file should be copied to TCB
       
  1167     //first copy it to temp location
       
  1168     if ( IsFileTcb( iFileName ) )
       
  1169         {
       
  1170         err = iFile.Replace( iFs, KTmpFileName, EFileWrite );
       
  1171         }
       
  1172         else
       
  1173         {
       
  1174         err = iFile.Replace(
       
  1175             iFs, iFileName, EFileWrite | EFileShareExclusive );
       
  1176         }
       
  1177 
       
  1178     if ( err != KErrNone )
       
  1179         {
       
  1180         err = iFile.Replace(
       
  1181             iFs, iFileName, EFileWrite | EFileShareAny );
       
  1182         }
       
  1183 
       
  1184     if ( err != KErrNone )
       
  1185         {
       
  1186         err = iFile.Replace(
       
  1187             iFs, iFileName, EFileWrite | EFileShareReadersOrWriters );
       
  1188         }
       
  1189 
       
  1190     if ( err != KErrNone )
       
  1191         {
       
  1192         if ( SetBURFakeState( ETrue ) == KErrNone )
       
  1193             {
       
  1194             err = iFile.Replace(
       
  1195                 iFs, iFileName, EFileWrite | EFileShareExclusive );
       
  1196             }
       
  1197         }
       
  1198 
       
  1199     if ( err != KErrNone )
       
  1200         {
       
  1201         HTI_LOG_TEXT("failed create file");
       
  1202         SendErrorMsg( err, KErrDescrFailedCreateFile );
       
  1203         return;
       
  1204         }
       
  1205 
       
  1206     //check that there is enough disk space
       
  1207     err = iFile.SetSize( iFileSize );
       
  1208     if ( err != KErrNone )
       
  1209         {
       
  1210         HTI_LOG_TEXT("not enough space");
       
  1211         SendErrorMsg( err, KErrDescrNoSpace );
       
  1212         iFile.Close();
       
  1213         iFs.Delete( iFileName );
       
  1214         return;
       
  1215         }
       
  1216 
       
  1217     // init receiving byte counter
       
  1218     iCurrentOffset = 0;
       
  1219     iState = EStorWait;
       
  1220 
       
  1221     //send ok and
       
  1222     User::LeaveIfError( SendControlMsg( EFtpOK, KNullDesC8 ) );
       
  1223     //...wait for data messages
       
  1224     HTI_LOG_FUNC_OUT("HandleReceiveFileL");
       
  1225     }
       
  1226 
       
  1227 void CHtiFtpServicePlugin::HandleSendFileL()
       
  1228     {
       
  1229     //open it
       
  1230     TInt err = iFile.Open( iFs, iFileName, EFileRead | EFileShareAny );
       
  1231 
       
  1232     if ( err != KErrNone )
       
  1233         {
       
  1234         err = iFile.Open( iFs, iFileName, EFileRead | EFileShareReadersOnly );
       
  1235         }
       
  1236 
       
  1237     if ( err != KErrNone )
       
  1238         {
       
  1239         err = iFile.Open( iFs, iFileName, EFileRead | EFileShareReadersOrWriters );
       
  1240         }
       
  1241 
       
  1242     if ( err != KErrNone )
       
  1243         {
       
  1244         if ( SetBURFakeState( ETrue ) == KErrNone )
       
  1245             {
       
  1246             err = iFile.Open(
       
  1247                 iFs, iFileName, EFileRead | EFileShareReadersOnly );
       
  1248             }
       
  1249         }
       
  1250 
       
  1251     if ( err != KErrNone )
       
  1252         {
       
  1253         HTI_LOG_FORMAT("failed open file %d", err);
       
  1254         SendErrorMsg( err, KErrDescrFailedOpenFile );
       
  1255         return;
       
  1256         }
       
  1257 
       
  1258     //send file size
       
  1259     err = iFile.Size( iFileSize );
       
  1260     if ( err != KErrNone )
       
  1261         {
       
  1262         HTI_LOG_TEXT("failed get filesize");
       
  1263         User::LeaveIfError( SendErrorMsg( err, KErrDescrFailedOpenFile ) );
       
  1264         }
       
  1265 
       
  1266     TBuf8<KFileSizeMsgSize> fileSizeMsg;
       
  1267     fileSizeMsg.Append( (TUint8*)(&iFileSize), 4 );
       
  1268     User::LeaveIfError( SendControlMsg( EFtpFILESIZE, fileSizeMsg ) );
       
  1269 
       
  1270     iCurrentOffset = 0;
       
  1271     //start sending
       
  1272     //always observe when sending
       
  1273     iDispatcher->AddMemoryObserver( this );
       
  1274 
       
  1275     //create handler for following RFile::Write
       
  1276     delete iHandlerAO;
       
  1277     iHandlerAO = NULL;
       
  1278     iHandlerAO = new(ELeave) CFtpHandlerAO( this );
       
  1279 
       
  1280     //start operation
       
  1281     ReadToBuffer();
       
  1282     }
       
  1283 
       
  1284 void CHtiFtpServicePlugin::ReadToBuffer()
       
  1285     {
       
  1286     HTI_LOG_FUNC_IN("ReadToBuffer");
       
  1287     //check that iHandlerAO valid
       
  1288     if ( iHandlerAO )
       
  1289         {
       
  1290         if ( !iHandlerAO->IsActive() )
       
  1291             {
       
  1292             //dispatch messages in the outgoing queue until run out of memory
       
  1293             TInt err;
       
  1294             //allocate memory and read from file
       
  1295             delete iSendBuffer;
       
  1296             iSendBuffer = NULL;
       
  1297 
       
  1298             TRAP( err, iSendBuffer = HBufC8::NewL( iBufferSize ) );
       
  1299             if ( err == KErrNone )
       
  1300                 {
       
  1301                 HTI_LOG_TEXT("read file");
       
  1302                 iState = ERetrBusy;
       
  1303                 iSendBufferDes.Set( iSendBuffer->Des() );
       
  1304                 iFile.Read( iSendBufferDes, iHandlerAO->iStatus  );
       
  1305                 iHandlerAO->Start();
       
  1306                 }
       
  1307             else
       
  1308                 {
       
  1309                 //go to idle state
       
  1310                 HTI_LOG_TEXT("impossible to alloc mem");
       
  1311                 iDispatcher->RemoveMemoryObserver( this );
       
  1312 
       
  1313                 delete iHandlerAO;
       
  1314                 iHandlerAO = NULL;
       
  1315 
       
  1316                 iFile.Close();
       
  1317                 iState = EIdle;
       
  1318                 //try to send err message
       
  1319                 SendErrorMsg( KErrNoMemory, KErrDescrNoMemory );
       
  1320                 }
       
  1321             }
       
  1322         else
       
  1323             {
       
  1324             //error, ignore
       
  1325             HTI_LOG_TEXT("ERROR: Call ReadBuffer with active handler");
       
  1326             }
       
  1327         }
       
  1328     else
       
  1329         {
       
  1330         //error
       
  1331         HTI_LOG_TEXT("ERROR: Call ReadBuffer with no handler");
       
  1332         //go to idle
       
  1333         iState = EIdle;
       
  1334         }
       
  1335     HTI_LOG_FUNC_OUT("ReadToBuffer");
       
  1336     }
       
  1337 
       
  1338 void CHtiFtpServicePlugin::SendBuffer()
       
  1339     {
       
  1340     HTI_LOG_FUNC_IN("SendBuffer");
       
  1341     if ( iSendBuffer )
       
  1342         {
       
  1343         HTI_LOG_FORMAT("iCurrentOffset %d bytes", iCurrentOffset);
       
  1344         //send buffer
       
  1345         TInt err = iDispatcher->DispatchOutgoingMessage( iSendBuffer,
       
  1346                         KFtpServiceUid,
       
  1347                         EFalse,
       
  1348                         EHtiPriorityData);
       
  1349 
       
  1350         if ( err == KErrNone )
       
  1351             {
       
  1352             HTI_LOG_TEXT("message was dispatched");
       
  1353             //message was dispatched
       
  1354             iSendBuffer = NULL;
       
  1355             //check do we have to continue
       
  1356             if ( iCurrentOffset >= iFileSize )
       
  1357                 {
       
  1358                 HTI_LOG_TEXT( "over sending" );
       
  1359 
       
  1360                 delete iHandlerAO;
       
  1361                 iHandlerAO = NULL;
       
  1362 
       
  1363                 iFile.Close();
       
  1364                 iState = EIdle;
       
  1365 
       
  1366                 iDispatcher->RemoveMemoryObserver( this );
       
  1367                 SetBURFakeState( EFalse );
       
  1368                 }
       
  1369             else
       
  1370                 {
       
  1371                 //read and send next package
       
  1372                 ReadToBuffer();
       
  1373                 }
       
  1374             }
       
  1375         else if ( err == KErrNoMemory )
       
  1376             {
       
  1377             //wait for memory
       
  1378             //observer should be active
       
  1379             iState = ERetrWait;
       
  1380             }
       
  1381         else if ( err != KErrNone )
       
  1382             {
       
  1383             HTI_LOG_FORMAT("error dispatching outgoing message %d", err );
       
  1384             //some err, abort operation
       
  1385             delete iSendBuffer;
       
  1386             iSendBuffer = NULL;
       
  1387 
       
  1388             delete iHandlerAO;
       
  1389             iHandlerAO = NULL;
       
  1390 
       
  1391             iFile.Close();
       
  1392 
       
  1393             iState = EIdle;
       
  1394 
       
  1395             iDispatcher->RemoveMemoryObserver( this );
       
  1396             SetBURFakeState( EFalse );
       
  1397             }
       
  1398         }
       
  1399     else
       
  1400         {
       
  1401         //really weird error, go to idle
       
  1402         HTI_LOG_TEXT("ERROR: SendBuffer with empty iSendBuffer");
       
  1403         iState = EIdle;
       
  1404         SetBURFakeState( EFalse );
       
  1405         }
       
  1406     HTI_LOG_FUNC_OUT("SendBuffer");
       
  1407     }
       
  1408 
       
  1409 void CHtiFtpServicePlugin::FtpComplete( TInt anError)
       
  1410     {
       
  1411     HTI_LOG_FUNC_IN("FtpComplete");
       
  1412     HTI_LOG_FORMAT("error %d", anError);
       
  1413 
       
  1414     //NOTE: can't leave from here
       
  1415     switch ( iState )
       
  1416         {
       
  1417         case ERmdBusy:
       
  1418             {
       
  1419             //send OK message
       
  1420             if ( anError == KErrNone )
       
  1421                 {
       
  1422                 SendControlMsg( EFtpOK, KNullDesC8 );
       
  1423                 }
       
  1424             else
       
  1425                 {
       
  1426                 SendErrorMsg( anError, KErrDescrFailedRmDir );
       
  1427                 }
       
  1428             delete iHandlerAO;
       
  1429             iHandlerAO = NULL;
       
  1430 
       
  1431             iState = EIdle;
       
  1432             }
       
  1433             break;
       
  1434         case EDeleBusy:
       
  1435             {
       
  1436             //send OK message
       
  1437             if ( anError == KErrNone )
       
  1438                 {
       
  1439                 SetBURFakeState( EFalse );
       
  1440                 SendControlMsg( EFtpOK, KNullDesC8 );
       
  1441                 }
       
  1442             else
       
  1443                 {
       
  1444                 if ( SetBURFakeState( ETrue ) != KErrNone )
       
  1445                     {
       
  1446                     // Force was not requested, not supported OR already tried.
       
  1447                     SendErrorMsg( anError, KErrDescrFailedDeleFile );
       
  1448                     }
       
  1449                 else
       
  1450                     {
       
  1451                     // try delete again
       
  1452                     TRAPD( err, HandleDeleteL( iFileName ) );
       
  1453                     if ( err == KErrNone )
       
  1454                         {
       
  1455                         break;
       
  1456                         }
       
  1457                     else
       
  1458                         {
       
  1459                         SendErrorMsg( err, KErrDescrFailedDeleFile );
       
  1460                         }
       
  1461                     }
       
  1462                 }
       
  1463             delete iHandlerAO;
       
  1464             iHandlerAO = NULL;
       
  1465 
       
  1466             iState = EIdle;
       
  1467             }
       
  1468             break;
       
  1469         case ERenameBusy:
       
  1470             {
       
  1471             //send OK message
       
  1472             if ( anError == KErrNone )
       
  1473                 {
       
  1474                 SetBURFakeState( EFalse );
       
  1475                 SendControlMsg( EFtpOK, KNullDesC8 );
       
  1476                 }
       
  1477             else
       
  1478                 {
       
  1479                 SendErrorMsg( anError, KErrDescrFailedRenameFile );
       
  1480                 }
       
  1481 
       
  1482             delete iHandlerAO;
       
  1483             iHandlerAO = NULL;
       
  1484 
       
  1485             iState = EIdle;
       
  1486             }
       
  1487             break;
       
  1488         case ECopyBusy:
       
  1489             {
       
  1490             //send OK message
       
  1491             if ( anError == KErrNone )
       
  1492                 {
       
  1493                 SetBURFakeState( EFalse );
       
  1494                 SendControlMsg( EFtpOK, KNullDesC8 );
       
  1495                 }
       
  1496             else
       
  1497                 {
       
  1498                 SendErrorMsg( anError, KErrDescrFailedCopyFile );
       
  1499                 }
       
  1500 
       
  1501             delete iHandlerAO;
       
  1502             iHandlerAO = NULL;
       
  1503 
       
  1504             iState = EIdle;
       
  1505             }
       
  1506             break;
       
  1507         case EMoveBusy:
       
  1508             {
       
  1509             //send OK message
       
  1510             if ( anError == KErrNone )
       
  1511                 {
       
  1512                 SetBURFakeState( EFalse );
       
  1513                 SendControlMsg( EFtpOK, KNullDesC8 );
       
  1514                 }
       
  1515             else
       
  1516                 {
       
  1517                 SendErrorMsg( anError, KErrDescrFailedMoveFile );
       
  1518                 }
       
  1519 
       
  1520             delete iHandlerAO;
       
  1521             iHandlerAO = NULL;
       
  1522 
       
  1523             iState = EIdle;
       
  1524             }
       
  1525             break;
       
  1526         case EMoveTcbBusy:
       
  1527             {
       
  1528             //send OK message
       
  1529             if ( anError == KErrNone )
       
  1530                 {
       
  1531                 SetBURFakeState( EFalse );
       
  1532                 SendControlMsg( EFtpOK, KNullDesC8 );
       
  1533                 }
       
  1534             else
       
  1535                 {
       
  1536                 SendErrorMsg( anError, KErrDescrFailedMoveFile );
       
  1537                 }
       
  1538 
       
  1539             delete iProcessLogonAO;
       
  1540             iProcessLogonAO = NULL;
       
  1541 
       
  1542             iState = EIdle;
       
  1543             }
       
  1544             break;
       
  1545         case ERenameTcbBusy:
       
  1546             {
       
  1547             //send OK message
       
  1548             if ( anError == KErrNone )
       
  1549                 {
       
  1550                 SetBURFakeState( EFalse );
       
  1551                 SendControlMsg( EFtpOK, KNullDesC8 );
       
  1552                 }
       
  1553             else
       
  1554                 {
       
  1555                 SendErrorMsg( anError, KErrDescrFailedRenameFile );
       
  1556                 }
       
  1557 
       
  1558             delete iProcessLogonAO;
       
  1559             iProcessLogonAO = NULL;
       
  1560 
       
  1561             iState = EIdle;
       
  1562             }
       
  1563             break;
       
  1564         case EDeleTcbBusy:
       
  1565             {
       
  1566             //send OK message
       
  1567             if ( anError == KErrNone )
       
  1568                 {
       
  1569                 SetBURFakeState( EFalse );
       
  1570                 SendControlMsg( EFtpOK, KNullDesC8 );
       
  1571                 }
       
  1572             else
       
  1573                 {
       
  1574                 if ( SetBURFakeState( ETrue ) != KErrNone )
       
  1575                     {
       
  1576                     // Force was not requested, not supported OR already tried.
       
  1577                     SendErrorMsg( anError, KErrDescrFailedDeleFile );
       
  1578                     }
       
  1579                 else
       
  1580                     {
       
  1581                      // try delete again
       
  1582                     TRAPD( err, HandleTcbDeleteL( iFileName ) );
       
  1583                     if ( err == KErrNone )
       
  1584                         {
       
  1585                         break;
       
  1586                         }
       
  1587                     else
       
  1588                         {
       
  1589                         SendErrorMsg( err, KErrDescrFailedDeleFile );
       
  1590                         }
       
  1591                     }
       
  1592                 }
       
  1593             delete iProcessLogonAO;
       
  1594             iProcessLogonAO = NULL;
       
  1595 
       
  1596             iState = EIdle;
       
  1597             }
       
  1598             break;
       
  1599         case EMkdTcbBusy:
       
  1600             {
       
  1601             if ( anError == KErrNone || anError == KErrAlreadyExists )
       
  1602                 {
       
  1603                 SendControlMsg( EFtpOK, KNullDesC8);
       
  1604                 }
       
  1605             else
       
  1606                 {
       
  1607                 SendErrorMsg( anError, KErrDescrFailedMkDir );
       
  1608                 }
       
  1609             delete iProcessLogonAO;
       
  1610             iProcessLogonAO = NULL;
       
  1611 
       
  1612             iState = EIdle;
       
  1613 
       
  1614             }
       
  1615             break;
       
  1616         case ERmdTcbBusy:
       
  1617             {
       
  1618             if ( anError == KErrNone || anError == KErrAlreadyExists )
       
  1619                 {
       
  1620                 SendControlMsg( EFtpOK, KNullDesC8);
       
  1621                 }
       
  1622             else
       
  1623                 {
       
  1624                 SendErrorMsg( anError, KErrDescrFailedRmDir );
       
  1625                 }
       
  1626             delete iProcessLogonAO;
       
  1627             iProcessLogonAO = NULL;
       
  1628 
       
  1629             iState = EIdle;
       
  1630 
       
  1631             }
       
  1632             break;
       
  1633 
       
  1634         case EStorBusy:
       
  1635             {
       
  1636             if ( anError == KErrNone  )
       
  1637                 {
       
  1638                 HTI_LOG_FORMAT("received %d", iCurrentOffset);
       
  1639                 if ( iCurrentOffset == iFileSize )
       
  1640                     {
       
  1641                     HTI_LOG_TEXT("receiveing is over");
       
  1642                     //receiveing is over
       
  1643                     delete iHandlerAO;
       
  1644                     iHandlerAO = NULL;
       
  1645 
       
  1646                     iState = EIdle;
       
  1647 
       
  1648                     TInt err = iFile.Flush();
       
  1649                     iFile.Close();
       
  1650                     if ( err != KErrNone )
       
  1651                         {
       
  1652                         //err
       
  1653                         HTI_LOG_TEXT("failed to close file");
       
  1654                         iFs.Delete(iFileName);
       
  1655                         SendErrorMsg( err, KErrDescrFailedCloseFile );
       
  1656                         }
       
  1657                     else
       
  1658                         {
       
  1659                         //if file should be copied to TCB
       
  1660                         //copy it to to TCB from temp location
       
  1661                         if ( IsFileTcb( iFileName ) )
       
  1662                             {
       
  1663                             TRAP( err, HandleTcbCopyL(
       
  1664                                 KTmpFileName, iFileName ) );
       
  1665                             if ( err != KErrNone )
       
  1666                                 {
       
  1667                                 SendErrorMsg( anError, KErrDescrFailedCopyTcb );
       
  1668                                 iFs.Delete( KTmpFileName );
       
  1669                                 delete iProcessLogonAO;
       
  1670                                 iProcessLogonAO = NULL;
       
  1671                                 iState = EIdle;
       
  1672                                 }
       
  1673                             }
       
  1674                         else
       
  1675                             {
       
  1676                             SetBURFakeState( EFalse );
       
  1677                             SendControlMsg( EFtpOK, KNullDesC8 );
       
  1678                             }
       
  1679                         }
       
  1680                     }
       
  1681                 else
       
  1682                     {
       
  1683                     iState = EStorWait;
       
  1684                     //busy state is over
       
  1685                     iDispatcher->Notify(KErrNone);
       
  1686                     }
       
  1687                 }
       
  1688             else
       
  1689                 {
       
  1690                 HTI_LOG_FORMAT("error writing file %d", anError);
       
  1691                 //abort operation and send err msg
       
  1692                 delete iHandlerAO;
       
  1693                 iHandlerAO = NULL;
       
  1694 
       
  1695                 iFile.Close();
       
  1696                 iFs.Delete(iFileName);
       
  1697                 iState = EIdle;
       
  1698                 SendErrorMsg( anError, KErrDescrFailedWrite );
       
  1699                 }
       
  1700             }
       
  1701             break;
       
  1702 
       
  1703         case EStorTcbBusy:
       
  1704             {
       
  1705             if ( anError == KErrNone )
       
  1706                 {
       
  1707                 SetBURFakeState( EFalse );
       
  1708                 SendControlMsg( EFtpOK, KNullDesC8 );
       
  1709                 }
       
  1710             else
       
  1711                 {
       
  1712                 if ( SetBURFakeState( ETrue ) != KErrNone )
       
  1713                     {
       
  1714                     // Force was not requested, not supported OR already tried.
       
  1715                     HTI_LOG_FORMAT("error copy to tcb %d", anError);
       
  1716                     //abort operation and send err msg
       
  1717                     SendErrorMsg( anError, KErrDescrFailedCopyTcb );
       
  1718                     }
       
  1719                 else
       
  1720                     {
       
  1721                     // try copy again
       
  1722                     TRAPD( err, HandleTcbCopyL( KTmpFileName, iFileName ) );
       
  1723                     if ( err == KErrNone )
       
  1724                         {
       
  1725                         break;
       
  1726                         // don't continue, this method will be called again
       
  1727                         // by the AO after copying is tried
       
  1728                         }
       
  1729                     else
       
  1730                         {
       
  1731                         SendErrorMsg( err, KErrDescrFailedCopyTcb );
       
  1732                         }
       
  1733                     }
       
  1734                 }
       
  1735 
       
  1736             //delete temp file
       
  1737             HTI_LOG_TEXT("delete tmp file");
       
  1738             TInt err = iFs.Delete(KTmpFileName);
       
  1739             if ( err != KErrNone )
       
  1740                 {
       
  1741                 HTI_LOG_FORMAT("error delete tmp file %d", err);
       
  1742                 }
       
  1743 
       
  1744             delete iProcessLogonAO;
       
  1745             iProcessLogonAO = NULL;
       
  1746             iState = EIdle;
       
  1747             }
       
  1748             break;
       
  1749 
       
  1750         case ERetrBusy:
       
  1751             {
       
  1752             if ( anError == KErrNone )
       
  1753                 {
       
  1754                 HTI_LOG_FORMAT("read %d bytes", iSendBuffer->Size());
       
  1755                 iCurrentOffset += iSendBuffer->Size();
       
  1756 
       
  1757                 SendBuffer();
       
  1758                 }
       
  1759             else
       
  1760                 {
       
  1761                 HTI_LOG_FORMAT("failed read file %d", anError);
       
  1762                 //error reading file
       
  1763                 //abort operation and send err msg
       
  1764                 delete iSendBuffer;
       
  1765                 iSendBuffer = NULL;
       
  1766 
       
  1767                 delete iHandlerAO;
       
  1768                 iHandlerAO = NULL;
       
  1769 
       
  1770                 iFile.Close();
       
  1771 
       
  1772                 iState = EIdle;
       
  1773                 iDispatcher->RemoveMemoryObserver( this );
       
  1774 
       
  1775                 SendErrorMsg( anError, KErrDescrFailedRead );
       
  1776                 }
       
  1777             }
       
  1778             break;
       
  1779         default:
       
  1780             {
       
  1781             //some error, should not be called
       
  1782             HTI_LOG_TEXT("invalid state for FtpComplete");
       
  1783             }
       
  1784         }
       
  1785     HTI_LOG_FUNC_OUT("FtpComplete");
       
  1786     }
       
  1787 
       
  1788 void CHtiFtpServicePlugin::NotifyMemoryChange( TInt aAvailableMemory )
       
  1789     {
       
  1790     HTI_LOG_FUNC_IN("NotifyMemoryChange");
       
  1791     switch ( iState )
       
  1792         {
       
  1793         case ERetrWait:
       
  1794             {
       
  1795             if ( iSendBuffer )
       
  1796                 {
       
  1797                 if ( aAvailableMemory >= iSendBuffer->Size() )
       
  1798                     {
       
  1799                     //continue sending
       
  1800                     SendBuffer();
       
  1801                     }
       
  1802                 }
       
  1803             else
       
  1804                 {//impossible
       
  1805                 //nothing to send
       
  1806                 //just reset
       
  1807                 HTI_LOG_TEXT("invalid state for mem");
       
  1808 
       
  1809                 delete iHandlerAO;
       
  1810                 iHandlerAO = NULL;
       
  1811                 iFile.Close();
       
  1812                 iDispatcher->RemoveMemoryObserver(this);
       
  1813                 iState = EIdle;
       
  1814                 }
       
  1815             }
       
  1816             break;
       
  1817         case EListBusy:
       
  1818             {
       
  1819             if ( iSendBuffer )
       
  1820                 {
       
  1821                 if ( aAvailableMemory >= iSendBuffer->Size() )
       
  1822                     {
       
  1823                     //send buffer
       
  1824                     TInt err = iDispatcher->DispatchOutgoingMessage(
       
  1825                                     iSendBuffer,
       
  1826                                     KFtpServiceUid,
       
  1827                                     EFalse,
       
  1828                                     EHtiPriorityData);
       
  1829                     if ( err != KErrNone )
       
  1830                         {
       
  1831                         //error, reset
       
  1832                         HTI_LOG_TEXT("failed to send LIST");
       
  1833                         delete iSendBuffer;
       
  1834                         }
       
  1835                     iSendBuffer = NULL;
       
  1836                     iDispatcher->RemoveMemoryObserver(this);
       
  1837                     iState = EIdle;
       
  1838                     }
       
  1839                 }
       
  1840             else
       
  1841                 {//impossible
       
  1842                 //nothing to send
       
  1843                 //just reset
       
  1844                 HTI_LOG_TEXT("invalid state for mem");
       
  1845                 iDispatcher->RemoveMemoryObserver(this);
       
  1846                 iState = EIdle;
       
  1847                 }
       
  1848             }
       
  1849             break;
       
  1850         default:
       
  1851             //some error, should not be called
       
  1852             HTI_LOG_TEXT("invalid state for mem");
       
  1853             //iDispatcher->RemoveMemoryObserver(this);
       
  1854             //iState = EIdle;
       
  1855         }
       
  1856     HTI_LOG_FUNC_OUT("NotifyMemoryChange");
       
  1857     }
       
  1858 
       
  1859 TBool CHtiFtpServicePlugin::IsFileTcb( const TDesC& aFilename )
       
  1860     {
       
  1861     return aFilename.FindF( KHtiTcbSys ) == KPathOffset ||
       
  1862            aFilename.FindF( KHtiTcbResource ) == KPathOffset;
       
  1863     }
       
  1864 
       
  1865 void CHtiFtpServicePlugin::HandleTcbDeleteL( const TDesC& aFilename )
       
  1866     {
       
  1867     HTI_LOG_FUNC_IN("HandleTcbDeleteL");
       
  1868     HBufC* cmdLine = HBufC::NewLC( aFilename.Length() + 2 );
       
  1869 
       
  1870     //make command line "d|filename"
       
  1871     cmdLine->Des().Copy( KHtiFileHlpDeleteCmd );
       
  1872     cmdLine->Des().Append( KHtiFileHlpDelim );
       
  1873     cmdLine->Des().Append( aFilename );
       
  1874 
       
  1875     HTI_LOG_DES( *cmdLine );
       
  1876 
       
  1877     delete iProcessLogonAO;
       
  1878     iProcessLogonAO = NULL;
       
  1879 
       
  1880     iProcessLogonAO = new(ELeave) CProcessLogonAO( this );
       
  1881     iProcessLogonAO->Start( *cmdLine );
       
  1882 
       
  1883     iState = EDeleTcbBusy;
       
  1884 
       
  1885     CleanupStack::PopAndDestroy( cmdLine );
       
  1886     HTI_LOG_FUNC_OUT("HandleTcbDeleteL");
       
  1887     }
       
  1888 
       
  1889 void CHtiFtpServicePlugin::HandleTcbCopyL( const TDesC& aFromFilename,
       
  1890                                            const TDesC& aToFilename )
       
  1891     {
       
  1892     HTI_LOG_FUNC_IN("HandleTcbCopyL");
       
  1893     HBufC* cmdLine = HBufC::NewLC( aFromFilename.Length() + aToFilename.Length() + 3 );
       
  1894 
       
  1895     //make command line "c|fromfilename|tofilename"
       
  1896     cmdLine->Des().Copy( KHtiFileHlpCopyCmd );
       
  1897     cmdLine->Des().Append( KHtiFileHlpDelim );
       
  1898     cmdLine->Des().Append( aFromFilename );
       
  1899     cmdLine->Des().Append( KHtiFileHlpDelim );
       
  1900     cmdLine->Des().Append( aToFilename );
       
  1901 
       
  1902     HTI_LOG_DES( *cmdLine );
       
  1903 
       
  1904     delete iProcessLogonAO;
       
  1905     iProcessLogonAO = NULL;
       
  1906 
       
  1907     iProcessLogonAO = new(ELeave) CProcessLogonAO( this );
       
  1908     iProcessLogonAO->Start( *cmdLine );
       
  1909 
       
  1910     iState = EStorTcbBusy;
       
  1911 
       
  1912     CleanupStack::PopAndDestroy( cmdLine );
       
  1913     HTI_LOG_FUNC_OUT("HandleTcbCopyL");
       
  1914     }
       
  1915 
       
  1916 void CHtiFtpServicePlugin::HandleTcbMkdL( const TDesC& aDirname )
       
  1917     {
       
  1918     HTI_LOG_FUNC_IN("HandleTcbMkdL");
       
  1919     HBufC* cmdLine = HBufC::NewLC( aDirname.Length() + 2 );
       
  1920 
       
  1921     //make command line "m|dirname"
       
  1922     cmdLine->Des().Copy( KHtiFileHlpMkdCmd );
       
  1923     cmdLine->Des().Append( KHtiFileHlpDelim );
       
  1924     cmdLine->Des().Append( aDirname );
       
  1925 
       
  1926     HTI_LOG_DES( *cmdLine );
       
  1927 
       
  1928     delete iProcessLogonAO;
       
  1929     iProcessLogonAO = NULL;
       
  1930 
       
  1931     iProcessLogonAO = new(ELeave) CProcessLogonAO( this );
       
  1932     iProcessLogonAO->Start(*cmdLine);
       
  1933 
       
  1934     iState = EMkdTcbBusy;
       
  1935 
       
  1936     CleanupStack::PopAndDestroy(cmdLine);
       
  1937     HTI_LOG_FUNC_OUT("HandleTcbMkdL");
       
  1938     }
       
  1939 
       
  1940 void CHtiFtpServicePlugin::HandleTcbRmdL( const TDesC& aDirname )
       
  1941     {
       
  1942     HTI_LOG_FUNC_IN("HandleTcbRmdL");
       
  1943     HBufC* cmdLine = HBufC::NewLC( aDirname.Length() + 2 );
       
  1944 
       
  1945     //make command line "r|dirname"
       
  1946     cmdLine->Des().Copy( KHtiFileHlpRmdCmd );
       
  1947     cmdLine->Des().Append( KHtiFileHlpDelim );
       
  1948     cmdLine->Des().Append( aDirname );
       
  1949 
       
  1950     HTI_LOG_DES( *cmdLine );
       
  1951 
       
  1952     delete iProcessLogonAO;
       
  1953     iProcessLogonAO = NULL;
       
  1954 
       
  1955     iProcessLogonAO = new ( ELeave ) CProcessLogonAO( this );
       
  1956     iProcessLogonAO->Start( *cmdLine );
       
  1957 
       
  1958     iState = ERmdTcbBusy;
       
  1959 
       
  1960     CleanupStack::PopAndDestroy( cmdLine );
       
  1961     HTI_LOG_FUNC_OUT("HandleTcbRmdL");
       
  1962     }
       
  1963 
       
  1964 void CHtiFtpServicePlugin::HandleTcbRenameL(
       
  1965         const TDesC& aTargetName, const TDesC& aDestName )
       
  1966     {
       
  1967     HTI_LOG_FUNC_IN("HandleTcbRenameL");
       
  1968     HBufC* cmdLine = HBufC::NewLC( aTargetName.Length() + 4 + aDestName.Length());
       
  1969 
       
  1970     //make command line "r|dirname"
       
  1971     cmdLine->Des().Copy( KHtiFileHlpRenameCmd );
       
  1972     cmdLine->Des().Append( KHtiFileHlpDelim );
       
  1973     cmdLine->Des().Append( aTargetName );
       
  1974     cmdLine->Des().Append( KHtiFileHlpDelim );
       
  1975     cmdLine->Des().Append( aDestName );
       
  1976 
       
  1977     HTI_LOG_DES( *cmdLine );
       
  1978 
       
  1979     delete iProcessLogonAO;
       
  1980     iProcessLogonAO = NULL;
       
  1981 
       
  1982     iProcessLogonAO = new ( ELeave ) CProcessLogonAO( this );
       
  1983     iProcessLogonAO->Start( *cmdLine );
       
  1984 
       
  1985     iState = ERenameTcbBusy;
       
  1986 
       
  1987     CleanupStack::PopAndDestroy( cmdLine );
       
  1988     HTI_LOG_FUNC_OUT("HandleTcbRenameL");
       
  1989     }
       
  1990 
       
  1991 void CHtiFtpServicePlugin::HandleTcbMoveL(
       
  1992         const TDesC& aTargetName, const TDesC& aDestName )
       
  1993     {
       
  1994     HTI_LOG_FUNC_IN("HandleTcbRenameL");
       
  1995     HBufC* cmdLine = HBufC::NewLC( aTargetName.Length() + 4 + aDestName.Length());
       
  1996 
       
  1997     //make command line "r|dirname"
       
  1998     cmdLine->Des().Copy( KHtiFileHlpMoveCmd );
       
  1999     cmdLine->Des().Append( KHtiFileHlpDelim );
       
  2000     cmdLine->Des().Append( aTargetName );
       
  2001     cmdLine->Des().Append( KHtiFileHlpDelim );
       
  2002     cmdLine->Des().Append( aDestName );
       
  2003 
       
  2004     HTI_LOG_DES( *cmdLine );
       
  2005 
       
  2006     delete iProcessLogonAO;
       
  2007     iProcessLogonAO = NULL;
       
  2008 
       
  2009     iProcessLogonAO = new ( ELeave ) CProcessLogonAO( this );
       
  2010     iProcessLogonAO->Start( *cmdLine );
       
  2011 
       
  2012     iState = EMoveTcbBusy;
       
  2013 
       
  2014     CleanupStack::PopAndDestroy( cmdLine );
       
  2015     HTI_LOG_FUNC_OUT("HandleTcbRenameL");
       
  2016     }
       
  2017 
       
  2018 TInt CHtiFtpServicePlugin::SetBURFakeState( TBool aOn )
       
  2019     {
       
  2020     HTI_LOG_FUNC_IN( "CHtiFtpServicePlugin::SetBURFakeStateL" );
       
  2021     TInt err = KErrNone;
       
  2022 
       
  2023     if ( iBackupFake == NULL )
       
  2024         {
       
  2025         // Foreced operations not requested or not supported
       
  2026         err = KErrNotSupported;
       
  2027         }
       
  2028 
       
  2029     else if ( aOn )
       
  2030         {
       
  2031         HTI_LOG_TEXT( "Calling ActivateBackup()" );
       
  2032         err = iBackupFake->ActivateBackup();
       
  2033         }
       
  2034 
       
  2035     else
       
  2036         {
       
  2037         HTI_LOG_TEXT( "Calling DeactivateBackup()" );
       
  2038         err = iBackupFake->DeactivateBackup();
       
  2039         }
       
  2040 
       
  2041     HTI_LOG_FUNC_OUT( "CHtiFtpServicePlugin::SetBURFakeStateL" );
       
  2042     return err;
       
  2043     }
       
  2044 
       
  2045 void CHtiFtpServicePlugin::HandleCheckSumCalcL( TAlgorithm aAlgorithm,
       
  2046                                                 const TDesC& aFilename )
       
  2047     {
       
  2048     HTI_LOG_FUNC_IN( "CHtiFtpServicePlugin::HandleCheckSumCalcL" );
       
  2049 
       
  2050     RFile file;
       
  2051     TInt err = file.Open( iFs, aFilename, EFileRead | EFileShareReadersOnly );
       
  2052     if ( err )
       
  2053         {
       
  2054         HTI_LOG_FORMAT( "Error opening file, err: %d", err );
       
  2055         SendErrorMsg( err, KErrDescrFailedOpenFile );
       
  2056         return;
       
  2057         }
       
  2058 
       
  2059     CleanupClosePushL( file );
       
  2060     switch ( aAlgorithm )
       
  2061         {
       
  2062         case EMD5:
       
  2063             {
       
  2064             HTI_LOG_TEXT( "Using MD5 algorithm" );
       
  2065             const TInt KBufSize( 1024 );
       
  2066             TInt size = 0;
       
  2067             TInt offset = 0;
       
  2068 
       
  2069             file.Size( size );
       
  2070 
       
  2071             HBufC8* buf = HBufC8::NewMaxLC( KBufSize );
       
  2072             TPtr8 filePtr( buf->Des() );
       
  2073 
       
  2074             CMD5* md5 = CMD5::NewL();
       
  2075             CleanupStack::PushL( md5 );
       
  2076 
       
  2077             while ( offset < size - KBufSize )
       
  2078                 {
       
  2079                 User::LeaveIfError( file.Read( filePtr, KBufSize ) );
       
  2080                 md5->Hash( filePtr );
       
  2081                 offset += filePtr.Length();
       
  2082                 }
       
  2083 
       
  2084             file.Read( filePtr, size - offset );
       
  2085             filePtr.SetLength( size - offset );
       
  2086             md5->Hash( filePtr );
       
  2087 
       
  2088             filePtr.Set( NULL, 0, 0 );
       
  2089             HBufC8* result = md5->Hash( filePtr ).AllocL();
       
  2090             CleanupStack::PushL( result );
       
  2091 
       
  2092             HTI_LOG_TEXT( "Got following MD5:" );
       
  2093             HTI_LOG_DES( *result );
       
  2094 
       
  2095             User::LeaveIfError(
       
  2096                 iDispatcher->DispatchOutgoingMessage( result,
       
  2097                                                       KFtpServiceUid,
       
  2098                                                       EFalse,
       
  2099                                                       EHtiPriorityControl ) );
       
  2100             CleanupStack::Pop( result ); // do not delete, ownership transfered
       
  2101             CleanupStack::PopAndDestroy( 2 ); // md5, buf
       
  2102             break;
       
  2103             }
       
  2104 
       
  2105         default:
       
  2106             {
       
  2107             HTI_LOG_FORMAT( "Invalid algorithm: %d", aAlgorithm );
       
  2108             SendErrorMsg( KErrNotFound, KErrDescrInvalidChecksumArgs );
       
  2109             break;
       
  2110             }
       
  2111         }
       
  2112     CleanupStack::PopAndDestroy(); // file
       
  2113 
       
  2114     HTI_LOG_FUNC_OUT( "CHtiFtpServicePlugin::HandleCheckSumCalcL" );
       
  2115     }
       
  2116 
       
  2117 void CHtiFtpServicePlugin::HandleFormat( const TUint8 aDrive, const TUint8 aMode )
       
  2118     {
       
  2119     HTI_LOG_FUNC_IN( "CHtiFtpServicePlugin::HandleFormat" );
       
  2120 
       
  2121     // Convert the format mode: in HTI protocol 0 means full format and 1
       
  2122     // (or anything else currently) means quick format
       
  2123     TUint formatMode = 0;
       
  2124     if ( aMode )
       
  2125         formatMode = ESpecialFormat | EQuickFormat;
       
  2126     else
       
  2127         formatMode = ESpecialFormat | EFullFormat;
       
  2128 
       
  2129     // Create the drive name (drive letter and colon)
       
  2130     TDriveName drive;
       
  2131     drive.Append( aDrive );
       
  2132     drive.Append( _L( ":" ) );
       
  2133 
       
  2134     // Check that HTI is not running from the drive that is to be formatted
       
  2135     RProcess thisProcess;
       
  2136     if ( thisProcess.FileName().FindF( drive ) == 0 )
       
  2137         {
       
  2138         HTI_LOG_FORMAT( "HTI running from drive %S cannot format", &drive );
       
  2139         SendErrorMsg( KErrInUse, KErrDescrFailedFormat );
       
  2140         HTI_LOG_FUNC_OUT( "CHtiFtpServicePlugin::HandleFormat" );
       
  2141         return;
       
  2142         }
       
  2143 
       
  2144     // Activate backup/restore to close apps that might have files open.
       
  2145     // Ignore errors - try to format even if backup fake is not supported.
       
  2146     SetBURFakeState( ETrue );
       
  2147 
       
  2148     // Start the format
       
  2149     HTI_LOG_FORMAT( "Starting to format drive %S", &drive );
       
  2150     HTI_LOG_FORMAT( "Format mode = %d", formatMode );
       
  2151     TInt remainingTracks = 0;
       
  2152     RFormat format;
       
  2153     TInt err = format.Open( iFs, drive, formatMode, remainingTracks );
       
  2154     if ( err == KErrNone )
       
  2155         {
       
  2156         HTI_LOG_FORMAT( "Formatting %d tracks", remainingTracks );
       
  2157         while ( remainingTracks && err == KErrNone )
       
  2158             {
       
  2159             err = format.Next( remainingTracks );
       
  2160             HTI_LOG_FORMAT( "Tracks remaining: %d", remainingTracks );
       
  2161             }
       
  2162         }
       
  2163     format.Close();
       
  2164 
       
  2165     // Deactivate backup/restore - errors ignored.
       
  2166     SetBURFakeState( EFalse );
       
  2167 
       
  2168     if ( err == KErrNone )
       
  2169         {
       
  2170         SendControlMsg( EFtpOK, KNullDesC8 );
       
  2171         }
       
  2172 
       
  2173     else
       
  2174         {
       
  2175         SendErrorMsg( err, KErrDescrFailedFormat );
       
  2176         }
       
  2177 
       
  2178     HTI_LOG_FUNC_OUT( "CHtiFtpServicePlugin::HandleFormat" );
       
  2179     }
       
  2180 
       
  2181 void CHtiFtpServicePlugin::HandleListDrivesL( TBool aUnicode )
       
  2182     {
       
  2183     HTI_LOG_FUNC_IN( "CHtiFtpServicePlugin::HandleListDrivesL" );
       
  2184     TInt driveCount = 0;
       
  2185     TDriveList driveList;
       
  2186 
       
  2187     User::LeaveIfError( iFs.DriveList( driveList, KDriveAttAll ) );
       
  2188 
       
  2189     // Buffer for the drive list that is returned
       
  2190     CBufFlat* driveListBuf = CBufFlat::NewL( 256 );
       
  2191     CleanupStack::PushL( driveListBuf );
       
  2192     TInt bufPos = 0;
       
  2193 
       
  2194     for ( TInt i = 0; i < KMaxDrives; i++ )
       
  2195         {
       
  2196         if ( driveList[i] )
       
  2197             {
       
  2198             HTI_LOG_FORMAT( "Found drive number %d", i );
       
  2199             TVolumeInfo volInfo;
       
  2200             if ( iFs.Volume( volInfo, i ) == KErrNone )
       
  2201                 {
       
  2202                 driveCount++;
       
  2203                 // root path with length byte
       
  2204                 TChar driveLetter;
       
  2205                 iFs.DriveToChar( i, driveLetter );
       
  2206                 HTI_LOG_FORMAT( "Got volume info for drive %c",
       
  2207                         TUint( driveLetter ) );
       
  2208                 TBuf<3> rootPathBuf;
       
  2209                 rootPathBuf.AppendFormat( KRootPathFormat,
       
  2210                         TUint( driveLetter ) );
       
  2211                 TBuf8<1> lengthBuf;
       
  2212                 lengthBuf.Append( rootPathBuf.Length() );
       
  2213                 TBuf8<6> rootPathBuf8;
       
  2214                 if ( aUnicode )
       
  2215                     {
       
  2216                     rootPathBuf8.Append( ( TUint8* ) rootPathBuf.Ptr(),
       
  2217                             rootPathBuf.Length() * 2 );
       
  2218                     }
       
  2219                 else
       
  2220                     {
       
  2221                     rootPathBuf8.Copy( rootPathBuf );
       
  2222                     }
       
  2223                 driveListBuf->ExpandL( bufPos, rootPathBuf8.Length() + 1 );
       
  2224                 driveListBuf->Write( bufPos, lengthBuf, 1 );
       
  2225                 bufPos++;
       
  2226                 driveListBuf->Write( bufPos, rootPathBuf8 );
       
  2227                 bufPos += rootPathBuf8.Length();
       
  2228 
       
  2229                 // media type 1 byte
       
  2230                 TBuf8<8> tmpBuf;
       
  2231                 tmpBuf.Append( volInfo.iDrive.iType );
       
  2232                 driveListBuf->ExpandL( bufPos, tmpBuf.Length() );
       
  2233                 driveListBuf->Write( bufPos, tmpBuf );
       
  2234                 bufPos += tmpBuf.Length();
       
  2235 
       
  2236                 // UID 4 bytes
       
  2237                 tmpBuf.Copy( ( TUint8* ) ( &volInfo.iUniqueID ), 4 );
       
  2238                 driveListBuf->ExpandL( bufPos, tmpBuf.Length() );
       
  2239                 driveListBuf->Write( bufPos, tmpBuf );
       
  2240                 bufPos += tmpBuf.Length();
       
  2241 
       
  2242                 // size 8 bytes
       
  2243                 tmpBuf.Copy( ( TUint8* ) ( &volInfo.iSize ), 8 );
       
  2244                 driveListBuf->ExpandL( bufPos, tmpBuf.Length() );
       
  2245                 driveListBuf->Write( bufPos, tmpBuf );
       
  2246                 bufPos += tmpBuf.Length();
       
  2247 
       
  2248                 // free space 8 bytes
       
  2249                 tmpBuf.Copy( ( TUint8* ) ( &volInfo.iFree ), 8 );
       
  2250                 driveListBuf->ExpandL( bufPos, tmpBuf.Length() );
       
  2251                 driveListBuf->Write( bufPos, tmpBuf );
       
  2252                 bufPos += tmpBuf.Length();
       
  2253 
       
  2254                 // name with length byte
       
  2255                 HBufC8* driveNameBuf8 = NULL;
       
  2256                 TInt driveNameLength = volInfo.iName.Length();
       
  2257                 lengthBuf.Zero();
       
  2258                 lengthBuf.Append( driveNameLength );
       
  2259                 driveListBuf->ExpandL( bufPos, 1 );
       
  2260                 driveListBuf->Write( bufPos, lengthBuf, 1 );
       
  2261                 bufPos++;
       
  2262                 if ( driveNameLength > 0 )
       
  2263                     {
       
  2264                     if ( aUnicode )
       
  2265                         {
       
  2266                         driveNameBuf8 = HBufC8::NewL( driveNameLength * 2 );
       
  2267                         driveNameBuf8->Des().Append(
       
  2268                                 ( TUint8* ) volInfo.iName.Ptr(),
       
  2269                                 driveNameLength * 2 );
       
  2270                         }
       
  2271                     else
       
  2272                         {
       
  2273                         driveNameBuf8 = HBufC8::NewL( driveNameLength );
       
  2274                         driveNameBuf8->Des().Append( volInfo.iName );
       
  2275                         }
       
  2276                     HTI_LOG_FORMAT( "Drive name: %S", &volInfo.iName );
       
  2277                     driveListBuf->ExpandL( bufPos, driveNameBuf8->Length() );
       
  2278                     driveListBuf->Write( bufPos, driveNameBuf8->Ptr(),
       
  2279                         driveNameBuf8->Length() );
       
  2280                     bufPos += driveNameBuf8->Length();
       
  2281                     delete driveNameBuf8;
       
  2282                     driveNameBuf8 = NULL;
       
  2283                     }
       
  2284                 }
       
  2285             }
       
  2286         }
       
  2287 
       
  2288     // All drives added - write number of drives to the beginning of buffer
       
  2289     TBuf8<1> countBuf;
       
  2290     countBuf.Append( ( TUint8* ) ( &driveCount ), 1 );
       
  2291     driveListBuf->InsertL( 0, countBuf, 1 );
       
  2292 
       
  2293     // Make a copy of the buffer to iSendBuffer
       
  2294     delete iSendBuffer;
       
  2295     iSendBuffer = NULL;
       
  2296     iSendBuffer = driveListBuf->Ptr( 0 ).AllocL();
       
  2297     CleanupStack::PopAndDestroy(); // driveListBuf
       
  2298 
       
  2299     // ...and send it away
       
  2300     TInt err = iDispatcher->DispatchOutgoingMessage(
       
  2301         iSendBuffer, KFtpServiceUid, EFalse, EHtiPriorityControl );
       
  2302 
       
  2303     if (  err != KErrNone )
       
  2304         {
       
  2305         //wait for memory
       
  2306         iState = EListBusy;
       
  2307         iDispatcher->AddMemoryObserver( this );
       
  2308         }
       
  2309     else
       
  2310         {
       
  2311         iSendBuffer = NULL; // ownership transferred
       
  2312         }
       
  2313 
       
  2314     HTI_LOG_FUNC_OUT( "CHtiFtpServicePlugin::HandleListDrivesL" );
       
  2315     }
       
  2316 
       
  2317 
       
  2318 // End of File