TInt MountNTFS()
	{
	TBuf<256> cmd;
	User::CommandLine(cmd);
	TLex cmdlex(cmd);
	cmdlex.SkipSpace();
	TUint c = (TUint)cmdlex.Get();
	if (c>='a' && c<='z')
		c-=0x20;
	if (c<'A' || c>'Z')
		return KErrArgument;
	TBuf<4> driveLetter;
	driveLetter.SetLength(1);
	driveLetter[0] = (TText)c;
    RDebug::Print(_L("Drive %S"), &driveLetter);
    
    TInt driveNumber = TInt(c-'A') + TInt(EDriveA);
	TInt r;
	driveLetter.Append(_L(":\\"));
    
    RDebug::Print(_L("Add file system: %S"), &KFileSystemDllName);
    r=TheFs.AddFileSystem(KFileSystemDllName);
    if (r!=KErrNone && r!=KErrAlreadyExists)
		{
		RDebug::Print(_L("Failed: %d"), r);
		return r;
		}

	TFullName name;
	r = TheFs.FileSystemName(name, driveNumber);
	if (name.Length() != 0)
		{
        RDebug::Print(_L("Dismounting %S on drive %S\r\n"), &name, &driveLetter);
        r=TheFs.DismountFileSystem(name, driveNumber);
		RDebug::Print(_L("Dismount ret=%d"), r);
    	}

    RDebug::Print(_L("Mount NTFS on drive %S\r\n"), &driveLetter);
    r = TheFs.MountFileSystem(KFileSystemName, driveNumber);
	RDebug::Print(_L("Mount r=%d"),r);
	return KErrNone;
	}
//////////////////////////////////////////////////////////////////////////////
//
// Application entry point
//
//////////////////////////////////////////////////////////////////////////////
static void RunAppL()
	{

    TInt error = KErrUnknown;

	//RDebug::Print(_L("USBMSAPP: Creating console\n"));
	console = Console::NewL(KTxtApp,TSize(KConsFullScreen,KConsFullScreen));
	CleanupStack::PushL(console);

	console->SetPos(0,2);
	console->Printf(_L("========================================"));

	// Command line: list of drive letters to auto-mount (all if not specified)
	User::CommandLine(mountList);
	mountList.UpperCase();

	CActiveScheduler* sched = new(ELeave) CActiveScheduler;
	CleanupStack::PushL(sched);
	CActiveScheduler::Install(sched);

	fs.Connect();
	CleanupClosePushL(fs);

	_LIT(KMountAllDefault,"(all)");
	console->SetPos(0,3);
	LogPrint(_L("Drives to auto-mount: %S"), (mountList.Length() ? &mountList : &KMountAllDefault));

	// Add MS file system
	error = fs.AddFileSystem(KMsFsy);
	if(error != KErrNone && error != KErrAlreadyExists)
		{
		//RDebug::Print(_L("AddFileSystem failed, err=%d\n"), error);
		User::Leave(error);
		}
	console->SetPos(0,4);
	LogPrint(_L("MSFS file system:\tAdded OK\n"));

	RUsb usb;

	// Load the logical device
	_LIT(KDriverFileName,"EUSBC.LDD");
	error = User::LoadLogicalDevice(KDriverFileName);
	if (error != KErrAlreadyExists)
		User::LeaveIfError(error);

	error = usb.Open(0);
	User::LeaveIfError(error);

	_LIT(KOtgdiLddFilename, "otgdi");
	// Check for OTG support
	TBuf8<KUsbDescSize_Otg> otg_desc;
	error = usb.GetOtgDescriptor(otg_desc);
	if (!(error == KErrNotSupported || error == KErrNone))
		{
		LogPrint(_L("Error %d while fetching OTG descriptor"), error);
		User::Leave(-1);
		return;
		}

	// On an OTG device we have to start the OTG driver, otherwise the Client
	// stack will remain disabled forever.
	if (error == KErrNotSupported)
	{
		CleanupClosePushL(usb);
		User::Leave(-1);
	}

	error = User::LoadLogicalDevice(KOtgdiLddFilename);
	if (error != KErrNone)
		{
		LogPrint(_L("Error %d on loading OTG LDD"), error);
		User::Leave(-1);
		return;
		}

	RUsbOtgDriver iOtgPort;

	error = iOtgPort.Open();
	if (error != KErrNone)
		{
		LogPrint(_L("Error %d on opening OTG port"), error);
		User::Leave(-1);
		return;
		}
	error = iOtgPort.StartStacks();
	if (error != KErrNone)
		{
		LogPrint(_L("Error %d on starting USB stack"), error);
		User::Leave(-1);
		return;
		}

	CleanupClosePushL(usb);

//		RDebug::Print(_L("USBMSAPP: Create active objects\n"));
	CMessageKeyProcessor::NewLC(console);
	CPropertyWatch::NewLC(EUsbMsDriveState_KBytesRead, PropertyHandlers::Read);
	CPropertyWatch::NewLC(EUsbMsDriveState_KBytesWritten, PropertyHandlers::Written);
	CPropertyWatch::NewLC(EUsbMsDriveState_DriveStatus, PropertyHandlers::DriveStatus);
	CPropertyWatch::NewLC(EUsbMsDriveState_MediaError, PropertyHandlers::MediaError);
	CUsbWatch::NewLC(usb);
	CPeriodUpdate::NewLC();

	RUsbMassStorage UsbMs;
	TBuf<8>  t_vendorId(_L("vendor"));
	TBuf<16> t_productId(_L("product"));
	TBuf<4>  t_productRev(_L("1.00"));

	TMassStorageConfig msConfig;
	msConfig.iVendorId.Copy(t_vendorId);
	msConfig.iProductId.Copy(t_productId);
	msConfig.iProductRev.Copy(t_productRev);

//   	console->Printf(_L("Connect to Mass Storage"));
	error = UsbMs.Connect();
	User::LeaveIfError(error);

//   	console->Printf(_L("Start Mass Storage"));
	error = UsbMs.Start(msConfig);
	User::LeaveIfError(error);

	TBuf8<KUsbDescSize_Device> deviceDescriptor;
	error = usb.GetDeviceDescriptor(deviceDescriptor);
	User::LeaveIfError(error);

	const TInt KUsbSpecOffset = 2;
	const TInt KUsbDeviceClassOffset = 4;
	const TInt KUsbVendorIdOffset = 8;
	const TInt KUsbProductIdOffset = 10;
	const TInt KUsbDevReleaseOffset = 12;
	//Change the USB spec number to 2.00
	deviceDescriptor[KUsbSpecOffset]   = 0x00;
	deviceDescriptor[KUsbSpecOffset+1] = 0x02;
	//Change the Device Class, Device SubClass and Device Protocol
	deviceDescriptor[KUsbDeviceClassOffset] = 0x00;
	deviceDescriptor[KUsbDeviceClassOffset+1] = 0x00;
	deviceDescriptor[KUsbDeviceClassOffset+2] = 0x00;
	//Change the device vendor ID (VID) to 0x0E22 (Symbian)
	deviceDescriptor[KUsbVendorIdOffset]   = 0x22;   // little endian
	deviceDescriptor[KUsbVendorIdOffset+1] = 0x0E;
	//Change the device product ID (PID) to 0x1111
	deviceDescriptor[KUsbProductIdOffset]   = 0x12;
	deviceDescriptor[KUsbProductIdOffset+1] = 0x11;
	//Change the device release number to 3.05
	deviceDescriptor[KUsbDevReleaseOffset]   = 0x05;
	deviceDescriptor[KUsbDevReleaseOffset+1] = 0x03;
	error = usb.SetDeviceDescriptor(deviceDescriptor);
	User::LeaveIfError(error);

	// Remove possible Remote-Wakup support in Configuration descriptor,
	// so that we can use the MSC device also easily for Chapter9 testing.
	TBuf8<KUsbDescSize_Config> configDescriptor;
	error = usb.GetConfigurationDescriptor(configDescriptor);
	User::LeaveIfError(error);
	const TInt KConfDesc_AttribOffset = 7;
	configDescriptor[KConfDesc_AttribOffset] &= ~KUsbDevAttr_RemoteWakeup;
	error = usb.SetConfigurationDescriptor(configDescriptor);
	User::LeaveIfError(error);

	_LIT16(productID_L, "Symbian USB Mass Storage Device (Base)");
	TBuf16<KUsbStringDescStringMaxSize / 2> productID(productID_L);
	error = usb.SetProductStringDescriptor(productID);
	User::LeaveIfError(error);

	TRequestStatus enum_status;
	console->SetPos(0,5);
	LogPrint(_L("Re-enumerating...\n"));
	usb.ReEnumerate(enum_status);
	User::LeaveIfError(error);
	console->SetPos(0,5);
	User::WaitForRequest(enum_status);
	if(enum_status.Int() == KErrNone)
		LogPrint(_L("Re-enumeration Done\n"));
	else
		LogPrint(_L("Re-enumeration not successfully done\n"));


    console->SetPos(0,14);
    TBuf<3>password(KDefPwd);
    LogPrint(_L("Password: %S"), &password);

	ShowDriveSelection();

	console->SetPos(0,17);

	_LIT(KMsgTitleB,"Menu: q=quit  d=chg drv\n      m=mount u=unmount\n       l=lock i=lock n=unlock\n      c=clr pwd");


	//RDebug::Print(_L("USBMSAPP: Start CActiveScheduler\n"));

	console->Printf(KMsgTitleB);

	CActiveScheduler::Start();

	error = UsbMs.Stop();
	User::LeaveIfError(error);
	UsbMs.Close();
	error = fs.RemoveFileSystem(KMsFs);
	User::LeaveIfError(error);

	CleanupStack::PopAndDestroy(11);

	iOtgPort.StopStacks();
	iOtgPort.Close();
	error = User::FreeLogicalDevice(RUsbOtgDriver::Name());
	User::LeaveIfError(error);

	error = User::FreeLogicalDevice(_L("USBC"));
	User::LeaveIfError(error);

	}
