|         |      1 /* | 
|         |      2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).  | 
|         |      3 * All rights reserved. | 
|         |      4 * This component and the accompanying materials are made available | 
|         |      5 * under the terms of "Eclipse Public License v1.0" | 
|         |      6 * which accompanies this distribution, and is available | 
|         |      7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". | 
|         |      8 * | 
|         |      9 * Initial Contributors: | 
|         |     10 * Nokia Corporation - initial contribution. | 
|         |     11 * | 
|         |     12 * Contributors: | 
|         |     13 * | 
|         |     14 * Description:   | 
|         |     15 * | 
|         |     16 */ | 
|         |     17  | 
|         |     18  | 
|         |     19 #include "FBFileOpServer.h" | 
|         |     20 #include "FBDrivePartitioner.h" | 
|         |     21  | 
|         |     22 #include <e32svr.h> | 
|         |     23 #include <bautils.h> | 
|         |     24  | 
|         |     25 // -------------------------------------------------------------------------------------------- | 
|         |     26  | 
|         |     27 //*********************************** | 
|         |     28 //CFBFileOpServer - implementations | 
|         |     29 //*********************************** | 
|         |     30  | 
|         |     31 CServer2* CFBFileOpServer::NewLC() | 
|         |     32 	{ | 
|         |     33 	CFBFileOpServer* self = new(ELeave) CFBFileOpServer; | 
|         |     34 	CleanupStack::PushL(self); | 
|         |     35 	self->ConstructL(); | 
|         |     36 	return self; | 
|         |     37 	} | 
|         |     38  | 
|         |     39 // -------------------------------------------------------------------------------------------- | 
|         |     40  | 
|         |     41 // | 
|         |     42 // 2nd phase construction - ensure the timer and server objects are running | 
|         |     43 // | 
|         |     44 void CFBFileOpServer::ConstructL() | 
|         |     45 	{ | 
|         |     46 	StartL(KMyServerName); | 
|         |     47 	iShutdown.ConstructL(); | 
|         |     48 	// ensure that the server still exits even if the 1st client fails to connect | 
|         |     49 	iShutdown.Start(); | 
|         |     50 	} | 
|         |     51  | 
|         |     52 // -------------------------------------------------------------------------------------------- | 
|         |     53  | 
|         |     54 // | 
|         |     55 // Cretae a new client session. This should really check the version number. | 
|         |     56 // | 
|         |     57 CSession2* CFBFileOpServer::NewSessionL(const TVersion&,const RMessage2&) const | 
|         |     58 	{ | 
|         |     59 	return new(ELeave) CFBFileOpServerSession(); | 
|         |     60 	} | 
|         |     61  | 
|         |     62 // -------------------------------------------------------------------------------------------- | 
|         |     63  | 
|         |     64 // | 
|         |     65 // A new session is being created | 
|         |     66 // Cancel the shutdown timer if it was running | 
|         |     67 // | 
|         |     68 void CFBFileOpServer::AddSession() | 
|         |     69 	{ | 
|         |     70 	++iSessionCount; | 
|         |     71 	iShutdown.Cancel(); | 
|         |     72 	} | 
|         |     73  | 
|         |     74 // -------------------------------------------------------------------------------------------- | 
|         |     75  | 
|         |     76 // | 
|         |     77 // A session is being destroyed | 
|         |     78 // Start the shutdown timer if it is the last session. | 
|         |     79 // | 
|         |     80 void CFBFileOpServer::DropSession() | 
|         |     81 	{ | 
|         |     82 	if (--iSessionCount==0) | 
|         |     83 		iShutdown.Start(); | 
|         |     84 	} | 
|         |     85  | 
|         |     86 // -------------------------------------------------------------------------------------------- | 
|         |     87      | 
|         |     88 CRequestObserver::CRequestObserver( TInt aPriority ) : CActive( aPriority ) | 
|         |     89     { | 
|         |     90     CActiveScheduler::Add( this ); | 
|         |     91     }    | 
|         |     92  | 
|         |     93 CRequestObserver::~CRequestObserver() | 
|         |     94     { | 
|         |     95     Cancel(); | 
|         |     96     } | 
|         |     97      | 
|         |     98 void CRequestObserver::StartWaiting( const RMessage2& aMsg ) | 
|         |     99     { | 
|         |    100     iMsg = aMsg; | 
|         |    101     SetActive(); | 
|         |    102     } | 
|         |    103      | 
|         |    104 void CRequestObserver::RunL() | 
|         |    105     { | 
|         |    106     iMsg.Complete( iStatus.Int() ); | 
|         |    107     } | 
|         |    108      | 
|         |    109 void CRequestObserver::DoCancel() | 
|         |    110     { | 
|         |    111     iMsg.Complete( KErrCancel ); | 
|         |    112     } | 
|         |    113  | 
|         |    114 // -------------------------------------------------------------------------------------------- | 
|         |    115  | 
|         |    116 //*********************************** | 
|         |    117 //CFBFileOpServerSession - implementations | 
|         |    118 //*********************************** | 
|         |    119  | 
|         |    120 // | 
|         |    121 // 2nd phase construct for sessions - called by the CServer framework | 
|         |    122 // | 
|         |    123 void CFBFileOpServerSession::CreateL() | 
|         |    124 	{ | 
|         |    125 	User::LeaveIfError(iFs.Connect()); | 
|         |    126 	iFileMan = CFileMan::NewL( iFs, this ); | 
|         |    127 	iReqObserver = new (ELeave) CRequestObserver( CActive::EPriorityStandard ); | 
|         |    128 	Server().AddSession(); | 
|         |    129 	} | 
|         |    130  | 
|         |    131 // -------------------------------------------------------------------------------------------- | 
|         |    132  | 
|         |    133 CFBFileOpServerSession::~CFBFileOpServerSession() | 
|         |    134 	{ | 
|         |    135 	if (iFileMan) | 
|         |    136 		{ | 
|         |    137 		delete iFileMan; | 
|         |    138 		iFileMan = NULL; | 
|         |    139 		} | 
|         |    140 	iFs.Close(); | 
|         |    141 	delete iReqObserver; | 
|         |    142 	Server().DropSession(); | 
|         |    143 	} | 
|         |    144  | 
|         |    145 // -------------------------------------------------------------------------------------------- | 
|         |    146 	 | 
|         |    147 /** | 
|         |    148 Services a client request. | 
|         |    149 */ | 
|         |    150 void CFBFileOpServerSession::ServiceL(const RMessage2& aMessage) | 
|         |    151 	{ | 
|         |    152 	TBool completeImmediately( ETrue ); | 
|         |    153 	TRAPD( err,DispatchMessageL( aMessage, completeImmediately ) ); | 
|         |    154 	if ( completeImmediately ) aMessage.Complete( err ); | 
|         |    155 	} | 
|         |    156  | 
|         |    157 // -------------------------------------------------------------------------------------------- | 
|         |    158  | 
|         |    159 /** | 
|         |    160 Called by ServiceL() | 
|         |    161  | 
|         |    162 It tests the function code and then delegates to | 
|         |    163 the appropriate function. | 
|         |    164 */ | 
|         |    165 void CFBFileOpServerSession::DispatchMessageL(const RMessage2& aMessage, TBool& aComplete) | 
|         |    166 	{ | 
|         |    167 	switch (aMessage.Function()) | 
|         |    168         { | 
|         |    169         case EFileOpCopy: | 
|         |    170             CopyL(aMessage); | 
|         |    171             aComplete = EFalse; | 
|         |    172             return; | 
|         |    173  | 
|         |    174         case EFileOpRename: | 
|         |    175             RenameL(aMessage); | 
|         |    176             return;             | 
|         |    177  | 
|         |    178         case EFileOpAttribs: | 
|         |    179             AttribsL(aMessage); | 
|         |    180             return;  | 
|         |    181  | 
|         |    182         case EFileOpRmDir: | 
|         |    183             RmDirL(aMessage, aComplete); | 
|         |    184             return;  | 
|         |    185  | 
|         |    186         case EFileOpDelete: | 
|         |    187             DeleteL(aMessage); | 
|         |    188             aComplete = EFalse; | 
|         |    189             return;  | 
|         |    190  | 
|         |    191         case EFileOpMkDirAll: | 
|         |    192             MkDirAllL(aMessage); | 
|         |    193             return;              | 
|         |    194  | 
|         |    195         case EFileOpCreateEmptyFile: | 
|         |    196             CreateEmptyFileL(aMessage); | 
|         |    197             return;             | 
|         |    198  | 
|         |    199         case EFileOpEraseMBR: | 
|         |    200             EraseMBRL(aMessage); | 
|         |    201             return; | 
|         |    202              | 
|         |    203         case EFileOpPartitionDrive: | 
|         |    204             PartitionDriveL(aMessage); | 
|         |    205             return; | 
|         |    206              | 
|         |    207         case EFileOpCancel:  | 
|         |    208             CancelOp(); | 
|         |    209             return;  | 
|         |    210              | 
|         |    211         default: | 
|         |    212             PanicClient(aMessage, EPanicIllegalFunction); | 
|         |    213             return; | 
|         |    214         } | 
|         |    215 	} | 
|         |    216  | 
|         |    217 // -------------------------------------------------------------------------------------------- | 
|         |    218  | 
|         |    219 void CFBFileOpServerSession::CopyL( const RMessage2& aMessage ) | 
|         |    220     { | 
|         |    221     __ASSERT_ALWAYS( iReqObserver && !iReqObserver->IsActive(), User::Leave( KErrServerBusy ) ); | 
|         |    222     TPckgBuf<TFileOpArgs> pckgBuf; | 
|         |    223     aMessage.ReadL( 0, pckgBuf, 0 ); | 
|         |    224     TFileOpArgs argsStruct = pckgBuf(); | 
|         |    225  | 
|         |    226     TInt err = iFileMan->Copy( argsStruct.iBuf1, argsStruct.iBuf2, argsStruct.iUint1, iReqObserver->iStatus ); | 
|         |    227     User::LeaveIfError( err ); | 
|         |    228     iFileManObserverResult = MFileManObserver::EContinue; | 
|         |    229     iReqObserver->StartWaiting( aMessage ); // start asynchronous waiting | 
|         |    230     } | 
|         |    231  | 
|         |    232 // -------------------------------------------------------------------------------------------- | 
|         |    233  | 
|         |    234 void CFBFileOpServerSession::RenameL(const RMessage2& aMessage) | 
|         |    235     { | 
|         |    236     TPckgBuf<TFileOpArgs> pckgBuf; | 
|         |    237     aMessage.ReadL(0, pckgBuf, 0); | 
|         |    238     TFileOpArgs argsStruct = pckgBuf(); | 
|         |    239      | 
|         |    240     iFileManObserverResult = MFileManObserver::EContinue; | 
|         |    241     User::LeaveIfError(iFileMan->Rename(argsStruct.iBuf1, argsStruct.iBuf2, argsStruct.iUint1)); | 
|         |    242     } | 
|         |    243  | 
|         |    244 // -------------------------------------------------------------------------------------------- | 
|         |    245  | 
|         |    246 void CFBFileOpServerSession::AttribsL(const RMessage2& aMessage) | 
|         |    247     { | 
|         |    248     TPckgBuf<TFileOpArgs> pckgBuf; | 
|         |    249     aMessage.ReadL(0, pckgBuf, 0); | 
|         |    250     TFileOpArgs argsStruct = pckgBuf(); | 
|         |    251      | 
|         |    252     iFileManObserverResult = MFileManObserver::EContinue; | 
|         |    253     User::LeaveIfError(iFileMan->Attribs(argsStruct.iBuf1, argsStruct.iUint1, argsStruct.iUint2, argsStruct.iTime1, argsStruct.iUint3)); | 
|         |    254     } | 
|         |    255  | 
|         |    256 // -------------------------------------------------------------------------------------------- | 
|         |    257  | 
|         |    258 void CFBFileOpServerSession::RmDirL( const RMessage2& aMessage, TBool& aComplete ) | 
|         |    259     { | 
|         |    260     TPckgBuf<TFileOpArgs> pckgBuf; | 
|         |    261     aMessage.ReadL( 0, pckgBuf, 0 ); | 
|         |    262     TFileOpArgs argsStruct = pckgBuf(); | 
|         |    263      | 
|         |    264     if ( argsStruct.iUint1 & CFileMan::ERecurse ) | 
|         |    265         { | 
|         |    266         __ASSERT_ALWAYS( iReqObserver && !iReqObserver->IsActive(), User::Leave( KErrServerBusy ) ); | 
|         |    267         User::LeaveIfError( iFileMan->RmDir( argsStruct.iBuf1, iReqObserver->iStatus ) ); | 
|         |    268         iFileManObserverResult = MFileManObserver::EContinue; | 
|         |    269         aComplete = EFalse; | 
|         |    270         iReqObserver->StartWaiting( aMessage ); // start asynchronous waiting | 
|         |    271         } | 
|         |    272     else | 
|         |    273         { | 
|         |    274         iFileManObserverResult = MFileManObserver::EContinue; | 
|         |    275         User::LeaveIfError( iFs.RmDir( argsStruct.iBuf1 ) ); | 
|         |    276         } | 
|         |    277     } | 
|         |    278  | 
|         |    279 // -------------------------------------------------------------------------------------------- | 
|         |    280  | 
|         |    281 void CFBFileOpServerSession::DeleteL( const RMessage2& aMessage ) | 
|         |    282     { | 
|         |    283     __ASSERT_ALWAYS( iReqObserver && !iReqObserver->IsActive(), User::Leave( KErrServerBusy ) ); | 
|         |    284     TPckgBuf<TFileOpArgs> pckgBuf; | 
|         |    285     aMessage.ReadL( 0, pckgBuf, 0 ); | 
|         |    286     TFileOpArgs argsStruct = pckgBuf(); | 
|         |    287      | 
|         |    288     User::LeaveIfError( iFileMan->Delete(argsStruct.iBuf1, argsStruct.iUint1, iReqObserver->iStatus ) );  | 
|         |    289     iFileManObserverResult = MFileManObserver::EContinue; | 
|         |    290     iReqObserver->StartWaiting( aMessage ); // start asynchronous waiting | 
|         |    291     } | 
|         |    292  | 
|         |    293 // -------------------------------------------------------------------------------------------- | 
|         |    294  | 
|         |    295 void CFBFileOpServerSession::MkDirAllL(const RMessage2& aMessage) | 
|         |    296     { | 
|         |    297     TPckgBuf<TFileOpArgs> pckgBuf; | 
|         |    298     aMessage.ReadL(0, pckgBuf, 0); | 
|         |    299     TFileOpArgs argsStruct = pckgBuf(); | 
|         |    300      | 
|         |    301     User::LeaveIfError(iFs.MkDirAll(argsStruct.iBuf1)); | 
|         |    302     } | 
|         |    303  | 
|         |    304 // -------------------------------------------------------------------------------------------- | 
|         |    305  | 
|         |    306 void CFBFileOpServerSession::CreateEmptyFileL(const RMessage2& aMessage) | 
|         |    307     { | 
|         |    308     TPckgBuf<TFileOpArgs> pckgBuf; | 
|         |    309     aMessage.ReadL(0, pckgBuf, 0); | 
|         |    310     TFileOpArgs argsStruct = pckgBuf(); | 
|         |    311      | 
|         |    312     TInt err(KErrNone); | 
|         |    313     RFile newFile; | 
|         |    314     err = newFile.Create(iFs, argsStruct.iBuf1, EFileShareExclusive); | 
|         |    315     if (err == KErrNone) | 
|         |    316         err = newFile.Flush();  | 
|         |    317     newFile.Close();  | 
|         |    318      | 
|         |    319     User::LeaveIfError(err); | 
|         |    320     } | 
|         |    321  | 
|         |    322 // -------------------------------------------------------------------------------------------- | 
|         |    323  | 
|         |    324 void CFBFileOpServerSession::EraseMBRL(const RMessage2& aMessage) | 
|         |    325     { | 
|         |    326     TPckgBuf<TFileOpArgs> pckgBuf; | 
|         |    327     aMessage.ReadL(0, pckgBuf, 0); | 
|         |    328     TFileOpArgs argsStruct = pckgBuf(); | 
|         |    329  | 
|         |    330 	RFs fs; | 
|         |    331 	CleanupClosePushL(fs); | 
|         |    332 	User::LeaveIfError(fs.Connect()); | 
|         |    333  | 
|         |    334     User::LeaveIfError(FBDrivePartioner::EraseMBR(fs, argsStruct.iUint1)); | 
|         |    335  | 
|         |    336     CleanupStack::PopAndDestroy(); //fs | 
|         |    337     } | 
|         |    338      | 
|         |    339 // -------------------------------------------------------------------------------------------- | 
|         |    340  | 
|         |    341 void CFBFileOpServerSession::PartitionDriveL(const RMessage2& aMessage) | 
|         |    342     { | 
|         |    343     TPckgBuf<TFileOpArgs> pckgBuf; | 
|         |    344     aMessage.ReadL(0, pckgBuf, 0); | 
|         |    345     TFileOpArgs argsStruct = pckgBuf(); | 
|         |    346  | 
|         |    347 	RFs fs; | 
|         |    348 	CleanupClosePushL(fs); | 
|         |    349 	User::LeaveIfError(fs.Connect()); | 
|         |    350  | 
|         |    351     FBDrivePartioner::CreatePartitions(fs, argsStruct.iUint1, argsStruct.iUint2); | 
|         |    352     User::LeaveIfError(FBDrivePartioner::FormatPartitions(fs, argsStruct.iUint1, argsStruct.iUint2)); | 
|         |    353  | 
|         |    354     CleanupStack::PopAndDestroy(); //fs | 
|         |    355     } | 
|         |    356                 | 
|         |    357 // -------------------------------------------------------------------------------------------- | 
|         |    358  | 
|         |    359 // | 
|         |    360 // Panics the client | 
|         |    361 // | 
|         |    362 void CFBFileOpServerSession::PanicClient(const RMessage2& aMessage, TInt aPanic) const | 
|         |    363 	{ | 
|         |    364 	_LIT(KTxtServer,"FBFileOpServer"); | 
|         |    365 	aMessage.Panic(KTxtServer, aPanic); | 
|         |    366 	} | 
|         |    367  | 
|         |    368 // -------------------------------------------------------------------------------------------- | 
|         |    369  | 
|         |    370 // | 
|         |    371 // Handle an error from CFBFileOpServerSession::ServiceL() | 
|         |    372 // A bad descriptor error implies a badly programmed client, so panic it; | 
|         |    373 // otherwise use the default handling (report the error to the client) | 
|         |    374 // | 
|         |    375 void CFBFileOpServerSession::ServiceError(const RMessage2& aMessage, TInt aError) | 
|         |    376 	{ | 
|         |    377 	if (aError==KErrBadDescriptor) | 
|         |    378 		PanicClient(aMessage,EPanicBadDescriptor); | 
|         |    379 	CSession2::ServiceError(aMessage,aError); | 
|         |    380 	} | 
|         |    381  | 
|         |    382 // -------------------------------------------------------------------------------------------- | 
|         |    383  | 
|         |    384 MFileManObserver::TControl CFBFileOpServerSession::NotifyFileManStarted() | 
|         |    385     { | 
|         |    386     return iFileManObserverResult; | 
|         |    387     } | 
|         |    388  | 
|         |    389 // -------------------------------------------------------------------------------------------- | 
|         |    390  | 
|         |    391 MFileManObserver::TControl CFBFileOpServerSession::NotifyFileManOperation() | 
|         |    392     { | 
|         |    393     return iFileManObserverResult; | 
|         |    394     } | 
|         |    395 // -------------------------------------------------------------------------------------------- | 
|         |    396  | 
|         |    397 MFileManObserver::TControl CFBFileOpServerSession::NotifyFileManEnded() | 
|         |    398     { | 
|         |    399     return iFileManObserverResult; | 
|         |    400     } | 
|         |    401  | 
|         |    402 // -------------------------------------------------------------------------------------------- | 
|         |    403  | 
|         |    404 void CFBFileOpServerSession::CancelOp() | 
|         |    405     { | 
|         |    406     iFileManObserverResult = MFileManObserver::ECancel; | 
|         |    407     iReqObserver->Cancel(); | 
|         |    408     } | 
|         |    409  | 
|         |    410 // -------------------------------------------------------------------------------------------- | 
|         |    411  | 
|         |    412 //********************************** | 
|         |    413 //Global functions | 
|         |    414 //********************************** | 
|         |    415  | 
|         |    416 // | 
|         |    417 // Initiate server exit when the timer expires | 
|         |    418 // | 
|         |    419 void CShutdown::RunL() | 
|         |    420 	{ | 
|         |    421 	CActiveScheduler::Stop(); | 
|         |    422 	} | 
|         |    423  | 
|         |    424 // -------------------------------------------------------------------------------------------- | 
|         |    425  | 
|         |    426 // | 
|         |    427 // Perform all server initialisation, in particular creation of the | 
|         |    428 // scheduler and server and then run the scheduler | 
|         |    429 // | 
|         |    430 static void RunServerL() | 
|         |    431 	{ | 
|         |    432 	// naming the server thread after the server helps to debug panics | 
|         |    433 	User::LeaveIfError(RThread::RenameMe(KMyServerName)); | 
|         |    434 	// | 
|         |    435 	// create and install the active scheduler we need | 
|         |    436 	CActiveScheduler* s=new(ELeave) CActiveScheduler; | 
|         |    437 	CleanupStack::PushL(s); | 
|         |    438 	CActiveScheduler::Install(s); | 
|         |    439 	// | 
|         |    440 	// create the server (leave it on the cleanup stack) | 
|         |    441 	CFBFileOpServer::NewLC(); | 
|         |    442 	// | 
|         |    443 	// Initialisation complete, now signal the client | 
|         |    444 	RProcess::Rendezvous(KErrNone); | 
|         |    445 	// | 
|         |    446 	// Ready to run | 
|         |    447 	CActiveScheduler::Start(); | 
|         |    448 	// | 
|         |    449 	// Cleanup the server and scheduler | 
|         |    450 	CleanupStack::PopAndDestroy(2); | 
|         |    451 	} | 
|         |    452  | 
|         |    453 // -------------------------------------------------------------------------------------------- | 
|         |    454  | 
|         |    455 // | 
|         |    456 // Server process entry-point | 
|         |    457 // | 
|         |    458 TInt E32Main() | 
|         |    459 	{ | 
|         |    460 	__UHEAP_MARK; | 
|         |    461 	// | 
|         |    462 	CTrapCleanup* cleanup=CTrapCleanup::New(); | 
|         |    463 	TInt r=KErrNoMemory; | 
|         |    464 	if (cleanup) | 
|         |    465 		{ | 
|         |    466 		TRAP(r,RunServerL()); | 
|         |    467 		delete cleanup; | 
|         |    468 		} | 
|         |    469 	// | 
|         |    470 	__UHEAP_MARKEND; | 
|         |    471 	return r; | 
|         |    472 	} | 
|         |    473  | 
|         |    474 // -------------------------------------------------------------------------------------------- |