os/kernelhwsrv/kerneltest/f32test/fileshare/handshare.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1999-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 the License "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 // f32test\loader\handshare.cpp
    15 // 
    16 //
    17 
    18 #include <e32svr.h>
    19 #include <e32test.h>
    20 #include "handshare.h"
    21 
    22 #ifdef __VC32__
    23 #pragma warning(disable:4706)
    24 #endif
    25 
    26 
    27 
    28 GLDEF_D RTest test(_L("HANDSHARE_SVR"));
    29 
    30 #define PANIC()		FHSvrPanic(__LINE__)
    31 #define FHS_ASSERT(c)	((void)((c)||(PANIC(),0)))
    32 
    33 const TTimeIntervalMicroSeconds32 KHalfSecond(500000);
    34 
    35 const TInt KHeapSize=0x2000;
    36 
    37 void FHSvrPanic(TInt aLine)
    38 	{
    39 	User::Panic(_L("FHServer"),aLine);
    40 	}
    41 
    42 LOCAL_D TInt gTestDrive;
    43 
    44 /******************************************************************************
    45  * Class Definitions
    46  ******************************************************************************/
    47 
    48 
    49 class CFHServer : public CServer2
    50 	{
    51 public:
    52 	static CFHServer* NewL();
    53 	void ConstructL();
    54 	virtual ~CFHServer();
    55 	virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
    56 	virtual TInt RunError(TInt aError);
    57 private:
    58 	CFHServer();
    59 	};
    60 
    61 class CFHSession : public CSession2
    62 	{
    63 public:
    64 	virtual ~CFHSession();
    65 	virtual void CreateL();
    66 	virtual void ServiceL(const RMessage2& aMessage);
    67 public:
    68 	
    69 	void GetFileHandle(const RMessage2& aMsg);
    70 	void GetFileHandle2(const RMessage2& aMsg);
    71 	void PassFileHandle(const RMessage2& aMsg);
    72 	void PassFileHandleProcess(const RMessage2& aMsg);
    73 	void PassInvalidFileHandle(const RMessage2& aMsg);
    74 	};
    75 
    76 // a second server so we can test passing file handles from 
    77 // client to server to server2
    78 class CFHServer2 : public CServer2
    79 	{
    80 public:
    81 	static CFHServer2* NewL();
    82 	void ConstructL();
    83 	virtual ~CFHServer2();
    84 	virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
    85 	virtual TInt RunError(TInt aError);
    86 private:
    87 	CFHServer2();
    88 public:
    89 	};
    90 
    91 
    92 class CFHSession2 : public CSession2
    93 	{
    94 public:
    95 	virtual ~CFHSession2();
    96 	virtual void CreateL();
    97 	virtual void ServiceL(const RMessage2& aMessage);
    98 public:
    99 	void PassFileHandle(const RMessage2& aMsg);
   100 	void GetFileHandle(const RMessage2& aMsg);
   101 	};
   102 
   103 
   104 /******************************************************************************
   105  * Class CFHSession/CFHServer
   106  ******************************************************************************/
   107 void ExceptionHandler(TExcType)
   108 	{
   109 	User::Leave(KErrGeneral);
   110 	}
   111 
   112 
   113 
   114 CFHSession::~CFHSession()
   115 	{
   116 	}
   117 
   118 void CFHSession::CreateL()
   119 	{
   120 
   121 	}
   122 
   123 void CFHSession::ServiceL(const RMessage2& aMessage)
   124 	{
   125 	__UHEAP_MARK;
   126 	TInt mid=aMessage.Function();
   127 	switch(mid)
   128 		{
   129 		case RFileHandleSharer::EMsgGetFileHandle:
   130 			GetFileHandle(aMessage);
   131 			break;
   132 
   133 		case RFileHandleSharer::EMsgGetFileHandle2:
   134 			GetFileHandle2(aMessage);
   135 			break;
   136 
   137 		case RFileHandleSharer::EMsgPassFileHandle:
   138 			PassFileHandle(aMessage);
   139 			break;
   140 		
   141 		case RFileHandleSharer::EMsgPassFileHandleProcess:
   142 			PassFileHandleProcess(aMessage);
   143 			break;
   144 
   145 		case RFileHandleSharer::EMsgPassInvalidFileHandle:
   146 			PassInvalidFileHandle(aMessage);
   147 			break;
   148 
   149 		case RFileHandleSharer::EMsgExit:
   150 			{
   151 			// stop server2
   152 			RFileHandleSharer2 handsvr2;
   153 			TInt r=handsvr2.Connect();
   154 			test(r==KErrNone);
   155 			r = handsvr2.Exit();
   156 			test(r==KErrNone || r == KErrServerTerminated);
   157 			handsvr2.Close();
   158 
   159 			aMessage.Complete(KErrNone);	
   160 
   161 			CActiveScheduler::Stop();
   162 			}
   163 			break;
   164 
   165 		case RFileHandleSharer::EMsgSync:
   166 			aMessage.Complete(KErrNone);	
   167 			break;
   168 
   169 		case RFileHandleSharer::EMsgDrive:
   170 			gTestDrive=aMessage.Int0();
   171 			aMessage.Complete(KErrNone);	
   172 			break;
   173 		default:
   174 			break;
   175 		}
   176 	__UHEAP_MARKEND;
   177 	}
   178 
   179 
   180 //
   181 // Returns session and relevant file handle to Client in read mode
   182 // This is to allow the client to test the deprcated function RFile::Adopt()
   183 void CFHSession::GetFileHandle(const RMessage2& aMsg)
   184 	{
   185 	test.Printf(_L("Get file handle"));
   186 
   187 	// get the requested file mode
   188 	TInt fileMode = aMsg.Int1();
   189 
   190 	RFs fs;
   191 	TInt r=fs.Connect();
   192 	r=fs.CreatePrivatePath(gTestDrive);
   193 	test(r==KErrNone);
   194 	r=fs.SetSessionToPrivate(gTestDrive);
   195 	test(r==KErrNone);
   196 	r=fs.ShareProtected();
   197 	test(r==KErrNone);
   198 	RFile file1;
   199 	r=file1.Create(fs,KSvrFileName,EFileWrite);
   200 	test(r==KErrNone || r==KErrAlreadyExists);
   201 	if (r==KErrAlreadyExists)
   202 		{
   203 		r=file1.Open(fs,KSvrFileName, EFileWrite);
   204 		test(r==KErrNone);
   205 		}
   206 	r=file1.Write(KTestData1());
   207 	test(r==KErrNone);
   208 	file1.Close();
   209 
   210 	r=file1.Open(fs,KSvrFileName, fileMode);
   211 	test(r==KErrNone);
   212 
   213 	TInt fssh=file1.SubSessionHandle();
   214 	r=aMsg.Write(0, TPckgC<TInt>(fssh));
   215 	test(r==KErrNone);
   216 	aMsg.Complete(fs);
   217 	fs.Close();
   218 	}
   219 
   220 //
   221 //	Returns a file handle from server2
   222 //
   223 void CFHSession::GetFileHandle2(const RMessage2& aMsg)
   224 	{
   225 	test.Next(_L("RFile::AdoptFromServer()"));
   226 
   227 	// pass the request on to FHServer2 - this will create a file
   228 	// which we can then adopt before returning it to the client
   229 
   230 	// get the requested file mode
   231 	TInt fileMode = aMsg.Int1();
   232 
   233 	RFileHandleSharer2 handsvr2;
   234 	TInt r = handsvr2.Connect();
   235 	test(r==KErrNone);
   236 
   237 	TInt ssh;
   238 	TInt fsh = handsvr2.GetFileHandle(ssh, TFileMode(fileMode));
   239 	test(fsh >= 0);
   240 
   241 	// adopt the file from FHServer2
   242 	RFile file;
   243 	r=file.AdoptFromServer(fsh, ssh);
   244 	test(r==KErrNone);
   245 
   246 	test.Next(_L("RFile::TransferToClient()"));
   247 
   248 	// transfer the file to the client
   249 	r = file.TransferToClient(aMsg, 0);
   250 	test(r==KErrNone);
   251 
   252 	// test we can still use the file
   253 	TInt pos = 0;
   254 	r = file.Seek(ESeekStart, pos);
   255 	test(r==KErrNone);
   256 	TBuf8<100> rbuf;
   257 	r=file.Read(0,rbuf);
   258 	test(r==KErrNone);
   259 	r=rbuf.CompareF(KTestData1());
   260 	test(r==KErrNone);
   261 
   262 	handsvr2.Close();
   263 
   264 	file.Close();
   265 
   266 	RDebug::Print(_L("completed"));	
   267 	}
   268 
   269 void CFHSession::PassFileHandle(const RMessage2& aMsg)
   270 //
   271 // Adopts file from test program and tests what it can and can't do
   272 // Uses new AdoptFromClient() API
   273 //	
   274 	{
   275 	test.Next(_L("RFile::AdoptFromClient()"));
   276 
   277 	// connect to FHServer2
   278 	RFileHandleSharer2 handsvr2;
   279 	TInt r = handsvr2.Connect();
   280 	test(r==KErrNone);
   281 
   282 	RFile file;
   283 
   284 	// Message slot 0 is a RFs handle
   285 	// Message slot 1 is a RFile Subsession handle (RFile::SubSessionHandle())
   286 	r = file.AdoptFromClient(aMsg, 0, 1);
   287 	test(r==KErrNone);
   288 
   289 
   290 
   291 	TBuf8<100> rbuf;
   292 	r=file.Read(0,rbuf);
   293 	test(r==KErrNone);
   294 	r=rbuf.CompareF(KTestData());
   295 	test(r==KErrNone);
   296 	r=file.Write(KTestData1());
   297 	test(r==KErrAccessDenied);
   298 	r=file.ChangeMode(EFileWrite);
   299 	test(r==KErrArgument);
   300 	r=file.Rename(_L("\\newname.txt"));
   301 	test(r==KErrPermissionDenied || r==KErrAccessDenied);
   302 //	should try a delete
   303 
   304 	// pass the file handle to FHServer2
   305 	test.Next(_L("RFile::TransferToServer()"));
   306 
   307 	TIpcArgs ipcArgs;
   308 	file.TransferToServer(ipcArgs, 0, 1);
   309 	r = handsvr2.PassFileHandle(ipcArgs);
   310 	test(r==KErrNone);
   311 
   312 	TInt pos = 0;
   313 	r = file.Seek(ESeekStart, pos);
   314 	test(r==KErrNone);
   315 	r=file.Read(0,rbuf);
   316 	test(r==KErrNone);
   317 	r=rbuf.CompareF(KTestData());
   318 	test(r==KErrNone);
   319 	
   320 	file.Close();
   321 
   322 	handsvr2.Close();
   323 
   324 	aMsg.Complete(KErrNone);
   325 	}
   326 
   327 //
   328 // Adopts file from test program and tests what it can and can't do
   329 // Uses new AdoptFromCreator() API
   330 //	
   331 void CFHSession::PassFileHandleProcess(const RMessage2& aMsg)
   332 	{
   333 	test.Next(_L("RFile::AdoptFromCreator()"));
   334 
   335 	RFile file;
   336 	TInt r = file.AdoptFromCreator(1, 2);
   337 	test(r == KErrNone);
   338 
   339 	TBuf8<100> rbuf;
   340 	r=file.Read(0,rbuf);
   341 	test(r==KErrNone);
   342 	r=rbuf.CompareF(KTestData());
   343 	test(r==KErrNone);
   344 
   345 	test.Next(_L("RFile::Rename()"));
   346 
   347 	// define a filename in our private path
   348 	RFs fs;
   349 	r=fs.Connect();
   350 	test(r==KErrNone);
   351 
   352 	TFileName sessionp;
   353 	fs.SessionPath(sessionp);
   354 	r = fs.MkDirAll(sessionp);
   355 	test(r==KErrNone || r==KErrAlreadyExists);
   356 
   357 	r=fs.ShareProtected();
   358 	test(r==KErrNone);
   359 
   360 	r=fs.CreatePrivatePath(gTestDrive);
   361 	test(r==KErrNone);
   362 	r=fs.SetSessionToPrivate(gTestDrive);
   363 	test(r==KErrNone);
   364 
   365 	TPath newPath;
   366 	fs.PrivatePath(newPath);
   367 	TFileName newFileName;
   368 	newFileName = newPath;
   369 	newFileName.Append(_L("newname.txt"));
   370 	
   371 	// delete the file before we try to rename anything to it
   372 	r = fs.Delete(newFileName);
   373 	test(r == KErrNone || r == KErrNotFound);
   374 
   375 	r=file.Rename(newFileName);
   376 	test(r==KErrNone);
   377 
   378 	file.Close();
   379 
   380 	// Next verify that we can delete the file (which should now 
   381 	// have been moved to our private directory)
   382 	test.Next(_L("RFs::Delete()"));
   383 	r = fs.Delete(newFileName);
   384 	test(r == KErrNone);
   385 
   386 	fs.Close();
   387 
   388 	
   389 	aMsg.Complete(KErrNone);
   390 	}
   391 
   392 void CFHSession::PassInvalidFileHandle(const RMessage2& aMsg)
   393 //
   394 // Attempts to adopt an invalid file handle from test program 
   395 // and tests that KErrBadHandle is returned by AdoptFromClient()
   396 //	
   397 	{
   398 	test.Next(_L("PassInvalidFileHandle - RFile::AdoptFromClient()"));
   399 
   400 	RFile file;
   401 
   402 	// Message slot 0 is a RFs handle
   403 	// Message slot 1 is a RFile Subsession handle (RFile::SubSessionHandle())
   404 	TInt r = file.AdoptFromClient(aMsg, 0, 1);
   405 	test(r==KErrBadHandle);
   406 
   407 
   408 	aMsg.Complete(r);
   409 	}
   410 
   411 CFHServer* CFHServer::NewL()
   412 	{
   413 	CFHServer* server = new (ELeave) CFHServer;
   414 	CleanupStack::PushL(server);
   415 	server->ConstructL();
   416 	CleanupStack::Pop(server);
   417 	return server;
   418 	}
   419 
   420 void CFHServer::ConstructL()
   421 	{
   422 	}
   423 
   424 CFHServer::CFHServer()
   425 	: CServer2(0,ESharableSessions)
   426 	{
   427 	}
   428 
   429 CFHServer::~CFHServer()
   430 	{
   431 	}
   432 
   433 CSession2* CFHServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
   434 //
   435 //	 Create New Session
   436 //
   437 	{
   438 	(void)aVersion;
   439 	CFHSession* s = new (ELeave) CFHSession;
   440 	return s;
   441 	}
   442 
   443 _LIT(KErr,"FHSERVER_ERR");
   444 CFHServer2* CFHServer2::NewL()
   445 	{
   446 	CFHServer2* server = new (ELeave) CFHServer2;
   447 	CleanupStack::PushL(server);
   448 	server->ConstructL();
   449 	CleanupStack::Pop(server);
   450 	return server;
   451 	}
   452 
   453 void CFHServer2::ConstructL()
   454 	{
   455 	}
   456 
   457 TInt CFHServer::RunError(TInt aError)
   458 	{
   459 	User::Panic(KErr,aError);
   460 	return 0;
   461 	}
   462 
   463 // File handle server #2
   464 CFHServer2::CFHServer2()
   465 	: CServer2(0,ESharableSessions)
   466 	{
   467 	}
   468 
   469 CFHServer2::~CFHServer2()
   470 	{
   471 	}
   472 
   473 CSession2* CFHServer2::NewSessionL(const TVersion& aVersion, const RMessage2&) const
   474 //
   475 //	 Create New Session
   476 //
   477 	{
   478 	(void)aVersion;
   479 	CFHSession2* s = new (ELeave) CFHSession2;
   480 	return s;
   481 	}
   482 
   483 _LIT(KErr2,"FHSERVER2_ERR");
   484 TInt CFHServer2::RunError(TInt aError)
   485 	{
   486 	User::Panic(KErr2,aError);
   487 	return 0;
   488 	}
   489 
   490 CFHSession2::~CFHSession2()
   491 	{
   492 	}
   493 
   494 void CFHSession2::CreateL()
   495 	{
   496 
   497 	}
   498 
   499 void CFHSession2::ServiceL(const RMessage2& aMessage)
   500 	{
   501 	__UHEAP_MARK;
   502 	TInt mid=aMessage.Function();
   503 	switch(mid)
   504 		{
   505 		case RFileHandleSharer::EMsgPassFileHandle:
   506 			PassFileHandle(aMessage);
   507 			break;
   508 
   509 		case RFileHandleSharer::EMsgGetFileHandle:
   510 			GetFileHandle(aMessage);
   511 			break;
   512 
   513 		case RFileHandleSharer::EMsgExit:
   514 			aMessage.Complete(KErrNone);	
   515 			CActiveScheduler::Stop();
   516 			break;
   517 
   518 		default:
   519 			break;
   520 		}
   521 	__UHEAP_MARKEND;
   522 	}
   523 
   524 
   525 //
   526 // Adopts file from server 1
   527 //	
   528 void CFHSession2::PassFileHandle(const RMessage2& aMsg)
   529 	{
   530 	RFile file;
   531 
   532 	// Message slot 0 is a RFs handle
   533 	// Message slot 1 is a RFile Subsession handle (RFile::SubSessionHandle())
   534 	TInt r = file.AdoptFromClient(aMsg, 0, 1);
   535 	if (r != KErrNone)
   536 		{
   537 		aMsg.Complete(r);
   538 		return;
   539 		}
   540 
   541 
   542 	TBuf8<100> rbuf;
   543 	
   544 	if (r == KErrNone)
   545 		r=file.Read(0,rbuf);
   546 
   547 	if (r == KErrNone)
   548 		r = rbuf.CompareF(KTestData());
   549 
   550 	if (r == KErrNone)
   551 		{
   552 		r = file.Write(KTestData1());
   553 		if (r == KErrAccessDenied)
   554 			r = KErrNone;
   555 		}
   556 
   557 	if (r == KErrNone)
   558 		{
   559 		r = file.ChangeMode(EFileWrite);
   560 		if (r == KErrArgument)
   561 			r = KErrNone;
   562 		}
   563 
   564 	if (r == KErrNone)
   565 		{
   566 		r = file.Rename(_L("\\newname.txt"));
   567 		if (r == KErrPermissionDenied || r == KErrAccessDenied)
   568 			r = KErrNone;
   569 		}
   570 
   571 	file.Close();
   572 
   573 	aMsg.Complete(r);
   574 	}
   575 
   576 
   577 void CFHSession2::GetFileHandle(const RMessage2& aMsg)
   578 //
   579 //	Returns a file handle in write mode
   580 //
   581 	{
   582 	RFs fs;
   583 	TInt r = fs.Connect();
   584 
   585 	if (r == KErrNone)
   586 		r = fs.CreatePrivatePath(gTestDrive);
   587 
   588 	if (r == KErrNone)
   589 		r = fs.SetSessionToPrivate(gTestDrive);
   590 
   591 	if (r == KErrNone)
   592 		r = fs.ShareProtected();
   593 
   594 	// make sure file exists & has valid data in it
   595 	RFile file1;
   596 	if (r == KErrNone)
   597 		r = file1.Replace(fs,KSvrFileName,EFileWrite);
   598 
   599 	if (r == KErrNone)
   600 		r = file1.Write(KTestData1());
   601 		
   602 	file1.Close();
   603 
   604 
   605 	// re-open the file with the mode the client has requested & pass it to the client
   606 	TFileMode fileMode = TFileMode(aMsg.Int1());
   607 	if (r == KErrNone)
   608 		r = file1.Open(fs,KSvrFileName, fileMode);
   609 	if (r == KErrNone)
   610 		r = file1.TransferToClient(aMsg, 0);
   611 	file1.Close();
   612 	
   613 	fs.Close();
   614 
   615 	if (r != KErrNone)
   616 		aMsg.Complete(r);
   617 	}
   618 
   619 LOCAL_C TInt FHServer2(TAny * /*anArg*/)
   620 	{	
   621 	RTest test(_L("FHServer2"));
   622 
   623 	// Remember the number of open handles. Just for a sanity check ....
   624 	TInt start_thc, start_phc;
   625 	RThread().HandleCount(start_phc, start_thc);
   626 
   627 
   628 	CTrapCleanup* cleanup;
   629 	cleanup=CTrapCleanup::New();
   630 
   631 	CActiveScheduler* sched=new CActiveScheduler;
   632 	FHS_ASSERT(sched);
   633 	CActiveScheduler::Install(sched);
   634 
   635 	CFHServer2* svr2 = NULL;
   636 	TRAP_IGNORE(svr2 = CFHServer2::NewL());
   637 	FHS_ASSERT(svr2);
   638 	FHS_ASSERT(svr2->Start(_L("FHServer2"))==KErrNone);
   639 
   640 	CActiveScheduler::Start();
   641 	
   642 	delete svr2;
   643 	delete sched;
   644 
   645 	delete cleanup;
   646 
   647 	// Sanity check for open handles
   648 	TInt end_thc, end_phc;
   649 	RThread().HandleCount(end_phc, end_thc);
   650 	test(start_thc == end_thc);
   651 	test(start_phc == end_phc);
   652 	// and also for pending requests ...
   653 	test(RThread().RequestCount() == 0);
   654 
   655 	
   656 	return KErrNone;
   657 	}
   658 
   659 
   660 
   661 GLDEF_C TInt E32Main()
   662 //
   663 // Test Server for file handle sharing
   664 //
   665 	{
   666 	test.Title();
   667 	test.Start(_L("Starting FHServer..."));
   668 
   669 	// Remember the number of open handles. Just for a sanity check ....
   670 	TInt start_thc, start_phc;
   671 	RThread().HandleCount(start_phc, start_thc);
   672 
   673 	CTrapCleanup* cleanup=CTrapCleanup::New();
   674 
   675 	FHS_ASSERT(cleanup);
   676 	CActiveScheduler* sched=new CActiveScheduler;
   677 	FHS_ASSERT(sched);
   678 	CActiveScheduler::Install(sched);
   679 
   680 	// start server1
   681 	CFHServer* svr = NULL;
   682 	TRAP_IGNORE(svr = CFHServer::NewL());
   683 	FHS_ASSERT(svr);
   684 	FHS_ASSERT(svr->Start(_L("FHServer"))==KErrNone);
   685 
   686 	test.Title();
   687 	test.Start(_L("Starting tests..."));
   688 
   689 	// start server2 in a seperate thread
   690 	RThread server2Thread;
   691 	TInt r = server2Thread.Create(_L("FHServer2"), FHServer2, KDefaultStackSize, KHeapSize, KHeapSize, NULL);	
   692 	test(r==KErrNone);	
   693 	TRequestStatus statq;
   694 	server2Thread.Logon(statq);
   695 	server2Thread.Resume();
   696 
   697 	CActiveScheduler::Start();
   698 
   699 
   700 	// wait for server2's thread to end gracefully
   701 	User::WaitForRequest(statq);
   702 
   703 
   704 	server2Thread.Close();
   705 
   706 	RFs cleanupfs;
   707 	r = cleanupfs.Connect();
   708 	test(r==KErrNone);
   709 	r=cleanupfs.SetSessionToPrivate(gTestDrive);
   710 	test(r==KErrNone);
   711 	r=cleanupfs.Delete(KSvrFileName);
   712 	test(r==KErrNone || r==KErrNotFound);
   713 	cleanupfs.Close();
   714 
   715 
   716 	test.End();
   717 
   718 	delete svr;
   719 	delete sched;
   720 	delete cleanup;
   721 
   722 	// Sanity check for open handles and pending requests
   723 	TInt end_thc, end_phc;
   724 	RThread().HandleCount(end_phc, end_thc);
   725 	test(start_thc == end_thc);
   726 	test(start_phc == end_phc);
   727 	test(RThread().RequestCount() == 0);
   728 	
   729 	return 0;
   730 	}