genericservices/httputils/Test/Integration/TestFileUriSuite/TestFileUriServer.cpp
changeset 31 ce057bb09d0b
parent 0 e4d67989cc36
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     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 	}