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_pwstr.cpp sl@0: // Tests peripheral bus controller password store. sl@0: // sl@0: // sl@0: sl@0: //#include sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: // define this macro to autodetect card re-insertion sl@0: #define __AUTO_DETECT_MEDIA_CHANGE__ sl@0: sl@0: const TUint KMMCCIDLength=16; sl@0: sl@0: class TCID sl@0: { sl@0: public: sl@0: inline TCID() {} // Default constructor sl@0: inline TCID(const TUint8*); sl@0: inline TCID& operator=(const TCID&); sl@0: inline TCID& operator=(const TUint8*); sl@0: inline TBool operator==(const TCID&) const; sl@0: inline TBool operator==(const TUint8*) const; sl@0: inline void Copy(TUint8*) const; // Copies big endian 16 bytes CID sl@0: inline TUint8 At(TUint anIndex) const; // Byte from CID at anIndex sl@0: //private: sl@0: public: sl@0: TUint8 iData[KMMCCIDLength]; // Big endian 128 bit bitfield representing CID sl@0: }; 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: // -------- class TCID -------- sl@0: sl@0: inline TCID::TCID(const TUint8* aPtr) sl@0: {memcpy(&iData[0], aPtr, KMMCCIDLength);} sl@0: sl@0: inline TCID& TCID::operator=(const TCID& aCID) sl@0: {memcpy(&iData[0], &aCID.iData[0], KMMCCIDLength); return(*this);} sl@0: sl@0: inline TCID& TCID::operator=(const TUint8* aPtr) sl@0: {memcpy(&iData[0], aPtr, KMMCCIDLength); return(*this);} sl@0: sl@0: inline TBool TCID::operator==(const TCID& aCID) const sl@0: {return(memcompare(&iData[0],KMMCCIDLength,&aCID.iData[0],KMMCCIDLength)==0);} sl@0: sl@0: inline TBool TCID::operator==(const TUint8* aPtr) const sl@0: {return(memcompare(&iData[0],KMMCCIDLength,aPtr,KMMCCIDLength)==0);} sl@0: sl@0: inline void TCID::Copy(TUint8* aPtr) const sl@0: {memcpy(aPtr, &iData[0], KMMCCIDLength);} sl@0: sl@0: inline TUint8 TCID::At(TUint anIndex) const sl@0: {return(iData[KMMCCIDLength-1-anIndex]);} 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: // Static data. sl@0: sl@0: LOCAL_D RTest test(_L("T_PWSTR")); sl@0: sl@0: LOCAL_D TBusLocalDrive TBLD; sl@0: LOCAL_D TBool TBLDChangedFlag; sl@0: sl@0: LOCAL_D TInt TBLDNum = -1; // Change this to specify the drive under test sl@0: // e.g. for the lm_pana board when fitted to the sl@0: // integrator, TBLDNum should be set to 3. sl@0: sl@0: LOCAL_D TInt RFsDNum = -1; // File Server Drive number sl@0: sl@0: struct TTestMapping sl@0: { sl@0: TInt iCIDIdx; // index in CID sl@0: TInt iPWDIdx; // index in PWD sl@0: }; sl@0: sl@0: const TInt KMaxLengthOfStoreMapping = KMMCCIDLength + sizeof(TInt32) + KMaxMediaPassword; sl@0: // EMaxPasswordLength is max size of the password store descriptor sl@0: // (which actually contains multiple mappings of CID and passwords) sl@0: const TInt KMaxNumOfStoreEntries= TPasswordStore::EMaxPasswordLength/KMaxLengthOfStoreMapping; sl@0: sl@0: const TInt KPWDCnt(4); sl@0: LOCAL_C TMediaPassword *PWDs[KPWDCnt]; sl@0: sl@0: //Allocate enough unique CIDs to be able to overflow the store sl@0: const TInt KCIDCnt(KMaxNumOfStoreEntries+1); sl@0: LOCAL_C TCID *CIDs[KCIDCnt]; sl@0: sl@0: //Let the descriptor be one mapping longer than allowed by the password sl@0: //store to test overflowing it. sl@0: const TInt KMaxPersistentStore(TPasswordStore::EMaxPasswordLength+KMaxLengthOfStoreMapping); sl@0: typedef TBuf8 TPersistentStore; sl@0: LOCAL_C TInt mapSizes[KCIDCnt][KPWDCnt]; sl@0: sl@0: // Static function prototypes. sl@0: sl@0: LOCAL_C void AllocateTestData(); sl@0: LOCAL_C void DeleteTestData(); sl@0: sl@0: LOCAL_C void AllocateCIDs(); sl@0: LOCAL_C void DeleteCIDs(); sl@0: sl@0: LOCAL_C void AllocatePasswords(); sl@0: LOCAL_C void DeletePasswords(); sl@0: sl@0: LOCAL_C void SetUpMapSizes(); sl@0: sl@0: LOCAL_C void AddMapping(TDes8 &aSt, const TCID *aCID, const TMediaPassword *aPWD); sl@0: LOCAL_C void DumpStore(const TDesC &aName, const TDesC8 &aSt); sl@0: LOCAL_C TBool StoresEqual(const TDesC8 &aSt0, const TDesC8 &aSt1); sl@0: LOCAL_C TBool IsStoreValid(const TDesC8 &aSt); sl@0: LOCAL_C void PrintCID(const TCID &aCID); sl@0: LOCAL_C void ParseStore(const TDesC8 &aStore, CArrayFixSeg *aMP); sl@0: LOCAL_C void TestStaticStore(); sl@0: sl@0: LOCAL_C void RemountMedia(); sl@0: LOCAL_C void AttemptToUnlock(TMediaPassword &aPWD, TBool aStore = EFalse); sl@0: LOCAL_C void TestLockUnlock(); sl@0: LOCAL_C void TestElidePasswords(); sl@0: LOCAL_C void TestNullPasswords(); sl@0: LOCAL_C void TestControllerStore(); sl@0: sl@0: LOCAL_C TInt AccessDisk(); sl@0: LOCAL_C void TestAutoUnlock(); sl@0: sl@0: LOCAL_C void RunTests(); sl@0: sl@0: // Test data sl@0: sl@0: sl@0: LOCAL_C void AllocateCIDs() sl@0: // sl@0: // Allocates a set of static global media identifiers on the heap. sl@0: // The identifiers are all exactly 128 bits. sl@0: // Because the test uses only one card, CIDs 1 through 3 can be arbitrary sl@0: // (they are just used to construct store data.) sl@0: // sl@0: // Format is "CIDXccccccccccc#", where X is the ASCII digit for the index. sl@0: // The CID is stored internally in big endian format. sl@0: // TCID::At(TInt i) returns the i'th byte, i.e. cid >> (i * 8) & 0xff, which sl@0: // is the opposite order to the way they are stored in the array. sl@0: // CIDs are formed in the same way in pp_mmc.cpp, the WINS ASSP layer. sl@0: // sl@0: // For actual card tests, CIDs[0] must correspond to the card's actual CID. sl@0: // sl@0: { sl@0: sl@0: #if 1 sl@0: static TUint8 ht0[KMMCCIDLength] = // 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: #else sl@0: static TUint8 ht0[KMMCCIDLength] = // BPC2 sl@0: { sl@0: 0x06, 0x00, 0x00, 0x31, sl@0: 0x36, 0x4d, 0x20, 0x20, sl@0: 0x20, 0x00, 0x89, 0xff, sl@0: 0xff, 0xff, 0x63, 0xa7 sl@0: }; sl@0: #endif sl@0: sl@0: test.Start(_L("AllocateCIDs")); sl@0: sl@0: TInt i; sl@0: for (i = 0; i < KCIDCnt; i++) sl@0: { sl@0: TUint8 bf[KMMCCIDLength]; sl@0: TUint j; sl@0: bf[0] = 'C'; sl@0: bf[1] = 'I'; sl@0: bf[2] = 'D'; sl@0: bf[3] = TUint8('0' + i); sl@0: for (j = 4; j < KMMCCIDLength - 1; j++) sl@0: bf[j] = 'c'; sl@0: bf[KMMCCIDLength - 1] = '#'; sl@0: sl@0: if (i == 0) sl@0: { sl@0: TUint cidIdx = 0; sl@0: TLocalDriveCapsV5 driveCaps; sl@0: TPckg driveCapsPkg(driveCaps); sl@0: if(TBLD.Caps(driveCapsPkg) == KErrNone) sl@0: { sl@0: // V5 of TLocalDriveCapsV5 now contains a serial number sl@0: // which for MMC cards is defined to be the unique CID sl@0: if(driveCaps.iSerialNumLength == KMMCCIDLength) sl@0: { sl@0: for(cidIdx=0; cidIdxAppend(TChar('a' + i + j)); sl@0: } sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void DeletePasswords() sl@0: // sl@0: // Deletes static global TMediaPassword objects from the heap. sl@0: // sl@0: { sl@0: test.Start(_L("DeletePasswords")); sl@0: sl@0: TInt i; sl@0: for (i = 0; i < KPWDCnt; i++) sl@0: delete PWDs[i]; sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void SetUpMapSizes() sl@0: // sl@0: // Initializes static global mapSizes[,] with the persistent store mapping sl@0: // sizes of each CID and password. sl@0: // sl@0: { sl@0: test.Start(_L("SetUpMapSizes")); sl@0: sl@0: TInt i; sl@0: for (i = 0; i < KCIDCnt; i++) sl@0: { sl@0: TInt j; sl@0: sl@0: for (j = 0; j < KPWDCnt; j++) sl@0: mapSizes[i][j] = KMMCCIDLength + sizeof(TInt32) + PWDs[j]->Length(); sl@0: } sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void AllocateTestData() sl@0: // sl@0: // Allocates all test data objects on the heap. sl@0: // sl@0: { sl@0: AllocateCIDs(); sl@0: AllocatePasswords(); sl@0: sl@0: SetUpMapSizes(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void DeleteTestData() sl@0: // sl@0: // Frees all test data objects on the heap. sl@0: // sl@0: { sl@0: DeletePasswords(); sl@0: DeleteCIDs(); sl@0: } sl@0: sl@0: sl@0: // Test functions. sl@0: sl@0: sl@0: LOCAL_C void TestStaticStore() sl@0: // sl@0: // Tests the non card specific virtual functions in DPeriphBusController. sl@0: // TInt ReadPasswordData(TDes8 &aBuf); sl@0: // TInt WritePasswordData(const TDesC8 &aBuf); sl@0: // TInt PasswordStoreLengthInBytes(); sl@0: // sl@0: // store is reset at start of DMMCController::WritePasswordData(). sl@0: // sl@0: { sl@0: test.Start(_L("TestStore")); sl@0: sl@0: // TBuf8 is 4 + 4 + 256 bytes, so allocate on heap. sl@0: TPersistentStore *pwStore; sl@0: test((pwStore = new TPersistentStore) != NULL); sl@0: TPersistentStore &wStore = *pwStore; sl@0: TPersistentStore *prStore; sl@0: test((prStore = new TPersistentStore) != NULL); sl@0: TPersistentStore &rStore = *prStore; sl@0: sl@0: // WritePasswordData() sl@0: sl@0: test.Next(_L("WritePasswordData()")); sl@0: sl@0: test(TBLD.WritePasswordData(wStore) == KErrNone);// empty sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: sl@0: AddMapping(wStore, CIDs[1], PWDs[1]); // exactly one entry sl@0: test(TBLD.WritePasswordData(wStore) == KErrNone); sl@0: test(TBLD.PasswordStoreLengthInBytes() == mapSizes[1][1]); sl@0: sl@0: AddMapping(wStore, CIDs[2], PWDs[2]); // exactly two entries sl@0: test(TBLD.WritePasswordData(wStore) == KErrNone); sl@0: test(TBLD.PasswordStoreLengthInBytes() == mapSizes[1][1] + mapSizes[2][2]); sl@0: sl@0: TInt i; sl@0: for (i = 0; i < wStore.Length(); i++) // corrupt (partial) sl@0: { sl@0: wStore.SetLength(i); sl@0: TInt r(TBLD.WritePasswordData(wStore)); sl@0: if (i == 0 || i == mapSizes[0][0] || i == mapSizes[0][0] + mapSizes[1][1]) sl@0: test(r == KErrNone); sl@0: else sl@0: test(r == KErrCorrupt && TBLD.PasswordStoreLengthInBytes() == 0); sl@0: } sl@0: sl@0: test.Next(_L("Exceeding password store size")); sl@0: sl@0: wStore.Zero(); // empty password store sl@0: test(TBLD.WritePasswordData(wStore) == KErrNone); sl@0: sl@0: test.Printf(_L("Adding mappings...\n")); sl@0: sl@0: const TMediaPassword password(_L8("abcdefghijklmnop")); //Need a max length password (KMaxMediaPassword) sl@0: for(TInt n=0; n ret=%d\n"), r); sl@0: if(n==KMaxNumOfStoreEntries) sl@0: test(r == KErrOverflow); sl@0: else sl@0: test(r == KErrNone); sl@0: } sl@0: sl@0: sl@0: // ReadPasswordData(). sl@0: sl@0: test.Next(_L("ReadPasswordData()")); sl@0: sl@0: wStore.Zero(); // empty sl@0: test(TBLD.WritePasswordData(wStore) == KErrNone); sl@0: test(TBLD.ReadPasswordData(rStore) == KErrNone); sl@0: test(rStore.Length() == 0); sl@0: sl@0: AddMapping(wStore, CIDs[1], PWDs[1]); // exactly one entry sl@0: test(TBLD.WritePasswordData(wStore) == KErrNone); sl@0: rStore.SetLength(0); // lt store len sl@0: test(TBLD.ReadPasswordData(rStore) == KErrNone); sl@0: test(rStore.Length() == TBLD.PasswordStoreLengthInBytes()); sl@0: // gt store len sl@0: rStore.SetLength(TBLD.PasswordStoreLengthInBytes() + 4); sl@0: test(TBLD.ReadPasswordData(rStore) == 0); sl@0: test(rStore.Length() == TBLD.PasswordStoreLengthInBytes()); sl@0: sl@0: TBuf8<2> srStore; // max lt store len sl@0: test(TBLD.ReadPasswordData(srStore) == KErrOverflow); sl@0: sl@0: // Stress test high turnover with memory failure. sl@0: sl@0: test.Next(_L("Memory test")); sl@0: sl@0: TInt r; // error code sl@0: sl@0: TInt m; sl@0: for (m = 1; m < 100; m++) sl@0: { sl@0: __KHEAP_SETFAIL(RHeap::EDeterministic, m); sl@0: sl@0: TInt j; sl@0: for (j = 1; j < KCIDCnt - 1; j++) sl@0: { sl@0: TInt k; sl@0: for (k = 1; k < KPWDCnt - 1; k++) sl@0: { sl@0: wStore.Zero(); sl@0: sl@0: AddMapping(wStore, CIDs[j], PWDs[k]); sl@0: AddMapping(wStore, CIDs[j + 1], PWDs[k + 1]); sl@0: sl@0: if ((r = TBLD.WritePasswordData(wStore)) != KErrNone) sl@0: { sl@0: test(r == KErrNoMemory); sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: } sl@0: else sl@0: { sl@0: test(TBLD.ReadPasswordData(rStore) == KErrNone); sl@0: test(IsStoreValid(rStore) && StoresEqual(rStore, wStore)); sl@0: } sl@0: } sl@0: } sl@0: __KHEAP_RESET; sl@0: } // for (m = 1; m < 16; m++) sl@0: sl@0: // Clear the store for subsequent tests. sl@0: sl@0: wStore.Zero(); sl@0: test(TBLD.WritePasswordData(wStore) == KErrNone); sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: sl@0: delete prStore; sl@0: delete pwStore; sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void AddMapping(TDes8 &aSt, const TCID *aCID, const TMediaPassword *aPWD) sl@0: // sl@0: // Adds aCID |-> aPWD mapping to persistent file's store contents. sl@0: // sl@0: { sl@0: aSt.SetLength(aSt.Length() + KMMCCIDLength); sl@0: aCID->Copy(&aSt[aSt.Length() - KMMCCIDLength]); sl@0: sl@0: TUint8 lenBuf[sizeof(TInt32)]; // TInt32, big endian sl@0: TMMC::BigEndian4Bytes(lenBuf, TInt32(aPWD->Length())); sl@0: aSt.Append(&lenBuf[0], sizeof(TInt32)); sl@0: sl@0: aSt.Append(*aPWD); sl@0: } sl@0: sl@0: sl@0: LOCAL_C TBool IsStoreValid(const TDesC8 &aSt) sl@0: // sl@0: // Checks the integrity of the supplied buffer. sl@0: // sl@0: { sl@0: TInt iBIdx; // buffer index sl@0: TBool corrupt(EFalse); // abort flag sl@0: for (iBIdx = 0; iBIdx < aSt.Length(); /* nop */) sl@0: { sl@0: // Enough raw data for CID, PWD_LEN and 1 byte of PWD. sl@0: corrupt = TUint(aSt.Length() - iBIdx) < KMMCCIDLength + sizeof(TInt32) + 1; sl@0: if (corrupt) sl@0: break; sl@0: sl@0: // PWD_LEN is valid and enough raw data left for PWD. sl@0: iBIdx += KMMCCIDLength; sl@0: const TInt32 pwd_len(TMMC::BigEndian32(aSt.Mid(iBIdx).TDesC8::Ptr())); sl@0: corrupt = !( sl@0: (pwd_len <= KMaxMediaPassword) sl@0: && aSt.Length() - iBIdx >= TInt(sizeof(TInt32)) + pwd_len ); sl@0: if (corrupt) sl@0: break; sl@0: sl@0: // skip over PWD_LEN and PWD to next entry. sl@0: iBIdx += sizeof(TInt32) + pwd_len; sl@0: } sl@0: sl@0: if (corrupt) sl@0: DumpStore(_L("invalid"), aSt); sl@0: sl@0: return ! corrupt; sl@0: } sl@0: sl@0: sl@0: LOCAL_C void PrintCID(const TCID &aCID) sl@0: // sl@0: // Prints the 128 bit CID in big endian format. sl@0: // sl@0: { sl@0: test.Printf(_L("CID: ")); sl@0: TInt i; sl@0: for (i = 0; i < TInt(KMMCCIDLength); i += 4) sl@0: { sl@0: TInt j; sl@0: for (j = i; j < i + 4; ++j) sl@0: { sl@0: test.Printf(_L("%02x: %02x "), j, aCID.At(KMMCCIDLength - j - 1)); sl@0: } sl@0: test.Printf(_L("\n")); sl@0: } sl@0: } sl@0: sl@0: sl@0: LOCAL_C void ParseStore(const TDesC8 &aSt, CArrayFixSeg *aMP) sl@0: // sl@0: // Fills aMP with the mappings in aSt. sl@0: // sl@0: { sl@0: TInt iBIdx; // buffer index sl@0: TInt r(KErrNone); // exit code sl@0: for (iBIdx = 0; r == KErrNone && iBIdx < aSt.Length(); /* nop */) sl@0: { sl@0: // Calculate index for CID. sl@0: TPtrC8 pCID(aSt.Mid(iBIdx, KMMCCIDLength)); // CID sl@0: const TCID cid(pCID.Ptr()); sl@0: TInt cidIdx; sl@0: for (cidIdx = 0; cidIdx < KCIDCnt && !(*(CIDs[cidIdx]) == cid); cidIdx++) sl@0: { /* empty. */ } sl@0: // If invalid CID then print CID with valid CIDs. sl@0: if (!(cidIdx < KCIDCnt)) sl@0: { sl@0: test.Printf(_L("ParseStore: invalid CID\n")); sl@0: PrintCID(cid); sl@0: TInt i; sl@0: for (i = 0; i < KCIDCnt; i++) sl@0: { sl@0: test.Printf(_L("ParseStore: valid CID %d\n"), i); sl@0: PrintCID(*CIDs[i]); sl@0: } sl@0: test(EFalse); sl@0: } sl@0: sl@0: const TInt32 pwd_len(TMMC::BigEndian32(&aSt[iBIdx + KMMCCIDLength])); sl@0: sl@0: // Calculate index for PWD. sl@0: TMediaPassword pwd; sl@0: pwd.Copy(&aSt[iBIdx + KMMCCIDLength + sizeof(TInt32)], pwd_len); sl@0: sl@0: TInt pwdIdx; sl@0: for (pwdIdx = 0; pwdIdx < KPWDCnt && *PWDs[pwdIdx] != pwd; pwdIdx++) sl@0: { /* empty. */ } sl@0: test(pwdIdx < KPWDCnt); sl@0: sl@0: TTestMapping mp; sl@0: mp.iCIDIdx = cidIdx; sl@0: mp.iPWDIdx = pwdIdx; sl@0: TRAP(r, aMP->InsertL(0, mp)); sl@0: test(r == KErrNone); sl@0: sl@0: iBIdx += KMMCCIDLength + sizeof(TInt32) + pwd_len; sl@0: } sl@0: } sl@0: sl@0: sl@0: LOCAL_C void DumpStore(const TDesC &aName, const TDesC8 &aSt) sl@0: // sl@0: // Prints the contents of the supplied store. sl@0: // sl@0: { sl@0: test.Printf(_L("\nstore %S: len = %d\n"), &aName, aSt.Length()); sl@0: sl@0: TInt i; sl@0: for (i = 0; i < aSt.Length(); i += 8) sl@0: { sl@0: TInt j; sl@0: for (j = i; j < Min(aSt.Length(), i + 8); j++) sl@0: test.Printf(_L("%02d: %03d : %02x : %c \n "), j, aSt[j], aSt[j], aSt[j]); sl@0: test.Printf(_L("\n")); sl@0: } sl@0: } sl@0: sl@0: sl@0: LOCAL_C TBool StoresEqual(const TDesC8 &aSt0, const TDesC8 &aSt1) sl@0: // sl@0: // Compares aSt1 with aSt2. Return value indicates whether or not the sl@0: // stores contain exactly the same mappings, but not necessarily in the sl@0: // same order. sl@0: // sl@0: { sl@0: TBool same(EFalse); sl@0: sl@0: CArrayFixSeg *ramp0, *ramp1; sl@0: sl@0: test((ramp0 = new(ELeave) CArrayFixSeg(2)) != NULL); sl@0: test((ramp1 = new(ELeave) CArrayFixSeg(2)) != NULL); sl@0: sl@0: test(IsStoreValid(aSt0)); sl@0: test(IsStoreValid(aSt1)); sl@0: sl@0: ParseStore(aSt0, ramp0); sl@0: ParseStore(aSt1, ramp1); sl@0: sl@0: TArray a0(ramp0->Array()); sl@0: TArray a1(ramp1->Array()); sl@0: sl@0: if (a0.Count() == a1.Count()) sl@0: // if #a0 == #a1 and a0 <= a1 then a0 == a1. sl@0: { sl@0: TBool allInA1(ETrue); sl@0: TInt i; sl@0: for (i = 0; allInA1 && i < a0.Count(); i++) sl@0: { sl@0: TBool found(EFalse); sl@0: TInt j; sl@0: for (j = 0; ! found && j < a0.Count(); j++) sl@0: { sl@0: found = ( sl@0: a0[i].iCIDIdx == a1[j].iCIDIdx sl@0: && a0[i].iPWDIdx == a1[j].iPWDIdx ); sl@0: } sl@0: allInA1 = found; sl@0: } sl@0: sl@0: same = allInA1; sl@0: } sl@0: sl@0: delete ramp1; sl@0: delete ramp0; sl@0: sl@0: if (! same) sl@0: { sl@0: DumpStore(_L("0"), aSt0); sl@0: DumpStore(_L("1"), aSt1); sl@0: } sl@0: sl@0: return same; sl@0: } sl@0: sl@0: sl@0: LOCAL_C void RemountMedia() sl@0: // sl@0: // Forces a media remount and waits for it to take effect. If the card has a sl@0: // password, it will become locked the next time that it is powered up. sl@0: // sl@0: { sl@0: //#ifdef __WINS__ sl@0: // TBLD.ForceMediaChange(); sl@0: // UserSvr::ForceRemountMedia(ERemovableMedia0); sl@0: // User::After(1 * 1000 * 1000); sl@0: //#else sl@0: sl@0: #ifdef __AUTO_DETECT_MEDIA_CHANGE__ sl@0: RFs fs; sl@0: test(fs.Connect() == KErrNone); sl@0: sl@0: test.Printf(_L("Remove and re-insert card..")); sl@0: sl@0: TInt r; sl@0: do sl@0: { sl@0: TRequestStatus status; sl@0: TDriveUnit driveUnit(RFsDNum); sl@0: TDriveName driveName = driveUnit.Name(); sl@0: fs.NotifyChange(ENotifyAll, status, driveName); sl@0: test(status == KRequestPending); sl@0: User::WaitForRequest(status); sl@0: test.Printf(_L("\rAccessing card... \r")); sl@0: sl@0: r = AccessDisk(); sl@0: if (r == KErrNotReady) sl@0: test.Printf(_L("\rRemove and re-insert card..")); sl@0: sl@0: if (r != KErrNone && r != KErrNotReady && r != KErrLocked) sl@0: test.Printf(_L("AccessDisk() returned %d"), r); sl@0: } sl@0: while (r == KErrNotReady); sl@0: sl@0: test.Printf(_L("\n")); sl@0: sl@0: fs.Close(); sl@0: sl@0: #else sl@0: // Power down the card so that it is locked the next time it is powered up. 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: //#endif sl@0: } sl@0: sl@0: sl@0: LOCAL_C void AttemptToUnlock(TMediaPassword &aPWD, TBool aStore) sl@0: // sl@0: // Tests that the card is locked and then tries to unlock it. sl@0: // sl@0: { sl@0: TInt r = AccessDisk(); sl@0: if (r != KErrLocked) sl@0: test.Printf(_L("AccessDisk() returned %d\n"), r); sl@0: test(r == KErrLocked); sl@0: test(TBLD.Unlock(aPWD, aStore) == KErrNone); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void TestLockUnlock() sl@0: // sl@0: // Tests TBusLocalDrive functions for locking / unlocking individual cards. sl@0: // Lock() currently means set password only. The media must be remounted before it sl@0: // can really be locked. 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: test.Start(_L("TestLockUnlock")); sl@0: sl@0: TMediaPassword nul(*PWDs[0]); sl@0: TMediaPassword arb1(*PWDs[1]); sl@0: TMediaPassword arb2(*PWDs[2]); sl@0: sl@0: // Clear the password store for when function run on its own. sl@0: TBuf8<1> nulSt; sl@0: test(TBLD.WritePasswordData(nulSt) == KErrNone);// empty sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: sl@0: // Give the card an arbitrary password sl@0: test.Next(_L("assign test password")); sl@0: test(TBLD.SetPassword(nul, arb1, EFalse) == KErrNone); sl@0: RemountMedia(); // card is now locked sl@0: sl@0: test.Next(_L("lock locked card")); sl@0: test(TBLD.SetPassword(arb2, arb1, EFalse) == KErrAccessDenied); // lock locked wrong sl@0: test(TBLD.SetPassword(arb1, arb1, EFalse) == KErrAccessDenied); // lock locked right sl@0: sl@0: test.Next(_L("unlock locked card")); sl@0: test(TBLD.Unlock(arb2, EFalse) == KErrAccessDenied); // unlock locked wrong sl@0: AttemptToUnlock(arb1); sl@0: sl@0: test.Next(_L("unlock unlocked card")); sl@0: test(TBLD.Unlock(arb1, EFalse) == KErrAlreadyExists); // unlock unlocked right sl@0: test(TBLD.Unlock(arb2, EFalse) == KErrAlreadyExists); // unlock unlocked wrong sl@0: sl@0: test.Next(_L("lock unlocked card")); sl@0: test(TBLD.SetPassword(arb2, arb1, EFalse) == KErrAccessDenied); // lock unlocked wrong sl@0: test(TBLD.SetPassword(arb1, arb1, EFalse) == KErrNone); // lock unlocked right sl@0: sl@0: test.Next(_L("clear unlocked card")); sl@0: test(TBLD.Clear(arb2) == KErrAccessDenied); // clear unlocked wrong sl@0: sl@0: //!!! If clear with wrong password, cannot clear with right password in same sl@0: // power session (H). sl@0: RemountMedia(); sl@0: AttemptToUnlock(arb1); sl@0: test(TBLD.Clear(arb1) == KErrNone); sl@0: sl@0: test.Next(_L("assign test password")); sl@0: test(TBLD.SetPassword(nul, arb1, EFalse) == KErrNone); // give test password sl@0: RemountMedia(); // make inaccessible sl@0: sl@0: test.Next(_L("clear locked card")); sl@0: test(TBLD.Clear(arb2) == KErrAccessDenied); // clear locked wrong sl@0: test(TBLD.Clear(arb1) == KErrAccessDenied); // clear locked right sl@0: sl@0: // Clear password for subsequent tests. sl@0: test.Next(_L("clear password")); sl@0: AttemptToUnlock(arb1); sl@0: test(TBLD.Clear(arb1) == KErrNone); sl@0: test(TBLD.WritePasswordData(nulSt) == KErrNone); sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: /** sl@0: * Because MultiMediaCards cannot distinguish where the current password ends sl@0: * and the new password begins, test the media driver can abort those operations sl@0: * that would end up giving the user unexpected passwords. sl@0: * sl@0: * The stores are directly compared with buffers because they only use one password sl@0: * and the passwords are not part of the standard test data. sl@0: */ sl@0: sl@0: LOCAL_C void TestElidePasswords() sl@0: { sl@0: test.Start(_L("TestElidePasswords")); sl@0: sl@0: TMediaPassword a((const TUint8*) "a"); TMediaPassword bcxyz((const TUint8*) "bcxyz"); sl@0: TMediaPassword ab((const TUint8*) "ab"); TMediaPassword cxyz((const TUint8*) "cxyz"); sl@0: TMediaPassword abc((const TUint8*) "abc"); TMediaPassword xyz((const TUint8*) "xyz"); sl@0: sl@0: TPersistentStore* pstoreAB; sl@0: test((pstoreAB = new TPersistentStore) != 0); sl@0: TPersistentStore& storeAB = *pstoreAB; sl@0: AddMapping(storeAB, CIDs[0], &ab); sl@0: sl@0: TPersistentStore* pstoreCXYZ; sl@0: test((pstoreCXYZ = new TPersistentStore) != 0); sl@0: TPersistentStore& storeCXYZ = *pstoreCXYZ; sl@0: AddMapping(storeCXYZ, CIDs[0], &cxyz); sl@0: sl@0: TPersistentStore *pstoreRd; // scratch for reading sl@0: test((pstoreRd = new TPersistentStore) != NULL); sl@0: TPersistentStore& storeRd = *pstoreRd; sl@0: sl@0: TBuf8<1> nulSt; sl@0: test(TBLD.SetPassword(nulSt, ab, ETrue) == KErrNone); sl@0: RemountMedia(); // card is now locked sl@0: test(AccessDisk() == KErrNone); sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(storeRd == storeAB); sl@0: sl@0: test.Next(_L("current password too short")); sl@0: test(TBLD.SetPassword(a, bcxyz, ETrue) == KErrAccessDenied); sl@0: test(AccessDisk() == KErrNone); sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(storeRd == storeAB); sl@0: sl@0: test.Next(_L("current password too long")); sl@0: test(TBLD.SetPassword(abc, xyz, ETrue) == KErrAccessDenied); sl@0: test(AccessDisk() == KErrNone); sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(storeRd == storeAB); sl@0: sl@0: test.Next(_L("current password exactly right")); sl@0: test(TBLD.SetPassword(ab, cxyz, ETrue) == KErrNone); sl@0: test(AccessDisk() == KErrNone); sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(storeRd == storeCXYZ); sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: test(TBLD.Clear(cxyz) == KErrNone); sl@0: test(TBLD.WritePasswordData(nulSt) == KErrNone); sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: sl@0: delete pstoreRd; sl@0: delete pstoreCXYZ; sl@0: delete pstoreAB; sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: /** sl@0: * test the special cases where null passwords are used. These are all failed with sl@0: * KErrAccessDenied by the controller. sl@0: */ sl@0: sl@0: LOCAL_C void TestNullPasswords() sl@0: { sl@0: test.Start(_L("TestNullPasswords")); sl@0: sl@0: TMediaPassword nul(*PWDs[0]); sl@0: TMediaPassword arb1(*PWDs[1]); sl@0: sl@0: test.Next(_L("card has no password")); sl@0: test(TBLD.SetPassword(nul, nul, ETrue) == KErrAccessDenied); sl@0: test(TBLD.Unlock(nul, ETrue) == KErrAlreadyExists); sl@0: test(TBLD.Clear(nul) == KErrAccessDenied); sl@0: sl@0: test.Next(_L("card has password and is unlocked")); sl@0: test(TBLD.SetPassword(nul, arb1, ETrue) == KErrNone); sl@0: RemountMedia(); sl@0: test(AccessDisk() == KErrNone); sl@0: test(TBLD.SetPassword(nul, nul, ETrue) == KErrAccessDenied); sl@0: test(TBLD.Unlock(nul, ETrue) == KErrAlreadyExists); sl@0: test(TBLD.Clear(nul) == KErrAccessDenied); sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: test(TBLD.Clear(arb1) == KErrNone); sl@0: TBuf8<1> nulSt; sl@0: test(TBLD.WritePasswordData(nulSt) == KErrNone); sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void TestControllerStore() sl@0: // sl@0: // Performs standard password functions but stores the mappings in the controller store. sl@0: // sl@0: // + mapping added to store (if not exists) sl@0: // - mapping removed from store (if exists) sl@0: // sl@0: // EPbPswdUnlock EPbPswdLock EPbPswdClear sl@0: // right wrong right wrong right wrong sl@0: // locked None1 AccDen- AccDec AccDen AccDen AccDen sl@0: // unlocked AccDen AccDen None+ AccDec- None- AccDen- sl@0: // sl@0: // Locked means inaccessible, not just has password. sl@0: // When the user supplies a password, the mapping in the password store is not used. sl@0: // sl@0: // 1. A locked card with the right mapping in the store cannot happen because of the sl@0: // automatic unlocking mechanism. sl@0: // sl@0: // Tests start with an unlocked card that has no password. sl@0: // sl@0: { sl@0: test.Start(_L("TestControllerStore")); sl@0: sl@0: test.Next(_L("allocate test data")); sl@0: sl@0: TMediaPassword nul(*PWDs[0]); sl@0: TMediaPassword arb1(*PWDs[1]); sl@0: TMediaPassword arb2(*PWDs[2]); sl@0: sl@0: TPersistentStore *pstoreDef; // { 3 |-> 3 } sl@0: test((pstoreDef = new TPersistentStore) != NULL); sl@0: TPersistentStore &storeDef = *pstoreDef; sl@0: AddMapping(storeDef, CIDs[3], PWDs[3]); sl@0: sl@0: TPersistentStore *pstore0_1; // { 3 |-> 3, 0 |-> 1 } sl@0: test((pstore0_1 = new TPersistentStore) != NULL); sl@0: TPersistentStore &store0_1 = *pstore0_1; sl@0: AddMapping(store0_1, CIDs[3], PWDs[3]); sl@0: AddMapping(store0_1, CIDs[0], PWDs[1]); sl@0: sl@0: TPersistentStore *pstore0_2; // { 3 |-> 3, 0 |-> 2 } sl@0: test((pstore0_2 = new TPersistentStore) != NULL); sl@0: TPersistentStore &store0_2 = *pstore0_2; sl@0: AddMapping(store0_2, CIDs[3], PWDs[3]); sl@0: AddMapping(store0_2, CIDs[0], PWDs[2]); sl@0: sl@0: TPersistentStore *pstoreRd; // temp for reading sl@0: test((pstoreRd = new TPersistentStore) != NULL); sl@0: TPersistentStore &storeRd = *pstoreRd; sl@0: sl@0: // Give card arbitrary password but do not lock or store. sl@0: test.Next(_L("assign test password")); sl@0: test(TBLD.SetPassword(nul, arb1, EFalse) == KErrNone); sl@0: sl@0: // Lock sl@0: sl@0: // Lock unlocked right out. sl@0: test.Next(_L("lock unlocked right out")); sl@0: test(TBLD.WritePasswordData(storeDef) == KErrNone); sl@0: test(TBLD.SetPassword(arb1, arb1, ETrue) == KErrNone); // + (0 |-> 1) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, store0_1)); sl@0: sl@0: // Lock unlocked right in (different to make sure store modified.) sl@0: test.Next(_L("lock unlocked right in")); sl@0: test(TBLD.WritePasswordData(store0_1) == KErrNone); sl@0: test(TBLD.SetPassword(arb1, arb2, ETrue) == KErrNone); // - (0 |-> 1) + (0 |-> 2) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, store0_2)); sl@0: sl@0: // Lock unlocked wrong out. sl@0: test.Next(_L("lock unlocked wrong out")); sl@0: test(TBLD.SetPassword(arb2, arb1, ETrue) == KErrNone); // restore to arb1 sl@0: test(TBLD.WritePasswordData(storeDef) == KErrNone); sl@0: test(TBLD.SetPassword(arb2, arb1, ETrue) == KErrAccessDenied); // not add (0 |-> 1) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, storeDef)); sl@0: sl@0: // Lock unlocked wrong in. sl@0: test.Next(_L("lock unlocked wrong in")); sl@0: test(TBLD.WritePasswordData(store0_1) == KErrNone); sl@0: test(TBLD.SetPassword(arb2, arb1, ETrue) == KErrAccessDenied); // - (0 |-> 1) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, store0_1)); sl@0: sl@0: sl@0: // Unlock sl@0: sl@0: // Unlock locked right out. sl@0: test.Next(_L("unlock locked right out")); sl@0: test(TBLD.WritePasswordData(storeDef) == KErrNone); sl@0: RemountMedia(); // make inaccessible sl@0: AttemptToUnlock(arb1, ETrue); // + (0 |-> 1) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, store0_1)); sl@0: sl@0: // Unlock locked right in - see note 1. sl@0: sl@0: // Unlock locked wrong in. sl@0: test.Next(_L("unlock locked wrong in")); sl@0: test(TBLD.WritePasswordData(store0_2) == KErrNone); sl@0: RemountMedia(); // make inaccessible sl@0: test(TBLD.Unlock(arb2, ETrue) == KErrAccessDenied); // - (0 |-> 2) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, storeDef)); sl@0: sl@0: // Unlock locked wrong out. sl@0: test.Next(_L("unlock locked wrong out")); sl@0: test(TBLD.WritePasswordData(storeDef) == KErrNone); sl@0: RemountMedia(); // make inaccessible sl@0: test(TBLD.Unlock(arb2, ETrue) == KErrAccessDenied); // not add (0 |-> 2) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, storeDef)); sl@0: sl@0: sl@0: // Clear sl@0: sl@0: // Clear unlocked right out. sl@0: test.Next(_L("clear unlocked right out")); sl@0: test(TBLD.WritePasswordData(storeDef) == KErrNone); sl@0: AttemptToUnlock(arb1); // make accessible sl@0: test(TBLD.Clear(arb1) == KErrNone); // not add (0 |-> 1) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, storeDef)); sl@0: sl@0: // Clear unlocked right in. sl@0: test.Next(_L("clear unlocked right in")); sl@0: test(TBLD.SetPassword(nul, arb1, EFalse) == KErrNone); // give password sl@0: test(TBLD.WritePasswordData(store0_1) == KErrNone); sl@0: test(TBLD.Clear(arb1) == KErrNone); // - (0 |-> 2) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, storeDef)); sl@0: sl@0: // Clear unlocked wrong out. sl@0: test.Next(_L("clear unlocked wrong out")); sl@0: test(TBLD.SetPassword(nul, arb1, EFalse) == KErrNone); // give password sl@0: test(TBLD.WritePasswordData(storeDef) == KErrNone); sl@0: test(TBLD.Clear(arb2) == KErrAccessDenied); // not add (0 |-> 2) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, storeDef)); sl@0: sl@0: // Clear unlocked wrong in. sl@0: test.Next(_L("clear unlocked wrong in")); sl@0: test(TBLD.WritePasswordData(store0_1) == KErrNone); sl@0: test(TBLD.Clear(arb2) == KErrAccessDenied); // - (0 |-> 2) sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, store0_1)); sl@0: sl@0: // Clear password for subsequent tests. sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: test(TBLD.WritePasswordData(storeDef) == KErrNone); sl@0: RemountMedia(); sl@0: AttemptToUnlock(arb1); sl@0: test(TBLD.Clear(arb1) == KErrNone); sl@0: TBuf8<1> nulSt; sl@0: test(TBLD.WritePasswordData(nulSt) == KErrNone); sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: sl@0: test.Next(_L("free test data")); sl@0: sl@0: delete pstoreRd; sl@0: delete pstore0_2; sl@0: delete pstore0_1; sl@0: delete pstoreDef; sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C TInt AccessDisk() sl@0: // sl@0: // Attempts to read the first sector of the removable media to determine whether sl@0: // it is locked. sl@0: // sl@0: { sl@0: const TInt KSectSize = 512; sl@0: TBuf8 sect; // 8 + 512 sl@0: sl@0: return TBLD.Read(0, KSectSize, sect); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void TestAutoUnlock() sl@0: // sl@0: // Tests controller internal store unlocking mechanism. sl@0: // A locked card should be transparently unlocked after the peripheral bus is sl@0: // powered up. sl@0: // sl@0: { sl@0: test.Start(_L("TestAutoUnlock")); sl@0: sl@0: test.Next(_L("allocate test data")); sl@0: sl@0: TMediaPassword nul(*PWDs[0]); sl@0: TMediaPassword arb1(*PWDs[1]); sl@0: sl@0: TPersistentStore *pstoreDef; // { 3 |-> 3 } sl@0: test((pstoreDef = new TPersistentStore) != NULL); sl@0: TPersistentStore &storeDef = *pstoreDef; sl@0: AddMapping(storeDef, CIDs[3], PWDs[3]); sl@0: sl@0: TPersistentStore *pstore0_1; // { 3 |-> 3, 0 |-> 1 } sl@0: test((pstore0_1 = new TPersistentStore) != NULL); sl@0: TPersistentStore &store0_1 = *pstore0_1; sl@0: AddMapping(store0_1, CIDs[3], PWDs[3]); sl@0: AddMapping(store0_1, CIDs[0], PWDs[1]); sl@0: sl@0: TPersistentStore *pstore0_2; // { 3 |-> 3, 0 |-> 2 } sl@0: test((pstore0_2 = new TPersistentStore) != NULL); sl@0: TPersistentStore &store0_2 = *pstore0_2; sl@0: AddMapping(store0_2, CIDs[3], PWDs[3]); sl@0: AddMapping(store0_2, CIDs[0], PWDs[2]); sl@0: sl@0: TPersistentStore *pstoreRd; // temp for reading sl@0: test((pstoreRd = new TPersistentStore) != NULL); sl@0: TPersistentStore &storeRd = *pstoreRd; sl@0: sl@0: test.Next(_L("assign password")); sl@0: test(TBLD.SetPassword(nul, arb1, EFalse) == KErrNone); // give password sl@0: sl@0: // No mapping in store. sl@0: test.Next(_L("no mapping in store")); sl@0: test(TBLD.WritePasswordData(storeDef) == KErrNone); sl@0: RemountMedia(); sl@0: test(AccessDisk() == KErrLocked); sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, storeDef)); sl@0: sl@0: // Right mapping in store. sl@0: test.Next(_L("right mapping in store")); sl@0: test(TBLD.WritePasswordData(store0_1) == KErrNone); sl@0: RemountMedia(); sl@0: test(AccessDisk() == KErrNone); sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, store0_1)); sl@0: sl@0: // Wrong mapping in store - mapping should be removed. sl@0: test.Next(_L("wrong mapping in store")); sl@0: test(TBLD.WritePasswordData(store0_2) == KErrNone); sl@0: RemountMedia(); sl@0: test(AccessDisk() == KErrLocked); sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, storeDef)); sl@0: sl@0: // Redundant mapping in store. sl@0: test.Next(_L("redundant mapping in store")); sl@0: AttemptToUnlock(arb1); sl@0: test(TBLD.Clear(arb1) == KErrNone); sl@0: test(TBLD.WritePasswordData(store0_2) == KErrNone); sl@0: RemountMedia(); sl@0: test(AccessDisk() == KErrNone); sl@0: test(TBLD.ReadPasswordData(storeRd) == KErrNone); sl@0: test(StoresEqual(storeRd, storeDef)); sl@0: sl@0: test.Next(_L("clean up for following tests")); sl@0: TBuf8<1> nulSt; sl@0: test(TBLD.WritePasswordData(nulSt) == KErrNone); sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: sl@0: test.Next(_L("free test data")); sl@0: delete pstoreRd; sl@0: delete pstore0_2; sl@0: delete pstore0_1; sl@0: delete pstoreDef; sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void TestPasswordFile() sl@0: // sl@0: // Additional test added for INC066636 sl@0: // sl@0: // Tests that the MMC password file is created in the correct place on the disk sl@0: // as defined by KMediaPWrdFile in f32fsys.h sl@0: // sl@0: // The following test cases are checked: sl@0: // o Card can be locked sl@0: // o Cannot lock the card or change its password if the wrong password is sl@0: // specified sl@0: // o Password can be changed sl@0: // o Password can be removed sl@0: // sl@0: { sl@0: const TInt KDriveNum = RFsDNum; sl@0: sl@0: TInt error = KErrNone; sl@0: sl@0: sl@0: test.Start(_L("Testing password file")); sl@0: sl@0: sl@0: test.Next(_L("open connection")); sl@0: RFs theFs; sl@0: test(theFs.Connect() == KErrNone); sl@0: sl@0: sl@0: sl@0: // Now set the first password that we will use sl@0: test.Next(_L("lock the media card")); sl@0: TMediaPassword& nulPWrd = *PWDs[0]; sl@0: TMediaPassword& oldPWrd = *PWDs[1]; sl@0: error = theFs.LockDrive(KDriveNum, nulPWrd, oldPWrd, ETrue); sl@0: test(KErrNone == error); sl@0: sl@0: sl@0: // Verify that the password file does exist and is in the correct place sl@0: test.Next(_L("check password file exists")); sl@0: TEntry theEntry; sl@0: TBuf mediaPWrdFile(KMediaPWrdFile); sl@0: mediaPWrdFile[0] = (TUint8) RFs::GetSystemDriveChar(); sl@0: error = theFs.Entry(mediaPWrdFile, theEntry); sl@0: test (KErrNone == error); sl@0: sl@0: sl@0: // Attempt to set a new password without specifying the current one sl@0: test.Next(_L("change password failure")); sl@0: TMediaPassword& newPWrd = *PWDs[2]; sl@0: error = theFs.LockDrive(KDriveNum, nulPWrd, newPWrd, ETrue); sl@0: test(KErrAccessDenied == error); sl@0: sl@0: sl@0: // Change the password for a new one... sl@0: test.Next(_L("change password success")); sl@0: error = theFs.LockDrive(KDriveNum, oldPWrd, newPWrd, ETrue); sl@0: test(KErrNone == error); sl@0: sl@0: sl@0: // Clear the password sl@0: test.Next(_L("clear the password")); sl@0: error = theFs.ClearPassword(KDriveNum, newPWrd); sl@0: test(KErrNone == error); sl@0: sl@0: sl@0: // Check that the password has been removed from the file sl@0: // (KMediaPWrdFile should now be zero bytes in size) sl@0: test.Next(_L("check password removal")); sl@0: error = theFs.Entry(mediaPWrdFile, theEntry); sl@0: test (KErrNone == error); sl@0: test (0 == theEntry.iSize); sl@0: sl@0: sl@0: // Remove the password file sl@0: test.Next(_L("tidy up")); sl@0: error = theFs.Delete(mediaPWrdFile); sl@0: test (KErrNone == error); sl@0: sl@0: sl@0: theFs.Close(); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void TestFormatErase() sl@0: // sl@0: // Additional test added for DEF067976 - MR1: Force Erase of MMC lock UI until complete sl@0: // sl@0: // Tests that a card can be locked & then force-erased using the new format switch sl@0: // sl@0: // Test modified for INC073653 - RFormat::Open returns KErrNone, even if card is locked sl@0: // sl@0: // RFormat:Open now returns KErrLocked if media is locked (previously this wasn't returned sl@0: // until calling RFormat::Next sl@0: // sl@0: // sl@0: { sl@0: TInt r = KErrNone; sl@0: sl@0: test.Start(_L("Testing force erase")); sl@0: sl@0: sl@0: test.Next(_L("open connection")); sl@0: RFs fs; sl@0: test(fs.Connect() == KErrNone); sl@0: sl@0: // Clear the password store for when function run on its own. sl@0: TBuf8<1> nulSt; sl@0: test(TBLD.WritePasswordData(nulSt) == KErrNone);// empty sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: sl@0: sl@0: test.Next(_L("lock card")); sl@0: // Now set the first password that we will use sl@0: TMediaPassword& nulPWrd = *PWDs[0]; sl@0: TMediaPassword& oldPWrd = *PWDs[1]; sl@0: r = fs.LockDrive(RFsDNum, nulPWrd, oldPWrd, EFalse); sl@0: if (r != KErrNone) sl@0: test.Printf(_L("RFs::LockDrive() returned %d\n"), r); sl@0: test(r == KErrNone); sl@0: sl@0: RemountMedia(); // card is now locked sl@0: sl@0: RFormat fmt; sl@0: TPckgBuf stepPkg; sl@0: TDriveUnit driveUnit(RFsDNum); sl@0: TDriveName driveName = driveUnit.Name(); sl@0: sl@0: test.Next(_L("format locked card")); sl@0: r = fmt.Open(fs, driveName, EHighDensity, stepPkg()); sl@0: if (r != KErrLocked) sl@0: test.Printf(_L("RFormat::Next() returned %d\n"), r); sl@0: test(r == KErrLocked); sl@0: sl@0: test.Printf(_L("\n")); sl@0: fmt.Close(); sl@0: sl@0: _LIT(KLitStars,"********************"); sl@0: test.Next(_L("force erase locked card")); sl@0: r = fmt.Open(fs, driveName, EHighDensity | EForceErase, stepPkg()); sl@0: if (r != KErrNone) sl@0: test.Printf(_L("RFormat::Open() returned %d\n"), r); sl@0: test (r == KErrNone); sl@0: sl@0: while (stepPkg() > 0) sl@0: { sl@0: TRequestStatus status; sl@0: fmt.Next(stepPkg, status); sl@0: test (status == KRequestPending || status == KErrNone); sl@0: User::WaitForRequest(status); sl@0: sl@0: TInt length=(100-stepPkg())/5; sl@0: length=Min(length,20); sl@0: TPtrC stars=KLitStars().Left(length); sl@0: test.Printf(_L("\r%S"),&stars); sl@0: } sl@0: test.Printf(_L("\n")); sl@0: fmt.Close(); sl@0: sl@0: fs.Close(); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: LOCAL_C void TestWriteToPasswordStoreUnlocksCard() sl@0: // sl@0: // Additional test added for INC096612 - Writing to password store should unlock the card sl@0: // sl@0: // Tests that a card can be auto-unlocked just by writing to the password store (as this is what sl@0: // estart does) sl@0: // sl@0: // sl@0: { sl@0: TInt r = KErrNone; sl@0: sl@0: test.Start(_L("Testing writing to password store unlocks the card")); sl@0: sl@0: test.Next(_L("open connection")); sl@0: RFs fs; sl@0: test(fs.Connect() == KErrNone); sl@0: sl@0: // Clear the password store for when function run on its own. sl@0: TMediaPassword& nulPWrd = *PWDs[0]; sl@0: TMediaPassword testPassword((const TUint8*) "xyz"); sl@0: sl@0: test(TBLD.WritePasswordData(nulPWrd) == KErrNone);// empty sl@0: test(TBLD.PasswordStoreLengthInBytes() == 0); sl@0: sl@0: test.Next(_L("lock card")); sl@0: test.Next(_L("assign test password")); sl@0: r = TBLD.SetPassword(nulPWrd, testPassword, EFalse); sl@0: test(r == KErrNone); sl@0: sl@0: RemountMedia(); // card is now locked sl@0: sl@0: // test Caps() reports that card is locked sl@0: test.Next(_L("test card is locked")); sl@0: TLocalDriveCapsV5 driveCaps; sl@0: TPckg driveCapsPkg(driveCaps); sl@0: r = TBLD.Caps(driveCapsPkg); sl@0: test.Printf(_L("Caps() returned %d , iMediaAtt %08x\n"), r, driveCaps.iMediaAtt); sl@0: sl@0: test (r == KErrNone); sl@0: test ((driveCaps.iMediaAtt & KMediaAttLocked) != 0); sl@0: sl@0: // Write correct password to store sl@0: test.Next(_L("write correct password to store")); sl@0: sl@0: TPersistentStore *pstoreDef; sl@0: test((pstoreDef = new TPersistentStore) != NULL); sl@0: TPersistentStore &storeDef = *pstoreDef; sl@0: AddMapping(storeDef, CIDs[0], &testPassword); sl@0: r = TBLD.WritePasswordData(storeDef); sl@0: sl@0: test.Printf(_L("WritePasswordData() returned %d\n"), r); sl@0: sl@0: test(r == KErrNone); sl@0: sl@0: // test Caps() reports that card is unlocked sl@0: test.Next(_L("test card is unlocked")); sl@0: r = TBLD.Caps(driveCapsPkg); sl@0: test.Printf(_L("Caps() returned %d , iMediaAtt %08x\n"), r, driveCaps.iMediaAtt); sl@0: sl@0: test (r == KErrNone); sl@0: test ((driveCaps.iMediaAtt & KMediaAttLocked) == 0); sl@0: sl@0: // Clear the password, remount and test card is unlocked sl@0: test.Next(_L("clear password, remount & test card is unlocked")); sl@0: test.Next(_L("clear the password")); sl@0: test(TBLD.Clear(testPassword) == KErrNone); sl@0: RemountMedia(); sl@0: test.Next(_L("test card is unlocked")); sl@0: sl@0: r = TBLD.Caps(driveCapsPkg); sl@0: test.Printf(_L("Caps() returned %d , iMediaAtt %08x\n"), r, driveCaps.iMediaAtt); sl@0: sl@0: test (r == KErrNone); sl@0: test ((driveCaps.iMediaAtt & KMediaAttLocked) == 0); sl@0: sl@0: sl@0: delete pstoreDef; sl@0: pstoreDef = NULL; sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C TBool SetupDrivesForPlatform(TInt& aDrive, TInt &aRFsDriveNum) sl@0: /** sl@0: * Finds a suitable drive for the password store test sl@0: * sl@0: * @param aDrive The number of the local drive to test sl@0: * @return TBool ETrue if a suitable drive is found, EFalse otherwise. sl@0: */ sl@0: { sl@0: sl@0: TDriveInfoV1Buf diBuf; sl@0: UserHal::DriveInfo(diBuf); sl@0: TDriveInfoV1 &di=diBuf(); sl@0: sl@0: test.Printf(_L(" iRegisteredDriveBitmask 0x%08X"), di.iRegisteredDriveBitmask); sl@0: sl@0: aDrive = -1; sl@0: sl@0: TLocalDriveCapsV5Buf capsBuf; sl@0: TBusLocalDrive TBLD; sl@0: TLocalDriveCapsV5& caps = capsBuf(); sl@0: TPtrC8 localSerialNum; sl@0: TInt registeredDriveNum = 0; sl@0: for(aDrive=0; aDrive < KMaxLocalDrives; aDrive++) sl@0: { sl@0: TInt driveNumberMask = 1 << aDrive; sl@0: if ((di.iRegisteredDriveBitmask & driveNumberMask) == 0) sl@0: continue; sl@0: sl@0: test.Printf(_L(" Drive %d - %S\r\n"), aDrive, &di.iDriveName[registeredDriveNum]); sl@0: sl@0: // check that the card is readable (so we can ignore for empty card slots) sl@0: if ((di.iDriveName[registeredDriveNum].MatchF(_L("MultiMediaCard0")) == KErrNone) || sl@0: (di.iDriveName[registeredDriveNum].MatchF(_L("SDIOCard0")) == KErrNone)) sl@0: { sl@0: sl@0: TBool TBLDChangedFlag; sl@0: TInt r = TBLD.Connect(aDrive, TBLDChangedFlag); sl@0: //test.Printf(_L(" Connect returned %d\n"), r); sl@0: if (r == KErrNone) sl@0: { sl@0: r = TBLD.Caps(capsBuf); sl@0: localSerialNum.Set(caps.iSerialNum, caps.iSerialNumLength); sl@0: const TInt KSectSize = 512; sl@0: TBuf8 sect; sl@0: r = TBLD.Read(0, KSectSize, sect); sl@0: //test.Printf(_L(" Read returned %d\n"), r); sl@0: sl@0: TBLD.Disconnect(); sl@0: if (r == KErrNone) sl@0: break; sl@0: } sl@0: } sl@0: registeredDriveNum++; sl@0: } sl@0: sl@0: if(aDrive == KMaxLocalDrives) sl@0: { sl@0: test.Printf(_L(" MMC Drive Not Found\r\n")); sl@0: return EFalse; sl@0: } sl@0: sl@0: // Work out the file server drive number (which isn't necessarily the same sl@0: // as the TBusLocalDrive drive number) sl@0: RFs theFs; sl@0: test(theFs.Connect() == KErrNone); sl@0: sl@0: TInt i; sl@0: for (i = EDriveA; i < EDriveZ; i++) sl@0: { sl@0: TMediaSerialNumber serialNum; sl@0: TInt r = theFs.GetMediaSerialNumber(serialNum, i); sl@0: TInt len = serialNum.Length(); sl@0: TInt n; sl@0: for (n=0; n buf; sl@0: for (TInt m=n; m hexBuf; sl@0: hexBuf.Format(_L("%02X "),serialNum[m]); sl@0: buf.Append(hexBuf); sl@0: } sl@0: buf.Append(_L("\n")); sl@0: test.Printf(buf); sl@0: } sl@0: if (serialNum.Compare(localSerialNum) == 0) sl@0: { sl@0: TVolumeInfo vi; sl@0: r = theFs.Volume(vi, i); sl@0: TBool sizeMatch = (vi.iSize < caps.iSize); sl@0: if (sizeMatch) sl@0: { sl@0: aRFsDriveNum = i; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: } sl@0: if (i == EDriveZ) sl@0: { sl@0: test.Printf(_L(" RFs MMC Drive Not Found\r\n")); sl@0: return EFalse; sl@0: } sl@0: sl@0: theFs.Close(); sl@0: sl@0: return ETrue; sl@0: } sl@0: sl@0: sl@0: TInt TestLockCard(RFs& aFs, TInt aTheMemoryCardDrive, TMediaPassword &aOldPassword, TMediaPassword& aNewPassword, TBool aStore) sl@0: { sl@0: TMediaPassword newPassWord; sl@0: TMediaPassword oldPassWord; sl@0: TInt err=0; sl@0: TDriveInfo dInfo; sl@0: sl@0: aFs.Drive(dInfo, RFsDNum); sl@0: sl@0: newPassWord.Append(aNewPassword); sl@0: oldPassWord.Append(aOldPassword); sl@0: sl@0: test (dInfo.iMediaAtt & KMediaAttLockable); sl@0: sl@0: err=aFs.LockDrive(RFsDNum, oldPassWord, newPassWord, aStore ); sl@0: sl@0: aFs.Drive(dInfo, aTheMemoryCardDrive); sl@0: return err; sl@0: } sl@0: sl@0: TInt TestUnlockCard(RFs& aFs, TInt aTheMemoryCardDrive, TMediaPassword& aPassword, TBool aStore) sl@0: { sl@0: TMediaPassword oldPw; sl@0: sl@0: oldPw.Append(aPassword); sl@0: TInt err = aFs.UnlockDrive( aTheMemoryCardDrive, oldPw, aStore); sl@0: return err; sl@0: } sl@0: sl@0: TInt TestClearPassword(RFs& aFs, TInt aTheMemoryCardDrive, TMediaPassword& aPassword) sl@0: { sl@0: TMediaPassword oldPwd = aPassword; sl@0: sl@0: TInt err = aFs.ClearPassword( aTheMemoryCardDrive, oldPwd ); sl@0: return err; sl@0: } sl@0: sl@0: sl@0: TInt ExecuteForcedEraseTestL(RFs& aFs, TInt aTheMemoryCardDrive) sl@0: { sl@0: TInt err = aFs.ErasePassword( aTheMemoryCardDrive ); sl@0: return err; sl@0: } sl@0: sl@0: sl@0: TBool TestLocked(RFs& aFs, TInt aTheMemoryCardDrive) sl@0: { sl@0: TDriveInfo info; sl@0: sl@0: TInt r = aFs.Drive(info, aTheMemoryCardDrive); sl@0: test (r == KErrNone); sl@0: sl@0: return (info.iMediaAtt & KMediaAttLocked)?(TBool)ETrue:(TBool)EFalse; sl@0: } sl@0: sl@0: void WaitForPowerDownLock(RFs& aFs, TInt aTheMemoryCardDrive) sl@0: { sl@0: test.Printf(_L("Waiting for stack to power down...\n")); sl@0: TInt n; sl@0: for (n=0; n<30 && !TestLocked(aFs, aTheMemoryCardDrive); n++) sl@0: { sl@0: User::After(1000000); sl@0: } sl@0: test(n < 30); sl@0: test(TestLocked(aFs, aTheMemoryCardDrive)); // should now be locked sl@0: } sl@0: sl@0: void WaitForPowerDownUnlock(RFs& /*aFs*/, TInt /*aTheMemoryCardDrive*/) sl@0: { sl@0: test.Printf(_L("Allow some time for stack to power down")); sl@0: for (TUint i=0; i < 80; ++i) sl@0: { sl@0: User::After(100000); sl@0: test.Printf(_L(".")); sl@0: } sl@0: test.Printf(_L("\n")); sl@0: } sl@0: sl@0: /* sl@0: INC103721: sl@0: The MMC Media drivers do not power up the MMC Stack to retrieve card status, sl@0: the following tests ensure that the 'lock status' is correctly returned after a sl@0: stack power down. sl@0: */ sl@0: LOCAL_C void TestPowerDownStatus() sl@0: { sl@0: TInt r = KErrNone; sl@0: TLocalDriveCapsV5 driveCaps; sl@0: TPckg driveCapsPkg(driveCaps); sl@0: TMediaPassword password = (TUint8*) "salasana"; sl@0: TMediaPassword oldpassword; sl@0: sl@0: test.Start(_L("Testing Power Down Status Reporting")); sl@0: sl@0: test.Next(_L("Open Connection")); sl@0: RFs fs; sl@0: test(fs.Connect() == KErrNone); sl@0: sl@0: // Lock card (with password stored) sl@0: test.Next(_L("Locking Card - Password Stored")); sl@0: sl@0: test.Next(_L("Locking card (Successful)")) ; sl@0: r = TestLockCard(fs, RFsDNum, oldpassword, password, ETrue); sl@0: test(r == KErrNone); sl@0: sl@0: test(!TestLocked(fs, RFsDNum)); // not locked yet as stack hasn't powered down sl@0: sl@0: test.Next(_L("Card reports unlocked - before PowerDown")); sl@0: r = TBLD.Caps(driveCapsPkg); sl@0: test.Printf(_L("\tCaps() returned %d , iMediaAtt %08x\n"), r, driveCaps.iMediaAtt); sl@0: sl@0: test (r == KErrNone); sl@0: test ((driveCaps.iMediaAtt & KMediaAttLocked) == 0); sl@0: sl@0: WaitForPowerDownUnlock(fs, RFsDNum); sl@0: sl@0: test.Next(_L("Check card reports unlocked - after PowerDown")); sl@0: r = TBLD.Caps(driveCapsPkg); sl@0: test.Printf(_L("\tCaps() returned %d , iMediaAtt %08x\n"), r, driveCaps.iMediaAtt); sl@0: sl@0: test (r == KErrNone); sl@0: test ((driveCaps.iMediaAtt & KMediaAttLocked) == 0); sl@0: sl@0: test.Next(_L("Clear password (Successful)")); sl@0: r = TestClearPassword(fs, RFsDNum, password); sl@0: test(r == KErrNone); sl@0: sl@0: // Lock card (without password in store) sl@0: test.Next(_L("Locking card - Password NOT Stored")); sl@0: sl@0: test.Next(_L("Locking card (Successful)")); sl@0: r = TestLockCard(fs, RFsDNum, oldpassword, password, EFalse); sl@0: test(r == KErrNone); sl@0: sl@0: test(!TestLocked(fs, RFsDNum)); // not locked yet as stack hasn't powered down sl@0: sl@0: test.Next(_L("Card is reports Unlocked - before PowerDown")); sl@0: r = TBLD.Caps(driveCapsPkg); sl@0: test.Printf(_L("\tCaps() returned %d , iMediaAtt %08x\n"), r, driveCaps.iMediaAtt); sl@0: sl@0: test (r == KErrNone); sl@0: test ((driveCaps.iMediaAtt & KMediaAttLocked) == 0); sl@0: sl@0: WaitForPowerDownLock(fs, RFsDNum); sl@0: sl@0: test.Next(_L("Card reports Locked - after PowerDown")); sl@0: r = TBLD.Caps(driveCapsPkg); sl@0: test.Printf(_L("\tCaps() returned %d , iMediaAtt %08x\n"), r, driveCaps.iMediaAtt); sl@0: sl@0: test (r == KErrNone); sl@0: test ((driveCaps.iMediaAtt & KMediaAttLocked) != 0); sl@0: sl@0: // Unlock card sl@0: test.Next(_L("Unlock 'locked' Card - Password Stored")); sl@0: sl@0: test.Next(_L("Unlocking card (Successful)")) ; sl@0: r = TestUnlockCard(fs, RFsDNum, password, ETrue); sl@0: test(r == KErrNone); sl@0: test (!TestLocked(fs, RFsDNum)); // not locked as stack hasn't powered down sl@0: sl@0: test.Next(_L("Card reports unlocked - before PowerDown")); sl@0: r = TBLD.Caps(driveCapsPkg); sl@0: test.Printf(_L("\tCaps() returned %d , iMediaAtt %08x\n"), r, driveCaps.iMediaAtt); sl@0: sl@0: test (r == KErrNone); sl@0: test ((driveCaps.iMediaAtt & KMediaAttLocked) == 0); sl@0: sl@0: WaitForPowerDownUnlock(fs, RFsDNum); sl@0: sl@0: test.Next(_L("Card reports unlocked - after PowerDown")); sl@0: r = TBLD.Caps(driveCapsPkg); sl@0: test.Printf(_L("\tCaps() returned %d , iMediaAtt %08x\n"), r, driveCaps.iMediaAtt); sl@0: sl@0: test (r == KErrNone); sl@0: test ((driveCaps.iMediaAtt & KMediaAttLocked) == 0); sl@0: sl@0: test.Next(_L("Clearing Password (Successful)")); sl@0: r = TestClearPassword(fs, RFsDNum, password); sl@0: test(r == KErrNone); sl@0: sl@0: fs.Close(); sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: LOCAL_C void TestFsLockUnlock() sl@0: { sl@0: TInt r = KErrNone; sl@0: sl@0: test.Start(_L("Testing RFs APIs")); sl@0: sl@0: test.Next(_L("open connection")); sl@0: RFs fs; sl@0: test(fs.Connect() == KErrNone); sl@0: sl@0: sl@0: test.Next(_L("test locking card")); sl@0: sl@0: TMediaPassword oldpassword; sl@0: TMediaPassword newpassword = (TUint8*) "salasana"; sl@0: TMediaPassword wrongpwd = (TUint8*) "failtest"; sl@0: sl@0: r = TestLockCard(fs, RFsDNum, oldpassword, newpassword, EFalse); sl@0: test(r == KErrNone); sl@0: test(!TestLocked(fs, RFsDNum)); // not locked yet as stack hasn't powered down sl@0: sl@0: test.Next(_L("test unlocking fails if still powered up")); sl@0: r = TestUnlockCard(fs, RFsDNum, newpassword, EFalse); sl@0: test(r == KErrAlreadyExists); // already unlocked (as stack won't have powered down yet) sl@0: test (!TestLocked(fs, RFsDNum)); sl@0: sl@0: test.Next(_L("test clearing succeeds if still powered up")); sl@0: r = TestClearPassword(fs, RFsDNum, newpassword); sl@0: test(r == KErrNone); sl@0: test(!TestLocked(fs, RFsDNum)); sl@0: sl@0: test.Next(_L("test locking card again")); sl@0: r = TestLockCard(fs, RFsDNum, oldpassword, newpassword, EFalse); sl@0: test(r == KErrNone); sl@0: test(!TestLocked(fs, RFsDNum)); // not locked yet as stack hasn't powered down sl@0: sl@0: WaitForPowerDownLock(fs, RFsDNum); sl@0: sl@0: // DEF111681: CheckDisk is returning bad error code when run on locked SD card sl@0: // RFs::CheckDisk() should return KErrNone or KErrLocked (not KErrCorrupt) if the card is locked and the sl@0: // stack powers down sl@0: // NB For FAT16 cards, the FAT will be entirely cached so CheckDisk will not actually access the media sl@0: // so KErrNone will be returned. For FAT32 cards, KErrLocked will be returned. sl@0: test.Next(_L("test CheckDisk() returns KErrLocked if the card is locked and the stack powered down")); sl@0: WaitForPowerDownLock(fs, RFsDNum); sl@0: TFileName sessionPath; sl@0: sessionPath=_L("?:\\"); sl@0: TChar driveLetter; sl@0: r = fs.DriveToChar(RFsDNum,driveLetter); sl@0: test(r==KErrNone); sl@0: sessionPath[0]=(TText)driveLetter; sl@0: r = fs.CheckDisk(sessionPath); sl@0: test(r == KErrNone || r == KErrLocked); sl@0: WaitForPowerDownLock(fs, RFsDNum); sl@0: sl@0: sl@0: // DEF111700: Formatting a locked SD/MMC leaves it in a bad state (causes panics later) sl@0: // This was caused by format calling TDrive::MountMedia(ETrue) and then not dismounting sl@0: r = fs.RemountDrive(RFsDNum); sl@0: test (r == KErrNone); sl@0: RFormat fmt; sl@0: TPckgBuf stepPkg; sl@0: TDriveUnit driveUnit(RFsDNum); sl@0: TDriveName driveName = driveUnit.Name(); sl@0: test.Next(_L("format locked card")); sl@0: r = fmt.Open(fs, driveName, EHighDensity, stepPkg()); sl@0: if (r != KErrLocked) sl@0: test.Printf(_L("RFormat::Next() returned %d\n"), r); sl@0: test(r == KErrLocked); sl@0: test.Printf(_L("\n")); sl@0: fmt.Close(); sl@0: r = fs.CheckDisk(sessionPath); sl@0: test(r == KErrLocked); sl@0: sl@0: sl@0: test.Next(_L("test unlocking fails after powered down & unlocked with wrong password")); sl@0: r = TestUnlockCard(fs, RFsDNum, wrongpwd, EFalse); sl@0: test(r == KErrAccessDenied); // unlocked should now fail sl@0: sl@0: test.Next(_L("test unlocking succeeds for correct password after powered down & locked")); sl@0: r = TestUnlockCard(fs, RFsDNum, newpassword, EFalse); sl@0: test(r == KErrNone); // unlocked should now succeed sl@0: sl@0: test.Next(_L("test unlocking fails after successful unlock")); sl@0: r = TestUnlockCard(fs, RFsDNum, wrongpwd, EFalse); sl@0: test(r == KErrAlreadyExists); // unlocked should now succeed sl@0: test(!TestLocked(fs, RFsDNum)); // not locked yet as stack hasn't powered down sl@0: sl@0: test.Next(_L("test locking card with new password (with wrong password as old password)")); sl@0: r = TestLockCard(fs, RFsDNum, wrongpwd, newpassword, EFalse); sl@0: test(r == KErrAccessDenied); sl@0: test(!TestLocked(fs, RFsDNum)); // not locked yet as stack hasn't powered down sl@0: sl@0: test.Next(_L("test locking card with new password (with right password as old password)")); sl@0: r = TestLockCard(fs, RFsDNum, newpassword, wrongpwd, EFalse); sl@0: test(r == KErrNone); sl@0: test(!TestLocked(fs, RFsDNum)); // not locked yet as stack hasn't powered down sl@0: sl@0: WaitForPowerDownLock(fs, RFsDNum); sl@0: sl@0: test.Next(_L("test clearing fails with wrong password if powered down & locked")); sl@0: r = TestClearPassword(fs, RFsDNum, newpassword); // Note: we have set the wrong password as the new password sl@0: test(r == KErrAccessDenied); sl@0: test(TestLocked(fs, RFsDNum)); sl@0: sl@0: test.Next(_L("test clearing succeeds with right password if powered down & locked")); sl@0: r = TestClearPassword(fs, RFsDNum, wrongpwd); sl@0: test(r == KErrNone); sl@0: test(!TestLocked(fs, RFsDNum)); sl@0: sl@0: test.Next(_L("test locking card again")); sl@0: r = TestLockCard(fs, RFsDNum, oldpassword, newpassword, EFalse); sl@0: test(r == KErrNone); sl@0: test(!TestLocked(fs, RFsDNum)); // not locked yet as stack hasn't powered down sl@0: sl@0: test.Next(_L("test forced erase fails if still powered up")); sl@0: r = ExecuteForcedEraseTestL(fs, RFsDNum); sl@0: test(r == KErrAccessDenied); // fails because card is not yet locked sl@0: sl@0: WaitForPowerDownLock(fs, RFsDNum); sl@0: sl@0: sl@0: test.Next(_L("test forced erase succeeds if powered down & locked")); sl@0: r = ExecuteForcedEraseTestL(fs, RFsDNum); sl@0: test(r == KErrNone); sl@0: sl@0: fs.Close(); sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: sl@0: /** sl@0: PDEF104639: Phone automatically reboots when inserting memory card with password. sl@0: Testing that TheFs.UnlockDrive() results in a notification - and doesn't crash the file server (!) sl@0: */ sl@0: void TestUnlockDriveNotifyChange() sl@0: { sl@0: RFs fs; sl@0: test(fs.Connect() == KErrNone); sl@0: sl@0: TFileName sessionPath; sl@0: sessionPath=_L("?:\\"); sl@0: TChar driveLetter; sl@0: TInt r=fs.DriveToChar(RFsDNum,driveLetter); sl@0: test(r==KErrNone); sl@0: sessionPath[0]=(TText)driveLetter; sl@0: r=fs.SetSessionPath(sessionPath); sl@0: test(r==KErrNone); sl@0: sl@0: TInt nRes; sl@0: TDriveInfo dInfo; sl@0: sl@0: nRes = fs.Drive(dInfo, RFsDNum); sl@0: test(nRes == KErrNone); sl@0: if (!(dInfo.iMediaAtt & KMediaAttLockable)) sl@0: { sl@0: test.Printf(_L("Drive %d is not lockable %d\n"), RFsDNum); sl@0: fs.Close(); sl@0: return; sl@0: } sl@0: sl@0: // attempt to lock the drive sl@0: TMediaPassword oldPassword; sl@0: TMediaPassword newPassword = (TUint8*) "salasana"; sl@0: nRes = fs.LockDrive(RFsDNum, oldPassword, newPassword, EFalse ); sl@0: test(nRes == KErrNone); sl@0: sl@0: WaitForPowerDownLock(fs, RFsDNum); sl@0: sl@0: TRequestStatus reqStatNotify1(KRequestPending); sl@0: sl@0: //-- set up notifier sl@0: fs.NotifyChange(ENotifyAll, reqStatNotify1, sessionPath); sl@0: test(reqStatNotify1.Int() == KRequestPending); sl@0: sl@0: //-- unlock the drive sl@0: nRes = fs.UnlockDrive(RFsDNum, newPassword, EFalse); sl@0: test.Printf(_L("UnlockDrive() %d reqStatNotify1 %d\n"), nRes, reqStatNotify1.Int()); sl@0: sl@0: //-- check that the notifier worked sl@0: User::WaitForRequest(reqStatNotify1); sl@0: test(reqStatNotify1.Int() == KErrNone); sl@0: sl@0: r = TestClearPassword(fs, RFsDNum, newPassword); sl@0: test(r == KErrNone); sl@0: test(!TestLocked(fs, RFsDNum)); sl@0: sl@0: sl@0: sl@0: fs.Close(); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void RunTests() sl@0: // sl@0: // Main test routine. Calls other test functions. sl@0: // sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: if(TBLDNum == -1) sl@0: { sl@0: if(!SetupDrivesForPlatform(TBLDNum, RFsDNum)) sl@0: { sl@0: test.Printf(_L("MMC Drive Not Found - Skipping test\r\n")); sl@0: return; sl@0: } sl@0: } sl@0: sl@0: test.Next(_L("Connecting TBLD")); sl@0: test(TBLD.Connect(TBLDNum, TBLDChangedFlag) == KErrNone); sl@0: sl@0: test.Next(_L("Allocating test data")); sl@0: AllocateTestData(); sl@0: sl@0: test.Next(_L("Testing locking / unlocking using file server APIs")); sl@0: TestFsLockUnlock(); sl@0: sl@0: test.Next(_L("Testing Power Down Status Reporting using file server APIs")); sl@0: TestPowerDownStatus(); sl@0: sl@0: test.Next(_L("Testing RFs::NotifyChange() with RFs::UnlockDrive()")); sl@0: TestUnlockDriveNotifyChange(); sl@0: sl@0: test.Next(_L("Forced Erase")); sl@0: TestFormatErase(); sl@0: test.Next(_L("Testing store management")); sl@0: TestStaticStore(); sl@0: test.Next(_L("Testing locking functions")); sl@0: TestLockUnlock(); sl@0: test.Next(_L("Testing Elide Passwords")); sl@0: TestElidePasswords(); sl@0: test.Next(_L("Testing Null Passwords")); sl@0: TestNullPasswords(); sl@0: test.Next(_L("Testing controller store")); sl@0: TestControllerStore(); sl@0: test.Next(_L("Testing auto unlock")); sl@0: TestAutoUnlock(); sl@0: test.Next(_L("Testing password file")); sl@0: TestPasswordFile(); sl@0: test.Next(_L("Testing writing a valid password to store unlocks card")); sl@0: TestWriteToPasswordStoreUnlocksCard(); sl@0: sl@0: test.Next(_L("Disconnecting TBLD")); sl@0: TBLD.Disconnect(); sl@0: sl@0: test.Next(_L("Deleting test data")); sl@0: DeleteTestData(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: TInt E32Main() sl@0: { sl@0: sl@0: test.Title(); sl@0: test.Start(_L("E32Main")); sl@0: sl@0: RunTests(); sl@0: sl@0: test.End(); sl@0: test.Close(); sl@0: sl@0: return KErrNone; sl@0: } sl@0: