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