sl@0: // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #ifndef EKA2 sl@0: GLDEF_C TInt E32Dll(TDllReason) sl@0: { sl@0: return KErrNone; sl@0: } sl@0: #endif sl@0: sl@0: // server name sl@0: _LIT(KRedirServerName,"RedirServer"); sl@0: sl@0: enum TRedirStream sl@0: { sl@0: ERedirRead, sl@0: ERedirWrite, sl@0: ERedirFlush sl@0: }; sl@0: sl@0: // A version must be specified when creating a session with the server sl@0: const TUint KRedirServMajorVersionNumber=1; sl@0: const TUint KRedirServMinorVersionNumber=0; sl@0: const TUint KRedirServBuildVersionNumber=0; sl@0: sl@0: sl@0: //********************************** sl@0: // CRedirSession sl@0: //********************************** sl@0: // This class represents a session in the server. sl@0: // Functions are provided to respond appropriately to client messages. sl@0: NONSHARABLE_CLASS(CRedirSession) : public CSession2 sl@0: { sl@0: public: sl@0: static CRedirSession* NewL(CStreamBase2* aStream); sl@0: //service request sl@0: virtual void ServiceL(const RMessage2 &aMessage); sl@0: private : sl@0: // construct/destruct sl@0: CRedirSession(CStreamBase2* aStream); sl@0: ~CRedirSession(); sl@0: //services available to handle read/write requests sl@0: TInt WriteStreamL(const RMessage2& aMessage); sl@0: private: sl@0: CStreamBase2* iStream; sl@0: }; sl@0: sl@0: // ------------------- CRedirServer2 implementation -------------------------- sl@0: sl@0: sl@0: /** sl@0: Constructs and allocates memory for a new CRedirServer2 object. sl@0: @return RedirServer sl@0: @param aStreamFactory Stream factory. sl@0: */ sl@0: EXPORT_C CRedirServer2* CRedirServer2::NewL(CStreamFactoryBase2* aStreamFactory) sl@0: { sl@0: CRedirServer2* r=new(ELeave) CRedirServer2(aStreamFactory); sl@0: CleanupStack::PushL(r); sl@0: r->StartL(KRedirServerName); sl@0: CleanupStack::Pop(); sl@0: return r; sl@0: } sl@0: sl@0: /** sl@0: Default constructor sl@0: @param aStreamFactory Stream factory. sl@0: */ sl@0: CRedirServer2::CRedirServer2(CStreamFactoryBase2* aStreamFactory) sl@0: : CServer2(EPriority) sl@0: { sl@0: iStreamFactory = aStreamFactory; sl@0: } sl@0: sl@0: /** sl@0: Virtual destructor sl@0: */ sl@0: CRedirServer2::~CRedirServer2() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Create a new server session. sl@0: Checks if the aVersion is the right version and make a new session. sl@0: @leave KErrNotSupported sl@0: @return Sharable Session for all threads within a single process. sl@0: @param aVersion Contains version information. sl@0: A version is defined by a set of three numbers:major,minor,build version number sl@0: */ sl@0: CSession2* CRedirServer2::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const sl@0: { sl@0: sl@0: TVersion v(KRedirServMajorVersionNumber,KRedirServMinorVersionNumber, sl@0: KRedirServBuildVersionNumber); sl@0: if (!User::QueryVersionSupported(v,aVersion)) sl@0: User::Leave(KErrNotSupported); sl@0: // get a stream object from the current stream factory sl@0: CStreamBase2* stream = iStreamFactory->GetStream(); sl@0: return CRedirSession::NewL(stream); sl@0: } sl@0: sl@0: /** sl@0: Sets the stream factory sl@0: @param aStreamFactory a factory to be set sl@0: */ sl@0: EXPORT_C void CRedirServer2::SetStreamFactory(CStreamFactoryBase2* aStreamFactory) sl@0: { sl@0: // set the stream factory sl@0: iStreamFactory = aStreamFactory; sl@0: } sl@0: sl@0: // ------------------- CRedirSession2 implementation -------------------------- sl@0: CRedirSession* CRedirSession::NewL(CStreamBase2* aStream) sl@0: { sl@0: return new(ELeave) CRedirSession(aStream); sl@0: } sl@0: sl@0: CRedirSession::CRedirSession(CStreamBase2* aStream) sl@0: : iStream(aStream) sl@0: {} sl@0: sl@0: CRedirSession::~CRedirSession() sl@0: { sl@0: // The stream returned by GetStream() is effectively a singleton as sl@0: // implemented in the current redirector, so we leave deletion to sl@0: // the factory sl@0: } sl@0: sl@0: void CRedirSession::ServiceL(const RMessage2& aMessage) sl@0: { sl@0: TInt ret = KErrNone; sl@0: switch (aMessage.Function()) sl@0: { sl@0: case ERedirRead: sl@0: // call the Stream to do the read for us sl@0: iStream->Read(aMessage); sl@0: break; sl@0: case ERedirWrite: sl@0: TRAP(ret,WriteStreamL(aMessage)); sl@0: aMessage.Complete(ret); sl@0: break; sl@0: case ERedirFlush: sl@0: // TO DO: ignore flushing? sl@0: aMessage.Complete(ret); sl@0: break; sl@0: default: sl@0: aMessage.Complete(KErrNotSupported); sl@0: break; sl@0: } sl@0: return; sl@0: } sl@0: sl@0: TInt CRedirSession::WriteStreamL(const RMessage2& aMessage) sl@0: { sl@0: const TInt KMaxTransfer=256; sl@0: // sl@0: // retrieve the length of the buffer the client wants to write sl@0: TInt length = aMessage.Int1(); sl@0: // retrieve the descriptor to be written sl@0: TBuf8 bufDes; sl@0: for (TInt offset=0;offsetWrite(bufDes); sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: // -------------- CLIENT IMPLEMENTATION ----------------------------- sl@0: sl@0: EXPORT_C TInt RRedirSession2::Connect() sl@0: { sl@0: TVersion version(KRedirServMajorVersionNumber,KRedirServMinorVersionNumber, sl@0: KRedirServBuildVersionNumber); sl@0: return CreateSession(KRedirServerName,version,1); // only one message allowed - no concurrency sl@0: } sl@0: sl@0: TInt RRedirSession2::CheckEOF(TRequestStatus& aStatus) sl@0: { sl@0: if (Handle()!=0) sl@0: return KErrNone; sl@0: TRequestStatus* aStatusPtr=&aStatus; sl@0: User::RequestComplete(aStatusPtr,KErrEof); sl@0: return KErrEof; sl@0: } sl@0: sl@0: EXPORT_C void RRedirSession2::Read(TRequestStatus& aStatus, TDes8& aDes) sl@0: { sl@0: Read(aStatus, aDes, aDes.MaxLength()); sl@0: } sl@0: sl@0: EXPORT_C void RRedirSession2::Read(TRequestStatus& aStatus, TDes8& aDes, TInt aLength) sl@0: { sl@0: if (CheckEOF(aStatus)) sl@0: return; sl@0: SendReceive(ERedirRead,TIpcArgs(&aDes,aLength),aStatus); sl@0: } sl@0: sl@0: EXPORT_C void RRedirSession2::Write(TRequestStatus& aStatus, const TDesC8& aDes) sl@0: { sl@0: Write(aStatus, aDes, aDes.Length()); sl@0: } sl@0: sl@0: EXPORT_C void RRedirSession2::Write(TRequestStatus& aStatus, const TDesC8& aDes, TInt aLength) sl@0: // sl@0: // Write aLength bytes sl@0: // sl@0: { sl@0: if (CheckEOF(aStatus)) sl@0: return; sl@0: SendReceive(ERedirWrite,TIpcArgs(&aDes,aLength),aStatus); sl@0: } sl@0: sl@0: EXPORT_C void RRedirSession2::Flush(TRequestStatus& aStatus) sl@0: // sl@0: // Flush output sl@0: // sl@0: { sl@0: if (CheckEOF(aStatus)) sl@0: return; sl@0: SendReceive(ERedirFlush,aStatus); sl@0: } sl@0: sl@0: sl@0: