sl@0: // Copyright (c) 1998-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: // f32test\server\t_mmc.cpp sl@0: // Tests locking, unlocking and clearing of a password on a suitable sl@0: // device. Currently, this device is a MultiMediaCard. The RFs API sl@0: // allows the user to store the password. sl@0: // This is a manual test, and the operator must observe that the notifier sl@0: // appears exactly when indicated by the program. sl@0: // sl@0: // sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: // definitions from p32mmc.h sl@0: sl@0: const TInt KMMCCIDLength = 16; sl@0: sl@0: class TMMC sl@0: { sl@0: public: sl@0: static inline TUint32 BigEndian32(const TUint8*); sl@0: static inline void BigEndian4Bytes(TUint8* aPtr, TUint32 aVal); sl@0: }; sl@0: sl@0: sl@0: inline TUint32 TMMC::BigEndian32(const TUint8* aPtr) sl@0: {return( (aPtr[0]<<24) | (aPtr[1]<<16) | (aPtr[2]<<8) | (aPtr[3]) );} sl@0: sl@0: inline void TMMC::BigEndian4Bytes(TUint8* aPtr, TUint32 aVal) sl@0: { sl@0: aPtr[0] = (TUint8)((aVal >> 24) & 0xFF); sl@0: aPtr[1] = (TUint8)((aVal >> 16) & 0xFF); sl@0: aPtr[2] = (TUint8)((aVal >> 8) & 0xFF); sl@0: aPtr[3] = (TUint8)(aVal & 0xFF); sl@0: } sl@0: sl@0: sl@0: sl@0: // local test data sl@0: sl@0: LOCAL_D RTest test(_L("t_mmc")); sl@0: sl@0: LOCAL_D RFs TheFs; sl@0: LOCAL_D RFile TheFile; sl@0: sl@0: #if defined(__WINS__) sl@0: _LIT(KSessionPath, "X:\\"); sl@0: const TInt KDrv = EDriveX; sl@0: const TText KDrvLtr = 'x'; sl@0: #else sl@0: _LIT(KSessionPath, "D:\\"); sl@0: const TInt KDrv = EDriveD; sl@0: const TText KDrvLtr = 'd'; sl@0: #endif sl@0: sl@0: _LIT(KTestFileName, "testFile"); sl@0: sl@0: enum TAccessType {EAccessUnlock, EAccessStore, EAccessCancel, EAccessWrongPw, EAccessNoNotifier}; sl@0: sl@0: LOCAL_D TMediaPassword KNul, KPw1, KPw2, KPw3, KPw4, KPw5; sl@0: sl@0: #ifdef __WINS__ sl@0: const static TUint8 cid0[KMMCCIDLength] = // "CID0ccccccccccc#"; sl@0: { sl@0: 'C', 'I', 'D', '0', sl@0: 'c', 'c', 'c', 'c', sl@0: 'c', 'c', 'c', 'c', sl@0: 'c', 'c', 'c', '#' sl@0: }; sl@0: #else sl@0: const static TUint8 cid0[KMMCCIDLength] = // big-endian, CID0 sl@0: { sl@0: 0x06, 0x00, 0x00, 0x31, sl@0: 0x36, 0x4d, 0x20, 0x20, sl@0: 0x20, 0x00, 0xb4, 0xff, sl@0: 0xff, 0xff, 0x63, 0xd9 sl@0: }; sl@0: #endif sl@0: sl@0: // local test functions sl@0: sl@0: LOCAL_C void RemountMedia(); sl@0: LOCAL_C void ClearControllerStore(); sl@0: LOCAL_C void DeletePasswordFile(); sl@0: LOCAL_C TInt CreateFile(); sl@0: LOCAL_C TInt PWFileSize(TInt &aLength); sl@0: LOCAL_C TInt AccessDisk(TAccessType aAccess, const TDesC8 &aPWD); sl@0: LOCAL_C void TestHasPassword(TBool aIL, TBool aHP); sl@0: sl@0: LOCAL_C void TestLockUnlockR(); sl@0: LOCAL_C void TestNullPasswords(); sl@0: LOCAL_C void TestLockUnlock(); sl@0: sl@0: LOCAL_C void TestPasswordStore(); sl@0: LOCAL_C void TestWriteToDisk(); sl@0: sl@0: LOCAL_C void TestFormat(); sl@0: LOCAL_C void TestRemount(); sl@0: sl@0: sl@0: /** force a remount on the removable media. */ sl@0: sl@0: LOCAL_C void RemountMedia() sl@0: { sl@0: #ifdef __WINS__ sl@0: // UserSvr::ForceRemountMedia(ERemovableMedia0); sl@0: User::After(1 * 1500 * 1000); sl@0: #else sl@0: // UserSvr::ForceRemountMedia(ERemovableMedia0); sl@0: // User::After(1 * 1500 * 1000); sl@0: test.Printf(_L("Remove and re-insert card. Press \'z\' when finished.\n")); sl@0: while (test.Getch() != 'z') sl@0: { /* empty. */ } sl@0: #endif sl@0: } sl@0: sl@0: sl@0: /** ask the user to replace the current lockable media with another */ sl@0: sl@0: LOCAL_C void ChangeMedia() sl@0: { sl@0: #ifdef __WINS__ sl@0: test.Printf(_L("Press f4 whilst holding down f5\n")); sl@0: test.Printf(_L("Press z when completed\n")); sl@0: while(test.Getch() != 'z') sl@0: { /* empty */ } sl@0: #else sl@0: test.Printf(_L("Remove and insert other card. Press \'z\' when finished.\n")); sl@0: while (test.Getch() != 'z') sl@0: { /* empty. */ } sl@0: #endif sl@0: } sl@0: sl@0: sl@0: /** disable auto-unlock by clearing controller store */ sl@0: sl@0: LOCAL_C void ClearControllerStore() sl@0: { sl@0: TBuf8<1> nulSt; sl@0: test(TBusLocalDrive::WritePasswordData(nulSt) == KErrNone);// empty sl@0: test(TBusLocalDrive::PasswordStoreLengthInBytes() == 0); sl@0: } sl@0: sl@0: sl@0: /** delete the password store file. Does not affect the auto-unlock mechanism. */ sl@0: sl@0: LOCAL_C void DeletePasswordFile() sl@0: { sl@0: TInt r; sl@0: TBuf mediaPWrdFile(KMediaPWrdFile); sl@0: mediaPWrdFile[0] = (TUint8) RFs::GetSystemDriveChar(); sl@0: do sl@0: { sl@0: User::After(100 * 1000); sl@0: r = TheFs.Delete(mediaPWrdFile); sl@0: } while (r == KErrInUse); sl@0: sl@0: test(r == KErrNone || r == KErrNotFound); sl@0: } sl@0: sl@0: sl@0: /** attempt to create a file on the removable media and return any error code */ sl@0: sl@0: LOCAL_C TInt CreateFile() sl@0: { sl@0: RFile f; sl@0: TInt r = f.Replace(TheFs, KTestFileName, EFileShareAny); sl@0: if (r == KErrNone) sl@0: f.Close(); sl@0: return r; sl@0: } sl@0: sl@0: sl@0: /** get size of the media store file in bytes, and return any error code */ sl@0: sl@0: LOCAL_C TInt PWFileSize(TInt &aLength) sl@0: { sl@0: TInt r; // error code sl@0: sl@0: // allow low priority background writer thread to start and finish sl@0: sl@0: User::After(1 * 1000 * 1000); sl@0: sl@0: TBuf mediaPWrdFile(KMediaPWrdFile); sl@0: mediaPWrdFile[0] = (TUint8) RFs::GetSystemDriveChar(); sl@0: RFile f; sl@0: if ((r = f.Open(TheFs, mediaPWrdFile, EFileShareAny)) == KErrNone) sl@0: { sl@0: r = f.Size(aLength); sl@0: f.Close(); sl@0: } sl@0: sl@0: return r; sl@0: } sl@0: sl@0: sl@0: /** sl@0: * write message to screen and attempt to access disk. If card is locked then async sl@0: * notifier will be brought up from within file server. sl@0: */ sl@0: sl@0: LOCAL_C TInt AccessDisk(TAccessType aAccess, const TDesC8 &aPWD) sl@0: { sl@0: TBuf16<16> pwd; sl@0: pwd.Copy((const TUint16 *)aPWD.Ptr(), aPWD.Length() / 2); sl@0: sl@0: if (aAccess == EAccessUnlock || aAccess == EAccessStore) sl@0: test.Printf(_L("\"%S\": "), &pwd); sl@0: sl@0: switch(aAccess) sl@0: { sl@0: case EAccessUnlock: sl@0: test.Printf(_L("unlock\n")); sl@0: break; sl@0: sl@0: case EAccessStore: sl@0: test.Printf(_L("store\n")); sl@0: break; sl@0: sl@0: case EAccessCancel: sl@0: test.Printf(_L("cancel\n")); sl@0: break; sl@0: sl@0: case EAccessWrongPw: sl@0: test.Printf(_L("wrong\n")); sl@0: break; sl@0: sl@0: case EAccessNoNotifier: sl@0: test.Printf(_L("** no notifier **\n")); sl@0: break; sl@0: sl@0: default: sl@0: test(EFalse); sl@0: break; sl@0: } sl@0: sl@0: TInt r = TheFile.Open(TheFs, KTestFileName, EFileShareAny); sl@0: if(r == KErrNone) sl@0: TheFile.Close(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: sl@0: /** sl@0: * uses RFs::DriveInfo() to test if the card has a password. Is checking sl@0: * that iHasPassword in TMMCCard is maintained properly. sl@0: */ sl@0: sl@0: inline TBool bits_set(TUint aMsk, TUint aSel) sl@0: { sl@0: return (aMsk & aSel) == aSel; sl@0: } sl@0: sl@0: LOCAL_C void TestHasPassword(TBool aIL, TBool aHP) sl@0: { sl@0: const TInt d = KDrv; sl@0: RFs &fs = TheFs; sl@0: sl@0: TDriveInfo di; sl@0: test(fs.Drive(di, d) == KErrNone); sl@0: sl@0: #ifdef __WINS__ sl@0: test(aIL == bits_set(di.iMediaAtt, KMediaAttLocked | KMediaAttLockable | KMediaAttHasPassword)); sl@0: test(aHP == bits_set(di.iMediaAtt, KMediaAttLockable | KMediaAttHasPassword)); sl@0: #else sl@0: test(aIL == bits_set(di.iMediaAtt, KMediaAttLocked | KMediaAttHasPassword)); sl@0: test(aHP == bits_set(di.iMediaAtt, KMediaAttHasPassword)); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: // -------- test functions -------- sl@0: sl@0: sl@0: /** sl@0: * test return values of LockDrive(), UnlockDrive() and ClearPassword() sl@0: * without trying use the disk. This tests that the functions return the sl@0: * same values as the TBusLocalDrive functions. sl@0: * sl@0: * EPbPswdUnlock EPbPswdLock EPbPswdClear sl@0: * right wrong right wrong right wrong sl@0: * locked None AccDen AccDec AccDen AccDen AccDen sl@0: * unlocked AldExst AldExst None AccDec None AccDen sl@0: * sl@0: * Locked means inaccessible, not just has password. sl@0: */ sl@0: sl@0: LOCAL_C void TestLockUnlockR() sl@0: { sl@0: test.Start(_L("TestLockUnlockR")); sl@0: sl@0: const TInt d = KDrv; sl@0: RFs &fs = TheFs; sl@0: sl@0: test.Next(_L("assign password")); sl@0: test(fs.LockDrive(d, KNul, KPw1, EFalse) == KErrNone); // assign test password sl@0: TestHasPassword(EFalse, ETrue); sl@0: RemountMedia(); // card is now locked sl@0: TestHasPassword(ETrue, ETrue); sl@0: sl@0: test.Next(_L("lock locked card")); sl@0: test(fs.LockDrive(d, KPw2, KPw1, EFalse) == KErrAccessDenied); // lock locked wrong sl@0: TestHasPassword(ETrue, ETrue); sl@0: test(fs.LockDrive(d, KPw1, KPw1, EFalse) == KErrAccessDenied); // lock locked right sl@0: TestHasPassword(ETrue, ETrue); sl@0: sl@0: test.Next(_L("unlock locked card")); sl@0: test(fs.UnlockDrive(d, KPw2, EFalse) == KErrAccessDenied); // unlock locked wrong sl@0: TestHasPassword(ETrue, ETrue); sl@0: test(fs.UnlockDrive(d, KPw1, EFalse) == KErrNone); // unlock locked right sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("unlock unlocked card")); sl@0: test(fs.UnlockDrive(d, KPw1, EFalse) == KErrAlreadyExists); // unlock unlocked right sl@0: TestHasPassword(EFalse, ETrue); sl@0: test(fs.UnlockDrive(d, KPw2, EFalse) == KErrAlreadyExists); // unlock unlocked wrong sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("lock unlocked card")); sl@0: test(fs.LockDrive(d, KPw2, KPw1, EFalse) == KErrAccessDenied); // lock unlocked wrong sl@0: TestHasPassword(EFalse, ETrue); sl@0: test(fs.LockDrive(d, KPw1, KPw1, EFalse) == KErrNone); // lock unlocked right sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("clear unlocked card")); sl@0: test(fs.ClearPassword(d, KPw2) == KErrAccessDenied); // clear unlocked wrong sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: RemountMedia(); sl@0: test(fs.UnlockDrive(d, KPw1, EFalse) == KErrNone); sl@0: TestHasPassword(EFalse, ETrue); sl@0: test(fs.ClearPassword(d, KPw1) == KErrNone); // clear unlocked right sl@0: TestHasPassword(EFalse, EFalse); sl@0: sl@0: test.Next(_L("assign password")); sl@0: test(fs.LockDrive(d, KNul, KPw1, EFalse) == KErrNone); // assign test password sl@0: TestHasPassword(EFalse, ETrue); sl@0: RemountMedia(); // card is now locked sl@0: TestHasPassword(ETrue, ETrue); sl@0: sl@0: test.Next(_L("clear locked card")); sl@0: test(fs.ClearPassword(d, KPw2) == KErrAccessDenied); // clear locked wrong sl@0: TestHasPassword(ETrue, ETrue); sl@0: test(fs.ClearPassword(d, KPw1) == KErrAccessDenied); // clear locked right sl@0: TestHasPassword(ETrue, ETrue); sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: test(fs.UnlockDrive(d, KPw1, EFalse) == KErrNone); sl@0: TestHasPassword(EFalse, ETrue); sl@0: test(fs.ClearPassword(d, KPw1) == KErrNone); sl@0: TestHasPassword(EFalse, EFalse); sl@0: sl@0: ClearControllerStore(); sl@0: DeletePasswordFile(); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: /** test the special cases where null passwords are used. */ sl@0: sl@0: LOCAL_C void TestNullPasswords() sl@0: { sl@0: test.Start(_L("TestNullPasswords")); sl@0: sl@0: test.Next(_L("card has no password")); sl@0: test(TheFs.LockDrive(KDrv, KNul, KNul, ETrue) == KErrAccessDenied); sl@0: test(TheFs.UnlockDrive(KDrv, KNul, ETrue) == KErrAlreadyExists); sl@0: test(TheFs.ClearPassword(KDrv, KNul) == KErrAccessDenied); sl@0: sl@0: test.Next(_L("card has password and is unlocked")); sl@0: test(TheFs.LockDrive(KDrv, KNul, KPw1, ETrue) == KErrNone); sl@0: RemountMedia(); sl@0: test(TheFs.LockDrive(KDrv, KNul, KNul, ETrue) == KErrAccessDenied); sl@0: test(TheFs.UnlockDrive(KDrv, KNul, ETrue) == KErrAlreadyExists); sl@0: test(TheFs.ClearPassword(KDrv, KNul) == KErrAccessDenied); sl@0: test(TheFs.ClearPassword(KDrv, KPw1) == KErrNone); sl@0: sl@0: test.Next(_L("unlock with null disallowed")); sl@0: RemountMedia(); sl@0: test(TheFs.UnlockDrive(KDrv, KNul, ETrue) == KErrAccessDenied); sl@0: test.Next(_L("check can still use card")); sl@0: test(TheFs.LockDrive(KDrv, KNul, KPw1, ETrue) == KErrNone); // check can still use sl@0: test(TheFs.ClearPassword(KDrv, KPw1) == KErrNone); sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: ClearControllerStore(); sl@0: DeletePasswordFile(); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: /** test LockDrive(), UnlockDrive() and ClearPassword() with locked media notifier */ sl@0: sl@0: LOCAL_C void TestLockUnlock() sl@0: { sl@0: test.Start(_L("TestLockUnlock")); sl@0: sl@0: const TInt d = KDrv; sl@0: RFs &fs = TheFs; sl@0: sl@0: test.Next(_L("create test file")); sl@0: test(CreateFile() == KErrNone); sl@0: sl@0: test.Next(_L("lock card and don't store")); sl@0: test(fs.LockDrive(d, KNul, KPw1, EFalse) == KErrNone); // unlocked KPw1 sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("access with right pwd")); sl@0: RemountMedia(); // locked KPw1 sl@0: TestHasPassword(ETrue, ETrue); sl@0: test(AccessDisk(EAccessUnlock, KPw1) == KErrNone); sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("access with cancelled pwd")); sl@0: RemountMedia(); // locked KPw1 sl@0: TestHasPassword(ETrue, ETrue); sl@0: test(AccessDisk(EAccessCancel, KNul) == KErrLocked); sl@0: TestHasPassword(ETrue, ETrue); sl@0: sl@0: test.Next(_L("access with new stored pwd")); sl@0: RemountMedia(); sl@0: TestHasPassword(ETrue, ETrue); sl@0: test(AccessDisk(EAccessStore, KPw1) == KErrNone); // unlocked KPw1 sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("access with stored pwd")); sl@0: RemountMedia(); // unlocked KPw1 (use store) sl@0: TestHasPassword(EFalse, ETrue); sl@0: test(AccessDisk(EAccessNoNotifier, KNul) == KErrNone); sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("lock wrong pwd")); sl@0: test(fs.LockDrive(d, KPw3, KPw2, EFalse) == KErrAccessDenied); // unlocked KPw1 sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("change pwd")); sl@0: test(fs.LockDrive(d, KPw1, KPw2, EFalse) == KErrNone); // unlocked KPw2 (rem from store) sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("mapping removed from store")); sl@0: RemountMedia(); sl@0: test(AccessDisk(EAccessUnlock, KPw2) == KErrNone); sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("wrong password")); sl@0: RemountMedia(); // locked KPw2 sl@0: TestHasPassword(ETrue, ETrue); sl@0: test(AccessDisk(EAccessWrongPw, KNul) == KErrLocked); sl@0: TestHasPassword(ETrue, ETrue); sl@0: sl@0: test.Next(_L("unlocked card")); sl@0: test(fs.UnlockDrive(d, KPw2, ETrue) == KErrNone); // unlocked KPw2 (add to store) sl@0: TestHasPassword(EFalse, ETrue); sl@0: test(AccessDisk(EAccessNoNotifier, KNul) == KErrNone); // before power down sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("clear wrong pwd")); sl@0: test(fs.ClearPassword(d, KPw1) == KErrAccessDenied); // KPw2 backup kept sl@0: TestHasPassword(EFalse, ETrue); sl@0: RemountMedia(); // unlocked KPw2 (use store) sl@0: TestHasPassword(EFalse, ETrue); sl@0: test(AccessDisk(EAccessNoNotifier, KNul) == KErrNone); sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("change pwd")); sl@0: test(fs.LockDrive(d, KPw2, KPw1, EFalse) == KErrNone); // locked KPw1 (rem from store) sl@0: TestHasPassword(EFalse, ETrue); sl@0: RemountMedia(); sl@0: TestHasPassword(ETrue, ETrue); sl@0: test(AccessDisk(EAccessUnlock, KPw1) == KErrNone); sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("cancelled pwd")); sl@0: RemountMedia(); sl@0: TestHasPassword(ETrue, ETrue); sl@0: test(AccessDisk(EAccessCancel, KNul) == KErrLocked); sl@0: TestHasPassword(ETrue, ETrue); sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: test(fs.UnlockDrive(d, KPw1, EFalse) == KErrNone); sl@0: TestHasPassword(EFalse, ETrue); sl@0: test(fs.ClearPassword(KDrv, KPw1) == KErrNone); sl@0: TestHasPassword(EFalse, EFalse); sl@0: RemountMedia(); sl@0: TestHasPassword(EFalse, EFalse); sl@0: test(AccessDisk(EAccessNoNotifier, KNul) == KErrNone); sl@0: TestHasPassword(EFalse, EFalse); sl@0: ClearControllerStore(); sl@0: DeletePasswordFile(); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: /** sl@0: * test password store by accessing disk in various states. Ensures password sl@0: * store file is right size after each operation. More detailed checking of sl@0: * the TBusLocalDrive::ReadPasswordData() ouput is done in t_pwstr. sl@0: */ sl@0: sl@0: LOCAL_C void TestPasswordStore() sl@0: { sl@0: test.Start(_L("TestPasswordStore")); sl@0: sl@0: // TInt r; // general error code sl@0: RFs &fs = TheFs; sl@0: const TInt d = KDrv; sl@0: sl@0: test.Next(_L("create test file on first media")); sl@0: test(CreateFile() == KErrNone); sl@0: sl@0: test.Next(_L("lock card and don't store")); sl@0: test(fs.LockDrive(d, KNul, KPw5, EFalse) == KErrNone); // {} sl@0: TestHasPassword(EFalse, ETrue); sl@0: TInt size1; sl@0: test(PWFileSize(size1) == KErrNotFound); sl@0: sl@0: test.Next(_L("lock card and store")); sl@0: test(fs.LockDrive(d, KPw5, KPw3, ETrue) == KErrNone); // {0 |-> 3} sl@0: TestHasPassword(EFalse, ETrue); sl@0: test.Next(_L("access media1 with stored password")); sl@0: sl@0: RemountMedia(); sl@0: TestHasPassword(EFalse, ETrue); sl@0: test(AccessDisk(EAccessNoNotifier, KNul) == KErrNone); sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("test password file exists")); sl@0: test(PWFileSize(size1) == KErrNone); sl@0: test(size1 == 16 + 4 + KPw3.Length()); sl@0: sl@0: test.Next(_L("change cards and add second password to store")); sl@0: ChangeMedia(); sl@0: sl@0: test.Next(_L("create test file on second media")); sl@0: test(CreateFile() == KErrNone); sl@0: sl@0: test.Next(_L("lock card and store")); sl@0: test(fs.LockDrive(d, KNul, KPw4, ETrue) == KErrNone); // {0 |-> 3, 1 |-> 4} sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: TInt size2; sl@0: test(PWFileSize(size2) == KErrNone); sl@0: test(size2 == 16 + 4 + KPw3.Length() + 16 + 4 + KPw4.Length()); sl@0: sl@0: test.Next(_L("access media2 with stored password")); sl@0: RemountMedia(); sl@0: test(AccessDisk(EAccessNoNotifier, KNul) == KErrNone); sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: test.Next(_L("change password")); sl@0: test(fs.LockDrive(d, KPw4, KPw5, ETrue) == KErrNone); // {0 |-> 3, 1 |-> 5} sl@0: TestHasPassword(EFalse, ETrue); sl@0: sl@0: TInt size3; sl@0: test(PWFileSize(size3) == KErrNone); sl@0: test(size3 == 16 + 4 + KPw3.Length() + 16 + 4 + KPw5.Length()); sl@0: sl@0: test.Next(_L("access media1 with stored password")); sl@0: ChangeMedia(); sl@0: test(AccessDisk(EAccessNoNotifier, KNul) == KErrNone); sl@0: sl@0: test.Next(_L("remove password from media 1")); sl@0: test(fs.ClearPassword(d, KPw3) == KErrNone); // {1 |-> 5} - 0 |-> 3 sl@0: TestHasPassword(EFalse, EFalse); sl@0: test(PWFileSize(size3) == KErrNone); sl@0: test(size3 == 16 + 4 + KPw5.Length()); sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: ChangeMedia(); sl@0: test(fs.ClearPassword(d, KPw5) == KErrNone); // {} - 1 |-> 5 sl@0: TestHasPassword(EFalse, EFalse); sl@0: test(PWFileSize(size3) == KErrNone); sl@0: test(size3 == 0); sl@0: test.Printf(_L("replace original card\n")); sl@0: ChangeMedia(); // use original card sl@0: ClearControllerStore(); sl@0: DeletePasswordFile(); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: /** sl@0: * check the spin off delayed writer thread can work when many requests are queued. sl@0: * sl@0: * The background writer runs at EPriorityMuchLess, so it will not be executed until sl@0: * this thread sleeps. sl@0: */ sl@0: sl@0: LOCAL_C void TestWriteToDisk() sl@0: { sl@0: test.Start(_L("TestWriteToDisk")); sl@0: sl@0: TInt r; // error code sl@0: TBuf8<1> noMappings; sl@0: sl@0: test.Next(_L("Queuing threads")); sl@0: test.Printf(_L("Queuing 100 writes\n")); sl@0: sl@0: const TInt KQueueCnt = 100; sl@0: sl@0: TInt i; sl@0: TMediaPassword oldPswd; // empty - no password at start sl@0: TMediaPassword newPswd; sl@0: for (i = 0; i < KQueueCnt; ++i) sl@0: { sl@0: newPswd.Fill(i, KMaxMediaPassword); sl@0: test(TheFs.LockDrive(KDrv, oldPswd, newPswd, ETrue) == KErrNone); sl@0: oldPswd.Copy(newPswd); sl@0: } sl@0: sl@0: test.Printf(_L("Waiting 20 seconds for threads to complete\n")); sl@0: User::After(20 * 1000 * 1000); sl@0: sl@0: // check password file contains the last writing. sl@0: sl@0: test.Next(_L("check password file contains last writing")); sl@0: const TInt KFileLen = 16 + sizeof(TUint32) + KMaxMediaPassword; sl@0: RFile f; sl@0: TBuf mediaPWrdFile(KMediaPWrdFile); sl@0: mediaPWrdFile[0] = (TUint8) RFs::GetSystemDriveChar(); sl@0: test(f.Open(TheFs, mediaPWrdFile, EFileShareExclusive | EFileStream | EFileRead) == KErrNone); sl@0: TInt sz; sl@0: test(f.Size(sz) == KErrNone); sl@0: test(sz == KFileLen); sl@0: sl@0: TBuf8 chkBuf; sl@0: test(f.Read(chkBuf, KFileLen) == KErrNone); sl@0: // defer checking buffer contents until after password cleared so not left sl@0: // with locked card if test fails. sl@0: f.Close(); sl@0: sl@0: test(TheFs.ClearPassword(KDrv, oldPswd) == KErrNone); sl@0: User::After(1 * 1000 * 1000); // wait to finish writing sl@0: sl@0: r = TheFs.Delete(mediaPWrdFile); sl@0: test(r == KErrNone || r == KErrNotFound); sl@0: test(TBusLocalDrive::WritePasswordData(noMappings) == KErrNone); sl@0: sl@0: // check contents of password file correspond to last written buffer. sl@0: sl@0: test(chkBuf.Length() == KFileLen); sl@0: test(chkBuf.Mid(0, KMMCCIDLength) == TPtrC8(cid0, KMMCCIDLength)); sl@0: const TUint32 len = TMMC::BigEndian32(chkBuf.Mid(KMMCCIDLength, sizeof(TUint32)).Ptr()); sl@0: test(len == TInt(KMaxMediaPassword)); sl@0: test(chkBuf.Mid(KMMCCIDLength + sizeof(TUint32), KMMCCIDLength) == oldPswd); sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: ClearControllerStore(); sl@0: DeletePasswordFile(); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: /** test unable to format locked card */ sl@0: sl@0: LOCAL_C void TestFormat() sl@0: { sl@0: test.Start(_L("TestFormat")); sl@0: sl@0: // TInt r; // error code sl@0: RFs &fs = TheFs; sl@0: const TInt d = KDrv; sl@0: sl@0: TBuf<3> bfDrv; sl@0: bfDrv.Append(KDrvLtr); sl@0: _LIT(KBP, ":\\"); sl@0: bfDrv.Append(KBP); sl@0: sl@0: test.Next(_L("create test file")); sl@0: test(CreateFile() == KErrNone); sl@0: sl@0: test.Next(_L("lock drive")); sl@0: test(TheFs.LockDrive(KDrv, KNul, KPw2, EFalse) == KErrNone); sl@0: RemountMedia(); sl@0: sl@0: test.Next(_L("unlock card and don't store")); sl@0: test(AccessDisk(EAccessUnlock, KPw2) == KErrNone); sl@0: sl@0: // format unlocked drive sl@0: test.Next(_L("format unlocked card")); sl@0: RFormat fmt; sl@0: TInt count; sl@0: test(fmt.Open(fs, bfDrv, EHighDensity, count) == KErrNone); sl@0: while (count > 0) sl@0: { sl@0: test.Printf(_L("\rfmt:%d "), count); sl@0: test(fmt.Next(count) == KErrNone); sl@0: } sl@0: test.Printf(_L("\n")); sl@0: fmt.Close(); sl@0: sl@0: test.Next(_L("format locked media")); sl@0: RemountMedia(); // locked KPw2 sl@0: test.Printf(_L("Notifier: No password required. Press cancel. \n")); sl@0: test(fmt.Open(fs, bfDrv, EHighDensity, count) == KErrLocked); sl@0: sl@0: test.Next(_L("unlock locked card")); sl@0: test(fs.UnlockDrive(d, KPw2, EFalse) == KErrNone); sl@0: test(fs.ClearPassword(d, KPw2) == KErrNone); sl@0: sl@0: test.Next(_L("create test file")); sl@0: test(CreateFile() == KErrNone); sl@0: sl@0: test.Next(_L("remount media, check not locked")); sl@0: RemountMedia(); sl@0: test(AccessDisk(EAccessNoNotifier, KNul) == KErrNone); sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: ClearControllerStore(); sl@0: DeletePasswordFile(); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: /** do media change with file open */ sl@0: sl@0: LOCAL_C void TestRemount() sl@0: { sl@0: test.Start(_L("TestRemount")); sl@0: sl@0: // TInt r; // general error code sl@0: RFs &fs = TheFs; sl@0: const TInt d = KDrv; sl@0: sl@0: test.Next(_L("create file")); sl@0: TFileName fn; sl@0: fn.Append(KDrvLtr); sl@0: _LIT(KFN, ":\\openfile"); sl@0: fn.Append(KFN); sl@0: test.Printf(_L("fn = \"%S\"\n"), &fn); sl@0: sl@0: RFile f; sl@0: test(f.Replace(fs, fn, EFileShareAny) == KErrNone); sl@0: sl@0: test.Next(_L("lock card")); sl@0: test(fs.LockDrive(d, KNul, KPw5, EFalse) == KErrNone); sl@0: sl@0: test.Next(_L("access with right pwd")); sl@0: RemountMedia(); sl@0: test(AccessDisk(EAccessUnlock, KPw5) == KErrNone); sl@0: sl@0: test.Next(_L("access with wrong pwd")); sl@0: RemountMedia(); sl@0: test(AccessDisk(EAccessWrongPw, KNul) == KErrLocked); sl@0: sl@0: test.Next(_L("access with cancelled pwd")); sl@0: RemountMedia(); sl@0: test(AccessDisk(EAccessCancel, KNul) == KErrLocked); sl@0: sl@0: test.Next(_L("clear password")); sl@0: test(fs.UnlockDrive(d, KPw5, EFalse) == KErrNone); sl@0: test(fs.ClearPassword(d, KPw5) == KErrNone); sl@0: sl@0: test(AccessDisk(EAccessNoNotifier, KNul) == KErrNone); sl@0: sl@0: test.Next(_L("close and delete file")); sl@0: f.Close(); sl@0: test(fs.Delete(fn) == KErrNone); sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: ClearControllerStore(); sl@0: DeletePasswordFile(); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: /** sl@0: * entry point. Displays instructions; sets up heap checking; sets up sl@0: * file server session and calls individual tests. Mounts drive for WINS. sl@0: */ sl@0: sl@0: _LIT(KSDProtDriverFileName,"MEDSDP"); sl@0: _LIT(KSDProtDriverObjName,"Media.SdP"); sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: test.Title(); sl@0: test.Start(_L("Starting T_MMC")); sl@0: sl@0: test.Printf(_L("The notifier should only apear along with user instructions.\n")); sl@0: test.Printf(_L("The test has failed otherwise.\n")); sl@0: test.Printf(_L("\n")); sl@0: test.Printf(_L("Use return to simulate unlock button on notifier\n")); sl@0: test.Printf(_L("Use space to simulate store button on notifier\n")); sl@0: test.Printf(_L("Use escape to simulate cancel button on notifier\n")); sl@0: test.Printf(_L("Press a key to continue ...\n\n")); sl@0: test.Getch(); sl@0: sl@0: test(TheFs.Connect() == KErrNone); sl@0: sl@0: TBuf mediaPWrdFile(KMediaPWrdFile); sl@0: mediaPWrdFile[0] = (TUint8) RFs::GetSystemDriveChar(); sl@0: TParsePtrC ppc(mediaPWrdFile); sl@0: TInt r = TheFs.MkDir(ppc.DriveAndPath()); sl@0: test(r == KErrNone || r == KErrAlreadyExists); sl@0: sl@0: // The media driver for the protected area of the SD card uses mount sl@0: // info. This is also used for password unlocking by the MMC media driver. sl@0: // Due to a temporary problem with the way mount info. is assigned to DMedia sl@0: // objects which results in a conflict between the two drivers, unload sl@0: // the protected area SD card driver for duration of test. sl@0: TheFs.RemountDrive(KDrv,NULL,KLocDrvRemountPostponeRemount); sl@0: User::FreePhysicalDevice(KSDProtDriverObjName); sl@0: sl@0: test(TheFs.SetSessionPath(KSessionPath) == KErrNone); sl@0: sl@0: // initialize the TMediaPassword data sl@0: KNul.Copy(reinterpret_cast(L""), 0); sl@0: KPw1.Copy(reinterpret_cast(L"b"), 2); sl@0: KPw2.Copy(reinterpret_cast(L"cd"), 4); sl@0: KPw3.Copy(reinterpret_cast(L"def"), 6); sl@0: KPw4.Copy(reinterpret_cast(L"efgh"), 8); sl@0: KPw5.Copy(reinterpret_cast(L"fghij"), 10); sl@0: sl@0: test.Next(_L("calling ClearControllerStore")); sl@0: ClearControllerStore(); sl@0: test.Next(_L("calling DeletePasswordFile")); sl@0: DeletePasswordFile(); sl@0: sl@0: test.Next(_L("calling TestLockUnlockR")); sl@0: TestLockUnlockR(); sl@0: test.Next(_L("calling TestNullPasswords")); sl@0: TestNullPasswords(); sl@0: test.Next(_L("calling TestLockUnlock")); sl@0: TestLockUnlock(); sl@0: sl@0: test.Next(_L("calling TestPasswordStore")); sl@0: TestPasswordStore(); sl@0: test.Next(_L("calling TestWriteToDisk")); sl@0: TestWriteToDisk(); sl@0: sl@0: test.Next(_L("calling TestFormat")); sl@0: TestFormat(); sl@0: test.Next(_L("calling TestRemount")); sl@0: TestRemount(); sl@0: sl@0: // Restore SD Card protected area media driver sl@0: User::LoadPhysicalDevice(KSDProtDriverFileName); sl@0: sl@0: TheFs.Close(); sl@0: test.End(); sl@0: test.Close(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: sl@0: return KErrNone; sl@0: } sl@0: