libraries/iosrv/server/session.cpp
changeset 0 7f656887cf89
child 86 56b6ee983610
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/iosrv/server/session.cpp	Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,797 @@
+// session.cpp
+// 
+// Copyright (c) 2006 - 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "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:
+// Accenture - Initial contribution
+//
+
+#include "server.h"
+#include "pipe.h"
+#include "console.h"
+#include "file.h"
+#include "null.h"
+#include "persistentconsole.h"
+#include "readwrite.h"
+#include "clientserver.h"
+#include "session.h"
+
+
+CIoSession::CIoSession()
+	{
+	}
+
+CIoServer& CIoSession::Server()
+	{
+#ifdef EKA2
+	return *static_cast<CIoServer*>(const_cast<CServer2*>(CSession2::Server()));
+#else
+	return *static_cast<CIoServer*>(const_cast<CServer*>(CSharableSession::Server()));
+#endif
+	}
+
+#ifdef EKA2
+void CIoSession::CreateL()
+#else
+void CIoSession::CreateL(const CServer& aServer)
+#endif
+	{
+#ifndef EKA2
+	CSharableSession::CreateL(aServer);	// does not leave
+#endif
+	iHandles = CObjectIx::NewL();
+	Server().AddSession();
+	}
+
+CIoSession::~CIoSession()
+	{
+	delete iFindByNameMatch;
+	const TInt maxNumObjects = iHandles->Count();
+	for (TInt i = 0; i < maxNumObjects; ++i)
+		{
+		CIoObject* obj = static_cast<CIoObject*>((*iHandles)[i]);
+		if (obj != NULL)
+			{
+			obj->SessionClosed(*this);
+			}
+		}
+	Server().DropSession();
+	delete iHandles;
+	LOG(CIoLog::Printf(_L("CIoSession 0x%08x destroyed\r\n"), this));
+	}
+
+void CIoSession::ServiceL(const RMsg& aMessage)
+	{
+	LOG(CIoLog::StartServiceLC(aMessage));
+
+	switch (aMessage.Function())
+		{
+		case EIoHandleSetOwner:
+			{
+			TThreadId owningThread(aMessage.Int0());
+			FindReadWriteObjectL(aMessage.Int3(), aMessage).SetOwnerL(owningThread);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoHandleSetUnderlyingConsole:
+			{
+			FindReadWriteObjectL(aMessage.Int3(), aMessage).SetConsole(FindConsoleL(aMessage.Int0(), aMessage));
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoHandleAttachedToConsole:
+			{
+			CIoReadWriteObject& obj = FindReadWriteObjectL(aMessage.Int3(), aMessage);
+			if (obj.IsType(RIoHandle::EReadObject))
+				{
+				Complete(aMessage, MIoReadEndPoint::AttachedToConsole((MIoReadEndPoint*)obj.EndPoint()));
+				}
+			else
+				{
+				Complete(aMessage, MIoWriteEndPoint::AttachedToConsole((MIoWriteEndPoint*)obj.EndPoint()));
+				}
+			break;
+			}
+		case EIoCreateReader:
+			{
+			CIoReadObject& readObj = Server().CreateReadObjLC();
+			LOG(CIoLog::Printf(_L("id: %d"), readObj.Id()));
+			CreateHandleL(readObj, ETrue, aMessage);
+			break;
+			}
+		case EIoOpenReaderByThreadId:
+			{
+			TThreadId clientThreadId(ClientThreadIdL(aMessage));
+			CIoReadObject* readObj = Server().NextReadObj(clientThreadId);
+			if (readObj == NULL)
+				{
+				Complete(aMessage, KErrNotFound);
+				}
+			else
+				{
+#ifdef EKA2
+				LOG(CIoLog::Printf(_L("thread id: %Lu"), clientThreadId.Id()));
+#else
+				LOG(CIoLog::Printf(_L("thread id: %u"), clientThreadId));
+#endif
+				OBJ_NAME(*readObj);
+				LOG(CIoLog::Printf(_L("name: \"%S\""), &objName));
+				User::LeaveIfError(readObj->Open(clientThreadId));
+				CleanupClosePushL(*readObj);
+				CreateHandleL(*readObj, EFalse, aMessage);
+				CleanupStack::Pop();
+				}
+			break;
+			}
+		case EIoOpenReaderByExplicitThreadId:
+			{
+			TThreadId clientThreadId;
+			TPckg<TThreadId> clientThreadIdPckg(clientThreadId);
+			MessageReadL(aMessage, 0, clientThreadIdPckg);
+			CIoReadObject* readObj = Server().NextReadObj(clientThreadId);
+			if (readObj == NULL)
+				{
+				Complete(aMessage, KErrNotFound);
+				}
+			else
+				{
+#ifdef EKA2
+				LOG(CIoLog::Printf(_L("thread id: %Lu"), clientThreadId.Id()));
+#else
+				LOG(CIoLog::Printf(_L("thread id: %u"), clientThreadId));
+#endif
+				OBJ_NAME(*readObj);
+				LOG(CIoLog::Printf(_L("name: \"%S\""), &objName));
+				User::LeaveIfError(readObj->Open(clientThreadId));
+				CleanupClosePushL(*readObj);
+				CreateHandleL(*readObj, EFalse, aMessage);
+				CleanupStack::Pop();
+				}
+			break;
+			}
+		case EIoDuplicateReader:
+			{
+			CIoReadObject& readObj = FindReadObjectL(aMessage.Int3(), aMessage);
+			CIoReadObject& duplicateReadObj = FindReadObjectL(aMessage.Int0(), aMessage);
+			readObj.DuplicateL(duplicateReadObj);
+			LOG(CIoLog::Printf(_L("Duplicating read object 0x%08x (id: %d) from 0x%08x (id: %d)"), &readObj, readObj.Id(), &duplicateReadObj, duplicateReadObj.Id()));
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoDuplicateReaderHandleFromThread:
+			{
+			TThreadId threadId(aMessage.Int0());
+			CIoReadObject& readObj = FindReadObjectL(aMessage.Int3(), aMessage);
+			CIoReadObject* otherThreadObj = Server().LastOpenedReadObj(threadId);
+			if (otherThreadObj)
+				{
+				LOG(CIoLog::Printf(_L("Duplicating read object 0x%08x (id: %d) from 0x%08x (id: %d)"), &readObj, readObj.Id(), otherThreadObj, otherThreadObj->Id()));
+				readObj.DuplicateL(*otherThreadObj);
+				}
+			else
+				{
+				User::Leave(KErrNotFound);
+				}
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoCreateWriter:
+			{
+			CIoWriteObject& writeObj = Server().CreateWriteObjLC();
+			LOG(CIoLog::Printf(_L("id: %d"), writeObj.Id()));
+			CreateHandleL(writeObj, ETrue, aMessage);
+			break;
+			}
+		case EIoOpenWriterByThreadId:
+			{
+			TThreadId clientThreadId(ClientThreadIdL(aMessage));
+			CIoWriteObject* writeObj = Server().NextWriteObj(clientThreadId);
+			if (writeObj == NULL)
+				{
+				Complete(aMessage, KErrNotFound);
+				}
+			else
+				{
+				LOG(CIoLog::Printf(_L("thread id: %u"), TUint(clientThreadId)));
+				OBJ_NAME(*writeObj);
+				LOG(CIoLog::Printf(_L("name: \"%S\""), &objName));
+				User::LeaveIfError(writeObj->Open(clientThreadId));
+				CleanupClosePushL(*writeObj);				
+				CreateHandleL(*writeObj, EFalse, aMessage);
+				CleanupStack::Pop();
+				}
+			break;
+			}
+		case EIoOpenWriterByExplicitThreadId:
+			{
+			TThreadId clientThreadId;
+			TPckg<TThreadId> clientThreadIdPckg(clientThreadId);
+			MessageReadL(aMessage, 0, clientThreadIdPckg);
+			CIoWriteObject* writeObj = Server().NextWriteObj(clientThreadId);
+			if (writeObj == NULL)
+				{
+				Complete(aMessage, KErrNotFound);
+				}
+			else
+				{
+				LOG(CIoLog::Printf(_L("thread id: %u"), TUint(clientThreadId)));
+				OBJ_NAME(*writeObj);
+				LOG(CIoLog::Printf(_L("name: \"%S\""), &objName));
+				User::LeaveIfError(writeObj->Open(clientThreadId));
+				CleanupClosePushL(*writeObj);				
+				CreateHandleL(*writeObj, EFalse, aMessage);
+				CleanupStack::Pop();
+				}
+			break;
+			}
+		case EIoDuplicateWriter:
+			{
+			CIoWriteObject& writeObj = FindWriteObjectL(aMessage.Int3(), aMessage);
+			CIoWriteObject& duplicateWriteObj = FindWriteObjectL(aMessage.Int0(), aMessage);
+			writeObj.DuplicateL(duplicateWriteObj);
+			LOG(CIoLog::Printf(_L("Duplicating write object 0x%08x (id: %d) from 0x%08x (id: %d)"), &writeObj, writeObj.Id(), &duplicateWriteObj, duplicateWriteObj.Id()));
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoDuplicateWriterHandleFromThread:
+			{
+			TThreadId threadId(aMessage.Int0());
+			CIoWriteObject& writeObj = FindWriteObjectL(aMessage.Int3(), aMessage);
+			CIoWriteObject* otherThreadObj = Server().LastOpenedWriteObj(threadId);
+			if (otherThreadObj)
+				{
+				LOG(CIoLog::Printf(_L("Duplicating write object 0x%08x (id: %d) from 0x%08x (id: %d)"), &writeObj, writeObj.Id(), otherThreadObj, otherThreadObj->Id()));
+				writeObj.DuplicateL(*otherThreadObj);
+				}
+			else
+				{
+				User::Leave(KErrNotFound);
+				}
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoSetReadWriteMode:
+			{
+			FindReadWriteObjectL(aMessage.Int3(), aMessage).SetModeL(aMessage);
+			break;
+			}
+		case EIoSetReadMode:
+			{
+			TInt mode(aMessage.Int0());
+			if ((mode >= RIoReadHandle::EFull) && (mode <= RIoReadHandle::EOneOrMore))
+				{
+				FindReadObjectL(aMessage.Int3(), aMessage).SetReadMode((RIoReadHandle::TReadMode)mode);
+				Complete(aMessage, KErrNone);
+				}
+			else
+				{
+				Complete(aMessage, KErrNotSupported);
+				}
+			break;
+			}
+		case EIoSetReaderToForeground:
+			{
+			FindReadObjectL(aMessage.Int3(), aMessage).SetToForegroundL();
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoRead:
+			{
+			FindReadObjectL(aMessage.Int3(), aMessage).ReadL(aMessage);
+			break;
+			}
+		case EIoReadCancel:
+			{
+			FindReadObjectL(aMessage.Int3(), aMessage).ReadCancel(*this);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoSetLineSeparator:
+			{
+			FindReadObjectL(aMessage.Int3(), aMessage).SetLineSeparatorL(aMessage);
+			break;
+			}
+		case EIoWrite:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).WriteL(aMessage);
+			break;
+			}
+		case EIoWriteCancel:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).WriteCancel(*this);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoIsForegroundReader:
+			{
+			Complete(aMessage, FindReadObjectL(aMessage.Int3(), aMessage).IsForegroundL());
+			break;
+			}
+		case EIoConsoleWaitForKey:
+			{
+			FindReadObjectL(aMessage.Int3(), aMessage).ReadKeyL(aMessage);
+			break;
+			}
+		case EIoConsoleWaitForKeyCancel:
+			{
+			FindReadObjectL(aMessage.Int3(), aMessage).ReadKeyCancel(*this);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoConsoleCaptureKey:
+			{
+			FindReadObjectL(aMessage.Int3(), aMessage).CaptureKeyL(aMessage);
+			break;
+			}
+		case EIoConsoleCancelCaptureKey:
+			{
+			FindReadObjectL(aMessage.Int3(), aMessage).CancelCaptureKey(aMessage);
+			break;
+			}
+		case EIoConsoleCaptureAllKeys:
+			{
+			FindReadObjectL(aMessage.Int3(), aMessage).CaptureAllKeys(aMessage);
+			break;
+			}
+		case EIoConsoleCancelCaptureAllKeys:
+			{
+			FindReadObjectL(aMessage.Int3(), aMessage).CancelCaptureAllKeys(aMessage);
+			break;
+			}
+		case EIoConsoleCursorPos:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).CursorPosL(aMessage);
+			break;
+			}
+		case EIoConsoleSetCursorPosAbs:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).SetCursorPosAbsL(aMessage);
+			break;
+			}
+		case EIoConsoleSetCursorPosRel:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).SetCursorPosRelL(aMessage);
+			break;
+			}
+		case EIoConsoleSetCursorHeight:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).SetCursorHeightL(aMessage);
+			break;
+			}
+		case EIoConsoleSetTitle:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).SetTitleL(aMessage);
+			break;
+			}
+		case EIoConsoleClearScreen:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).ClearScreen(aMessage);
+			break;
+			}
+		case EIoConsoleClearToEndOfLine:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).ClearToEndOfLine(aMessage);
+			break;
+			}
+		case EIoConsoleScreenSize:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).ScreenSizeL(aMessage);
+			break;
+			}
+		case EIoConsoleSetAttributes:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).SetAttributesL(aMessage);
+			break;
+			}
+		case EIoCreatePipe:
+			{
+			CIoPipe& pipe = Server().CreatePipeLC();
+			CreateHandleL(pipe, ETrue, aMessage);
+			break;
+			}
+		case EIoHandleClose:
+			{
+			const TInt handle = aMessage.Int3();
+			LOG(CIoLog::Printf(_L("handle: %d"), handle));
+			CIoObject* obj = (CIoObject*)iHandles->AtL(handle); // Leaves with KErrBadHandle if not found, which will result in client getting panic'd.
+			obj->ClosedBy(*this);
+			iHandles->Remove(handle);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoEndPointAttachReader:
+			{
+			CIoEndPoint& endPoint = FindEndPointL(aMessage.Int3(), aMessage);
+			CIoReadObject& readObj = FindReadObjectL(aMessage.Int0(), aMessage);
+			RIoEndPoint::TReadMode mode = (RIoEndPoint::TReadMode)aMessage.Int1();
+			LOG(CIoLog::Printf(_L("read obj id:      %d, address: 0x%08x"), readObj.Id(), &readObj));
+			LOG(CIoLog::Printf(_L("end point handle: %d, address: 0x%08x"), aMessage.Int3(), &endPoint));
+			readObj.AttachL(endPoint, mode);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoEndPointAttachWriter:
+			{
+			CIoEndPoint& endPoint = FindEndPointL(aMessage.Int3(), aMessage);
+			CIoWriteObject& writeObj = FindWriteObjectL(aMessage.Int0(), aMessage);
+			LOG(CIoLog::Printf(_L("write obj id:     %d, address: 0x%08x"), writeObj.Id(), &writeObj));
+			LOG(CIoLog::Printf(_L("end point handle: %d, address: 0x%08x"), aMessage.Int3(), &endPoint));
+			writeObj.AttachL(endPoint);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoEndPointSetForegroundReadHandle:
+			{
+			CIoEndPoint& endPoint = FindEndPointL(aMessage.Int3(), aMessage);
+			CIoReadObject& readObj = FindReadObjectL(aMessage.Int0(), aMessage);
+			LOG(CIoLog::Printf(_L("read obj id:      %d, address: 0x%08x"), readObj.Id(), &readObj));
+			LOG(CIoLog::Printf(_L("end point handle: %d, address: 0x%08x"), aMessage.Int3(), &endPoint));
+			endPoint.IorepSetForegroundReaderL(readObj);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoCreateConsole:
+			{
+			HBufC* titleBuf = HBufC::NewLC(DesLengthL(aMessage, 0));
+			TPtr titlePtr(titleBuf->Des());
+			MessageReadL(aMessage, 0, titlePtr);
+			TPckgBuf<TConsoleCreateParams> paramsPckg;
+			MessageReadL(aMessage, 1, paramsPckg);
+			HBufC* implBuf = HBufC::NewLC(DesLengthL(aMessage, 2));
+			TPtr implPtr(implBuf->Des());
+			MessageReadL(aMessage, 2, implPtr);
+			CIoConsole* underlyingCons = NULL;
+			if (paramsPckg().iUnderlyingConsoleHandle != KNullHandle)
+				{
+				underlyingCons = &FindConsoleL(paramsPckg().iUnderlyingConsoleHandle, aMessage);
+				}
+			CIoConsole& console = Server().CreateConsoleLC(*implBuf, *titleBuf, paramsPckg().iSize, underlyingCons, paramsPckg().iOptions);
+			CreateHandleL(console, ETrue, aMessage); //pops console
+			CleanupStack::PopAndDestroy(2, titleBuf);
+			break;
+			}
+		case EIoOpenConsole:
+			{
+			CIoConsole* console = FindReadWriteObjectL(aMessage.Int0(), aMessage).Console();
+			if (console)
+				{
+				User::LeaveIfError(console->Open());
+				CleanupClosePushL(*console);
+				CreateHandleL(*console, EFalse, aMessage);
+				CleanupStack::Pop();
+				}
+			else
+				{
+				Complete(aMessage, KErrNotFound);
+				}
+			break;
+			}
+		case EIoConsoleImplementation:
+			{
+			TInt clientDesLen = MaxDesLengthL(aMessage, 0);
+			const TDesC& impl(FindConsoleL(aMessage.Int3(), aMessage).Implementation());
+			MessageWriteL(aMessage, 0, impl.Left(clientDesLen));
+			Complete(aMessage, impl.Length() > clientDesLen ? KErrOverflow : KErrNone);
+			break;
+			}
+		case EIoCreateFile:
+			{
+			HBufC* fileNameBuf = HBufC::NewLC(DesLengthL(aMessage, 0));
+			TPtr fileNamePtr(fileNameBuf->Des());
+			MessageReadL(aMessage, 0, fileNamePtr);
+			CIoFile& file = Server().CreateFileLC(*fileNameBuf, (RIoFile::TMode)aMessage.Int1());
+			CreateHandleL(file, ETrue, aMessage);
+			CleanupStack::PopAndDestroy(fileNameBuf);
+			break;
+			}
+		case EIoCreateNull:
+			{
+			CIoNull& null = Server().CreateNullLC();
+			CreateHandleL(null, ETrue, aMessage);
+			break;
+			}
+		case EIoSetObjectName:
+			{
+			CObject* obj = iHandles->AtL(aMessage.Int0());
+			HBufC* name = HBufC::NewLC(DesLengthL(aMessage, 1));
+			TPtr namePtr(name->Des());
+			MessageReadL(aMessage, 1, namePtr);
+			LOG(CIoLog::Printf(_L("Setting object (handle: %d, address: 0x%08x) to \"%S\""), aMessage.Int0(), &obj, name));
+			TPtrC truncatedName(name->Left(KMaxName));
+			obj->SetName(&truncatedName);
+			CleanupStack::PopAndDestroy(name);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoCreatePersistentConsole:
+			{
+			HBufC* nameBuf = HBufC::NewLC(DesLengthL(aMessage, 1));
+			TPtr namePtr(nameBuf->Des());
+			MessageReadL(aMessage, 0, namePtr);
+			
+			HBufC* titleBuf = HBufC::NewLC(DesLengthL(aMessage, 0));
+			TPtr titlePtr(titleBuf->Des());
+			MessageReadL(aMessage, 1, titlePtr);
+
+			CIoPersistentConsole& pcons = Server().CreatePersistentConsoleLC(*nameBuf, *titleBuf, aMessage);
+			CreateHandleL(pcons, ETrue, aMessage);
+			CleanupStack::PopAndDestroy(2, nameBuf);
+			break;
+			}
+		case EIoOpenPersistentConsoleByName:
+			{
+			HBufC* nameBuf = HBufC::NewLC(DesLengthL(aMessage, 0));
+			TPtr namePtr(nameBuf->Des());
+			MessageReadL(aMessage, 0, namePtr);
+			
+			CIoPersistentConsole& pcons = Server().FindPersistentConsoleL(*nameBuf);
+			User::LeaveIfError(pcons.Open());
+			CleanupClosePushL(pcons);
+			CreateHandleL(pcons, EFalse, aMessage);
+			CleanupStack::Pop(&pcons);
+			CleanupStack::PopAndDestroy(nameBuf);
+			break;
+			};
+		case EIoPersistentConsoleAttachReadEndPoint:
+			{
+			CIoPersistentConsole& pcons = FindPersistentConsoleL(aMessage.Int3(), aMessage);
+			CIoEndPoint& endPoint = FindEndPointL(aMessage.Int0(), aMessage);
+			RIoPersistentConsole::TCloseBehaviour onClose = (RIoPersistentConsole::TCloseBehaviour)aMessage.Int1();
+			pcons.AttachTransientReaderL(endPoint, onClose == RIoPersistentConsole::EDetachOnHandleClose ? this : NULL);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoPersistentConsoleAttachWriteEndPoint:
+			{
+			CIoPersistentConsole& pcons = FindPersistentConsoleL(aMessage.Int3(), aMessage);
+			CIoEndPoint& endPoint = FindEndPointL(aMessage.Int0(), aMessage);
+			RIoPersistentConsole::TCloseBehaviour onClose = (RIoPersistentConsole::TCloseBehaviour)aMessage.Int1();
+			pcons.AttachTransientWriterL(endPoint, onClose == RIoPersistentConsole::EDetachOnHandleClose ? this : NULL);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoPersistentConsoleDetachReadEndPoint:
+			{
+			CIoPersistentConsole& pcons = FindPersistentConsoleL(aMessage.Int3(), aMessage);
+			pcons.DetachTransientReader();
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoPersistentConsoleDetachWriteEndPoint:
+			{
+			CIoPersistentConsole& pcons = FindPersistentConsoleL(aMessage.Int3(), aMessage);
+			pcons.DetachTransientWriter();
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoPersistentConsoleNotifyReadDetach:
+			{
+			CIoPersistentConsole& pcons = FindPersistentConsoleL(aMessage.Int3(), aMessage);
+			pcons.NotifyReadDetachL(aMessage);
+			break;
+			}
+		case EIoPersistentConsoleNotifyWriteDetach:
+			{
+			CIoPersistentConsole& pcons = FindPersistentConsoleL(aMessage.Int3(), aMessage);
+			pcons.NotifyWriteDetachL(aMessage);
+			break;
+			}
+		case EIoPersistentConsoleCancelNotifyReadDetach:
+			{
+			CIoPersistentConsole& pcons = FindPersistentConsoleL(aMessage.Int3(), aMessage);
+			pcons.CancelNotifyReadDetach((TRequestStatus*)aMessage.Int0());
+			break;
+			}
+		case EIoPersistentConsoleCancelNotifyWriteDetach:
+			{
+			CIoPersistentConsole& pcons = FindPersistentConsoleL(aMessage.Int3(), aMessage);
+			pcons.CancelNotifyWriteDetach((TRequestStatus*)aMessage.Int0());
+			break;
+			}
+		case EIoPersistentConsoleGetAttachedNames:
+			{
+			CIoPersistentConsole& pcons = FindPersistentConsoleL(aMessage.Int3(), aMessage);
+			MessageWriteL(aMessage, 0, pcons.TransientReaderName());
+			MessageWriteL(aMessage, 1, pcons.TransientWriterName());
+			Complete(aMessage, KErrNone);
+			break;
+			}		
+		case EIoPersistentConsoleGetCreatorThreadId:
+			{
+			CIoPersistentConsole& pcons = FindPersistentConsoleL(aMessage.Int3(), aMessage);
+			MessageWriteL(aMessage, 0, TPckg<TThreadId>(pcons.Creator()));
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoHandleIsType:
+			{
+			CIoObject& obj = FindObjectL(aMessage.Int3());
+			Complete(aMessage, obj.IsType((RIoHandle::TType)aMessage.Int0()));
+			break;
+			}
+		case EIoFindFirstHandle:
+			{
+			iFindByNameType = (RIoHandle::TType)aMessage.Int0();
+
+			delete iFindByNameMatch;
+			iFindByNameMatch = NULL;
+			iFindByNameMatch = HBufC::NewL(DesLengthL(aMessage, 1));
+			TPtr matchPtr(iFindByNameMatch->Des());
+			MessageReadL(aMessage, 1, matchPtr);
+
+			TName foundName;
+			iFindByNameHandle = 0;
+			CIoObject* obj = Server().FindObjectByName(iFindByNameType, iFindByNameHandle, *iFindByNameMatch, foundName);
+			if (obj)
+				{
+				MessageWriteL(aMessage, 2, TPckg<TInt>(iFindByNameHandle));
+				MessageWriteL(aMessage, 3, foundName);
+				Complete(aMessage, KErrNone);	
+				}
+			else
+				{
+				Complete(aMessage, KErrNotFound);	
+				}
+			break;
+			}
+		case EIoFindNextHandle:
+			{
+			if (!(iFindByNameMatch && iFindByNameHandle))
+				{
+				PanicClient(aMessage, EPanicFindNextWithNoFindFirst);
+				break;
+				}
+				
+			TName foundName;
+			CIoObject* obj = Server().FindObjectByName(iFindByNameType, iFindByNameHandle, *iFindByNameMatch, foundName);
+			if (obj)
+				{
+				MessageWriteL(aMessage, 0, TPckg<TInt>(iFindByNameHandle));
+				MessageWriteL(aMessage, 1, foundName);
+				Complete(aMessage, KErrNone);	
+				}
+			else
+				{
+				Complete(aMessage, KErrNotFound);	
+				}
+			break;
+			}
+		case EIoOpenFoundHandle:
+			{
+			if (!(iFindByNameMatch && iFindByNameHandle))
+				{
+				PanicClient(aMessage, EPanicOpenFoundWithNoFind);
+				break;
+				}
+			
+			CIoObject& obj = Server().OpenObjectLC(aMessage.Int0());
+			CreateHandleL(obj, EFalse, aMessage);
+			CleanupStack::Pop(&obj);
+			break;
+			}
+		case EIoHandleGetName:
+			{
+			CIoObject& obj = FindObjectL(aMessage.Int3());
+			TName name(obj.Name());
+			MessageWriteL(aMessage, 0, name.Left(MaxDesLengthL(aMessage, 0)));
+			Complete(aMessage, MaxDesLengthL(aMessage, 0) < name.Length() ? KErrOverflow : KErrNone);	
+			break;
+			};
+		case EIoHandleEquals:
+			{
+			CIoObject& tweedledee = FindObjectL(aMessage.Int3());
+			CIoObject& tweedledum = FindObjectL(aMessage.Int0());
+			Complete(aMessage, &tweedledee == &tweedledum);
+			break;
+			};
+		case EIoReadHandleNotifyChange:
+			{
+			CIoReadObject& readObj = FindReadObjectL(aMessage.Int3(), aMessage);
+			readObj.NotifyChange(aMessage);
+			break;
+			}
+		case EIoReadHandleCancelNotifyChange:
+			{
+			CIoReadObject& readObj = FindReadObjectL(aMessage.Int3(), aMessage);
+			readObj.CancelNotifyChange(*this);
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		case EIoSetIsStdErr:
+			{
+			FindWriteObjectL(aMessage.Int3(), aMessage).SetIsStdErr((TBool)aMessage.Int0());
+			Complete(aMessage, KErrNone);
+			break;
+			}
+		default:
+			{
+			PanicClient(aMessage, EPanicUnknownOpcode);
+			break;
+			}
+		}
+
+	LOG(CleanupStack::PopAndDestroy());
+	}
+
+void CIoSession::CreateHandleL(CObject& aObject, TBool aDoPop, const RMsg& aMessage)
+	{
+	const TInt handle = iHandles->AddL(&aObject);
+	if (aDoPop)
+		{
+		CleanupStack::Pop(&aObject);
+		}
+	TPckgC<TInt> handlePckg(handle);
+	TRAPD(err, MessageWriteL(aMessage, 3, handlePckg));
+	if (err)
+		{
+		iHandles->Remove(handle);
+		User::Leave(err);
+		}
+	LOG(CIoLog::Printf(_L("Created handle %d"), handle));
+	Complete(aMessage, err);
+	}
+	
+CIoObject& CIoSession::FindObjectL(TInt aHandle)
+	{
+	CIoObject* obj = static_cast<CIoObject*>(iHandles->AtL(aHandle));
+	return *obj;
+	}
+
+CIoEndPoint& CIoSession::FindEndPointL(TInt aHandle, const RMsg& aMessage)
+	{
+	CIoObject* obj = static_cast<CIoObject*>(iHandles->AtL(aHandle));
+	__ASSERT_ALWAYS(obj->IsType(RIoHandle::EEndPoint), PanicClient(aMessage, EPanicNotAnEndPoint));
+	return *static_cast<CIoEndPoint*>(obj);
+	}
+
+CIoPipe& CIoSession::FindPipeL(TInt aHandle, const RMsg& aMessage)
+	{
+	CIoObject* obj = static_cast<CIoObject*>(iHandles->AtL(aHandle));
+	__ASSERT_ALWAYS(obj->IsType(RIoHandle::EPipe), PanicClient(aMessage, EPanicNotAPipe));
+	return *static_cast<CIoPipe*>(obj);
+	}
+
+CIoConsole& CIoSession::FindConsoleL(TInt aHandle, const RMsg& aMessage)
+	{
+	CIoObject* obj = static_cast<CIoObject*>(iHandles->AtL(aHandle));
+	__ASSERT_ALWAYS(obj->IsType(RIoHandle::EConsole), PanicClient(aMessage, EPanicNotAConsole));
+	return *static_cast<CIoConsole*>(obj);
+	}
+	
+CIoPersistentConsole& CIoSession::FindPersistentConsoleL(TInt aHandle, const RMsg& aMessage)
+	{
+	CIoObject* obj = static_cast<CIoObject*>(iHandles->AtL(aHandle));
+	__ASSERT_ALWAYS(obj->IsType(RIoHandle::EPersistentConsole), PanicClient(aMessage, EPanicNotAPersistentConsole));
+	return *static_cast<CIoPersistentConsole*>(obj);
+	}
+
+CIoReadWriteObject& CIoSession::FindReadWriteObjectL(TInt aHandle, const RMsg& aMessage)
+	{
+	CIoObject* obj = static_cast<CIoObject*>(iHandles->AtL(aHandle));
+	__ASSERT_ALWAYS(obj->IsType(RIoHandle::EReadWriteObject), PanicClient(aMessage, EPanicNotAReadWriteObject));
+	return *static_cast<CIoReadWriteObject*>(obj);
+	}
+
+CIoReadObject& CIoSession::FindReadObjectL(TInt aHandle, const RMsg& aMessage)
+	{
+	CIoObject* obj = static_cast<CIoObject*>(iHandles->AtL(aHandle));
+	__ASSERT_ALWAYS(obj->IsType(RIoHandle::EReadObject), PanicClient(aMessage, EPanicNotAReadObject));
+	return *static_cast<CIoReadObject*>(obj);
+	}
+
+CIoWriteObject& CIoSession::FindWriteObjectL(TInt aHandle, const RMsg& aMessage)
+	{
+	CIoObject* obj = static_cast<CIoObject*>(iHandles->AtL(aHandle));
+	__ASSERT_ALWAYS(obj->IsType(RIoHandle::EWriteObject), PanicClient(aMessage, EPanicNotAWriteObject));
+	return *static_cast<CIoWriteObject*>(obj);
+	}
+
+void CIoSession::Complete(const RMsg& aMessage, TInt aError)
+	{
+	LOG(CIoLog::LogCompletion(aMessage, aError));
+	aMessage.Complete(aError);
+	}