sl@0: // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of the License "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: // USB Mass Storage Application - also used as an improvised boot loader mechanism
sl@0: //
sl@0: //
sl@0: 
sl@0: 
sl@0: 
sl@0: /**
sl@0:  @file
sl@0: */
sl@0: 
sl@0: #include <e32cons.h>
sl@0: #include <f32file.h>
sl@0: 
sl@0: #include "rusbotgsession.h"
sl@0: 
sl@0: #include "usbtypes.h"
sl@0: #include "mdrivedisplay.h"
sl@0: #include "cdisplay.h"
sl@0: 
sl@0: // Display positions and test constants
sl@0: // Number of attached devices
sl@0: static const TInt KRow_DevicesNumber = 13;
sl@0: _LIT(KMsg_DevicesAttached, "USB Devices Attached = %d");
sl@0: 
sl@0: // Device Map
sl@0: static const TInt KStartRow_DeviceMap = KRow_DevicesNumber + 2;
sl@0: static const TInt KMaxRows_DeviceMap = 4;
sl@0: _LIT(KMsg_DeviceMap_DriveList, "%d: ");          // [drive index]
sl@0: _LIT(KMsg_DeviceMap_DriveLunEntry, "%c ");       // [drive letter]
sl@0: 
sl@0: 
sl@0: // Drive Map
sl@0: static const TInt KStartRow_DriveMap = KStartRow_DeviceMap + KMaxRows_DeviceMap;
sl@0: static const TInt KMaxRows_DriveMap = 4;
sl@0: _LIT(KMsg_DriveMap_EntryLetter, "%c token = %d");           // [drive letter] [token]
sl@0: _LIT(KDbgMsg_DriveMap_EntryLetter, "*** %c token = %d");    // [drive letter] [token]
sl@0: 
sl@0: // System Status
sl@0: static const TInt KStartRow_UpTime = 28;
sl@0: _LIT(KMsg_UpTime, "up time     : %dh:%dm:%ds   ");	// use trailing space to overwrite any leftover chars in line
sl@0: 
sl@0: static const TInt KStartRow_MemoryFree = 29;
sl@0: _LIT(KMsg_MemoryFree, "mem (bytes) : 0x%X");
sl@0: 
sl@0: // User Keys
sl@0: static const TInt KStartRow_UserKeys = 25;
sl@0: _LIT(KMsgUser1Keys, "[Esc]=Quit [A-Z]=DriveInfo");
sl@0: _LIT(KMsgUser2Keys, "[F5]=Hub update");
sl@0: 
sl@0: 
sl@0: // Scroll Window status
sl@0: _LIT(KScrollWindowStatus, "Page %d of %d");
sl@0: 
sl@0: // Available drives
sl@0: static const TInt KStartRow_AvailableDrives = 1;
sl@0: _LIT(KAvailDriveMsg, "Drives: ");
sl@0: 
sl@0: _LIT(KDriveAtts,"DriveList %c: %02x ");
sl@0: 
sl@0: // Drive info
sl@0: static const TInt KStartRow_MsgWindow = 3;
sl@0: static const TInt KStartRow_DriveInfo = KStartRow_MsgWindow;
sl@0: 
sl@0: // ****************************************************************************
sl@0: 
sl@0: 
sl@0: CScrollWindow* CScrollWindow::NewL(CConsoleBase& aConsole)
sl@0:     {
sl@0: 	CScrollWindow* r = new (ELeave) CScrollWindow(aConsole);
sl@0: 	CleanupStack::PushL(r);
sl@0: 	r->ConstructL();
sl@0:     CleanupStack::Pop(r);
sl@0: 	return r;
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CScrollWindow::ConstructL()
sl@0:     {
sl@0: 
sl@0:     }
sl@0: 
sl@0: 
sl@0: CScrollWindow::CScrollWindow(CConsoleBase& aConsole)
sl@0: :   iConsole(aConsole)
sl@0:     {
sl@0:     }
sl@0: 
sl@0: CScrollWindow::~CScrollWindow()
sl@0:     {
sl@0:     iLineArray.Close();
sl@0:     }
sl@0: 
sl@0: void CScrollWindow::Reset()
sl@0:     {
sl@0:     iPage = 0;
sl@0:     iLineArray.Reset();
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CScrollWindow::AppendL(const TDesC& aLine)
sl@0:     {
sl@0:     iTmpLine.Zero();
sl@0:     iLineArray.AppendL(iTmpLine);
sl@0:     TInt last = iLineArray.Count() - 1;
sl@0:     iLineArray[last].Copy(aLine);
sl@0:     }
sl@0: 
sl@0: 
sl@0: TLine* CScrollWindow::NewLineL()
sl@0:     {
sl@0:     iTmpLine.Zero();
sl@0:     iLineArray.AppendL(iTmpLine);
sl@0:     TInt last = iLineArray.Count() - 1;
sl@0:     return &iLineArray[last];
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CScrollWindow::Update()
sl@0:     {
sl@0:     TInt line = iPage * KPageLength;
sl@0: 
sl@0:     TInt row = KStartRow_DriveInfo;
sl@0:     do
sl@0:         {
sl@0:         iConsole.SetPos(0, row + line%KPageLength);
sl@0:         if (line < iLineArray.Count())
sl@0:             {
sl@0:             iConsole.Printf(iLineArray[line]);
sl@0:             }
sl@0:         iConsole.ClearToEndOfLine();
sl@0:         line++;
sl@0:         }
sl@0:     while (((line-1)%KPageLength) != (KPageLength - 1));
sl@0:     iConsole.SetPos(0, KStartRow_DriveInfo + KPageLength);
sl@0:     iConsole.Printf(KScrollWindowStatus, iPage + 1, iLineArray.Count()/KPageLength + 1);
sl@0:     }
sl@0: 
sl@0: void CScrollWindow::PageInc()
sl@0:     {
sl@0:     TInt lastPage = iLineArray.Count()/KPageLength;
sl@0:     if (iPage == lastPage)
sl@0:         {
sl@0:         iPage = 0;
sl@0:         }
sl@0:     else
sl@0:         {
sl@0:         iPage++;
sl@0:         }
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CScrollWindow::PageDec()
sl@0:     {
sl@0:     if (iPage == 0)
sl@0:         {
sl@0:         TInt lastPage = iLineArray.Count()/KPageLength;
sl@0:         iPage = lastPage;
sl@0:         }
sl@0:     else
sl@0:         {
sl@0:         iPage--;
sl@0:         }
sl@0:     }
sl@0: 
sl@0: 
sl@0: 
sl@0: CDisplay* CDisplay::NewLC(RFs& aFs, CConsoleBase& aConsole)
sl@0:     {
sl@0: 	CDisplay* r = new (ELeave) CDisplay(aFs, aConsole);
sl@0: 	CleanupStack::PushL(r);
sl@0: 	r->ConstructL();
sl@0: 	return r;
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CDisplay::ConstructL()
sl@0:     {
sl@0:     iScrollWindow = CScrollWindow::NewL(iConsole);
sl@0:     }
sl@0: 
sl@0: 
sl@0: CDisplay::CDisplay(RFs& aFs, CConsoleBase& aConsole)
sl@0: :   iFs(aFs),
sl@0:     iConsole(aConsole)
sl@0:     {
sl@0:     iConsole.ClearScreen();
sl@0:     }
sl@0: 
sl@0: 
sl@0: CDisplay::~CDisplay()
sl@0:     {
sl@0:     delete iScrollWindow;
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CDisplay::Menu()
sl@0:     {
sl@0:     iConsole.SetPos(0, KStartRow_UserKeys);
sl@0:     iConsole.Printf(KMsgUser1Keys);
sl@0:     iConsole.SetPos(0, KStartRow_UserKeys + 1);
sl@0:     iConsole.Printf(KMsgUser2Keys);
sl@0:     iCursorPos = iConsole.CursorPos();
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CDisplay::DriveListL() const
sl@0: {
sl@0:     TDriveList drivelist;
sl@0:     TRAPD(err, iFs.DriveList(drivelist));
sl@0:     if (err)
sl@0:         {
sl@0:         return;
sl@0:         }
sl@0:     // A TDriveList (the list of available drives), is an array of
sl@0:     // 26 bytes. Each byte with a non zero value signifies that the
sl@0:     // corresponding drive is available.
sl@0:     TBuf<KDisplayWidth> iLineBuffer;
sl@0:     iLineBuffer = KAvailDriveMsg;
sl@0:     TChar driveLetter;
sl@0: 
sl@0:     for (TInt driveNumber = EDriveA; driveNumber <= EDriveZ;driveNumber++)
sl@0:         {
sl@0:         if (drivelist[driveNumber]) // if drive-list entry non-zero, drive is available
sl@0:             {
sl@0:             // overflow check
sl@0:             if (iLineBuffer.Length() == iLineBuffer.MaxLength())
sl@0:                 {
sl@0:                 iLineBuffer[iLineBuffer.MaxLength() - 1] = '>';
sl@0:                 break;
sl@0:                 }
sl@0: 
sl@0:             User::LeaveIfError(iFs.DriveToChar(driveNumber,driveLetter));
sl@0: 
sl@0:             // The following line prints the drive letter followed by the hex value
sl@0:             // of the integer indicating that drive's attributes
sl@0:             RDebug::Print(KDriveAtts,TUint(driveLetter), drivelist[driveNumber]);
sl@0:             iLineBuffer.Append(driveLetter);
sl@0: 
sl@0:             }
sl@0:         }
sl@0: 
sl@0: 	iConsole.SetPos(0, KStartRow_AvailableDrives);
sl@0:     iConsole.Printf(iLineBuffer);
sl@0: 	iConsole.ClearToEndOfLine();
sl@0:     CursorHome();
sl@0: }
sl@0: 
sl@0: 
sl@0: void CDisplay::DevicesNumber(TInt aDevicesNumber) const
sl@0:     {
sl@0: 	iConsole.SetPos(0, KRow_DevicesNumber);
sl@0: 	iConsole.Printf(KMsg_DevicesAttached, aDevicesNumber);
sl@0: 	iConsole.ClearToEndOfLine();
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CDisplay::DriveMapL(const TDriveMap& aDriveMap) const
sl@0:     {
sl@0:     TChar letter;
sl@0: 
sl@0:     TInt i = 0;
sl@0: 
sl@0:     // Output to debug port
sl@0:     for (; i < aDriveMap.Count(); i++)
sl@0:         {
sl@0:         TToken token = aDriveMap[i];
sl@0:         if (token)
sl@0:             {
sl@0:             User::LeaveIfError(iFs.DriveToChar(i, letter));
sl@0:             RDebug::Print(KDbgMsg_DriveMap_EntryLetter, TUint(letter), token);
sl@0:             }
sl@0:         }
sl@0: 
sl@0:     // Output to console
sl@0:     TInt row = KStartRow_DriveMap;
sl@0:     for (i = (aDriveMap.Count() -1); i >= 0  &&  row < (KStartRow_DriveMap + KMaxRows_DriveMap); i--)
sl@0:         {
sl@0:         TToken token = aDriveMap[i];
sl@0:         if (token)
sl@0:             {
sl@0:             User::LeaveIfError(iFs.DriveToChar(i, letter));
sl@0:             iConsole.SetPos(0, row);
sl@0:             iConsole.Printf(KMsg_DriveMap_EntryLetter, TUint(letter), token);
sl@0:             iConsole.ClearToEndOfLine();
sl@0:             row++;
sl@0:             }
sl@0:         }
sl@0: 
sl@0:     for (; row < KStartRow_DriveMap + KMaxRows_DriveMap; row++)
sl@0:         {
sl@0:         iConsole.SetPos(0, row);
sl@0:         iConsole.ClearToEndOfLine();
sl@0:         }
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CDisplay::DeviceMapL(TInt aRow, TInt deviceIndex, const TDeviceMap& aDeviceMap) const
sl@0:     {
sl@0:     TChar letter;
sl@0:     TInt drive;
sl@0: 
sl@0:     // Output to debug port
sl@0:     RDebug::Printf("*** deviceIndex = %d", deviceIndex);
sl@0:     for (TInt lunIndex = 0; lunIndex < 16; lunIndex++)
sl@0:         {
sl@0:         drive = aDeviceMap[lunIndex];
sl@0: 
sl@0:         if (drive == 0)
sl@0:             break;
sl@0: 
sl@0:         User::LeaveIfError(iFs.DriveToChar(drive, letter));
sl@0:         RDebug::Printf("*** drive=%d %c", drive, TUint(letter));
sl@0:         }
sl@0: 
sl@0:     //  Output to console
sl@0:     if (aRow >= KMaxRows_DeviceMap)
sl@0:         {
sl@0:         return;
sl@0:         }
sl@0:     RDebug::Printf("-----> Device MAP %x", deviceIndex);
sl@0:     TInt row = KStartRow_DeviceMap + aRow;
sl@0:     iConsole.SetPos(0, row);
sl@0:     iConsole.Printf(KMsg_DeviceMap_DriveList, deviceIndex);
sl@0: 
sl@0:     for (TInt lunIndex = 0; lunIndex < 16; lunIndex++)
sl@0:         {
sl@0:         drive = aDeviceMap[lunIndex];
sl@0: 
sl@0:         if (drive == 0)
sl@0:             break;
sl@0: 
sl@0:         User::LeaveIfError(iFs.DriveToChar(drive, letter));
sl@0:         iConsole.Printf(KMsg_DeviceMap_DriveLunEntry, TUint(letter));
sl@0:         iConsole.ClearToEndOfLine();
sl@0:         }
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CDisplay::DeviceMapClear(TInt aRow) const
sl@0:     {
sl@0:     TInt row = KStartRow_DeviceMap;
sl@0: 
sl@0:     if (aRow > KMaxRows_DeviceMap)
sl@0:         return;
sl@0: 
sl@0:     for (row = KStartRow_DeviceMap + aRow; row < KStartRow_DeviceMap + KMaxRows_DeviceMap; row++)
sl@0:         {
sl@0:         iConsole.SetPos(0, row);
sl@0:         iConsole.ClearToEndOfLine();
sl@0:         }
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CDisplay::GetDriveInfoL(TChar aChar)
sl@0:     {
sl@0:     iScrollWindow->Reset();
sl@0: 
sl@0:     TDriveInfo driveInfo;
sl@0: 
sl@0:     TInt driveNumber;
sl@0:     User::LeaveIfError(iFs.CharToDrive(aChar, driveNumber));
sl@0: 
sl@0:     TLine* line;
sl@0:     line = iScrollWindow->NewLineL();
sl@0:     _LIT(KDrive,"Drive=%d %C");
sl@0:     line->Format(KDrive, driveNumber, TInt(aChar.GetUpperCase()));
sl@0: 
sl@0:     iFs.Drive(driveInfo, driveNumber);
sl@0:     if (driveInfo.iDriveAtt == KDriveAbsent)
sl@0:         {
sl@0:         _LIT(KTxt_MappingDriveError, "Drive absent !");
sl@0:         iScrollWindow->AppendL(KTxt_MappingDriveError);
sl@0:         return;
sl@0:         }
sl@0: 
sl@0:     FormatDriveInfoL(driveInfo);
sl@0: 
sl@0:     TVolumeInfo volumeInfo;
sl@0: 
sl@0:     TInt err = iFs.Volume(volumeInfo, driveNumber);
sl@0:     if (err != KErrNotReady)
sl@0:         // Volume() returns KErrNotReady if no volume present.
sl@0:         // In this case, check next drive number
sl@0:         {
sl@0:         FormatVolumeInfoL(volumeInfo);
sl@0:         }
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CDisplay::DriveInfo()
sl@0:     {
sl@0:     iScrollWindow->Update();
sl@0:     CursorHome();
sl@0:     }
sl@0: 
sl@0: void CDisplay::FormatDriveInfoL(const TDriveInfo& aDriveInfo)
sl@0:     {
sl@0:     // Append battery, media and drive information to aBuffer
sl@0:     // Define descriptor constants using the _LIT macro
sl@0:     _LIT(KDriveInfo1, "iType=%02x %02x iDriveAtt=%04x");
sl@0:     _LIT(KDriveInfo2, "iMediaAtt=%02x");
sl@0:     _LIT(KConnectionBusInternal,"Connection Bus Internal");
sl@0:     _LIT(KConnectionBusUsb,"Connection Bus USB");
sl@0:     _LIT(KConnectionBusUnknown,"Connection Bus Unknown");
sl@0:     _LIT(KNotPresent,"No media present");
sl@0:     _LIT(KFloppy,"Media is floppy disk");
sl@0:     _LIT(KHard,"Media is hard disk");
sl@0:     _LIT(KCDROM,"Media is CD-ROM");
sl@0:     _LIT(KRam,"Media is RAM");
sl@0:     _LIT(KFlash,"Media is flash");
sl@0:     _LIT(KRom,"Media is ROM");
sl@0:     _LIT(KRemote,"Media is remote");
sl@0:     _LIT(KExternal,"Media is external");
sl@0:     _LIT(KNANDFlash,"Media is NAND flash");
sl@0:     _LIT(KUnknown,"Media unknown");
sl@0:     _LIT(KDriveAtts,"Drive attributes:");
sl@0:     _LIT(KLocal," local");
sl@0:     _LIT(KROMDrive," ROM");
sl@0:     _LIT(KRedirected," redirected");
sl@0:     _LIT(KSubstituted," substituted");
sl@0:     _LIT(KInternal," internal");
sl@0:     _LIT(KRemovable," removable");
sl@0:     _LIT(KMediaAtts,"Media attributes:");
sl@0:     _LIT(KDynamic," dynamic");
sl@0:     _LIT(KDual," dual-density");
sl@0:     _LIT(KFormattable," formattable");
sl@0:     _LIT(KLockable," lockable");
sl@0:     _LIT(KLocked," locked");
sl@0:     _LIT(KHasPassword," has password");
sl@0:     _LIT(KWriteProtected," write-protected");
sl@0: 
sl@0:     TLine* line;
sl@0:     line = iScrollWindow->NewLineL();
sl@0:     line->Format(KDriveInfo1, TInt(aDriveInfo.iType), TInt(aDriveInfo.iConnectionBusType), TInt(aDriveInfo.iDriveAtt));
sl@0: 
sl@0:     line = iScrollWindow->NewLineL();
sl@0:     line->Format(KDriveInfo2, TInt(aDriveInfo.iMediaAtt));
sl@0: 
sl@0:     line = iScrollWindow->NewLineL();
sl@0:     switch (aDriveInfo.iConnectionBusType)
sl@0:         {
sl@0:         case EConnectionBusInternal:
sl@0:             line->Append(KConnectionBusInternal);
sl@0:             break;
sl@0:         case EConnectionBusUsb:
sl@0:             line->Append(KConnectionBusUsb);
sl@0:             break;
sl@0:         default:
sl@0:             line->Append(KConnectionBusUnknown);
sl@0:         }
sl@0: 
sl@0:     line = iScrollWindow->NewLineL();
sl@0:     switch (aDriveInfo.iType)
sl@0:             {
sl@0:         case EMediaNotPresent:
sl@0:             line->Append(KNotPresent);
sl@0:             break;
sl@0:         case EMediaFloppy:
sl@0:             line->Append(KFloppy);
sl@0:             break;
sl@0:         case EMediaHardDisk:
sl@0:             line->Append(KHard);
sl@0:             break;
sl@0:         case EMediaCdRom:
sl@0:             line->Append(KCDROM);
sl@0:             break;
sl@0:         case EMediaRam:
sl@0:             line->Append(KRam);
sl@0:             break;
sl@0:         case EMediaFlash:
sl@0:             line->Append(KFlash);
sl@0:             break;
sl@0:         case EMediaRom:
sl@0:             line->Append(KRom);
sl@0:             break;
sl@0:         case EMediaRemote:
sl@0:             line->Append(KRemote);
sl@0:             break;
sl@0:         case EMediaNANDFlash:
sl@0:             line->Append(KNANDFlash);
sl@0:             break;
sl@0:         default:
sl@0:             line->Append(KUnknown);
sl@0:         }
sl@0: 
sl@0:         // Drive Attributes
sl@0:         line = iScrollWindow->NewLineL();
sl@0:         line->Append(KDriveAtts);
sl@0:         if (aDriveInfo.iDriveAtt & KDriveAttLocal)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KLocal);
sl@0:             }
sl@0:         if (aDriveInfo.iDriveAtt & KDriveAttRom)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KROMDrive);
sl@0:             }
sl@0:         if (aDriveInfo.iDriveAtt & KDriveAttRedirected)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KRedirected);
sl@0:             }
sl@0:         if (aDriveInfo.iDriveAtt & KDriveAttSubsted)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KSubstituted);
sl@0:             }
sl@0:         if (aDriveInfo.iDriveAtt & KDriveAttInternal)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KInternal);
sl@0:             }
sl@0:         if (aDriveInfo.iDriveAtt & KDriveAttRemovable)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KRemovable);
sl@0:             }
sl@0:         if (aDriveInfo.iDriveAtt & KDriveAttExternal)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KExternal);
sl@0:             }
sl@0: 
sl@0:         // Media Attributes
sl@0:         line = iScrollWindow->NewLineL();
sl@0:         line->Append(KMediaAtts);
sl@0:         if (aDriveInfo.iMediaAtt & KMediaAttVariableSize)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KDynamic);
sl@0:             }
sl@0:         if (aDriveInfo.iMediaAtt & KMediaAttDualDensity)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KDual);
sl@0:             }
sl@0:         if (aDriveInfo.iMediaAtt & KMediaAttFormattable)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KFormattable);
sl@0:             }
sl@0:         if (aDriveInfo.iMediaAtt & KMediaAttWriteProtected)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KWriteProtected);
sl@0:             }
sl@0:         if (aDriveInfo.iMediaAtt & KMediaAttLockable)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KLockable);
sl@0:             }
sl@0: 
sl@0:         if (aDriveInfo.iMediaAtt & KMediaAttLocked)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KLocked);
sl@0:             }
sl@0:         if (aDriveInfo.iMediaAtt & KMediaAttHasPassword)
sl@0:             {
sl@0:             line = iScrollWindow->NewLineL();
sl@0:             line->Append(KHasPassword);
sl@0:             }
sl@0:     }
sl@0: 
sl@0: void CDisplay::FormatVolumeInfoL(const TVolumeInfo& aVolumeInfo)
sl@0:     {
sl@0:     // Append volume information to line
sl@0:     _LIT(KUID,  "Unique ID:  0x%08X");
sl@0:     _LIT(KSize, "Size:       0x%LX bytes");
sl@0:     _LIT(KFree, "Free space: 0x%LX bytes");
sl@0:     _LIT(KVolName, "Volume name: %S");
sl@0:     TLine* line;
sl@0:     line = iScrollWindow->NewLineL();
sl@0:     line->Format(KUID, aVolumeInfo.iUniqueID);
sl@0:     line = iScrollWindow->NewLineL();
sl@0:     line->Format(KSize, aVolumeInfo.iSize);
sl@0:     line = iScrollWindow->NewLineL();
sl@0:     line->Format(KFree, aVolumeInfo.iFree);
sl@0:     line = iScrollWindow->NewLineL();
sl@0:     line->Format(KVolName, &aVolumeInfo.iName);
sl@0: 
sl@0:     }
sl@0: 
sl@0: 
sl@0: void CDisplay::UpTime(TUint aUpTime) const
sl@0:     {
sl@0:     TUint totalMins = aUpTime/60;
sl@0:     TUint totalHrs = totalMins/60;
sl@0:     iConsole.SetPos(0, KStartRow_UpTime);
sl@0:     iConsole.Printf(KMsg_UpTime, totalHrs, totalMins%60, aUpTime%60);
sl@0:     CursorHome();
sl@0:     }
sl@0: 
sl@0: void CDisplay::MemoryFree(TInt aBytes) const
sl@0:     {
sl@0: 	iConsole.SetPos(0, KStartRow_MemoryFree);
sl@0: 	iConsole.Printf(KMsg_MemoryFree, aBytes);
sl@0:     CursorHome();
sl@0:     }
sl@0: 
sl@0: 
sl@0: //////////////////////////////////////////////////////////////////////////////
sl@0: //
sl@0: // CMessageKeyProcessor
sl@0: //
sl@0: //////////////////////////////////////////////////////////////////////////////
sl@0: CMessageKeyProcessor::CMessageKeyProcessor(CDisplay& aDisplay, RUsbOtgSession& aUsbOtgSession)
sl@0: :   CActive(CActive::EPriorityUserInput),
sl@0:     iDisplay(aDisplay),
sl@0:     iUsbOtgSession(aUsbOtgSession)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: CMessageKeyProcessor* CMessageKeyProcessor::NewLC(CDisplay& aDisplay, RUsbOtgSession& aUsbOtgSession)
sl@0: 	{
sl@0: 	CMessageKeyProcessor* self=new (ELeave) CMessageKeyProcessor(aDisplay, aUsbOtgSession);
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL();
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: void CMessageKeyProcessor::ConstructL()
sl@0: 	{
sl@0: 	// Add to active scheduler
sl@0: 	CActiveScheduler::Add(this);
sl@0: 	RequestCharacter();
sl@0: 	}
sl@0: 
sl@0: 
sl@0: CMessageKeyProcessor::~CMessageKeyProcessor()
sl@0: 	{
sl@0: 	// Make sure we're cancelled
sl@0: 	Cancel();
sl@0: 	}
sl@0: 
sl@0: void CMessageKeyProcessor::DoCancel()
sl@0: 	{
sl@0: 	iDisplay.ReadCancel();
sl@0: 	}
sl@0: 
sl@0: void CMessageKeyProcessor::RunL()
sl@0: 	{
sl@0: 	  // Handle completed request
sl@0: 	ProcessKeyPressL(iDisplay.KeyCode());
sl@0: 	}
sl@0: 
sl@0: void CMessageKeyProcessor::RequestCharacter()
sl@0: 	{
sl@0: 	// A request is issued to the CConsoleBase to accept a
sl@0: 	// character from the keyboard.
sl@0: 	iDisplay.Read(iStatus);
sl@0: 	SetActive();
sl@0: 	}
sl@0: 
sl@0: void CMessageKeyProcessor::ProcessKeyPressL(TKeyCode aKeyCode)
sl@0: 	{
sl@0:     TBool done = HandleKeyL(aKeyCode);
sl@0: 
sl@0:     if (done)
sl@0:         {
sl@0:         CActiveScheduler::Stop();
sl@0:         return;
sl@0:         }
sl@0: 
sl@0:     RequestCharacter();
sl@0: 	}
sl@0: 
sl@0: 
sl@0: TBool CMessageKeyProcessor::HandleKeyL(TKeyCode aKeyCode)
sl@0:     {
sl@0:     TBool done = EFalse;
sl@0:     if (TChar(aKeyCode).IsAlpha())
sl@0:         {
sl@0:         iDisplay.GetDriveInfoL(aKeyCode);
sl@0:         iDisplay.DriveInfo();
sl@0:         return done;
sl@0:         }
sl@0: 
sl@0:     switch (aKeyCode)
sl@0:         {
sl@0:         case EKeyF5:
sl@0:             {
sl@0:             // Update USB status
sl@0:             iUsbOtgSession.DeviceInserted();
sl@0:             iDisplay.DriveListL();
sl@0:             }
sl@0:             break;
sl@0: 
sl@0:         case EKeyUpArrow:
sl@0:         case EKeyPageUp:
sl@0:             iDisplay.PageDec();
sl@0:             iDisplay.DriveInfo();
sl@0:             break;
sl@0:         case EKeyDownArrow:
sl@0:         case EKeyPageDown:
sl@0:             iDisplay.PageInc();
sl@0:             iDisplay.DriveInfo();
sl@0:             break;
sl@0:         case EKeyEscape:
sl@0:             done = ETrue;
sl@0:             break;
sl@0:         default:
sl@0:             break;
sl@0:         }
sl@0:     return done;
sl@0:     }
sl@0: 
sl@0: