Fixed chunkinfo and RAllocatorHelper crashes.
Details:
* Tidied leak docs
* Updated dialog command to workaround text windowserver bug and implement DIALOG_IMPL as an enum option. Also tried to support dismissing the dialog with CTRL-C but ended up just printing a warning as the notifier API is broken
* Fixed RAllocatorHelper::OpenChunkHeap() (and thus chunkinfo <address>) and took Adrian's latest changes.
* Fixed chunkinfo OOM problem
// ymodem.cpp// // Copyright (c) 2008 - 2010 Accenture. All rights reserved.// This component and the accompanying materials are made available// under the terms of the "Eclipse Public License v1.0"// which accompanies this distribution, and is available// at the URL "http://www.eclipse.org/legal/epl-v10.html".// // Initial Contributors:// Accenture - Initial contribution//#include <fshell/ioutils.h>#include "ymodem.h"using namespace IoUtils;CCommandBase* CCmdYmodem::NewLC() { CCmdYmodem* self = new(ELeave) CCmdYmodem(); CleanupStack::PushL(self); self->BaseConstructL(); self->ConstructL(); return self; }CCmdYmodem::~CCmdYmodem() { iFileNames.Close(); }CCmdYmodem::CCmdYmodem() { }const TDesC& CCmdYmodem::Name() const { _LIT(KName, "ymodem"); return KName; }class TFailedFile {public: TFailedFile();public: TInt iError; TFileName2 iFileName; };TFailedFile::TFailedFile() : iError(KErrNone) { }void CCmdYmodem::DoRunL() { PrepareConsoleToTransferL(); if (iMode == EReceive) { TPtrC receiveDir; if (iFileNames.Count() > 1) { PrintError(KErrArgument, _L("Too many arguments - only the receive directory may be specified in receive mode.")); User::Leave(KErrArgument); } else if (iFileNames.Count() == 1) { TFileName2 fileName(iFileNames[0]); receiveDir.Set(iFileNames[0]); if ((fileName.Exists(FsL()) && !fileName.IsDirL(FsL())) || (!fileName.Exists(FsL()) && !iOverwrite)) { LeaveIfErr(KErrArgument, _L("\"%S\" is not a directory"), &fileName); } } else { receiveDir.Set(Env().Pwd()); } Progress(_L("YMODEM receive to \"%S\"\r\n"), &receiveDir); RArray<TFileName2> receivedFiles; CleanupClosePushL(receivedFiles); TFailedFile failedFile; TBool finished(EFalse); while (!finished) { TSyncResult syncResult = SendSyncL(); if (syncResult == EEot) { finished = ETrue; } else { iPacketNumber = 0; TBool isFinalBlock(EFalse); TPtrC block(ReceiveBlockL(ETrue, isFinalBlock)); TPtrC fileName(block.Ptr()); // filename is the first null terminated string in the block. if (fileName.Length() > 0) { TFileName2 fileName2(fileName); fileName2.MakeAbsoluteL(receiveDir); TLex lex(block.Mid(fileName.Length() + 1)); TInt size; User::LeaveIfError(lex.Val(size)); TInt err = KErrNone; if (!iOverwrite && fileName2.Exists(FsL())) { err = KErrAlreadyExists; } RFile file; if (err == KErrNone) { if (size == 0) { if (iOverwrite) { err = file.Replace(FsL(), fileName2, EFileWrite); } else { err = file.Create(FsL(), fileName2, EFileWrite); } } else { Progress(_L("Starting receive of \"%S\" (%d bytes)\r\n"), &fileName, size); SendSyncL(); TRAP(err, ReceiveToFileL(fileName2)); if (err == KErrNone) { err = file.Open(FsL(), fileName2, EFileWrite); if (err == KErrNone) { err = file.SetSize(size); } } else { Fs().Delete(fileName2); } } } else { TRAP_IGNORE(ReceiveToNullL()); } file.Close(); if (err) { failedFile.iError = err; failedFile.iFileName = fileName2; finished = ETrue; } else { receivedFiles.Append(fileName2); // Ignore error. } } else { finished = ETrue; } } } CleanupClonsoleAfterTransferL(); const TInt numFilesReceived = receivedFiles.Count(); if (numFilesReceived == 0) { if (failedFile.iError == KErrNone) { Printf(_L("No files to receive.\r\n")); } } else if (numFilesReceived == 1) { const TFileName2& fileName = receivedFiles[0]; Printf(_L("Successfully received \"%S\".\r\n"), &fileName); } else { Printf(_L("Successfully received:\r\n")); for (TInt i = 0; i < numFilesReceived; ++i) { const TFileName2& fileName = receivedFiles[i]; Printf(_L("\t\"%S\"\r\n"), &fileName); } } if (failedFile.iError) { PrintError(failedFile.iError, _L("Failed to receive \"%S\""), &failedFile.iFileName); } CleanupStack::PopAndDestroy(&receivedFiles); } else if (iMode == ESend) { const TInt numFiles = iFileNames.Count(); if (numFiles == 0) { PrintError(KErrArgument, _L("No files to send specified")); User::Leave(KErrArgument); } for (TInt i = 0; i < numFiles; ++i) { const TFileName2& fileName = iFileNames[i]; if (fileName.Exists(FsL())) { if (fileName.IsDirL(FsL())) { LeaveIfErr(KErrArgument, _L("\"%S\" is not a file"), &fileName); } } else { LeaveIfErr(KErrArgument, _L("\"%S\" does not exist"), &fileName); } } WaitForSyncL(); HBufC* buf = HBufC::NewLC(iBlockSize); TPtr bufPtr(buf->Des()); for (TInt i = 0; i < numFiles; ++i) { const TFileName2& fileName = iFileNames[i]; LeaveIfFileNotFound(fileName); TEntry entry; User::LeaveIfError(FsL().Entry(fileName, entry)); bufPtr.SetLength(bufPtr.MaxLength()); bufPtr.FillZ(); bufPtr.Copy(fileName.NameAndExt()); bufPtr.SetLength(buf->Length() + 1); // To leave a terminating null after the file name. bufPtr.AppendNum(entry.iSize); if (bufPtr.Length() < iBlockSize) { // There's not enough data to fill this block, so pad with NULL. bufPtr.AppendFill(0, iBlockSize - bufPtr.Length()); } iPacketNumber = 0; SendBlockL(*buf); WaitForSyncL(); SendFileL(fileName); } iPacketNumber = 0; bufPtr.SetLength(bufPtr.MaxLength()); bufPtr.FillZ(); SendBlockL(*buf); CleanupStack::PopAndDestroy(buf); CleanupClonsoleAfterTransferL(); if (numFiles == 1) { Printf(_L("Successfully sent \"%S\".\r\n"), &iFileNames[0]); } else { Printf(_L("Successfully sent:\r\n")); for (TInt i = 0; i < numFiles; ++i) { const TFileName2& fileName = iFileNames[i]; Printf(_L("\t\"%S\"\r\n"), &fileName); } } } User::LeaveIfError(Stdin().CancelCaptureAllKeys()); }void CCmdYmodem::ArgumentsL(RCommandArgumentList& aArguments) { _LIT(KArg1, "mode"); aArguments.AppendEnumL((TInt&)iMode, KArg1); _LIT(KArg2, "file_name"); aArguments.AppendFileNameL(iFileNames, KArg2); }void CCmdYmodem::OptionsL(RCommandOptionList& aOptions) { CCmdXmodem::OptionsL(aOptions); }