/*+ −
* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).+ −
* All rights reserved.+ −
* This component and the accompanying materials are made available+ −
* under the terms of the License "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: + −
* (c) 1999-2003 Symbian Ltd+ −
*+ −
*/+ −
+ −
+ −
/**+ −
@file+ −
*/+ −
+ −
#include <e32std.h>+ −
#include <random.h>+ −
#include <hash.h>+ −
#include <e32math.h>+ −
#include "randsvr.h"+ −
#include "randcliserv.h"+ −
+ −
_LIT(KRandomServerImg,"z:\\system\\libs\\randsvr.exe"); // DLL/EXE name+ −
_LIT(KRandomServerConnect, "Randsvr connect");+ −
_LIT(KRandomServerGet, "Randsvr get");+ −
+ −
const TUid KServerUid3={0x100066dc};+ −
+ −
extern "C" {+ −
EXPORT_C void RAND_bytes(unsigned char* buf,int bytes)+ −
{+ −
TPtr8 ptr(buf,bytes,bytes);+ −
buf[0]++;+ −
TRandom::Random(ptr);+ −
}+ −
}+ −
+ −
EXPORT_C CRandom::CRandom(void)+ −
{+ −
}+ −
+ −
EXPORT_C CSystemRandom* CSystemRandom::NewL(void)+ −
{+ −
CSystemRandom* self = new(ELeave)CSystemRandom();+ −
return self;+ −
}+ −
+ −
EXPORT_C CSystemRandom* CSystemRandom::NewLC(void)+ −
{+ −
CSystemRandom* self = NewL();+ −
CleanupStack::PushL(self);+ −
return self;+ −
}+ −
+ −
void CSystemRandom::GenerateBytesL(TDes8& aDest)+ −
{+ −
TRandom::RandomL(aDest);+ −
}+ −
+ −
CSystemRandom::CSystemRandom(void)+ −
{+ −
}+ −
+ −
EXPORT_C void TRandom::Random(TDes8& aDestination)+ −
{+ −
RRandomSession rs;+ −
TRAPD(ret,rs.ConnectL());+ −
if (ret)+ −
{+ −
User::Panic(KRandomServerConnect, ret);+ −
}+ −
TInt err=rs.GetRandom(aDestination);+ −
if (err)+ −
{+ −
User::Panic(KRandomServerGet, err);+ −
}+ −
rs.Close();+ −
}+ −
+ −
EXPORT_C void TRandom::RandomL(TDes8& aDestination)+ −
{+ −
RRandomSession rs;+ −
TRAPD(ret,rs.ConnectL());+ −
User::LeaveIfError(ret);+ −
CleanupClosePushL(rs);+ −
+ −
TInt err=rs.GetRandom(aDestination);+ −
User::LeaveIfError(err);+ −
+ −
CleanupStack::PopAndDestroy(); // rs+ −
}+ −
+ −
EXPORT_C RRandomSession::RRandomSession(void)+ −
{+ −
}+ −
+ −
static TInt StartServer()+ −
// Borrowed from AndrewT's server startup code.+ −
// Start the server process/thread which lives in an EPOCEXE object+ −
//+ −
{+ −
+ −
const TUidType serverUid(KNullUid,KNullUid,KServerUid3);+ −
+ −
//+ −
// EPOC and EKA2 is easy, we just create a new server process. Simultaneous+ −
// launching of two such processes should be detected when the second one+ −
// attempts to create the server object, failing with KErrAlreadyExists.+ −
//+ −
RProcess server;+ −
TInt r=server.Create(KRandomServerImg, KNullDesC, serverUid);+ −
+ −
if (r!=KErrNone)+ −
return r;+ −
TRequestStatus stat;+ −
server.Rendezvous(stat);+ −
if (stat!=KRequestPending)+ −
server.Kill(0); // abort startup+ −
else+ −
server.Resume(); // logon OK - start the server+ −
User::WaitForRequest(stat); // wait for start or death+ −
// we can't use the 'exit reason' if the server panicked as this+ −
// is the panic 'reason' and may be '0' which cannot be distinguished+ −
// from KErrNone+ −
r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();+ −
server.Close();+ −
return r;+ −
+ −
}+ −
+ −
EXPORT_C void RRandomSession::ConnectL(void)+ −
{+ −
TInt retry=2;+ −
for (;;)+ −
{+ −
TInt r=CreateSession(KRandomServerName,TVersion(0,0,0),1);+ −
if (r!=KErrNotFound && r!=KErrServerTerminated)+ −
User::Leave(r);+ −
if (--retry==0)+ −
User::Leave(r);+ −
r=StartServer();+ −
if (r!=KErrNone && r!=KErrAlreadyExists)+ −
User::Leave(r);+ −
}+ −
}+ −
+ −
EXPORT_C TInt RRandomSession::GetRandom(TDes8& aDestination)+ −
{+ −
if (aDestination.Length()<KRandomBlockSize)+ −
{+ −
return SendReceive(CRandomSession::KRandomRequest,+ −
TIpcArgs(&aDestination, aDestination.Length()));+ −
}+ −
else+ −
{+ −
TInt i;+ −
TInt err=KErrNone;+ −
TInt length=aDestination.Length();+ −
for (i=0;(i+KRandomBlockSize)<length;i+=KRandomBlockSize)+ −
{+ −
TPtr8 buffer(&aDestination[i],KRandomBlockSize,KRandomBlockSize);+ −
err=SendReceive(CRandomSession::KRandomRequest,+ −
TIpcArgs(&buffer, KRandomBlockSize));+ −
if (err)+ −
{+ −
return err;+ −
}+ −
}+ −
TPtr8 buffer(&aDestination[i],length%KRandomBlockSize,KRandomBlockSize);+ −
err=SendReceive(CRandomSession::KRandomRequest,+ −
TIpcArgs(&buffer, length-i));+ −
return err;+ −
}+ −
}+ −
+ −