diff -r 000000000000 -r 95b198f216e5 omadrm/drmengine/roapstorage/src/RoapStorageServer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omadrm/drmengine/roapstorage/src/RoapStorageServer.cpp Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,431 @@ +/* +* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +// INCLUDE FILES +#include + +#ifdef RD_MULTIPLE_DRIVE +#include +#endif + +#include "RoapStorageServer.h" +#include "DRMContextDB.h" +#include "RoapLog.h" +#include "drmroapclientserver.h" +#include "drmcommonclientserver.h" +#include "drmkeystorage.h" + +// EXTERNAL DATA STRUCTURES +// EXTERNAL FUNCTION PROTOTYPES +// CONSTANTS +// MACROS + + +// LOCAL CONSTANTS AND MACROS +const TUint8 KMaxStartTries = 5; +const TInt KWaitingTime = 1000000; // 10 secs + +_LIT( KRoapStorageThread, "RoapStorageServer" ); + +#ifdef RD_MULTIPLE_DRIVE +_LIT( KRIContextFileName, "%c:\\private\\101F51F2\\ricontexts.dat" ); +_LIT( KDomainContextFileName, "%c:\\private\\101F51F2\\domaincontexts.dat" ); +// File names and paths for importing keys +_LIT( KImportDir, "%c:\\private\\101F51F2\\import\\" ); +_LIT( KInputFilePattern, "%c:\\private\\101F51F2\\import\\SigningCert*" ); +_LIT( KDeviceKeyFileName, "%c:\\private\\101F51F2\\import\\DevicePrivateKey.der" ); +_LIT( KDeviceCertFileName, "%c:\\private\\101F51F2\\import\\DeviceCert.der" ); +#else +// File names and paths for importing keys +_LIT( KImportDir, "c:\\private\\101F51F2\\import\\" ); +_LIT( KInputFilePattern, "c:\\private\\101F51F2\\import\\SigningCert*" ); +_LIT( KDeviceKeyFileName, "c:\\private\\101F51F2\\import\\DevicePrivateKey.der" ); +_LIT( KDeviceCertFileName, "c:\\private\\101F51F2\\import\\DeviceCert.der" ); +#endif + +// MODULE DATA STRUCTURES +using Roap::KServerMajorVersion; +using Roap::KServerMinorVersion; +using Roap::KServerBuildVersion; + +// LOCAL FUNCTION PROTOTYPES +LOCAL_C TInt StartRoapServer( RSemaphore& aClientSem ); + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// Function StartRoapServer(). +// This function starts the actual server under TRAP harness and starts +// waiting for connections. This function returns only if there has been +// errors during server startup or the server is stopped for some reason. +// +// Returns: TInt: Symbian OS error code. +// ----------------------------------------------------------------------------- +LOCAL_C TInt StartRoapServer( RSemaphore& aClientSem ) + + { + TInt error = KErrNone; + CRoapStorageServer* server = NULL; + TUint8 count = 0; + + do + { + ++count; + TRAP( error, ( server = CRoapStorageServer::NewL() ) ); + if ( error ) + { + User::After( TTimeIntervalMicroSeconds32(KWaitingTime) ); + } + + } while( error && ( count <= KMaxStartTries ) ); + + if( error ) + { + return error; + } + + // Release the semaphore... + aClientSem.Signal(); + aClientSem.Close(); + + // Start waiting for connections + CActiveScheduler::Start(); + + // Delete CRoapStorageServer + delete server; + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// Function ReadFileL(). +// Read a file into a buffer +// ----------------------------------------------------------------------------- +LOCAL_C void ReadFileL( RFs& aFs, HBufC8*& aContent, const TDesC& aName ) + { + TInt size = 0; + RFile file; + + User::LeaveIfError( file.Open( aFs, aName, EFileRead ) ); + CleanupClosePushL( file ); + User::LeaveIfError( file.Size( size ) ); + aContent = HBufC8::NewLC( size ); + TPtr8 ptr( aContent->Des() ); + User::LeaveIfError( file.Read( ptr, size) ); + CleanupStack::Pop(); // aContent + CleanupStack::PopAndDestroy(); // file + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CRoapStorageServer::NewLC +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CRoapStorageServer* CRoapStorageServer::NewL() + { + CRoapStorageServer* self = new( ELeave ) CRoapStorageServer(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// Destructor +// ----------------------------------------------------------------------------- +CRoapStorageServer::~CRoapStorageServer() + { + iRFs.Close(); + delete iRoapStorage; + } + +// ----------------------------------------------------------------------------- +// CRoapStorageServer::RunErrorL +// From CActive. Complete the request and restart the scheduler. +// ----------------------------------------------------------------------------- +// +TInt CRoapStorageServer::RunError( TInt aError ) + { + // Inform the client. + Message().Complete( aError ); + // Restart the scheduler. + ReStart(); + // Error handled. + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CRoapStorageServer::NewSessionL +// Called when a client requires a new instance. +// ----------------------------------------------------------------------------- +CSession2* CRoapStorageServer::NewSessionL( + const TVersion& aVersion, + const RMessage2& /*aMessage*/) const + { + RThread client; + // Check that the versions are compatible. + if ( ! User::QueryVersionSupported( TVersion( KServerMajorVersion, + KServerMinorVersion, + KServerBuildVersion ), + aVersion ) ) + { + // Sorry, no can do. + User::Leave( KErrNotSupported ); + } + return CRoapStorageSession::NewL(); + } + +// ----------------------------------------------------------------------------- +// CRoapStorageServer::CRoapStorageServer +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CRoapStorageServer::CRoapStorageServer() : + CServer2( EPriorityStandard ), + iRoapStorage( NULL ) + { + // Nothing + } + +// ----------------------------------------------------------------------------- +// CRoapStorageServer::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CRoapStorageServer::ConstructL() + { + TInt err = KErrNone; + + User::RenameThread( KRoapStorageThread ); + StartL( Roap::KServerName ); + User::LeaveIfError(iRFs.Connect()); + +#ifndef RD_MULTIPLE_DRIVE + + iRoapStorage = CDRMContextDB::NewL( KRIContextFile(), + KDomainContextFile(), + iRFs ); + +#else //RD_MULTIPLE_DRIVE + + TInt driveNumber( -1 ); + TChar driveLetter; + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); + iRFs.DriveToChar( driveNumber, driveLetter ); + + TFileName riContextFile; + riContextFile.Format( KRIContextFileName, (TUint)driveLetter ); + + TFileName domainContextFile; + domainContextFile.Format( KDomainContextFileName, (TUint)driveLetter ); + + iRoapStorage = CDRMContextDB::NewL( riContextFile, + domainContextFile, + iRFs ); + +#endif + + TRAP( err, ImportKeysL() ); + } + +// ----------------------------------------------------------------------------- +// CRoapStorageServer::ContextDB +// Return the internal ROAP storage object +// ----------------------------------------------------------------------------- +// +CDRMContextDB* CRoapStorageServer::ContextDB() + { + return iRoapStorage; + } + +// ----------------------------------------------------------------------------- +// CRoapStorageServer::ImportKeys +// Import keys which are stored in the import directory into the private +// directory. Only one key pair plus assocated certificates can be imported +// at a time. The file names are DevicePrivateKey.der, DeviceCert.der and +// SigningCertXX.der. +// ----------------------------------------------------------------------------- +// +void CRoapStorageServer::ImportKeysL() + { + MDrmKeyStorage* storage = NULL; + HBufC8* privateKey = NULL; + HBufC8* cert = NULL; + RArray certChain; + RPointerArray buffers; + TFileName fileName; + RFile file; + TInt i; + CDir* dir = NULL; + TInt err = KErrNone; + + __UHEAP_MARK; + LOG( _L( "CRoapStorageServer::ImportKeysL" ) ); + CleanupClosePushL( buffers ); + CleanupClosePushL( certChain ); + +#ifndef RD_MULTIPLE_DRIVE + + ReadFileL( iRFs, privateKey, KDeviceKeyFileName ); + +#else //RD_MULTIPLE_DRIVE + + TFileName tempPath; + TFileName tempPath2; + TInt driveNumber( -1 ); + TChar driveLetter; + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); + iRFs.DriveToChar( driveNumber, driveLetter ); + + tempPath.Format( KDeviceKeyFileName, (TUint)driveLetter ); + + ReadFileL( iRFs, privateKey, tempPath ); + +#endif + + CleanupStack::PushL( privateKey ); + +#ifndef RD_MULTIPLE_DRIVE + + ReadFileL( iRFs, cert, KDeviceCertFileName ); + +#else //RD_MULTIPLE_DRIVE + + tempPath2.Format( KDeviceCertFileName, (TUint)driveLetter ); + + ReadFileL( iRFs, cert, tempPath2 ); + +#endif + + CleanupStack::PushL( cert ); + buffers.AppendL( cert ); + +#ifndef RD_MULTIPLE_DRIVE + + iRFs.Delete( KDeviceKeyFileName ); + iRFs.Delete( KDeviceCertFileName ); + +#else //RD_MULTIPLE_DRIVE + + iRFs.Delete( tempPath ); + iRFs.Delete( tempPath2 ); + +#endif + +#ifndef RD_MULTIPLE_DRIVE + + User::LeaveIfError( iRFs.GetDir( KInputFilePattern, KEntryAttNormal, + ESortByName, dir ) ); + +#else //RD_MULTIPLE_DRIVE + + tempPath.Format( KInputFilePattern, (TUint)driveLetter ); + + User::LeaveIfError( iRFs.GetDir( tempPath, KEntryAttNormal, + ESortByName, dir ) ); + +#endif + + CleanupStack::PushL( dir ); + + for ( i = 0; i < dir->Count(); i++ ) + { + +#ifndef RD_MULTIPLE_DRIVE + + fileName.Copy( KImportDir ); + +#else //RD_MULTIPLE_DRIVE + + tempPath.Format( KImportDir, (TUint)driveLetter ); + + fileName.Copy( tempPath ); + +#endif + + fileName.Append( (*dir)[i].iName ); + ReadFileL( iRFs, cert, fileName ); + CleanupStack::PushL( cert ); + buffers.AppendL( cert ); + + iRFs.Delete( fileName ); + } + for ( i = 0; i < buffers.Count(); i++ ) + { + certChain.AppendL( *( buffers[i] ) ); + } + storage = DrmKeyStorageNewL(); + TRAP( err, storage->ImportDataL( *privateKey, certChain ) ); + delete storage; + CleanupStack::PopAndDestroy( i + 1 ); // certs & dir + CleanupStack::PopAndDestroy( 3 ); // privateKey, certChain, buffers + LOG( _L( "CRoapStorageServer::ImportKeysL done" ) ); + __UHEAP_MARKEND; + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= +// ----------------------------------------------------------------------------- +// Function StartupRoapStorage(). +// This function starts the actual Roap Storage +// the cleanup stack and active scheduler. +// Returns: TInt: Symbian OS error code. +// ----------------------------------------------------------------------------- +// + +TInt StartupRoapStorage( TAny* ) + { + TInt error = KErrNone; + CTrapCleanup* trap = CTrapCleanup::New(); + __ASSERT_ALWAYS( trap, User::Invariant() ); + + CActiveScheduler* scheduler = new CActiveScheduler(); + __ASSERT_ALWAYS( scheduler, User::Invariant() ); + + CActiveScheduler::Install( scheduler ); + RSemaphore clientSem; + __ASSERT_ALWAYS( clientSem.OpenGlobal( KDRMEngCommonSemaphore ) == 0, User::Invariant() ); + + error = StartRoapServer( clientSem ); + + if ( error ) { + // Server creation failed. Release the semaphore. + // In case of successful startup, CRoapStorageServer + // releases the semaphore. + clientSem.Signal(); + clientSem.Close(); + } + + delete scheduler; + scheduler = NULL; + + delete trap; + trap = NULL; + + // __ASSERT_ALWAYS( !error, User::Invariant() ); + + return KErrNone; + } + +// End of File