sl@0: // Copyright (c) 2004-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 "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: // sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: */ sl@0: sl@0: // System Include sl@0: #include sl@0: sl@0: // User Includes sl@0: #include "TestFileUriServer.h" sl@0: #include "TestCreateFileStep.h" sl@0: #include "TestGetFileNameFromUriStep.h" sl@0: #include "TestGenerateFileUriStep.h" sl@0: #include "TestDeleteFileStep.h" sl@0: #include "TestForAllFilesStep.h" sl@0: sl@0: // The system-wide unique name for the test-server sl@0: _LIT(KServerName, "TestFileUriServer"); sl@0: sl@0: TBuf CTestFileUriServer::iRemovableDrives(KNullDesC); sl@0: sl@0: /** sl@0: Static factory constructor. Creates and returns instance of the test server sl@0: @return A pointer to the newly created CTestFileUriServer object sl@0: */ sl@0: CTestFileUriServer* CTestFileUriServer::NewL() sl@0: { sl@0: // Construct the server sl@0: CTestFileUriServer* server = new(ELeave) CTestFileUriServer(); sl@0: CleanupStack::PushL(server); sl@0: sl@0: // CServer base class call sl@0: // Name the server using the system-wide unique string sl@0: // Clients use this to create server sessions. sl@0: server->StartL(KServerName); sl@0: sl@0: CleanupStack::Pop(server); sl@0: return server; sl@0: } sl@0: sl@0: sl@0: #if (!defined EKA2) sl@0: sl@0: /** sl@0: Creates the Active Scheduler, then creates the test-server, synchronises the sl@0: thread with the client and then enters the active scheduler. sl@0: sl@0: This is EKA1 version of MainL(). Uses sempahore to sync with client sl@0: as Rendezvous calls are not available sl@0: */ sl@0: LOCAL_C void MainL() sl@0: { sl@0: // Create and install the active scheduler. sl@0: CActiveScheduler* sched = NULL; sl@0: sched = new(ELeave) CActiveScheduler; sl@0: CleanupStack::PushL(sched); sl@0: CActiveScheduler::Install(sched); sl@0: sl@0: // Create the server inside trap harness sl@0: CTestFileUriServer *server = NULL; sl@0: TRAPD(err, server = CTestFileUriServer::NewL()); sl@0: if (!err) sl@0: { sl@0: CleanupStack::PushL(server); sl@0: RSemaphore sem; sl@0: sl@0: // The client API of TestExecute will already have created the sl@0: // semaphore and will be waiting on it. sl@0: User::LeaveIfError(sem.OpenGlobal(KServerName)); sl@0: sl@0: CleanupStack::Pop(server); sl@0: sl@0: // Signal the client sl@0: sem.Signal(); sl@0: sem.Close(); sl@0: sl@0: // Enter the active scheduler sl@0: sched->Start(); sl@0: } sl@0: CleanupStack::Pop(sched); sl@0: delete server; sl@0: delete sched; sl@0: } sl@0: #else sl@0: /** sl@0: EKA2 version of MainL() sl@0: Uses the new Rendezvous call isntead of the older semaphore. sl@0: */ sl@0: LOCAL_C void MainL() sl@0: { sl@0: // For platform security sl@0: #if (defined __DATA_CAGING__) sl@0: RProcess().DataCaging(RProcess::EDataCagingOn); sl@0: RProcess().SecureApi(RProcess::ESecureApiOn); sl@0: #endif sl@0: CActiveScheduler* sched = NULL; sl@0: sched = new(ELeave) CActiveScheduler; sl@0: CActiveScheduler::Install(sched); sl@0: CTestFileUriServer* server = NULL; sl@0: sl@0: // Create the test-server sl@0: TRAPD(err, server = CTestFileUriServer::NewL()); sl@0: sl@0: if(!err) sl@0: { sl@0: // Sync with the client and enter the active scheduler sl@0: RProcess::Rendezvous(KErrNone); sl@0: sched->Start(); sl@0: } sl@0: delete server; sl@0: delete sched; sl@0: } sl@0: #endif // #if (!defined EKA2) sl@0: sl@0: sl@0: #if (defined __WINS__ && !defined EKA2) sl@0: /** sl@0: DLL entry-point for EKA1 emulator builds. sl@0: */ sl@0: GLDEF_C TInt E32Dll(enum TDllReason /*aDllReason*/) sl@0: { sl@0: return KErrNone; sl@0: } sl@0: sl@0: #else sl@0: /** sl@0: Exe entry point code, for EKA1 hardware and EKA2 builds. sl@0: */ sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: __UHEAP_MARK; sl@0: CTrapCleanup *cleanup = CTrapCleanup::New(); sl@0: if (cleanup == NULL) sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: TInt err = KErrNone; sl@0: TRAP(err, MainL()); sl@0: delete cleanup; sl@0: __UHEAP_MARKEND; sl@0: return KErrNone; sl@0: } sl@0: #endif // #if (defined __WINS__ && !defined EKA2) sl@0: sl@0: #if (defined __WINS__ && !defined EKA2) sl@0: /** sl@0: For EKA1 emulator builds. This function is called when the thread is first sl@0: resumed. Has the standard thread entry siganture. sl@0: */ sl@0: TInt ThreadFunc (TAny* /*aParam*/) sl@0: { sl@0: __UHEAP_MARK; sl@0: CTrapCleanup* cleanup = CTrapCleanup::New(); sl@0: if (cleanup == NULL) sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: TInt err = KErrNone; sl@0: TRAP(err, MainL()); sl@0: delete cleanup; sl@0: __UHEAP_MARKEND; sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: For EKA1 emulator builds. Creates and starts a thread for the server to run. sl@0: */ sl@0: EXPORT_C TInt NewServer() sl@0: { sl@0: _LIT(KThread, "Thread"); sl@0: RThread thread; sl@0: sl@0: // Name the thread as "Thread" making it hopefully unique sl@0: TBuf threadName(KServerName); sl@0: threadName.Append(KThread); sl@0: sl@0: const TInt KMaxHeapSize = 0x1000000; sl@0: sl@0: // Create the thread sl@0: TInt err = thread.Create(threadName, ThreadFunc, KDefaultStackSize, sl@0: KMinHeapSize, KMaxHeapSize, NULL, EOwnerProcess); sl@0: if (err != KErrNone) sl@0: { sl@0: return err; sl@0: } sl@0: sl@0: // Start the thread -> effectively calls ThreadFunc sl@0: thread.Resume(); sl@0: sl@0: thread.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: #endif // #if (defined __WINS__ && !defined EKA2) sl@0: sl@0: sl@0: /** sl@0: Base class pure virtual sl@0: @return - Instance of the test step sl@0: */ sl@0: CTestStep* CTestFileUriServer::CreateTestStep(const TDesC& aStepName) sl@0: { sl@0: CTestStep *testStep = NULL; sl@0: sl@0: if (aStepName == KTestCreateFileStep) sl@0: { sl@0: testStep = new (ELeave) CTestCreateFileStep; sl@0: } sl@0: else if (aStepName == KTestGetFileNameFromUriStep) sl@0: { sl@0: testStep = new (ELeave) CTestGetFileNameFromUriStep; sl@0: } sl@0: else if (aStepName == KTestGenerateFileUriStep) sl@0: { sl@0: testStep = new (ELeave) CTestGenerateFileUriStep; sl@0: } sl@0: else if (aStepName == KTestDeleteFileStep) sl@0: { sl@0: testStep = new (ELeave) CTestDeleteFileStep; sl@0: } sl@0: else if (aStepName == KTestForAllFilesStep) sl@0: { sl@0: testStep = new (ELeave) CTestForAllFilesStep(); sl@0: } sl@0: return testStep; sl@0: } sl@0: sl@0: /** sl@0: Returns the equivalent drive number of a drive sl@0: */ sl@0: void CTestFileUriServer::GetDriveNumber(const TDesC& aDrive, TDriveNumber& aDriveNum) sl@0: { sl@0: TBuf<1> driveLetter(aDrive.Left(1)); sl@0: driveLetter.LowerCase(); sl@0: aDriveNum = static_cast (driveLetter[0] - KLetterA); sl@0: } sl@0: sl@0: /** sl@0: Checks whether a specific drive is a removable drive sl@0: */ sl@0: TInt CTestFileUriServer::IsRemovableDrive(const TDriveNumber& aDriveNum, TBool& aResult) sl@0: { sl@0: TInt err = KErrNone; sl@0: TDriveInfo driveInfo; sl@0: RFs fs; sl@0: aResult = EFalse; sl@0: err = fs.Connect(); sl@0: if(err == KErrNone) sl@0: { sl@0: err = fs.Drive(driveInfo, aDriveNum); sl@0: if (err == KErrNone && driveInfo.iDriveAtt & KDriveAttRemovable) sl@0: { sl@0: aResult = ETrue; sl@0: } sl@0: fs.Close(); sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: /** sl@0: Replaces the drive placeholder with the actual drive sl@0: */ sl@0: HBufC16* CTestFileUriServer::CheckAndFillDriveNameL(const TPtrC& aFileUri, const TPtrC& aDrive) sl@0: { sl@0: HBufC16* expectedUriWithDrive = aFileUri.AllocL(); sl@0: TInt placeHolderPos = aFileUri.Find(KDrivePlaceHolder); sl@0: if(placeHolderPos >= KErrNone) sl@0: { sl@0: if(aDrive == KExtMedia) sl@0: {// Create a descriptor that is big enough sl@0: // Just in case ReAllocL leaves sl@0: CleanupStack::PushL(expectedUriWithDrive); sl@0: expectedUriWithDrive = expectedUriWithDrive->ReAllocL(aFileUri.Length() + (KExtMedia().Length() - KDrivePlaceHolder().Length())); sl@0: CleanupStack::Pop(); // expectedUriWithDrive sl@0: } sl@0: expectedUriWithDrive->Des().Replace(placeHolderPos, KDrivePlaceHolder().Length(), aDrive); sl@0: } sl@0: return expectedUriWithDrive; sl@0: } sl@0: sl@0: /** sl@0: Private function used to find the remobale drives and populate iRemovableDrives sl@0: */ sl@0: TInt CTestFileUriServer::PopulateRemovableDrivesBuf(const RFs& aFs) sl@0: { sl@0: TInt err = KErrNone; sl@0: TDriveInfo driveInfo; sl@0: TInt driveNum; sl@0: for (driveNum = EDriveA; driveNum <= EDriveZ; driveNum++) sl@0: { sl@0: // Populate iRemovableDrives with all removable drives in alphabetical order sl@0: err = aFs.Drive(driveInfo, driveNum); sl@0: if (err == KErrNone && (driveInfo.iDriveAtt & KDriveAttRemovable)) sl@0: { sl@0: iRemovableDrives.Append(TInt16('a' + driveNum)); sl@0: } sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: /** sl@0: Searches whether a file with same name and path exists in any other removable drive sl@0: */ sl@0: TInt CTestFileUriServer::FirstRemovableDriveWithSameFileName(const TDesC& aFileName, TBuf<1>& aCorrectDrive) sl@0: { sl@0: aCorrectDrive = aFileName.Left(1); sl@0: TInt err = KErrNone; sl@0: RFs fs; sl@0: if((err = fs.Connect()) != KErrNone) sl@0: { sl@0: return err; sl@0: } sl@0: sl@0: if(iRemovableDrives == KNullDesC) sl@0: { sl@0: if((err = PopulateRemovableDrivesBuf(fs)) != KErrNone) sl@0: { sl@0: return err; sl@0: } sl@0: } sl@0: TInt index; sl@0: HBufC* tempFileName = NULL; sl@0: if((tempFileName = aFileName.Alloc()) == NULL) sl@0: { sl@0: return KErrGeneral; sl@0: } sl@0: for(index = 0; index < iRemovableDrives.Length(); ++index) sl@0: { sl@0: TUint attValue; sl@0: // change the drive in the filename and check whether such a file exists sl@0: tempFileName->Des()[0] = iRemovableDrives[index]; sl@0: err = fs.Att(tempFileName->Des(), attValue); sl@0: if(err == KErrNone) sl@0: { sl@0: aCorrectDrive[0] = iRemovableDrives[index]; sl@0: break; sl@0: } sl@0: } sl@0: if(index >= iRemovableDrives.Length()) sl@0: {// File not found on any removable drive sl@0: aCorrectDrive = KNullDesC; sl@0: } sl@0: delete tempFileName; sl@0: fs.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: Obtains the private directory of the application and appends it along with the sl@0: relative filename and drive to create the fully qualified filename sl@0: */ sl@0: TInt CTestFileUriServer::CreateFullyQualifiedName(const TPtrC& aRelativeName, const TPtrC& aDrive, TFileName& aFullyQualifiedName) sl@0: { sl@0: RFs fs; sl@0: TInt err = fs.Connect(); sl@0: if(err != KErrNone) sl@0: { sl@0: return err; sl@0: } sl@0: // Get private dir name sl@0: err = fs.PrivatePath(aFullyQualifiedName); sl@0: fs.Close(); sl@0: if(err != KErrNone) sl@0: { sl@0: return err; sl@0: } sl@0: // Construct fully-qualified filename sl@0: aFullyQualifiedName.Insert(0, KDriveSeparator); sl@0: aFullyQualifiedName.Insert(0, aDrive); sl@0: TInt position = 0; sl@0: // If backslash already exists dont include again sl@0: if(aRelativeName.Left(1) == KBackSlash) sl@0: { sl@0: ++position; sl@0: } sl@0: aFullyQualifiedName.Append(aRelativeName.Right(aRelativeName.Length() - position)); sl@0: return KErrNone; sl@0: }