726 } |
732 } |
727 |
733 |
728 |
734 |
729 void DoTest14(TInt aDrvNum); |
735 void DoTest14(TInt aDrvNum); |
730 TInt CreateStuffedFile(RFs& aFs, const TDesC& aFileName, TUint aFileSize); |
736 TInt CreateStuffedFile(RFs& aFs, const TDesC& aFileName, TUint aFileSize); |
731 TInt CreateEmptyFile(RFs& aFs, const TDesC& aFileName, TUint aFileSize); |
|
732 TBool CheckFileContents(RFs& aFs, const TDesC& aFileName); |
737 TBool CheckFileContents(RFs& aFs, const TDesC& aFileName); |
733 #ifndef __NFE_MEDIA_DRIVER_PRESENT__ |
738 #ifndef __NFE_MEDIA_DRIVER_PRESENT__ |
734 TBool CheckBufferContents(const TDesC8& aBuffer, TUint aPrintBaseAddr=0); |
739 TBool CheckBufferContents(const TDesC8& aBuffer, TUint aPrintBaseAddr=0); |
735 #endif |
740 #endif |
736 |
741 |
737 /** |
742 /** |
738 Testing unallocated data initialization vulnerability in RFile |
743 Testing unallocated data initialization vulnerability in RFile |
739 This test is performed on RAM drives and non-removable media that supports DeleteNotify (KMediaAttDeleteNotify flag) |
744 This test is performed on RAM drives and non-removable media that supports DeleteNotify (KMediaAttDeleteNotify flag) |
740 e.g. XSR NAND |
745 e.g. XSR NAND |
741 */ |
746 */ |
742 LOCAL_C void Test14() |
747 static void Test14() |
743 { |
748 { |
744 TInt nRes; |
|
745 |
749 |
746 test.Next(_L("Testing unallocated data initialization vulnerability in RFile")); |
750 test.Next(_L("Testing unallocated data initialization vulnerability in RFile")); |
747 |
751 |
748 TDriveList driveList; |
752 TDriveInfo driveInfo; |
749 TDriveInfo driveInfo; |
753 |
750 |
754 //-- get drive info |
751 //-- 1. get drives list |
755 test(TheFs.Drive(driveInfo, gDriveNum) == KErrNone); |
752 nRes=TheFs.DriveList(driveList); |
756 |
753 test_KErrNone(nRes); |
757 const TBool bMediaSuitable = (driveInfo.iType == EMediaRam) || //-- RAM drives should be tested |
754 |
758 (driveInfo.iType == EMediaFlash) || //-- NOR FLASH drives should be tested |
755 //-- 2. walk through all drives, performing the test only on suitable ones |
759 (driveInfo.iType == EMediaNANDFlash && driveInfo.iMediaAtt & KMediaAttDeleteNotify); //-- NAND media with DeleteNotify support |
756 for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum) |
760 |
|
761 if(!bMediaSuitable) |
757 { |
762 { |
758 if(!driveList[drvNum]) |
763 test.Printf(_L("This test can't be performed on this type of the media! Skipping.\n")); |
759 continue; //-- skip unexisting drive |
764 return; |
760 |
765 } |
761 //-- get drive info |
766 |
762 test(TheFs.Drive(driveInfo, drvNum) == KErrNone); |
767 DoTest14(gDriveNum); |
763 |
|
764 //-- select a suitable drive for the testing. It shall be RAM drive, of FLASH but not removable |
|
765 //-- and not read only, if it is FLASH, it shall support "Delete Notify" facility |
|
766 switch(driveInfo.iType) |
|
767 { |
|
768 //-- RAM drive, OK |
|
769 case EMediaRam: |
|
770 break; |
|
771 |
|
772 //-- FLASH drive, OK |
|
773 case EMediaFlash: |
|
774 case EMediaNANDFlash: |
|
775 if(driveInfo.iMediaAtt & KMediaAttDeleteNotify) |
|
776 break; //-- this type of media shall support DeleteNotify flag, otherwise this test is inconsistent |
|
777 else continue; |
|
778 |
|
779 //break; //unreacable |
|
780 |
|
781 default: |
|
782 continue; |
|
783 }//switch(driveInfo.iType) |
|
784 |
|
785 if (driveInfo.iDriveAtt & KDriveAttSubsted) |
|
786 { |
|
787 // skip subst drives. |
|
788 continue; |
|
789 } |
|
790 |
|
791 TBool readOnly = driveInfo.iMediaAtt & KMediaAttWriteProtected; |
|
792 if(readOnly) |
|
793 continue; //-- nothing to do, can't create any file etc. |
|
794 |
|
795 //-- skip test on the emulator's C: drive, doesn't make any sense because |
|
796 //-- in this case we deal with WIN32 API and filesystem. |
|
797 #ifdef __WINS__ |
|
798 if(drvNum == 2) |
|
799 { |
|
800 test.Printf(_L("Skipping test on emulator's C: drive\n")); |
|
801 continue; |
|
802 } |
|
803 #endif |
|
804 |
|
805 DoTest14(drvNum); |
|
806 |
|
807 }// for (TInt drvNum=0; ... |
|
808 |
|
809 } |
768 } |
810 |
769 |
811 //-------------------------------------------------------- |
770 //-------------------------------------------------------- |
812 |
771 |
813 /** |
772 /** |
1393 } |
1326 } |
1394 |
1327 |
1395 return bRes; |
1328 return bRes; |
1396 } |
1329 } |
1397 |
1330 |
1398 |
1331 //-------------------------------------------------------- |
1399 GLDEF_C void CallTestsL() |
1332 /** |
1400 // |
1333 Check if the drive aDriveNo is finalised or not. |
1401 // Call tests that may leave |
1334 The "CleanShutDown" is obtained by QueryVolumeInfoExt API which is FS-agnostic. |
1402 // |
1335 |
|
1336 @param aDriveNo drive number to query. |
|
1337 @return ETrue if the drive if finalised |
|
1338 */ |
|
1339 static TBool IsVolumeFinalised(TInt aDriveNo) |
|
1340 { |
|
1341 TInt nRes; |
|
1342 TPckgBuf<TBool> boolPckg; |
|
1343 |
|
1344 //-- 1. get "Finalised" state by using the API |
|
1345 nRes = TheFs.QueryVolumeInfoExt(aDriveNo, EIsDriveFinalised, boolPckg); |
|
1346 test_KErrNone(nRes); |
|
1347 |
|
1348 return boolPckg(); |
|
1349 } |
|
1350 |
|
1351 |
|
1352 //-------------------------------------------------------- |
|
1353 /** |
|
1354 This is a file system - agnostic test that verifies RFs::FinaliseDrive() API |
|
1355 There are also file system - specific tests that check similar functionallity (see t_mount for example) |
|
1356 |
|
1357 */ |
|
1358 void TestDriveFinalisation() |
|
1359 { |
|
1360 test.Next(_L("TestDriveFinalisation(). Testing RFs::FinaliseDrives() API\n")); |
|
1361 |
|
1362 |
|
1363 if((!Is_Fat(TheFs, gDriveNum) && !Is_ExFat(TheFs, gDriveNum)) || Is_Fat12(TheFs, gDriveNum) ) |
|
1364 { |
|
1365 test.Printf(_L("This test can't be performed on current file system, skipping.\n")); |
|
1366 return; |
|
1367 } |
|
1368 |
|
1369 TVolumeInfo v; |
|
1370 TInt nRes; |
|
1371 |
|
1372 nRes = TheFs.Volume(v); |
|
1373 test(nRes==KErrNone); |
|
1374 |
|
1375 if(v.iDrive.iMediaAtt & KMediaAttVariableSize) |
|
1376 { |
|
1377 test.Printf(_L("Skipping. RAM drive not tested.\n")); |
|
1378 return; |
|
1379 } |
|
1380 |
|
1381 |
|
1382 TBool bDriveFinalised; |
|
1383 |
|
1384 //============= 1. finalise the drive (RW mode) and check the result |
|
1385 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1386 test_KErrNone(nRes); |
|
1387 |
|
1388 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1389 test(bDriveFinalised); |
|
1390 |
|
1391 //-- 1.1 finalise the drive second time EFinal_RW -> EFinal_RW shall work |
|
1392 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1393 test_KErrNone(nRes); |
|
1394 |
|
1395 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1396 test(bDriveFinalised); |
|
1397 |
|
1398 //============= 2. create a file. Shall succeed (EFinal_RW), the volume shall become unfinalised |
|
1399 |
|
1400 RFile file; |
|
1401 _LIT(KFileName, "\\my_file1.dat"); |
|
1402 _LIT8(KSomeData, "this is some data"); |
|
1403 |
|
1404 nRes = CreateEmptyFile(TheFs, KFileName, 128000); |
|
1405 test_KErrNone(nRes); |
|
1406 |
|
1407 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1408 test(!bDriveFinalised); //-- the volume has become "unfinalised" |
|
1409 |
|
1410 //---------------------------------------------------------------------------------- |
|
1411 //-- test volume finalisation with opened objects |
|
1412 |
|
1413 //-- 2.1 having opened files should be OK for volume finalisation |
|
1414 |
|
1415 //-- 2.1.1 RW finalisation; after the volume finalised it should be possible to write to the opened file |
|
1416 nRes = file.Open(TheFs, KFileName, EFileWrite | EFileWriteDirectIO); |
|
1417 test_KErrNone(nRes); |
|
1418 |
|
1419 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1420 test_KErrNone(nRes); |
|
1421 |
|
1422 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1423 test(bDriveFinalised); |
|
1424 |
|
1425 nRes = file.Write(0, KSomeData); |
|
1426 test_KErrNone(nRes); |
|
1427 |
|
1428 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1429 test(!bDriveFinalised); //-- the volume should become "unfinalised" |
|
1430 |
|
1431 //-- 2.1.2 RO finalisation; after the volume finalised it shouldn't be possible to write to the opened file |
|
1432 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); |
|
1433 test_KErrNone(nRes); |
|
1434 |
|
1435 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1436 test(bDriveFinalised); |
|
1437 |
|
1438 nRes = file.Write(0, KSomeData); |
|
1439 test(nRes == KErrAccessDenied); //-- no write access to the volume |
|
1440 |
|
1441 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1442 test(bDriveFinalised); //-- the volume should become "unfinalised" |
|
1443 |
|
1444 file.Close(); |
|
1445 |
|
1446 //-- remount FS, the drive shall become RW |
|
1447 nRes = RemountFS(TheFs, gDriveNum); |
|
1448 test_KErrNone(nRes); |
|
1449 |
|
1450 |
|
1451 //-- 2.2 having opened directories should be OK for volume finalisation |
|
1452 _LIT(KDirName, "\\Dir11235tt\\"); |
|
1453 MakeDir(KDirName); |
|
1454 RDir dir; |
|
1455 |
|
1456 //-- 2.2.1 RW finalisation; after the volume finalised it should be possible to have write access to it |
|
1457 nRes = dir.Open(TheFs, KDirName, KEntryAttNormal); |
|
1458 test_KErrNone(nRes); |
|
1459 |
|
1460 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1461 test_KErrNone(nRes); |
|
1462 |
|
1463 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1464 test(bDriveFinalised); |
|
1465 |
|
1466 nRes = CreateEmptyFile(TheFs, KFileName, 128000); |
|
1467 test_KErrNone(nRes); |
|
1468 |
|
1469 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1470 test(!bDriveFinalised); |
|
1471 |
|
1472 //-- 2.1.2 RO finalisation; after the volume finalised it shouldn't be possible to write to it |
|
1473 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); |
|
1474 test_KErrNone(nRes); |
|
1475 |
|
1476 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1477 test(bDriveFinalised); |
|
1478 |
|
1479 nRes = CreateEmptyFile(TheFs, KFileName, 128000); |
|
1480 test(nRes == KErrAccessDenied); //-- no write access to the volume |
|
1481 |
|
1482 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1483 test(bDriveFinalised); //-- the volume should become "unfinalised" |
|
1484 |
|
1485 dir.Close(); |
|
1486 |
|
1487 //-- remount FS, the drive shall become RW |
|
1488 nRes = RemountFS(TheFs, gDriveNum); |
|
1489 test_KErrNone(nRes); |
|
1490 |
|
1491 //-- 2.3 having opened disk access objects, like formats or raw disks makes finalisation impossible |
|
1492 RFormat format; |
|
1493 RRawDisk rawDisk; |
|
1494 TInt fmtCnt; |
|
1495 |
|
1496 //-- 2.3.1 format |
|
1497 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1498 test_KErrNone(nRes); |
|
1499 |
|
1500 nRes = format.Open(TheFs, gSessionPath, EFullFormat, fmtCnt); |
|
1501 test_KErrNone(nRes); |
|
1502 |
|
1503 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1504 test(nRes == KErrInUse); |
|
1505 |
|
1506 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); |
|
1507 test(nRes == KErrInUse); |
|
1508 |
|
1509 format.Close(); |
|
1510 |
|
1511 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1512 test_KErrNone(nRes); |
|
1513 |
|
1514 //-- 2.3.2 raw disk |
|
1515 nRes = rawDisk.Open(TheFs, gDriveNum); |
|
1516 test_KErrNone(nRes); |
|
1517 |
|
1518 |
|
1519 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1520 test(nRes == KErrInUse); |
|
1521 |
|
1522 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); |
|
1523 test(nRes == KErrInUse); |
|
1524 |
|
1525 rawDisk.Close(); |
|
1526 |
|
1527 //-- 2.4 Volume finalisation and file system dismounting |
|
1528 |
|
1529 //-- 2.4.1 "graceful" dismounting should finalise the drive correctly |
|
1530 |
|
1531 //-- "unfinalise the volume" |
|
1532 nRes = CreateEmptyFile(TheFs, KFileName, 128000); |
|
1533 test_KErrNone(nRes); |
|
1534 |
|
1535 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1536 test(!bDriveFinalised); |
|
1537 |
|
1538 TFSDescriptor fsDesc; |
|
1539 nRes = GetFileSystemDescriptor(TheFs, gDriveNum, fsDesc); |
|
1540 test_KErrNone(nRes); |
|
1541 |
|
1542 //-- gracefully dismount the file system |
|
1543 nRes = TheFs.DismountFileSystem(fsDesc.iFsName, gDriveNum); |
|
1544 test_KErrNone(nRes); |
|
1545 |
|
1546 //-- mount it back |
|
1547 nRes = MountFileSystem(TheFs, gDriveNum, fsDesc); |
|
1548 test_KErrNone(nRes); |
|
1549 |
|
1550 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1551 test(bDriveFinalised); |
|
1552 |
|
1553 //-- 2.4.2 "forced" dismounting, usually happens when "graceful doesn't work, because there are files opened on the volume. |
|
1554 //-- Should also finalise the drive correctly |
|
1555 |
|
1556 //-- "unfinalise the volume" |
|
1557 nRes = CreateEmptyFile(TheFs, KFileName, 128000); |
|
1558 test_KErrNone(nRes); |
|
1559 |
|
1560 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1561 test(!bDriveFinalised); |
|
1562 |
|
1563 //-- open a file on the volume, this will prevent graceful dismounting |
|
1564 nRes = file.Open(TheFs, KFileName, EFileWrite | EFileWriteDirectIO); |
|
1565 test_KErrNone(nRes); |
|
1566 |
|
1567 nRes = GetFileSystemDescriptor(TheFs, gDriveNum, fsDesc); |
|
1568 test_KErrNone(nRes); |
|
1569 |
|
1570 //-- try gracefully dismount the file system |
|
1571 nRes = TheFs.DismountFileSystem(fsDesc.iFsName, gDriveNum); |
|
1572 test(nRes == KErrInUse); //-- no luck, as expected |
|
1573 |
|
1574 //-- now do dismounting by force |
|
1575 TRequestStatus rqStat; |
|
1576 TheFs.NotifyDismount(gDriveNum, rqStat, EFsDismountForceDismount); |
|
1577 User::WaitForRequest(rqStat); |
|
1578 test_KErrNone(rqStat.Int()); |
|
1579 |
|
1580 nRes = file.Write(0, KSomeData); |
|
1581 test(nRes == KErrNotReady); |
|
1582 |
|
1583 file.Close(); |
|
1584 |
|
1585 //-- mount it back |
|
1586 nRes = MountFileSystem(TheFs, gDriveNum, fsDesc); |
|
1587 test_KErrNone(nRes); |
|
1588 |
|
1589 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1590 test(bDriveFinalised); |
|
1591 |
|
1592 //============= 3. test "unfinalise API" |
|
1593 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EForceUnfinalise); |
|
1594 test_KErrNone(nRes); |
|
1595 |
|
1596 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1597 test(!bDriveFinalised); //-- the volume has become "unfinalised" |
|
1598 |
|
1599 //============= 4. test finalisation into RO mode |
|
1600 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); //-- the volume becomes RO |
|
1601 test_KErrNone(nRes); |
|
1602 |
|
1603 //-- try to write a file on RO volume; it shall fail with KErrAccessDenied |
|
1604 nRes = CreateEmptyFile(TheFs, KFileName, 128000); |
|
1605 test(nRes == KErrAccessDenied); |
|
1606 file.Close(); |
|
1607 |
|
1608 //-- 4.1 try to finalise into EFinal_RW mode, shall fail with KErrAccessDenied |
|
1609 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1610 test(nRes == KErrAccessDenied); |
|
1611 |
|
1612 //-- 4.2 "unfinalise" the volume, it still shall remain RO |
|
1613 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EForceUnfinalise); |
|
1614 test_KErrNone(nRes); |
|
1615 |
|
1616 //-- try to write a file on RO volume; it shall fail with KErrAccessDenied |
|
1617 nRes = CreateEmptyFile(TheFs, KFileName, 128000); |
|
1618 test(nRes == KErrAccessDenied); |
|
1619 file.Close(); |
|
1620 |
|
1621 //-- remount FS, the drive shall become RW |
|
1622 nRes = RemountFS(TheFs, gDriveNum); |
|
1623 test_KErrNone(nRes); |
|
1624 |
|
1625 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1626 test(bDriveFinalised); |
|
1627 |
|
1628 //-- try to write a file on RW volume, shall be OK |
|
1629 nRes = CreateEmptyFile(TheFs, KFileName, 128000); |
|
1630 test(nRes == KErrNone); |
|
1631 file.Close(); |
|
1632 |
|
1633 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1634 test(!bDriveFinalised); |
|
1635 |
|
1636 //============= 5. test various finalisation modes |
|
1637 |
|
1638 //-- 5.1 Not finalised -> EFinal_RW (KErrNone) |
|
1639 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1640 test(nRes == KErrNone); |
|
1641 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1642 test(bDriveFinalised); |
|
1643 |
|
1644 //-- 5.2 EFinal_RW -> EFinal_RO (KErrNone) |
|
1645 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); |
|
1646 test(nRes == KErrNone); |
|
1647 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1648 test(bDriveFinalised); |
|
1649 |
|
1650 //-- 5.2 EFinal_RO -> EFinal_RW (KErrAccessDenied) |
|
1651 nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW); |
|
1652 test(nRes == KErrAccessDenied); |
|
1653 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1654 test(bDriveFinalised); |
|
1655 |
|
1656 //-- 5.3 restore |
|
1657 nRes = RemountFS(TheFs, gDriveNum); |
|
1658 test_KErrNone(nRes); |
|
1659 |
|
1660 |
|
1661 //============= 6. test old RFs::FinaliseDrives API |
|
1662 |
|
1663 nRes = CreateEmptyFile(TheFs, KFileName, 128000); |
|
1664 test(nRes == KErrNone); |
|
1665 |
|
1666 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1667 test(!bDriveFinalised); |
|
1668 |
|
1669 TheFs.FinaliseDrives(); //-- shall work as TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW) but for ALL drives |
|
1670 |
|
1671 bDriveFinalised = IsVolumeFinalised(gDriveNum); |
|
1672 test(bDriveFinalised); |
|
1673 |
|
1674 nRes = CreateEmptyFile(TheFs, KFileName, 128000); |
|
1675 test(nRes == KErrNone); |
|
1676 |
|
1677 |
|
1678 |
|
1679 } |
|
1680 |
|
1681 |
|
1682 void CallTestsL() |
1403 { |
1683 { |
1404 |
1684 //-- set up console output |
|
1685 F32_Test_Utils::SetConsole(test.Console()); |
|
1686 |
|
1687 TInt nRes=TheFs.CharToDrive(gDriveToTest, gDriveNum); |
|
1688 test_KErrNone(nRes); |
|
1689 |
|
1690 PrintDrvInfo(TheFs, gDriveNum); |
|
1691 |
|
1692 TestDriveFinalisation(); |
1405 Test1(); |
1693 Test1(); |
1406 Test2(); |
1694 Test2(); |
1407 Test3(); |
1695 Test3(); |
1408 Test4(); |
1696 Test4(); |
1409 Test5(); |
1697 Test5(); |