os/ossrv/genericservices/httputils/Test/Integration/TestFileUriSuite/TestFileUriServer.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 /**
    17  @file
    18  @internalTechnology 
    19 */
    20 
    21 // System Include
    22 #include <escapeutils.h>
    23 
    24 // User Includes
    25 #include "TestFileUriServer.h"
    26 #include "TestCreateFileStep.h"
    27 #include "TestGetFileNameFromUriStep.h"
    28 #include "TestGenerateFileUriStep.h"
    29 #include "TestDeleteFileStep.h"
    30 #include "TestForAllFilesStep.h"
    31 
    32 // The system-wide unique name for the test-server
    33 _LIT(KServerName, "TestFileUriServer");
    34 
    35 TBuf<KMaxDrives> CTestFileUriServer::iRemovableDrives(KNullDesC);
    36 
    37 /**
    38 Static factory constructor. Creates and returns instance of the test server
    39 @return		A pointer to the newly created CTestFileUriServer object
    40 */
    41 CTestFileUriServer*  CTestFileUriServer::NewL()
    42 	{
    43 	// Construct the server
    44 	CTestFileUriServer* server = new(ELeave) CTestFileUriServer();
    45 	CleanupStack::PushL(server);
    46 
    47 	// CServer base class call
    48 	// Name the server using the system-wide unique string
    49 	// Clients use this to create server sessions.
    50 	server->StartL(KServerName);
    51 	
    52 	CleanupStack::Pop(server);
    53 	return server;
    54 	}
    55 	
    56 	
    57 #if (!defined EKA2)
    58 
    59 /**
    60 Creates the Active Scheduler, then creates the test-server, synchronises the 
    61 thread with the client and then enters the active scheduler.
    62 
    63 This is EKA1 version of MainL(). Uses sempahore to sync with client
    64 as Rendezvous calls are not available
    65 */
    66 LOCAL_C void MainL()
    67 	{
    68 	// Create and install the active scheduler.
    69 	CActiveScheduler* sched = NULL;
    70 	sched = new(ELeave) CActiveScheduler;
    71 	CleanupStack::PushL(sched);
    72 	CActiveScheduler::Install(sched);
    73 	
    74 	// Create the server inside trap harness
    75 	CTestFileUriServer *server = NULL;
    76 	TRAPD(err, server = CTestFileUriServer::NewL());
    77 	if (!err)
    78 		{
    79 		CleanupStack::PushL(server);
    80 		RSemaphore sem;
    81 		
    82 		// The client API of TestExecute will already have created the 
    83 		// semaphore and will be waiting on it.
    84 		User::LeaveIfError(sem.OpenGlobal(KServerName));
    85 		
    86 		CleanupStack::Pop(server);
    87 		
    88 		// Signal the client
    89 		sem.Signal();
    90 		sem.Close();
    91 		
    92 		// Enter the active scheduler
    93 		sched->Start();
    94 		}
    95 	CleanupStack::Pop(sched);
    96 	delete server;
    97 	delete sched;
    98 	}
    99 #else
   100 /**
   101 EKA2 version of MainL()
   102 Uses the new Rendezvous call isntead of the older semaphore.
   103 */
   104 LOCAL_C void MainL()
   105 	{
   106 	// For platform security
   107 #if (defined __DATA_CAGING__)
   108 	RProcess().DataCaging(RProcess::EDataCagingOn);	
   109 	RProcess().SecureApi(RProcess::ESecureApiOn);	
   110 #endif
   111 	CActiveScheduler* sched = NULL;
   112 	sched = new(ELeave) CActiveScheduler; 
   113 	CActiveScheduler::Install(sched);
   114 	CTestFileUriServer* server = NULL;
   115 	
   116 	// Create the test-server
   117 	TRAPD(err, server = CTestFileUriServer::NewL());
   118 	
   119 	if(!err)
   120 		{
   121 		// Sync with the client and enter the active scheduler
   122 		RProcess::Rendezvous(KErrNone);
   123 		sched->Start();
   124 		}
   125 	delete server;
   126 	delete sched;	
   127 	}
   128 #endif		// #if (!defined EKA2)
   129 	
   130 
   131 #if (defined __WINS__ && !defined EKA2)
   132 /**
   133 DLL entry-point for EKA1 emulator builds.
   134 */
   135 GLDEF_C TInt E32Dll(enum TDllReason /*aDllReason*/)
   136 	{
   137 	return KErrNone;
   138 	}
   139 	
   140 #else
   141 /**
   142 Exe entry point code, for EKA1 hardware and EKA2 builds.
   143 */
   144 GLDEF_C TInt E32Main()
   145 	{
   146 	__UHEAP_MARK;
   147 	CTrapCleanup *cleanup = CTrapCleanup::New();
   148 	if (cleanup == NULL)
   149 		{
   150 		return KErrNoMemory;
   151 		}
   152 	TInt err = KErrNone;
   153 	TRAP(err, MainL());
   154 	delete cleanup;
   155 	__UHEAP_MARKEND;
   156 	return KErrNone;
   157 	}
   158 #endif		// #if (defined __WINS__ && !defined EKA2)
   159 
   160 #if (defined __WINS__ && !defined EKA2)
   161 /**
   162 For EKA1 emulator builds. This function is called when the thread is first 
   163 resumed. Has the standard thread entry siganture. 
   164 */
   165 TInt ThreadFunc (TAny* /*aParam*/)
   166 	{
   167 	__UHEAP_MARK;
   168 	CTrapCleanup* cleanup = CTrapCleanup::New();
   169 	if (cleanup == NULL)
   170 		{
   171 		return KErrNoMemory;
   172 		}
   173 	TInt err = KErrNone;
   174 	TRAP(err, MainL());
   175 	delete cleanup;
   176 	__UHEAP_MARKEND;
   177 	return KErrNone;
   178 	}
   179 
   180 /**
   181 For EKA1 emulator builds. Creates and starts a thread for the server to run.
   182 */
   183 EXPORT_C TInt NewServer()
   184 	{
   185 	_LIT(KThread, "Thread");
   186 	RThread thread;
   187 	
   188 	// Name the thread as "<Server-Name>Thread" making it hopefully unique
   189 	TBuf<KMaxTestExecuteNameLength> threadName(KServerName);
   190 	threadName.Append(KThread);
   191 	
   192 	const TInt KMaxHeapSize = 0x1000000;
   193 	
   194 	// Create the thread
   195 	TInt err = thread.Create(threadName, ThreadFunc, KDefaultStackSize, 
   196 							 KMinHeapSize, KMaxHeapSize, NULL, EOwnerProcess);
   197 	if (err != KErrNone)
   198 		{
   199 		return err;
   200 		}
   201 	
   202 	// Start the thread -> effectively calls ThreadFunc
   203 	thread.Resume();
   204 	
   205 	thread.Close();
   206 	return KErrNone;
   207 	}
   208 	
   209 #endif 		// #if (defined __WINS__ && !defined EKA2)
   210 
   211 
   212 /**
   213 Base class pure virtual
   214 @return - Instance of the test step
   215 */
   216 CTestStep* CTestFileUriServer::CreateTestStep(const TDesC& aStepName)
   217 	{
   218 	CTestStep *testStep = NULL;
   219 	
   220 	if (aStepName == KTestCreateFileStep)
   221 		{
   222 		testStep = new (ELeave) CTestCreateFileStep;
   223 		}
   224 	else if (aStepName == KTestGetFileNameFromUriStep)
   225 		{
   226 		testStep = new (ELeave) CTestGetFileNameFromUriStep;
   227 		}	
   228 	else if (aStepName == KTestGenerateFileUriStep)
   229 		{
   230 		testStep = new (ELeave) CTestGenerateFileUriStep;
   231 		}
   232 	else if (aStepName == KTestDeleteFileStep)
   233 		{
   234 		testStep = new (ELeave) CTestDeleteFileStep;
   235 		}
   236 	else if (aStepName == KTestForAllFilesStep)
   237 		{
   238 		testStep = new (ELeave) CTestForAllFilesStep();
   239 		}
   240 		return testStep;
   241 	}
   242 
   243 /**
   244 Returns the equivalent drive number of a drive
   245 */
   246 void CTestFileUriServer::GetDriveNumber(const TDesC& aDrive, TDriveNumber& aDriveNum)
   247 	{
   248 	TBuf<1> driveLetter(aDrive.Left(1));
   249 	driveLetter.LowerCase();
   250 	aDriveNum = static_cast <TDriveNumber> (driveLetter[0] - KLetterA);
   251 	}
   252 
   253 /**
   254 Checks whether a specific drive is a removable drive
   255 */
   256 TInt CTestFileUriServer::IsRemovableDrive(const TDriveNumber& aDriveNum, TBool& aResult)
   257 	{
   258 	TInt err = KErrNone;
   259 	TDriveInfo driveInfo;	
   260 	RFs fs;
   261 	aResult = EFalse;
   262 	err = fs.Connect();
   263 	if(err == KErrNone)
   264 		{
   265 		err = fs.Drive(driveInfo, aDriveNum);
   266 		if (err == KErrNone && driveInfo.iDriveAtt & KDriveAttRemovable)
   267 			{
   268 			aResult = ETrue;
   269 			}
   270 		fs.Close();	
   271 		}
   272 	return err;	
   273 	}
   274 	
   275 /**
   276 Replaces the drive placeholder <drive> with the actual drive
   277 */
   278 HBufC16* CTestFileUriServer::CheckAndFillDriveNameL(const TPtrC& aFileUri, const TPtrC& aDrive)
   279 	{
   280 	HBufC16* expectedUriWithDrive = aFileUri.AllocL();
   281 	TInt placeHolderPos = aFileUri.Find(KDrivePlaceHolder);	
   282 	if(placeHolderPos >= KErrNone)
   283 		{
   284 		if(aDrive == KExtMedia)
   285 			{// Create a descriptor that is big enough
   286 			// Just in case ReAllocL leaves
   287 			CleanupStack::PushL(expectedUriWithDrive);
   288 			expectedUriWithDrive = expectedUriWithDrive->ReAllocL(aFileUri.Length() + (KExtMedia().Length() - KDrivePlaceHolder().Length()));
   289 			CleanupStack::Pop(); // expectedUriWithDrive
   290 			}
   291 		expectedUriWithDrive->Des().Replace(placeHolderPos, KDrivePlaceHolder().Length(), aDrive);
   292 		}
   293 	return expectedUriWithDrive;
   294 	}
   295 
   296 /**
   297 Private function used to find the remobale drives and populate iRemovableDrives
   298 */
   299 TInt CTestFileUriServer::PopulateRemovableDrivesBuf(const RFs& aFs)
   300 	{
   301 	TInt err = KErrNone;
   302 	TDriveInfo driveInfo;
   303 	TInt driveNum;
   304 	for (driveNum = EDriveA; driveNum <= EDriveZ; driveNum++)   
   305 		{
   306 		// Populate iRemovableDrives with all removable drives in alphabetical order
   307 		err = aFs.Drive(driveInfo, driveNum);
   308 		if (err == KErrNone && (driveInfo.iDriveAtt & KDriveAttRemovable))       
   309 			{
   310 			iRemovableDrives.Append(TInt16('a' + driveNum));
   311 			}
   312 		}
   313 	return err;
   314 	}
   315 
   316 /**
   317 Searches whether a file with same name and path exists in any other removable drive
   318 */
   319 TInt CTestFileUriServer::FirstRemovableDriveWithSameFileName(const TDesC& aFileName, TBuf<1>& aCorrectDrive)
   320 	{
   321 	aCorrectDrive = aFileName.Left(1);
   322 	TInt err = KErrNone;
   323 	RFs fs;
   324 	if((err = fs.Connect()) != KErrNone)
   325 		{
   326 		return err;
   327 		}
   328 
   329 	if(iRemovableDrives == KNullDesC)
   330 		{
   331 		if((err = PopulateRemovableDrivesBuf(fs)) != KErrNone)
   332 			{
   333 			return err;
   334 			}
   335 		}
   336 	TInt index;
   337 	HBufC* tempFileName	= NULL;
   338 	if((tempFileName = aFileName.Alloc()) == NULL)
   339 		{
   340 		return KErrGeneral;
   341 		}
   342 	for(index = 0; index < iRemovableDrives.Length(); ++index)
   343 		{
   344 		TUint attValue;
   345 		// change the drive in the filename and check whether such a file exists
   346 		tempFileName->Des()[0] = iRemovableDrives[index];
   347 		err = fs.Att(tempFileName->Des(), attValue);
   348 		if(err == KErrNone)
   349 			{
   350 			aCorrectDrive[0] = iRemovableDrives[index];
   351 			break;
   352 			}
   353 		}
   354 	if(index >= iRemovableDrives.Length())
   355 		{// File not found on any removable drive
   356 		aCorrectDrive = KNullDesC;
   357 		}
   358 	delete tempFileName;
   359 	fs.Close();	
   360 	return KErrNone;
   361 	}
   362 	
   363 /**
   364 Obtains the private directory of the application and appends it along with the
   365 relative filename and drive to create the fully qualified filename
   366 */
   367 TInt CTestFileUriServer::CreateFullyQualifiedName(const TPtrC& aRelativeName, const TPtrC& aDrive, TFileName& aFullyQualifiedName)
   368 	{
   369 	RFs fs;
   370 	TInt err = fs.Connect();
   371 	if(err != KErrNone)
   372 		{
   373 		return err;
   374 		}
   375 	// Get private dir name
   376 	err = fs.PrivatePath(aFullyQualifiedName);
   377 	fs.Close();
   378 	if(err != KErrNone)
   379 		{
   380 		return err;
   381 		}
   382 	// Construct fully-qualified filename
   383 	aFullyQualifiedName.Insert(0, KDriveSeparator);
   384 	aFullyQualifiedName.Insert(0, aDrive);
   385 	TInt position = 0;
   386 	// If backslash already exists dont include again
   387 	if(aRelativeName.Left(1) == KBackSlash)
   388 		{
   389 		++position;
   390 		}
   391 	aFullyQualifiedName.Append(aRelativeName.Right(aRelativeName.Length() - position));
   392 	return KErrNone;
   393 	}