omadrm/drmengine/roapstorage/src/RoapStorageServer.cpp
changeset 23 493788a4a8a4
parent 0 95b198f216e5
equal deleted inserted replaced
5:79d62d1d7957 23:493788a4a8a4
     9 * Initial Contributors:
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    10 * Nokia Corporation - initial contribution.
    11 *
    11 *
    12 * Contributors:
    12 * Contributors:
    13 *
    13 *
    14 * Description:  
    14 * Description:
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 
    18 
    19 
    19 
    20 // INCLUDE FILES
    20 // INCLUDE FILES
    21 #include <e32std.h>
    21 #include <e32std.h>
    22 
    22 
    23 #ifdef RD_MULTIPLE_DRIVE
    23 #ifdef RD_MULTIPLE_DRIVE
    24 #include <DriveInfo.h>
    24 #include <driveinfo.h>
    25 #endif
    25 #endif
    26 
    26 
    27 #include "RoapStorageServer.h"
    27 #include "RoapStorageServer.h"
    28 #include "DRMContextDB.h"
    28 #include "DRMContextDB.h"
    29 #include "RoapLog.h"
    29 #include "RoapLog.h"
    30 #include "drmroapclientserver.h"
    30 #include "drmroapclientserver.h"
    31 #include "drmcommonclientserver.h"
    31 #include "drmcommonclientserver.h"
    32 #include "drmkeystorage.h"
    32 #include "DrmKeyStorage.h"
    33 
    33 
    34 // EXTERNAL DATA STRUCTURES
    34 // EXTERNAL DATA STRUCTURES
    35 // EXTERNAL FUNCTION PROTOTYPES  
    35 // EXTERNAL FUNCTION PROTOTYPES
    36 // CONSTANTS
    36 // CONSTANTS
    37 // MACROS
    37 // MACROS
    38 
    38 
    39 
    39 
    40 // LOCAL CONSTANTS AND MACROS
    40 // LOCAL CONSTANTS AND MACROS
    75 // -----------------------------------------------------------------------------
    75 // -----------------------------------------------------------------------------
    76 // Function StartRoapServer().
    76 // Function StartRoapServer().
    77 // This function starts the actual server under TRAP harness and starts
    77 // This function starts the actual server under TRAP harness and starts
    78 // waiting for connections. This function returns only if there has been
    78 // waiting for connections. This function returns only if there has been
    79 // errors during server startup or the server is stopped for some reason.
    79 // errors during server startup or the server is stopped for some reason.
    80 // 
    80 //
    81 // Returns: TInt: Symbian OS error code.
    81 // Returns: TInt: Symbian OS error code.
    82 // -----------------------------------------------------------------------------
    82 // -----------------------------------------------------------------------------
    83 LOCAL_C TInt StartRoapServer( RSemaphore& aClientSem ) 
    83 LOCAL_C TInt StartRoapServer( RSemaphore& aClientSem )
    84 
    84 
    85     {
    85     {
    86     TInt error = KErrNone;
    86     TInt error = KErrNone;
    87     CRoapStorageServer* server = NULL;
    87     CRoapStorageServer* server = NULL;
    88     TUint8 count = 0;
    88     TUint8 count = 0;
    89 
    89 
    90     do 
    90     do
    91         {
    91         {
    92         ++count;
    92         ++count;
    93         TRAP( error, ( server = CRoapStorageServer::NewL() ) );
    93         TRAP( error, ( server = CRoapStorageServer::NewL() ) );
    94         if ( error ) 
    94         if ( error )
    95            {
    95            {
    96            User::After( TTimeIntervalMicroSeconds32(KWaitingTime) );
    96            User::After( TTimeIntervalMicroSeconds32(KWaitingTime) );
    97            }
    97            }
    98        
    98 
    99         } while( error && ( count <= KMaxStartTries ) );
    99         } while( error && ( count <= KMaxStartTries ) );
   100     
   100 
   101     if( error ) 
   101     if( error )
   102         {
   102         {
   103         return error;
   103         return error;
   104         }
   104         }
   105         
   105 
   106     // Release the semaphore...
   106     // Release the semaphore...
   107     aClientSem.Signal();
   107     aClientSem.Signal();
   108     aClientSem.Close();
   108     aClientSem.Close();
   109     
   109 
   110     // Start waiting for connections
   110     // Start waiting for connections
   111     CActiveScheduler::Start();
   111     CActiveScheduler::Start();
   112     
   112 
   113     // Delete CRoapStorageServer
   113     // Delete CRoapStorageServer
   114     delete server;
   114     delete server;
   115     
   115 
   116     return KErrNone;
   116     return KErrNone;
   117     }
   117     }
   118 
   118 
   119 // -----------------------------------------------------------------------------
   119 // -----------------------------------------------------------------------------
   120 // Function ReadFileL().
   120 // Function ReadFileL().
   121 // Read a file into a buffer
   121 // Read a file into a buffer
   122 // -----------------------------------------------------------------------------
   122 // -----------------------------------------------------------------------------
   123 LOCAL_C void ReadFileL( RFs& aFs, HBufC8*& aContent, const TDesC& aName )
   123 LOCAL_C void ReadFileL( RFs& aFs, HBufC8*& aContent, const TDesC& aName )
   124 	{	
   124     {
   125 	TInt size = 0;
   125     TInt size = 0;
   126 	RFile file;
   126     RFile file;
   127 	
   127 
   128 	User::LeaveIfError( file.Open( aFs, aName, EFileRead ) );
   128     User::LeaveIfError( file.Open( aFs, aName, EFileRead ) );
   129 	CleanupClosePushL( file );
   129     CleanupClosePushL( file );
   130     User::LeaveIfError( file.Size( size ) );
   130     User::LeaveIfError( file.Size( size ) );
   131     aContent = HBufC8::NewLC( size );
   131     aContent = HBufC8::NewLC( size );
   132     TPtr8 ptr( aContent->Des() );
   132     TPtr8 ptr( aContent->Des() );
   133     User::LeaveIfError( file.Read( ptr, size) );
   133     User::LeaveIfError( file.Read( ptr, size) );
   134     CleanupStack::Pop(); // aContent
   134     CleanupStack::Pop(); // aContent
   135 	CleanupStack::PopAndDestroy(); // file
   135     CleanupStack::PopAndDestroy(); // file
   136 	}
   136     }
   137 
   137 
   138 // ============================ MEMBER FUNCTIONS ===============================
   138 // ============================ MEMBER FUNCTIONS ===============================
   139 
   139 
   140 // -----------------------------------------------------------------------------
   140 // -----------------------------------------------------------------------------
   141 // CRoapStorageServer::NewLC
   141 // CRoapStorageServer::NewLC
   145 CRoapStorageServer* CRoapStorageServer::NewL()
   145 CRoapStorageServer* CRoapStorageServer::NewL()
   146     {
   146     {
   147     CRoapStorageServer* self = new( ELeave ) CRoapStorageServer();
   147     CRoapStorageServer* self = new( ELeave ) CRoapStorageServer();
   148     CleanupStack::PushL( self );
   148     CleanupStack::PushL( self );
   149     self->ConstructL();
   149     self->ConstructL();
   150     CleanupStack::Pop( self ); 
   150     CleanupStack::Pop( self );
   151     return self;
   151     return self;
   152     }
   152     }
   153 
   153 
   154 // -----------------------------------------------------------------------------
   154 // -----------------------------------------------------------------------------
   155 // Destructor
   155 // Destructor
   156 // -----------------------------------------------------------------------------
   156 // -----------------------------------------------------------------------------
   157 CRoapStorageServer::~CRoapStorageServer() 
   157 CRoapStorageServer::~CRoapStorageServer()
   158     {
   158     {
   159     iRFs.Close();
   159     iRFs.Close();
   160     delete iRoapStorage;
   160     delete iRoapStorage;
   161     }
   161     }
   162 
   162 
   163 // -----------------------------------------------------------------------------
   163 // -----------------------------------------------------------------------------
   164 // CRoapStorageServer::RunErrorL
   164 // CRoapStorageServer::RunErrorL
   165 // From CActive. Complete the request and restart the scheduler.
   165 // From CActive. Complete the request and restart the scheduler.
   166 // -----------------------------------------------------------------------------
   166 // -----------------------------------------------------------------------------
   167 //
   167 //
   168 TInt CRoapStorageServer::RunError( TInt aError ) 
   168 TInt CRoapStorageServer::RunError( TInt aError )
   169     {
   169     {
   170     // Inform the client.
   170     // Inform the client.
   171     Message().Complete( aError );
   171     Message().Complete( aError );
   172     // Restart the scheduler.
   172     // Restart the scheduler.
   173     ReStart();
   173     ReStart();
   185     {
   185     {
   186     RThread client;
   186     RThread client;
   187     // Check that the versions are compatible.
   187     // Check that the versions are compatible.
   188     if ( ! User::QueryVersionSupported( TVersion( KServerMajorVersion,
   188     if ( ! User::QueryVersionSupported( TVersion( KServerMajorVersion,
   189                                                   KServerMinorVersion,
   189                                                   KServerMinorVersion,
   190                                                   KServerBuildVersion ), 
   190                                                   KServerBuildVersion ),
   191                                         aVersion ) ) 
   191                                         aVersion ) )
   192         {
   192         {
   193         // Sorry, no can do.
   193         // Sorry, no can do.
   194         User::Leave( KErrNotSupported );
   194         User::Leave( KErrNotSupported );
   195         }
   195         }
   196     return CRoapStorageSession::NewL();
   196     return CRoapStorageSession::NewL();
   200 // CRoapStorageServer::CRoapStorageServer
   200 // CRoapStorageServer::CRoapStorageServer
   201 // C++ default constructor can NOT contain any code, that
   201 // C++ default constructor can NOT contain any code, that
   202 // might leave.
   202 // might leave.
   203 // -----------------------------------------------------------------------------
   203 // -----------------------------------------------------------------------------
   204 //
   204 //
   205 CRoapStorageServer::CRoapStorageServer() : 
   205 CRoapStorageServer::CRoapStorageServer() :
   206     CServer2( EPriorityStandard ),
   206     CServer2( EPriorityStandard ),
   207     iRoapStorage( NULL )
   207     iRoapStorage( NULL )
   208     {
   208     {
   209     // Nothing
   209     // Nothing
   210     }
   210     }
   211     
   211 
   212 // -----------------------------------------------------------------------------
   212 // -----------------------------------------------------------------------------
   213 // CRoapStorageServer::ConstructL
   213 // CRoapStorageServer::ConstructL
   214 // Symbian 2nd phase constructor can leave.
   214 // Symbian 2nd phase constructor can leave.
   215 // -----------------------------------------------------------------------------
   215 // -----------------------------------------------------------------------------
   216 //
   216 //
   217 void CRoapStorageServer::ConstructL() 
   217 void CRoapStorageServer::ConstructL()
   218     {
   218     {
   219     TInt err = KErrNone;
   219     TInt err = KErrNone;
   220     
   220 
   221     User::RenameThread( KRoapStorageThread );
   221     User::RenameThread( KRoapStorageThread );
   222     StartL( Roap::KServerName );
   222     StartL( Roap::KServerName );
   223     User::LeaveIfError(iRFs.Connect());
   223     User::LeaveIfError(iRFs.Connect());
   224     
   224 
   225 #ifndef RD_MULTIPLE_DRIVE
   225 #ifndef RD_MULTIPLE_DRIVE
   226     
   226 
   227     iRoapStorage = CDRMContextDB::NewL( KRIContextFile(), 
   227     iRoapStorage = CDRMContextDB::NewL( KRIContextFile(),
   228                                         KDomainContextFile(),
   228                                         KDomainContextFile(),
   229                                         iRFs );
   229                                         iRFs );
   230     
   230 
   231 #else //RD_MULTIPLE_DRIVE
   231 #else //RD_MULTIPLE_DRIVE
   232     
   232 
   233     TInt driveNumber( -1 );
   233     TInt driveNumber( -1 );
   234     TChar driveLetter;
   234     TChar driveLetter;
   235     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
   235     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
   236 	iRFs.DriveToChar( driveNumber, driveLetter );
   236     iRFs.DriveToChar( driveNumber, driveLetter );
   237 	
   237 
   238 	TFileName riContextFile;
   238     TFileName riContextFile;
   239 	riContextFile.Format( KRIContextFileName, (TUint)driveLetter );
   239     riContextFile.Format( KRIContextFileName, (TUint)driveLetter );
   240     
   240 
   241     TFileName domainContextFile;
   241     TFileName domainContextFile;
   242 	domainContextFile.Format( KDomainContextFileName, (TUint)driveLetter );
   242     domainContextFile.Format( KDomainContextFileName, (TUint)driveLetter );
   243     
   243 
   244     iRoapStorage = CDRMContextDB::NewL( riContextFile, 
   244     iRoapStorage = CDRMContextDB::NewL( riContextFile,
   245                                         domainContextFile,
   245                                         domainContextFile,
   246                                         iRFs );
   246                                         iRFs );
   247     
   247 
   248 #endif
   248 #endif
   249     
   249 
   250     TRAP( err, ImportKeysL() );
   250     TRAP( err, ImportKeysL() );
   251     }
   251     }
   252     
   252 
   253 // -----------------------------------------------------------------------------
   253 // -----------------------------------------------------------------------------
   254 // CRoapStorageServer::ContextDB
   254 // CRoapStorageServer::ContextDB
   255 // Return the internal ROAP storage object
   255 // Return the internal ROAP storage object
   256 // -----------------------------------------------------------------------------
   256 // -----------------------------------------------------------------------------
   257 //       
   257 //
   258 CDRMContextDB* CRoapStorageServer::ContextDB()
   258 CDRMContextDB* CRoapStorageServer::ContextDB()
   259     {
   259     {
   260     return iRoapStorage;
   260     return iRoapStorage;
   261     }
   261     }
   262 
   262 
   265 // Import keys which are stored in the import directory into the private
   265 // Import keys which are stored in the import directory into the private
   266 // directory. Only one key pair plus assocated certificates can be imported
   266 // directory. Only one key pair plus assocated certificates can be imported
   267 // at a time. The file names are DevicePrivateKey.der, DeviceCert.der and
   267 // at a time. The file names are DevicePrivateKey.der, DeviceCert.der and
   268 // SigningCertXX.der.
   268 // SigningCertXX.der.
   269 // -----------------------------------------------------------------------------
   269 // -----------------------------------------------------------------------------
   270 //       
   270 //
   271 void CRoapStorageServer::ImportKeysL()
   271 void CRoapStorageServer::ImportKeysL()
   272     {
   272     {
   273     MDrmKeyStorage* storage = NULL; 
   273     MDrmKeyStorage* storage = NULL;
   274     HBufC8* privateKey = NULL;
   274     HBufC8* privateKey = NULL;
   275     HBufC8* cert = NULL;
   275     HBufC8* cert = NULL;
   276     RArray<TPtrC8> certChain;
   276     RArray<TPtrC8> certChain;
   277     RPointerArray<HBufC8> buffers;
   277     RPointerArray<HBufC8> buffers;
   278     TFileName fileName;
   278     TFileName fileName;
   279     RFile file;
   279     RFile file;
   280     TInt i;
   280     TInt i;
   281     CDir* dir = NULL;
   281     CDir* dir = NULL;
   282     TInt err = KErrNone;
   282     TInt err = KErrNone;
   283     
   283 
   284     __UHEAP_MARK;
   284     __UHEAP_MARK;
   285     LOG( _L( "CRoapStorageServer::ImportKeysL" ) );
   285     LOG( _L( "CRoapStorageServer::ImportKeysL" ) );
   286     CleanupClosePushL( buffers );
   286     CleanupClosePushL( buffers );
   287     CleanupClosePushL( certChain );
   287     CleanupClosePushL( certChain );
   288     
   288 
   289 #ifndef RD_MULTIPLE_DRIVE
   289 #ifndef RD_MULTIPLE_DRIVE
   290     
   290 
   291     ReadFileL( iRFs, privateKey, KDeviceKeyFileName );
   291     ReadFileL( iRFs, privateKey, KDeviceKeyFileName );
   292     
   292 
   293 #else //RD_MULTIPLE_DRIVE
   293 #else //RD_MULTIPLE_DRIVE
   294     
   294 
   295     TFileName tempPath;
   295     TFileName tempPath;
   296     TFileName tempPath2;
   296     TFileName tempPath2;
   297     TInt driveNumber( -1 );
   297     TInt driveNumber( -1 );
   298     TChar driveLetter;
   298     TChar driveLetter;
   299     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
   299     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
   300 	iRFs.DriveToChar( driveNumber, driveLetter );
   300     iRFs.DriveToChar( driveNumber, driveLetter );
   301 	
   301 
   302 	tempPath.Format( KDeviceKeyFileName, (TUint)driveLetter );
   302     tempPath.Format( KDeviceKeyFileName, (TUint)driveLetter );
   303     
   303 
   304     ReadFileL( iRFs, privateKey, tempPath );
   304     ReadFileL( iRFs, privateKey, tempPath );
   305     
   305 
   306 #endif
   306 #endif
   307     
   307 
   308     CleanupStack::PushL( privateKey );
   308     CleanupStack::PushL( privateKey );
   309     
   309 
   310 #ifndef RD_MULTIPLE_DRIVE
   310 #ifndef RD_MULTIPLE_DRIVE
   311     
   311 
   312     ReadFileL( iRFs, cert, KDeviceCertFileName );
   312     ReadFileL( iRFs, cert, KDeviceCertFileName );
   313     
   313 
   314 #else //RD_MULTIPLE_DRIVE
   314 #else //RD_MULTIPLE_DRIVE
   315     
   315 
   316 	tempPath2.Format( KDeviceCertFileName, (TUint)driveLetter );
   316     tempPath2.Format( KDeviceCertFileName, (TUint)driveLetter );
   317     
   317 
   318     ReadFileL( iRFs, cert, tempPath2 );
   318     ReadFileL( iRFs, cert, tempPath2 );
   319     
   319 
   320 #endif
   320 #endif
   321     
   321 
   322     CleanupStack::PushL( cert );
   322     CleanupStack::PushL( cert );
   323     buffers.AppendL( cert );
   323     buffers.AppendL( cert );
   324     
   324 
   325 #ifndef RD_MULTIPLE_DRIVE
   325 #ifndef RD_MULTIPLE_DRIVE
   326     
   326 
   327     iRFs.Delete( KDeviceKeyFileName );
   327     iRFs.Delete( KDeviceKeyFileName );
   328     iRFs.Delete( KDeviceCertFileName );
   328     iRFs.Delete( KDeviceCertFileName );
   329     
   329 
   330 #else //RD_MULTIPLE_DRIVE
   330 #else //RD_MULTIPLE_DRIVE
   331     
   331 
   332 	iRFs.Delete( tempPath );
   332     iRFs.Delete( tempPath );
   333     iRFs.Delete( tempPath2 );
   333     iRFs.Delete( tempPath2 );
   334     
   334 
   335 #endif
   335 #endif
   336     
   336 
   337 #ifndef RD_MULTIPLE_DRIVE
   337 #ifndef RD_MULTIPLE_DRIVE
   338     
   338 
   339     User::LeaveIfError( iRFs.GetDir( KInputFilePattern, KEntryAttNormal,
   339     User::LeaveIfError( iRFs.GetDir( KInputFilePattern, KEntryAttNormal,
   340         ESortByName, dir ) );
   340         ESortByName, dir ) );
   341     
   341 
   342 #else //RD_MULTIPLE_DRIVE
   342 #else //RD_MULTIPLE_DRIVE
   343     
   343 
   344 	tempPath.Format( KInputFilePattern, (TUint)driveLetter );
   344     tempPath.Format( KInputFilePattern, (TUint)driveLetter );
   345     
   345 
   346     User::LeaveIfError( iRFs.GetDir( tempPath, KEntryAttNormal,
   346     User::LeaveIfError( iRFs.GetDir( tempPath, KEntryAttNormal,
   347         ESortByName, dir ) );
   347         ESortByName, dir ) );
   348     
   348 
   349 #endif
   349 #endif
   350     
   350 
   351     CleanupStack::PushL( dir );
   351     CleanupStack::PushL( dir );
   352     
   352 
   353     for ( i = 0; i < dir->Count(); i++ )
   353     for ( i = 0; i < dir->Count(); i++ )
   354         {
   354         {
   355         
   355 
   356 #ifndef RD_MULTIPLE_DRIVE
   356 #ifndef RD_MULTIPLE_DRIVE
   357     
   357 
   358         fileName.Copy( KImportDir );
   358         fileName.Copy( KImportDir );
   359     
   359 
   360 #else //RD_MULTIPLE_DRIVE
   360 #else //RD_MULTIPLE_DRIVE
   361     
   361 
   362 	    tempPath.Format( KImportDir, (TUint)driveLetter );
   362         tempPath.Format( KImportDir, (TUint)driveLetter );
   363         
   363 
   364         fileName.Copy( tempPath );
   364         fileName.Copy( tempPath );
   365     
   365 
   366 #endif
   366 #endif
   367         
   367 
   368         fileName.Append( (*dir)[i].iName );
   368         fileName.Append( (*dir)[i].iName );
   369         ReadFileL( iRFs, cert, fileName );
   369         ReadFileL( iRFs, cert, fileName );
   370         CleanupStack::PushL( cert );
   370         CleanupStack::PushL( cert );
   371         buffers.AppendL( cert );
   371         buffers.AppendL( cert );
   372         
   372 
   373         iRFs.Delete( fileName );
   373         iRFs.Delete( fileName );
   374         }
   374         }
   375     for ( i = 0; i < buffers.Count(); i++ )
   375     for ( i = 0; i < buffers.Count(); i++ )
   376         {
   376         {
   377         certChain.AppendL( *( buffers[i] ) );
   377         certChain.AppendL( *( buffers[i] ) );
   392 // the cleanup stack and active scheduler.
   392 // the cleanup stack and active scheduler.
   393 // Returns: TInt: Symbian OS error code.
   393 // Returns: TInt: Symbian OS error code.
   394 // -----------------------------------------------------------------------------
   394 // -----------------------------------------------------------------------------
   395 //
   395 //
   396 
   396 
   397 TInt StartupRoapStorage( TAny* ) 
   397 TInt StartupRoapStorage( TAny* )
   398     {    
   398     {
   399     TInt error = KErrNone;
   399     TInt error = KErrNone;
   400     CTrapCleanup* trap = CTrapCleanup::New();
   400     CTrapCleanup* trap = CTrapCleanup::New();
   401     __ASSERT_ALWAYS( trap, User::Invariant() );
   401     __ASSERT_ALWAYS( trap, User::Invariant() );
   402     
   402 
   403     CActiveScheduler* scheduler = new CActiveScheduler();
   403     CActiveScheduler* scheduler = new CActiveScheduler();
   404     __ASSERT_ALWAYS( scheduler, User::Invariant() );
   404     __ASSERT_ALWAYS( scheduler, User::Invariant() );
   405     
   405 
   406     CActiveScheduler::Install( scheduler );
   406     CActiveScheduler::Install( scheduler );
   407     RSemaphore clientSem;
   407     RSemaphore clientSem;
   408     __ASSERT_ALWAYS( clientSem.OpenGlobal( KDRMEngCommonSemaphore ) == 0, User::Invariant() );
   408     __ASSERT_ALWAYS( clientSem.OpenGlobal( KDRMEngCommonSemaphore ) == 0, User::Invariant() );
   409     
   409 
   410     error = StartRoapServer( clientSem );
   410     error = StartRoapServer( clientSem );
   411     
   411 
   412     if ( error ) {
   412     if ( error ) {
   413         // Server creation failed. Release the semaphore.
   413         // Server creation failed. Release the semaphore.
   414         // In case of successful startup, CRoapStorageServer
   414         // In case of successful startup, CRoapStorageServer
   415         // releases the semaphore.
   415         // releases the semaphore.
   416         clientSem.Signal();
   416         clientSem.Signal();
   417         clientSem.Close();
   417         clientSem.Close();
   418         }
   418         }
   419     
   419 
   420     delete scheduler; 
   420     delete scheduler;
   421     scheduler = NULL;
   421     scheduler = NULL;
   422     
   422 
   423     delete trap;
   423     delete trap;
   424     trap = NULL;
   424     trap = NULL;
   425     
   425 
   426     // __ASSERT_ALWAYS( !error, User::Invariant() );
   426     // __ASSERT_ALWAYS( !error, User::Invariant() );
   427     
   427 
   428     return KErrNone;
   428     return KErrNone;
   429     }
   429     }
   430 
   430 
   431 //  End of File
   431 //  End of File