LOCAL_C void doComponentTest()
    //
    // Do the component test
    //
	{
#ifndef __NO_HEAP_CHECK
	__UHEAP_MARK;
#endif	

    TInt ret;
    test.Printf(_L("Start MountStart test. Be sure MMC card is inserted.\n"));
    // Parse the CommandLine argument: removal drive
    ParseCommandArguments();

    // Connect to the server
    LOG_AND_TEST(KErrNone,  fs.Connect());
	CleanupClosePushL(fs); 
	   
    // Convert drive letter to its numerical equivalent
	ret = fs.CharToDrive(driveLetter,removalDrvNo);
	LOG_AND_TEST(ret,  KErrNone);	

	// Load the logical device
	_LIT(KDriverFileName,"TESTUSBC.LDD");
	ret = User::LoadLogicalDevice(KDriverFileName);
	LOG_AND_TEST(KErrNone, ret);

    // Add MS file system
	_LIT(KMsFsFsy, "MSFS.FSY");
	LOG_AND_TEST(KErrNone, fs.AddFileSystem(KMsFsFsy));
	
    // Start Ms file system
    RUsbMassStorage usbMs;
    CleanupClosePushL(usbMs);

    TMassStorageConfig config;
    
    config.iVendorId.Copy(_L("vendorId"));
    config.iProductId.Copy(_L("productId"));
    config.iProductRev.Copy(_L("rev"));

	ret = usbMs.Connect();
    LOG_AND_TEST(KErrNone, ret);
  
    // Start usb mass storage device
    LOG_AND_TEST(KErrNone , usbMs.Start(config));

    // Format removable drive using FAT FS
    RFormat format;
    TBuf<2> removalDrive;
    removalDrive.Append(driveLetter);
    removalDrive.Append(':');
    TInt tracksRemaining;
    test.Printf(_L("Start MMC card formatting\n"));
    LOG_AND_TEST(KErrNone, format.Open(fs, removalDrive, EHighDensity|EQuickFormat, tracksRemaining));
    while (tracksRemaining)
        {
        test.Printf(_L("."));
        LOG_AND_TEST(KErrNone,  format.Next(tracksRemaining));
        }
    format.Close();
  	test.Printf(_L("\nDone!\n"));

    // Open a session to LDD
    test.Printf(_L("Open LDD\n"));
    LOG_AND_TEST(KErrNone, usbcClient.Open(0));

	test.Printf(_L("Creating CActiveScheduler\n"));
	CActiveScheduler* sched = new(ELeave) CActiveScheduler;
	CleanupStack::PushL(sched);
	CActiveScheduler::Install(sched);
  	
	// Create a state machine
	CStateMachine* sm = CStateMachine::NewL();
	CleanupStack::PushL(sm);
    sm->AddState(EUsbMsDriveState_Disconnected);
    sm->AddState(EUsbMsDriveState_Connecting);
    sm->AddState(EUsbMsDriveState_Connected);
    sm->AddState(EUsbMsDriveState_Disconnecting);
    sm->AddState(EUsbMsDriveState_Active);
    sm->AddState(EUsbMsDriveState_Locked);
    sm->AddState(EUsbMsState_Written);
    sm->AddState(EUsbMsState_Read);
    
    sm->SetInitState(EUsbMsDriveState_Disconnected);

  	CPropertyHandler* driveStatusHandler 	= CMsDriveStatusHandler::NewLC(removalDrvNo, *sm);
  	CPropertyHandler* readStatusHandler 	= CMsReadStatusHandler::NewLC(removalDrvNo, *sm);
  	CPropertyHandler* writtenStatusHandler 	= CMsWrittenStatusHandler::NewLC(removalDrvNo, *sm);
  	
 	CPropertyWatch::NewLC(EUsbMsDriveState_DriveStatus, *driveStatusHandler);
 	CPropertyWatch::NewLC(EUsbMsDriveState_KBytesRead, *readStatusHandler);
 	CPropertyWatch::NewLC(EUsbMsDriveState_KBytesWritten, *writtenStatusHandler);
 	
	CActiveScheduler::Start();

	ret = usbMs.Stop();
	test.Printf(_L("usbMs.Stop returned %d\n"), ret);
	test(ret == KErrNone);
	usbMs.Close();
	// 1 sec delay for MSFS to stop
	User::After(1000000);
	ret = fs.RemoveFileSystem(KMsFs);
	test(ret == KErrNone || ret == KErrNotFound);
	test.Printf(_L("RemoveFileSystem returned %d\n"), ret);

	usbcClient.Close();
	ret = User::FreeLogicalDevice(_L("USBC"));
	test.Printf(_L("FreeLogicalDevice returned %d\n"), ret);
	test(ret == KErrNone);			

	CleanupStack::PopAndDestroy(3);	// 3 CPropertyWatches 
	CleanupStack::PopAndDestroy(3);	// 3 property status change handlers
	CleanupStack::PopAndDestroy(sm);
	CleanupStack::PopAndDestroy(sched);
	CleanupStack::PopAndDestroy(&usbMs);
	CleanupStack::PopAndDestroy(&fs);

#ifndef __NO_HEAP_CHECK
	__UHEAP_MARKEND;
#endif
	}