os/ossrv/genericservices/httputils/Test/Integration/TestFileUriSuite/TestFileUriServer.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/genericservices/httputils/Test/Integration/TestFileUriSuite/TestFileUriServer.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,393 @@
     1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +/**
    1.20 + @file
    1.21 + @internalTechnology 
    1.22 +*/
    1.23 +
    1.24 +// System Include
    1.25 +#include <escapeutils.h>
    1.26 +
    1.27 +// User Includes
    1.28 +#include "TestFileUriServer.h"
    1.29 +#include "TestCreateFileStep.h"
    1.30 +#include "TestGetFileNameFromUriStep.h"
    1.31 +#include "TestGenerateFileUriStep.h"
    1.32 +#include "TestDeleteFileStep.h"
    1.33 +#include "TestForAllFilesStep.h"
    1.34 +
    1.35 +// The system-wide unique name for the test-server
    1.36 +_LIT(KServerName, "TestFileUriServer");
    1.37 +
    1.38 +TBuf<KMaxDrives> CTestFileUriServer::iRemovableDrives(KNullDesC);
    1.39 +
    1.40 +/**
    1.41 +Static factory constructor. Creates and returns instance of the test server
    1.42 +@return		A pointer to the newly created CTestFileUriServer object
    1.43 +*/
    1.44 +CTestFileUriServer*  CTestFileUriServer::NewL()
    1.45 +	{
    1.46 +	// Construct the server
    1.47 +	CTestFileUriServer* server = new(ELeave) CTestFileUriServer();
    1.48 +	CleanupStack::PushL(server);
    1.49 +
    1.50 +	// CServer base class call
    1.51 +	// Name the server using the system-wide unique string
    1.52 +	// Clients use this to create server sessions.
    1.53 +	server->StartL(KServerName);
    1.54 +	
    1.55 +	CleanupStack::Pop(server);
    1.56 +	return server;
    1.57 +	}
    1.58 +	
    1.59 +	
    1.60 +#if (!defined EKA2)
    1.61 +
    1.62 +/**
    1.63 +Creates the Active Scheduler, then creates the test-server, synchronises the 
    1.64 +thread with the client and then enters the active scheduler.
    1.65 +
    1.66 +This is EKA1 version of MainL(). Uses sempahore to sync with client
    1.67 +as Rendezvous calls are not available
    1.68 +*/
    1.69 +LOCAL_C void MainL()
    1.70 +	{
    1.71 +	// Create and install the active scheduler.
    1.72 +	CActiveScheduler* sched = NULL;
    1.73 +	sched = new(ELeave) CActiveScheduler;
    1.74 +	CleanupStack::PushL(sched);
    1.75 +	CActiveScheduler::Install(sched);
    1.76 +	
    1.77 +	// Create the server inside trap harness
    1.78 +	CTestFileUriServer *server = NULL;
    1.79 +	TRAPD(err, server = CTestFileUriServer::NewL());
    1.80 +	if (!err)
    1.81 +		{
    1.82 +		CleanupStack::PushL(server);
    1.83 +		RSemaphore sem;
    1.84 +		
    1.85 +		// The client API of TestExecute will already have created the 
    1.86 +		// semaphore and will be waiting on it.
    1.87 +		User::LeaveIfError(sem.OpenGlobal(KServerName));
    1.88 +		
    1.89 +		CleanupStack::Pop(server);
    1.90 +		
    1.91 +		// Signal the client
    1.92 +		sem.Signal();
    1.93 +		sem.Close();
    1.94 +		
    1.95 +		// Enter the active scheduler
    1.96 +		sched->Start();
    1.97 +		}
    1.98 +	CleanupStack::Pop(sched);
    1.99 +	delete server;
   1.100 +	delete sched;
   1.101 +	}
   1.102 +#else
   1.103 +/**
   1.104 +EKA2 version of MainL()
   1.105 +Uses the new Rendezvous call isntead of the older semaphore.
   1.106 +*/
   1.107 +LOCAL_C void MainL()
   1.108 +	{
   1.109 +	// For platform security
   1.110 +#if (defined __DATA_CAGING__)
   1.111 +	RProcess().DataCaging(RProcess::EDataCagingOn);	
   1.112 +	RProcess().SecureApi(RProcess::ESecureApiOn);	
   1.113 +#endif
   1.114 +	CActiveScheduler* sched = NULL;
   1.115 +	sched = new(ELeave) CActiveScheduler; 
   1.116 +	CActiveScheduler::Install(sched);
   1.117 +	CTestFileUriServer* server = NULL;
   1.118 +	
   1.119 +	// Create the test-server
   1.120 +	TRAPD(err, server = CTestFileUriServer::NewL());
   1.121 +	
   1.122 +	if(!err)
   1.123 +		{
   1.124 +		// Sync with the client and enter the active scheduler
   1.125 +		RProcess::Rendezvous(KErrNone);
   1.126 +		sched->Start();
   1.127 +		}
   1.128 +	delete server;
   1.129 +	delete sched;	
   1.130 +	}
   1.131 +#endif		// #if (!defined EKA2)
   1.132 +	
   1.133 +
   1.134 +#if (defined __WINS__ && !defined EKA2)
   1.135 +/**
   1.136 +DLL entry-point for EKA1 emulator builds.
   1.137 +*/
   1.138 +GLDEF_C TInt E32Dll(enum TDllReason /*aDllReason*/)
   1.139 +	{
   1.140 +	return KErrNone;
   1.141 +	}
   1.142 +	
   1.143 +#else
   1.144 +/**
   1.145 +Exe entry point code, for EKA1 hardware and EKA2 builds.
   1.146 +*/
   1.147 +GLDEF_C TInt E32Main()
   1.148 +	{
   1.149 +	__UHEAP_MARK;
   1.150 +	CTrapCleanup *cleanup = CTrapCleanup::New();
   1.151 +	if (cleanup == NULL)
   1.152 +		{
   1.153 +		return KErrNoMemory;
   1.154 +		}
   1.155 +	TInt err = KErrNone;
   1.156 +	TRAP(err, MainL());
   1.157 +	delete cleanup;
   1.158 +	__UHEAP_MARKEND;
   1.159 +	return KErrNone;
   1.160 +	}
   1.161 +#endif		// #if (defined __WINS__ && !defined EKA2)
   1.162 +
   1.163 +#if (defined __WINS__ && !defined EKA2)
   1.164 +/**
   1.165 +For EKA1 emulator builds. This function is called when the thread is first 
   1.166 +resumed. Has the standard thread entry siganture. 
   1.167 +*/
   1.168 +TInt ThreadFunc (TAny* /*aParam*/)
   1.169 +	{
   1.170 +	__UHEAP_MARK;
   1.171 +	CTrapCleanup* cleanup = CTrapCleanup::New();
   1.172 +	if (cleanup == NULL)
   1.173 +		{
   1.174 +		return KErrNoMemory;
   1.175 +		}
   1.176 +	TInt err = KErrNone;
   1.177 +	TRAP(err, MainL());
   1.178 +	delete cleanup;
   1.179 +	__UHEAP_MARKEND;
   1.180 +	return KErrNone;
   1.181 +	}
   1.182 +
   1.183 +/**
   1.184 +For EKA1 emulator builds. Creates and starts a thread for the server to run.
   1.185 +*/
   1.186 +EXPORT_C TInt NewServer()
   1.187 +	{
   1.188 +	_LIT(KThread, "Thread");
   1.189 +	RThread thread;
   1.190 +	
   1.191 +	// Name the thread as "<Server-Name>Thread" making it hopefully unique
   1.192 +	TBuf<KMaxTestExecuteNameLength> threadName(KServerName);
   1.193 +	threadName.Append(KThread);
   1.194 +	
   1.195 +	const TInt KMaxHeapSize = 0x1000000;
   1.196 +	
   1.197 +	// Create the thread
   1.198 +	TInt err = thread.Create(threadName, ThreadFunc, KDefaultStackSize, 
   1.199 +							 KMinHeapSize, KMaxHeapSize, NULL, EOwnerProcess);
   1.200 +	if (err != KErrNone)
   1.201 +		{
   1.202 +		return err;
   1.203 +		}
   1.204 +	
   1.205 +	// Start the thread -> effectively calls ThreadFunc
   1.206 +	thread.Resume();
   1.207 +	
   1.208 +	thread.Close();
   1.209 +	return KErrNone;
   1.210 +	}
   1.211 +	
   1.212 +#endif 		// #if (defined __WINS__ && !defined EKA2)
   1.213 +
   1.214 +
   1.215 +/**
   1.216 +Base class pure virtual
   1.217 +@return - Instance of the test step
   1.218 +*/
   1.219 +CTestStep* CTestFileUriServer::CreateTestStep(const TDesC& aStepName)
   1.220 +	{
   1.221 +	CTestStep *testStep = NULL;
   1.222 +	
   1.223 +	if (aStepName == KTestCreateFileStep)
   1.224 +		{
   1.225 +		testStep = new (ELeave) CTestCreateFileStep;
   1.226 +		}
   1.227 +	else if (aStepName == KTestGetFileNameFromUriStep)
   1.228 +		{
   1.229 +		testStep = new (ELeave) CTestGetFileNameFromUriStep;
   1.230 +		}	
   1.231 +	else if (aStepName == KTestGenerateFileUriStep)
   1.232 +		{
   1.233 +		testStep = new (ELeave) CTestGenerateFileUriStep;
   1.234 +		}
   1.235 +	else if (aStepName == KTestDeleteFileStep)
   1.236 +		{
   1.237 +		testStep = new (ELeave) CTestDeleteFileStep;
   1.238 +		}
   1.239 +	else if (aStepName == KTestForAllFilesStep)
   1.240 +		{
   1.241 +		testStep = new (ELeave) CTestForAllFilesStep();
   1.242 +		}
   1.243 +		return testStep;
   1.244 +	}
   1.245 +
   1.246 +/**
   1.247 +Returns the equivalent drive number of a drive
   1.248 +*/
   1.249 +void CTestFileUriServer::GetDriveNumber(const TDesC& aDrive, TDriveNumber& aDriveNum)
   1.250 +	{
   1.251 +	TBuf<1> driveLetter(aDrive.Left(1));
   1.252 +	driveLetter.LowerCase();
   1.253 +	aDriveNum = static_cast <TDriveNumber> (driveLetter[0] - KLetterA);
   1.254 +	}
   1.255 +
   1.256 +/**
   1.257 +Checks whether a specific drive is a removable drive
   1.258 +*/
   1.259 +TInt CTestFileUriServer::IsRemovableDrive(const TDriveNumber& aDriveNum, TBool& aResult)
   1.260 +	{
   1.261 +	TInt err = KErrNone;
   1.262 +	TDriveInfo driveInfo;	
   1.263 +	RFs fs;
   1.264 +	aResult = EFalse;
   1.265 +	err = fs.Connect();
   1.266 +	if(err == KErrNone)
   1.267 +		{
   1.268 +		err = fs.Drive(driveInfo, aDriveNum);
   1.269 +		if (err == KErrNone && driveInfo.iDriveAtt & KDriveAttRemovable)
   1.270 +			{
   1.271 +			aResult = ETrue;
   1.272 +			}
   1.273 +		fs.Close();	
   1.274 +		}
   1.275 +	return err;	
   1.276 +	}
   1.277 +	
   1.278 +/**
   1.279 +Replaces the drive placeholder <drive> with the actual drive
   1.280 +*/
   1.281 +HBufC16* CTestFileUriServer::CheckAndFillDriveNameL(const TPtrC& aFileUri, const TPtrC& aDrive)
   1.282 +	{
   1.283 +	HBufC16* expectedUriWithDrive = aFileUri.AllocL();
   1.284 +	TInt placeHolderPos = aFileUri.Find(KDrivePlaceHolder);	
   1.285 +	if(placeHolderPos >= KErrNone)
   1.286 +		{
   1.287 +		if(aDrive == KExtMedia)
   1.288 +			{// Create a descriptor that is big enough
   1.289 +			// Just in case ReAllocL leaves
   1.290 +			CleanupStack::PushL(expectedUriWithDrive);
   1.291 +			expectedUriWithDrive = expectedUriWithDrive->ReAllocL(aFileUri.Length() + (KExtMedia().Length() - KDrivePlaceHolder().Length()));
   1.292 +			CleanupStack::Pop(); // expectedUriWithDrive
   1.293 +			}
   1.294 +		expectedUriWithDrive->Des().Replace(placeHolderPos, KDrivePlaceHolder().Length(), aDrive);
   1.295 +		}
   1.296 +	return expectedUriWithDrive;
   1.297 +	}
   1.298 +
   1.299 +/**
   1.300 +Private function used to find the remobale drives and populate iRemovableDrives
   1.301 +*/
   1.302 +TInt CTestFileUriServer::PopulateRemovableDrivesBuf(const RFs& aFs)
   1.303 +	{
   1.304 +	TInt err = KErrNone;
   1.305 +	TDriveInfo driveInfo;
   1.306 +	TInt driveNum;
   1.307 +	for (driveNum = EDriveA; driveNum <= EDriveZ; driveNum++)   
   1.308 +		{
   1.309 +		// Populate iRemovableDrives with all removable drives in alphabetical order
   1.310 +		err = aFs.Drive(driveInfo, driveNum);
   1.311 +		if (err == KErrNone && (driveInfo.iDriveAtt & KDriveAttRemovable))       
   1.312 +			{
   1.313 +			iRemovableDrives.Append(TInt16('a' + driveNum));
   1.314 +			}
   1.315 +		}
   1.316 +	return err;
   1.317 +	}
   1.318 +
   1.319 +/**
   1.320 +Searches whether a file with same name and path exists in any other removable drive
   1.321 +*/
   1.322 +TInt CTestFileUriServer::FirstRemovableDriveWithSameFileName(const TDesC& aFileName, TBuf<1>& aCorrectDrive)
   1.323 +	{
   1.324 +	aCorrectDrive = aFileName.Left(1);
   1.325 +	TInt err = KErrNone;
   1.326 +	RFs fs;
   1.327 +	if((err = fs.Connect()) != KErrNone)
   1.328 +		{
   1.329 +		return err;
   1.330 +		}
   1.331 +
   1.332 +	if(iRemovableDrives == KNullDesC)
   1.333 +		{
   1.334 +		if((err = PopulateRemovableDrivesBuf(fs)) != KErrNone)
   1.335 +			{
   1.336 +			return err;
   1.337 +			}
   1.338 +		}
   1.339 +	TInt index;
   1.340 +	HBufC* tempFileName	= NULL;
   1.341 +	if((tempFileName = aFileName.Alloc()) == NULL)
   1.342 +		{
   1.343 +		return KErrGeneral;
   1.344 +		}
   1.345 +	for(index = 0; index < iRemovableDrives.Length(); ++index)
   1.346 +		{
   1.347 +		TUint attValue;
   1.348 +		// change the drive in the filename and check whether such a file exists
   1.349 +		tempFileName->Des()[0] = iRemovableDrives[index];
   1.350 +		err = fs.Att(tempFileName->Des(), attValue);
   1.351 +		if(err == KErrNone)
   1.352 +			{
   1.353 +			aCorrectDrive[0] = iRemovableDrives[index];
   1.354 +			break;
   1.355 +			}
   1.356 +		}
   1.357 +	if(index >= iRemovableDrives.Length())
   1.358 +		{// File not found on any removable drive
   1.359 +		aCorrectDrive = KNullDesC;
   1.360 +		}
   1.361 +	delete tempFileName;
   1.362 +	fs.Close();	
   1.363 +	return KErrNone;
   1.364 +	}
   1.365 +	
   1.366 +/**
   1.367 +Obtains the private directory of the application and appends it along with the
   1.368 +relative filename and drive to create the fully qualified filename
   1.369 +*/
   1.370 +TInt CTestFileUriServer::CreateFullyQualifiedName(const TPtrC& aRelativeName, const TPtrC& aDrive, TFileName& aFullyQualifiedName)
   1.371 +	{
   1.372 +	RFs fs;
   1.373 +	TInt err = fs.Connect();
   1.374 +	if(err != KErrNone)
   1.375 +		{
   1.376 +		return err;
   1.377 +		}
   1.378 +	// Get private dir name
   1.379 +	err = fs.PrivatePath(aFullyQualifiedName);
   1.380 +	fs.Close();
   1.381 +	if(err != KErrNone)
   1.382 +		{
   1.383 +		return err;
   1.384 +		}
   1.385 +	// Construct fully-qualified filename
   1.386 +	aFullyQualifiedName.Insert(0, KDriveSeparator);
   1.387 +	aFullyQualifiedName.Insert(0, aDrive);
   1.388 +	TInt position = 0;
   1.389 +	// If backslash already exists dont include again
   1.390 +	if(aRelativeName.Left(1) == KBackSlash)
   1.391 +		{
   1.392 +		++position;
   1.393 +		}
   1.394 +	aFullyQualifiedName.Append(aRelativeName.Right(aRelativeName.Length() - position));
   1.395 +	return KErrNone;
   1.396 +	}