sl@0: // Copyright (c) 2006-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\loader\t_loader_delete.cpp sl@0: // sl@0: // sl@0: sl@0: sl@0: #include sl@0: #include sl@0: sl@0: #include "t_loader_delete.h" sl@0: sl@0: static RTest test(_L("t_loader_delete")); sl@0: sl@0: // helper functions sl@0: static void TestWithCaps(TUint32 aCaps, TInt aExpectedError); sl@0: static void TestWithCaps(TUint32 aCaps, TInt aExpectedError, const TDesC& aFileName); sl@0: static void SetHelperCaps(TUint32 aCaps); sl@0: static void CreateTestFile(RFs& aFs, const TDesC& aTestFile); sl@0: static void RunHelper(const TDesC& aFileToDelete, TInt aExpectedError); sl@0: sl@0: static void TestWithCaps(TUint32 aCaps, TInt aExpectedError) sl@0: /** sl@0: Test calling RLoader::Delete from a process with the supplied capabilities. sl@0: sl@0: @param aCapMask Capabilities of process which calls RLoader::Delete. sl@0: @param aExpectedError Expected error reason. The launched executable is expected sl@0: to panic with category KTldPanicCat and this reason, which sl@0: is the expected return code from RLoader::Delete. sl@0: */ sl@0: { sl@0: TestWithCaps(aCaps, aExpectedError, KTldTcbFile); sl@0: TestWithCaps(aCaps, aExpectedError, KTldAllFilesFile); sl@0: sl@0: // the following function function calls should fail with either sl@0: // KErrPermissionDenied if this process is not TCB+AllFiles, or with KErrBadName sl@0: // because the filename is not fully qualified. sl@0: TBool pdExp = (aExpectedError == KErrPermissionDenied); sl@0: sl@0: // test filenames which are not fully qualified sl@0: TInt remapErr = pdExp ? KErrPermissionDenied : KErrBadName; sl@0: TestWithCaps(aCaps, remapErr, KTldFileNoPath); sl@0: TestWithCaps(aCaps, remapErr, KTldFileNoDrive); sl@0: sl@0: // test cannot delete non-existent file sl@0: TInt rootNonExistErr = pdExp ? KErrPermissionDenied : KErrNotFound; sl@0: TestWithCaps(aCaps, rootNonExistErr, KTldFileNonExistRoot); sl@0: TInt dirNonExistErr = pdExp ? KErrPermissionDenied : KErrPathNotFound; sl@0: TestWithCaps(aCaps, dirNonExistErr, KTldFileNonExistDir); sl@0: } sl@0: sl@0: static void TestWithCaps(TUint32 aCaps, TInt aExpectedError, const TDesC& aFileName) sl@0: /** sl@0: Helper function for TestWithCaps(TUint32, TInt). This function invokes sl@0: a helper executable with the supplied capabilities and tells it to delete sl@0: the supplied filename. sl@0: sl@0: @param aCapMask Capabilities of process which calls RLoader::Delete. sl@0: @param aExpectedError Expected error reason. The launched executable is expected sl@0: to panic with category KTldPanicCat and this reason, which sl@0: is the expected return code from RLoader::Delete. sl@0: @param aFileName The helper executable is told to delete this file. sl@0: */ sl@0: { sl@0: test.Printf( sl@0: _L("TestWithCaps,aCaps=0x%x,aExpectedError=%d,aFileName=\"%S\"\n"), sl@0: aCaps, aExpectedError, &aFileName); sl@0: sl@0: TInt r; sl@0: sl@0: // create the file to delete sl@0: RFs fs; sl@0: r = fs.Connect(); sl@0: test(r == KErrNone); sl@0: sl@0: // if this file is expected to exist then create it sl@0: TPtrC dirName; sl@0: TBool shouldExist = (aFileName == KTldTcbFile || aFileName == KTldAllFilesFile); sl@0: if (shouldExist) sl@0: { sl@0: TParsePtrC pp(aFileName); sl@0: dirName.Set(pp.DriveAndPath()); sl@0: r = fs.MkDirAll(dirName); sl@0: test(r == KErrNone || r == KErrAlreadyExists); sl@0: CreateTestFile(fs, aFileName); sl@0: } sl@0: sl@0: SetHelperCaps(aCaps); sl@0: RunHelper(aFileName, aExpectedError); sl@0: sl@0: if (shouldExist) sl@0: { sl@0: // if the file could not be deleted then delete it now sl@0: TEntry e; sl@0: // a C++ bool for the following equality operator sl@0: bool exists = (fs.Entry(aFileName, e) == KErrNone); sl@0: test(exists == (aExpectedError != KErrNone)); sl@0: sl@0: if (exists) sl@0: { sl@0: r = fs.Delete(aFileName); sl@0: test(r == KErrNone); sl@0: } sl@0: sl@0: // delete the immediate containing directory. The error code is not sl@0: // used because the directory may be used for something else. sl@0: fs.RmDir(dirName); sl@0: } sl@0: sl@0: // delete the generated different-caps file sl@0: r = fs.Delete(_L("c:\\sys\\bin\\tld_helper_caps.exe")); sl@0: test(r == KErrNone); sl@0: r = fs.Delete(_L("c:\\sys\\hash\\tld_helper_caps.exe")); sl@0: test(r == KErrNone || r == KErrNotFound || r == KErrPathNotFound); sl@0: sl@0: fs.Close(); sl@0: } sl@0: sl@0: static void SetHelperCaps(TUint32 aCaps) sl@0: /** sl@0: Create an instance of the helper executable, tld_helper.exe, sl@0: with the supplied capabilities. sl@0: */ sl@0: { sl@0: TInt r; sl@0: _LIT(KCommandLineArgsFormat, "tld_helper.exe %x c:\\sys\\bin\\tld_helper_caps.exe"); sl@0: TBuf<128> cmdLine; sl@0: cmdLine.Format(KCommandLineArgsFormat, aCaps); sl@0: sl@0: RProcess p; sl@0: r = p.Create(_L("setcap.exe"), cmdLine); sl@0: test(r == KErrNone); sl@0: sl@0: TRequestStatus rs; sl@0: p.Logon(rs); sl@0: test(rs == KRequestPending); sl@0: p.Resume(); sl@0: User::WaitForRequest(rs); sl@0: sl@0: p.Close(); sl@0: } sl@0: sl@0: static void CreateTestFile(RFs& aFs, const TDesC& aTestFile) sl@0: /** sl@0: Create an empty file with the supplied name. This function is used sl@0: to create file which can be deleted with RLoader::Delete. sl@0: sl@0: @param aFs Open file server session. sl@0: @param aTestFile The test file's name. sl@0: */ sl@0: { sl@0: TInt r; sl@0: sl@0: RFile f; sl@0: r = f.Replace(aFs, aTestFile, EFileWrite | EFileStream | EFileShareExclusive); sl@0: test(r == KErrNone); sl@0: f.Close(); sl@0: } sl@0: sl@0: static void RunHelper(const TDesC& aFileToDelete, TInt aExpectedError) sl@0: /** sl@0: Invoke the helper executable, tell it to delete the supplied file. sl@0: sl@0: @param aFileToDelete Name of file which helper executable should delete sl@0: with RLoader::Delete. sl@0: @param aExpectedError The expected return code from RLoader::Delete. sl@0: */ sl@0: { sl@0: TInt r; sl@0: sl@0: // run the helper exe, which will try to delete the file with RLoader::Delete sl@0: RProcess ph; sl@0: r = ph.Create(_L("tld_helper_caps.exe"), aFileToDelete); sl@0: test(r == KErrNone); sl@0: sl@0: TRequestStatus rsh; sl@0: ph.Logon(rsh); sl@0: test(rsh == KRequestPending); sl@0: ph.Resume(); sl@0: User::WaitForRequest(rsh); sl@0: sl@0: // process has died so check the panic category and reason match the expected values sl@0: test(ph.ExitType() == EExitPanic); sl@0: test(ph.ExitCategory() == KTldPanicCat); sl@0: test(ph.ExitReason() == aExpectedError); sl@0: sl@0: ph.Close(); sl@0: } sl@0: sl@0: TInt E32Main() sl@0: /** sl@0: Executable entrypoint calls test functions within heap check. sl@0: */ sl@0: { sl@0: test.Title(); sl@0: test.Start(_L("Testing RLoader::Delete")); sl@0: sl@0: __UHEAP_MARK; sl@0: const TUint32 KTcbMask = 1UL << ECapabilityTCB; sl@0: const TUint32 KAllFilesMask = 1UL << ECapabilityAllFiles; sl@0: sl@0: //Check whether RLoader::Delete handles the case of a bad descriptor being passed sl@0: //as the filename( KBadDescriptor is not itself the malformed desciptor but sl@0: //it trigers the check) sl@0: TestWithCaps(KTcbMask | KAllFilesMask , KErrBadDescriptor, KBadDescriptor); sl@0: sl@0: // TCB | AllFiles sufficient without any other caps sl@0: TestWithCaps(KTcbMask | KAllFilesMask, KErrNone); sl@0: // TCB necessary sl@0: TestWithCaps(~KTcbMask, KErrPermissionDenied); sl@0: // AllFiles necessary sl@0: TestWithCaps(~KAllFilesMask, KErrPermissionDenied); sl@0: // neither TCB nor AllFiles sl@0: TestWithCaps(~(KTcbMask | KAllFilesMask), KErrPermissionDenied); sl@0: TestWithCaps(0, KErrPermissionDenied); sl@0: __UHEAP_MARKEND; sl@0: sl@0: test.End(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: