landmarks/locationlandmarks/server/src/EPos_CPosLmServerSession.cpp
changeset 0 667063e416a2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/landmarks/locationlandmarks/server/src/EPos_CPosLmServerSession.cpp	Tue Feb 02 01:06:48 2010 +0200
@@ -0,0 +1,937 @@
+/*
+* Copyright (c) 2002-2005 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:  Landmarks Server session class.
+*
+*/
+
+
+#include <epos_cposlmsettingshandler.h>
+#include <epos_poslmdatabaseutility.h>
+#include <EPos_CPosLmDbRegistry.h>
+#include <EPos_CPosLmDatabaseIterator.h>
+#include <EPos_HPosLmDatabaseInfo.h>
+#include <epos_cposlmdiskutilities.h>
+
+#include "epos_lmdebug.h"
+#include "EPos_CPosLmServer.h"
+#include "EPos_PosLmServerCommon.h"
+#include "EPos_LmServerGlobal.h"
+#include "EPos_LandmarksServerPanics.h"
+#include "EPos_CPosLmSubsessionBase.h"
+#include "EPos_CPosLmSubsessionRegistry.h"
+#include "EPos_CPosLmLocalAccessSubsession.h"
+#include "EPos_CPosLmEventListenerSubsession.h"
+#include "EPos_CPosLmLocalDbManSubsession.h"
+#include "EPos_CPosLmServerSession.h"
+
+const TInt KArrayGranularity  = 5;
+const TChar KDriveUnspecified = 0;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CPosLmServerSession::CPosLmServerSession(
+    CPosLmServer& aServer) :
+    CSession2(),
+    iLmServer(aServer)
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::ConstructL()
+    {
+    iLmServer.LeaveIfBackupIsRunningL();
+    // This call will also cancel any server shutdown in progress.
+
+    iLmServer.IncrementSessions();
+    iDecrementSessions = ETrue;
+
+    iSubsessionRegistry = CPosLmSubsessionRegistry::NewL();
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CPosLmServerSession* CPosLmServerSession::NewL(
+    CPosLmServer& aServer)
+    {
+    CPosLmServerSession* self =
+        new( ELeave ) CPosLmServerSession(aServer);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CPosLmServerSession::~CPosLmServerSession()
+    {
+    iDbInfoArray.ResetAndDestroy();
+    iDbInfoArray.Close();
+    delete iDesArray;
+    iLmServer.RemoveSessionMessages(this);
+
+    if (iDecrementSessions)
+        {
+        iLmServer.DecrementSessions();
+        }
+    delete iSubsessionRegistry;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmServerSession::HasWriteLock(
+    const TDesC& aUri)
+    {
+    TBool hasLock = EFalse;
+
+    TInt count = iSubsessionRegistry->Count();
+    for (TInt i = 0; i < count && !hasLock; i++)
+        {
+        CPosLmSubsessionBase* subsession =
+            iSubsessionRegistry->SubsessionFromIndex(i);
+        if (subsession->SubsessionType() ==
+            CPosLmSubsessionBase::EPosLocalAccessSubsession)
+            {
+            hasLock = (static_cast<CPosLmLocalAccessSubsession*>(subsession))->
+                HasWriteLock(aUri);
+            }
+        }
+
+    return hasLock;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmServerSession::HasAnyLock(
+    const TDesC& aUri)
+    {
+    TBool hasLock = EFalse;
+
+    TInt count = iSubsessionRegistry->Count();
+    for (TInt i = 0; i < count && !hasLock; i++)
+        {
+        CPosLmSubsessionBase* subsession =
+            iSubsessionRegistry->SubsessionFromIndex(i);
+        if (subsession->SubsessionType() ==
+            CPosLmSubsessionBase::EPosLocalAccessSubsession)
+            {
+            hasLock = (static_cast<CPosLmLocalAccessSubsession*>(subsession))->
+                HasAnyLock(aUri);
+            }
+        }
+
+    return hasLock;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::HandleOperationEventL(
+    TPosLmEvent aEvent,
+    const TDesC& aUri,
+    TBool aCheckUri)
+    {
+    TInt count = iSubsessionRegistry->Count();
+    for (TInt i = 0; i < count; i++)
+        {
+        CPosLmSubsessionBase* subsession =
+            iSubsessionRegistry->SubsessionFromIndex(i);
+        if (subsession->SubsessionType() ==
+            CPosLmSubsessionBase::EPosLocalAccessSubsession)
+            {
+            (static_cast<CPosLmLocalAccessSubsession*>(subsession))->
+                HandleOperationEventL(aEvent, aUri, aCheckUri);
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::HandleOperationEventL(
+    TPosLmDatabaseEvent aEvent,
+    const TDesC& aUri)
+    {
+    TInt count = iSubsessionRegistry->Count();
+    for (TInt i = 0; i < count; i++)
+        {
+        CPosLmSubsessionBase* subsession =
+            iSubsessionRegistry->SubsessionFromIndex(i);
+        if (subsession->SubsessionType() ==
+            CPosLmSubsessionBase::EPosEventListenerSubsession)
+            {
+            (static_cast<CPosLmEventListenerSubsession*>(subsession))->
+                HandleOperationEventL(aEvent, aUri);
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::CompleteOutstandingEventRequest(
+    TInt aError)
+    {
+    TInt count = iSubsessionRegistry->Count();
+    for (TInt i = 0; i < count; i++)
+        {
+        CPosLmSubsessionBase* subsession =
+            iSubsessionRegistry->SubsessionFromIndex(i);
+        if (subsession->SubsessionType() ==
+            CPosLmSubsessionBase::EPosEventListenerSubsession)
+            {
+            (static_cast<CPosLmEventListenerSubsession*>(subsession))->
+                CompleteOutstandingEventRequest(aError);
+            }
+        else if (subsession->SubsessionType() ==
+            CPosLmSubsessionBase::EPosLocalAccessSubsession)
+            {
+            (static_cast<CPosLmLocalAccessSubsession*>(subsession))->
+                CompleteOutstandingEventRequest(aError);
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::ServiceL(
+    const RMessage2& aMessage)
+    {
+    iLmServer.LeaveIfBackupIsRunningL();
+
+    TRAPD(err, DispatchMessageL(aMessage));
+
+    if (err != KErrNone)
+        {
+        LOG2("ServerSession::ServiceL: message %d failed with %d", aMessage.Function(), err);
+        LmServerGlobal::Complete(aMessage, err);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::DispatchMessageL(
+    const RMessage2& aMessage)
+    {
+    switch (aMessage.Function())
+        {
+        // subsession management
+        case EPosLmServerRegisterLocalAccessSubsession:
+            CreateLocalAccessSubsessionL(aMessage);
+            break;
+        case EPosLmServerRegisterEventListenerSubsession:
+            CreateEventListenerSubsessionL(aMessage);
+            break;
+        case EPosLmServerRegisterLocalDbManSubsession:
+            CreateLocalDbManSubsessionL(aMessage);
+            break;
+        case EPosLmServerUnregisterSubsession:
+            CloseSubsession(aMessage);
+            break;
+
+        // server API
+        case EPosLmServerRegisterDatabase:
+            RegisterDatabaseL(aMessage);
+            break;
+        case EPosLmServerUnregisterDatabase:
+            UnregisterDatabaseL(aMessage);
+            break;
+        case EPosLmServerUnregisterAllDatabases:
+            UnregisterAllDatabasesL(aMessage);
+            break;
+        case EPosLmServerModifyDatabaseSettings:
+            ModifyDatabaseSettingsL(aMessage);
+            break;
+        case EPosLmServerReadDatabaseSettings:
+            ReadDatabaseSettingsL(aMessage);
+            break;
+        case EPosLmServerListDatabaseUris:
+            ListDatabaseUrisL(aMessage);
+            break;
+        case EPosLmServerRemainingDatabaseUris:
+            RemainingDatabaseUrisL(aMessage);
+            break;
+        case EPosLmServerListDatabaseInfo:
+            ListDatabaseInfoL(aMessage);
+            break;
+        case EPosLmServerRemainingDatabaseInfo:
+            RemainingDatabaseInfoL(aMessage);
+            break;
+        case EPosLmServerReportDbEvent:
+            ReportEventL(aMessage);
+            break;
+        case EPosLmServerFreeResources:
+            FreeResources(aMessage);
+            break;
+        default:
+            ForwardToSubsessionL(aMessage);
+            break;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::AddSubsessionToRegistryL(
+    CPosLmSubsessionBase* aSubsession,
+    const RMessage2& aMessage)
+    {
+    TInt subsessionHandle = iSubsessionRegistry->AddInstanceL(aSubsession);
+
+    // Note: Nothing must leave in the remainder of this method, since
+    // there is double ownership of the subsession object.
+
+    // Set the client subsession identifier.
+    TPckg<TInt> handlePackage(subsessionHandle);
+
+    if (LmServerGlobal::Write(aMessage, 3, handlePackage) != KErrNone)
+        {
+        // Don't bother about the return code. This client has already been
+        // panicked.
+        iSubsessionRegistry->CloseSubsession(subsessionHandle);
+        }
+    else
+        {
+        LmServerGlobal::Complete(aMessage, KErrNone);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::CloseSubsession(
+    const RMessage2& aMessage)
+    {
+    LmServerGlobal::Complete(aMessage,
+        iSubsessionRegistry->CloseSubsession(aMessage.Int3()));
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::ForwardToSubsessionL(
+    const RMessage2& aMessage)
+    {
+    CPosLmSubsessionBase* subsession =
+        iSubsessionRegistry->SubsessionFromHandleL(aMessage.Int3());
+
+    if (!subsession)
+        {
+        User::Leave(KErrNotSupported);
+        }
+
+    subsession->ServiceL(aMessage);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::CreateLocalAccessSubsessionL(
+    const RMessage2& aMessage)
+    {
+    CPosLmLocalAccessSubsession* subsession =
+        CPosLmLocalAccessSubsession::NewLC(&iLmServer);
+    AddSubsessionToRegistryL(subsession, aMessage);
+    CleanupStack::Pop(subsession); // Ownership transferred
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::CreateEventListenerSubsessionL(
+    const RMessage2& aMessage)
+    {
+    CPosLmEventListenerSubsession* subsession =
+        CPosLmEventListenerSubsession::NewLC(&iLmServer);
+    AddSubsessionToRegistryL(subsession, aMessage);
+    CleanupStack::Pop(subsession); // Ownership transferred
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::CreateLocalDbManSubsessionL(
+    const RMessage2& aMessage)
+    {
+    CPosLmLocalDbManSubsession* subsession =
+        CPosLmLocalDbManSubsession::NewLC(&iLmServer);
+    AddSubsessionToRegistryL(subsession, aMessage);
+    CleanupStack::Pop(subsession); // Ownership transferred
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::RegisterDatabaseL(const RMessage2& aMessage)
+    {
+    TInt dbInfoLength = aMessage.GetDesLength(KPosLmServerDbInfoArg);
+    if (dbInfoLength < 0)
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    HBufC8* buf = HBufC8::NewLC(dbInfoLength);
+    TPtr8 bufPtr = buf->Des();
+    if (LmServerGlobal::Read(
+        aMessage, KPosLmServerDbInfoArg, bufPtr) == KErrNone)
+        {
+        TUint8* dbInfoPtr = const_cast<TUint8*>(buf->Ptr());
+        HPosLmDatabaseInfo* dbInfo =
+            reinterpret_cast<HPosLmDatabaseInfo*>(dbInfoPtr);
+
+        TChar drive = GetSystemDriveChar();
+        if (dbInfo->DatabaseDrive() != 0)
+            {
+            drive = dbInfo->DatabaseDrive();
+            }
+
+        CPosLmDbRegistry* reg = iLmServer.GetRegistryL(drive, ETrue);
+        if (reg)
+            {
+            reg->RegisterDatabaseL(dbInfo->DatabaseUri(), dbInfo->Settings());
+            User::LeaveIfError(reg->Compact());
+            }
+        LmServerGlobal::Complete(aMessage, KErrNone);
+        }
+    CleanupStack::PopAndDestroy(buf);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::UnregisterDatabaseL(const RMessage2& aMessage)
+    {
+    TInt uriLength = aMessage.GetDesLength(KPosLmServerUriArg);
+    TInt driveLength = aMessage.GetDesLength(KPosLmServerDriveArg);
+
+    if (uriLength < 0 || driveLength < 0)
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    HBufC* uri = HBufC::NewLC(uriLength);
+    TPtr uriPtr = uri->Des();
+    TChar drive;
+    TPckg<TChar> drivePckg(drive);
+
+    if (LmServerGlobal::Read(
+        aMessage, KPosLmServerUriArg, uriPtr) == KErrNone &&
+        LmServerGlobal::Read(
+            aMessage, KPosLmServerDriveArg, drivePckg) == KErrNone)
+        {
+        if (drive == 0)
+            {
+            drive = GetSystemDriveChar();
+            }
+
+        CPosLmDbRegistry* reg = iLmServer.GetRegistryL(drive);
+        if (reg)
+            {
+            reg->UnregisterDatabaseL(*uri);
+            User::LeaveIfError(reg->Compact());
+            }
+        LmServerGlobal::Complete(aMessage, KErrNone);
+        }
+
+    CleanupStack::PopAndDestroy(uri);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::UnregisterAllDatabasesL(const RMessage2& aMessage)
+    {
+    TInt protocolLength = aMessage.GetDesLength(KPosLmServerProtocolArg);
+    if (protocolLength < 0)
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    HBufC* protocol = HBufC::NewLC(protocolLength);
+    TPtr protPtr = protocol->Des();
+
+    if (LmServerGlobal::Read(
+        aMessage, KPosLmServerProtocolArg, protPtr) != KErrNone)
+        {
+        CleanupStack::PopAndDestroy(protocol);
+        return;
+        }
+
+    TDriveList driveList;
+    User::LeaveIfError(iLmServer.FileSession().DriveList(driveList));
+
+    for (TInt driveNumber = EDriveA; driveNumber <= EDriveY; driveNumber++)
+        {
+        if ( driveList[driveNumber] && !( driveList[driveNumber] & KDriveAttRemote ) ) // avoid remote drives
+            {
+	        TDriveInfo drvInfo;
+	        TInt err = iLmServer.FileSession().Drive( drvInfo, driveNumber );
+
+            if ( !err && drvInfo.iType != EMediaNotPresent )
+	            {
+	            TDriveUnit unit(driveNumber);
+	            TChar drive((unit.Name())[0]);
+	            CPosLmDbRegistry* reg = iLmServer.GetRegistryL(drive);
+	            if (reg)
+	                {
+	                reg->UnregisterAllL(*protocol);
+	                User::LeaveIfError(reg->Compact());
+	                }
+	            }
+			}
+        }
+
+    LmServerGlobal::Complete(aMessage, KErrNone);
+    CleanupStack::PopAndDestroy(protocol);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::ModifyDatabaseSettingsL(const RMessage2& aMessage)
+    {
+    TInt uriLength = aMessage.GetDesLength(KPosLmServerUriArg);
+    TInt driveLength = aMessage.GetDesLength(KPosLmServerDriveArg);
+    TInt settingsLength = aMessage.GetDesLength(KPosLmServerDbSettingsArg);
+
+    if (uriLength < 0 || driveLength < 0 || settingsLength < 0 )
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    HBufC* uri = HBufC::NewLC(uriLength);
+    TPtr uriPtr = uri->Des();
+    TChar drive;
+    TPckg<TChar> drivePckg(drive);
+    TPosLmDatabaseSettings settings;
+    TPckg<TPosLmDatabaseSettings> settingsPckg(settings);
+
+    if (LmServerGlobal::Read(
+            aMessage, KPosLmServerUriArg, uriPtr) == KErrNone &&
+        LmServerGlobal::Read(
+            aMessage, KPosLmServerDriveArg, drivePckg) == KErrNone &&
+        LmServerGlobal::Read(
+            aMessage, KPosLmServerDbSettingsArg, settingsPckg) == KErrNone)
+        {
+        if (drive == 0)
+            {
+            drive = GetSystemDriveChar();
+            }
+
+        CPosLmDbRegistry* reg = iLmServer.GetRegistryL(drive);
+        if (!reg)
+            {
+            User::Leave(KErrNotFound);
+            }
+        reg->ModifyDatabaseSettingsL(*uri, settings);
+
+        User::LeaveIfError(reg->Compact());
+        LmServerGlobal::Complete(aMessage, KErrNone);
+        }
+
+    CleanupStack::PopAndDestroy(uri);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::ReadDatabaseSettingsL(const RMessage2& aMessage)
+    {
+    TInt dbInfoLength = aMessage.GetDesLength(KPosLmServerDbInfoArg);
+    if (dbInfoLength < 0)
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    HBufC8* buf = HBufC8::NewLC(dbInfoLength);
+    TPtr8 ptr = buf->Des();
+
+    if (LmServerGlobal::Read(aMessage, KPosLmServerDbInfoArg, ptr) == KErrNone)
+        {
+        TUint8* pointer = const_cast<TUint8*>(buf->Ptr());
+        HPosLmDatabaseInfo* dbInfo =
+            reinterpret_cast<HPosLmDatabaseInfo*>(pointer);
+
+        TChar drive = GetSystemDriveChar();
+        if (dbInfo->DatabaseDrive() != 0)
+            {
+            drive = dbInfo->DatabaseDrive();
+            }
+
+        CPosLmDbRegistry* reg = iLmServer.GetRegistryL(drive);
+        if (!reg)
+            {
+            User::Leave(KErrNotFound);
+            }
+
+        TPtrC uri = dbInfo->DatabaseUri();
+        reg->ReadDatabaseSettingsL(uri, dbInfo->Settings());
+
+        if (LmServerGlobal::Write(aMessage, KPosLmServerDbInfoArg, *buf)
+            == KErrNone)
+            {
+            LmServerGlobal::Complete(aMessage, KErrNone);
+            }
+        }
+    CleanupStack::PopAndDestroy(buf);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::ListDatabaseUrisL(const RMessage2& aMessage)
+    {
+    TInt protocolLength = aMessage.GetDesLength(KPosLmServerProtocolArg);
+    TInt bufferLength = aMessage.GetDesMaxLength(KPosLmServerBufferArg);
+
+    if (protocolLength < 0 || bufferLength < 0)
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    HBufC* protocol = HBufC::NewLC(protocolLength);
+    TPtr protPtr = protocol->Des();
+
+    if (LmServerGlobal::Read(
+        aMessage, KPosLmServerProtocolArg, protPtr) != KErrNone)
+        {
+        CleanupStack::PopAndDestroy(protocol);
+        return;
+        }
+
+    HBufC8* buffer = HBufC8::NewLC(bufferLength);
+    TPtr8 bufPtr = buffer->Des();
+    TInt allocLength = 0;
+    TDriveList driveList;
+
+    User::LeaveIfError(iLmServer.FileSession().DriveList(driveList));
+    for (TInt driveNumber = EDriveA; driveNumber <= EDriveZ; driveNumber++)
+        {
+        if ( driveList[driveNumber] && !( driveList[driveNumber] & KDriveAttRemote ) ) // avoid remote drives
+            {
+            TDriveInfo drvInfo;
+            TInt err = iLmServer.FileSession().Drive( drvInfo, driveNumber );
+
+            if ( !err && drvInfo.iType != EMediaNotPresent )
+                {
+                TDriveUnit unit(driveNumber);
+                TChar drive((unit.Name())[0]);
+                CPosLmDbRegistry* reg = iLmServer.GetRegistryL(drive);
+                if (reg)
+                    {
+                    CPosLmDatabaseIterator* iter = reg->ListDatabasesL(*protocol);
+                    CleanupStack::PushL(iter);
+
+                    while (iter->NextItemL())
+                        {
+                        TPtrC uri = iter->UriL();
+                        TPckgC<TInt> intPckg(uri.Length());
+
+                        TInt pckgLength = intPckg.Length();
+                        TInt nextItemLength = pckgLength + uri.Length() * 2;
+
+                        if ((nextItemLength + buffer->Length()) >
+                            bufPtr.MaxLength())
+                            {
+                            if (!iDesArray)
+                                {
+                                iDesArray =
+                                    new (ELeave) CDesCArrayFlat(KArrayGranularity);
+                                }
+                            iDesArray->AppendL(uri);
+                            allocLength += nextItemLength;
+                            }
+                        else
+                            {
+                            TInt uriSize = uri.Size();
+                            TPtr8 uriPtr(reinterpret_cast<TUint8*>(
+                                const_cast<TUint16*>(uri.Ptr())), uriSize, uriSize);
+
+                            bufPtr.Append(intPckg);
+                            bufPtr.Append(uriPtr);
+                            }
+                        }
+                    CleanupStack::PopAndDestroy(iter);
+                    }
+                }
+            }
+        }
+
+    TPckg<TInt> allocPckg(allocLength);
+    if (LmServerGlobal::Write(
+            aMessage, KPosLmServerBufferArg, *buffer) == KErrNone &&
+        LmServerGlobal::Write(
+            aMessage, KPosLmServerAllocLengthArg, allocPckg) == KErrNone)
+        {
+        LmServerGlobal::Complete(aMessage, KErrNone);
+        }
+
+    CleanupStack::PopAndDestroy(2, protocol); //buffer
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::RemainingDatabaseUrisL(const RMessage2& aMessage)
+    {
+    if ( !iDesArray || (iDesArray && iDesArray->Count() == 0) )
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    TInt bufferLength = aMessage.GetDesMaxLength(KPosLmServerBufferArg);
+
+    if (bufferLength < 0)
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    HBufC8* buffer = HBufC8::NewLC(bufferLength);
+    TPtr8 bufPtr = buffer->Des();
+
+    TInt sumUriSize = 0;
+    for (TInt i = 0; i < iDesArray->Count(); i++)
+        {
+        TInt uriLength = (*iDesArray)[i].Length();
+        TPckgC<TInt> intPckg(uriLength);
+
+        sumUriSize += intPckg.Size() + (*iDesArray)[i].Size();
+        if (sumUriSize > bufferLength)
+            {
+            iDesArray->Reset();
+            CleanupStack::PopAndDestroy(buffer);
+            PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+            return;
+            }
+
+        TInt uriSize = (*iDesArray)[i].Size();
+        TPtr8 uriPtr(reinterpret_cast<TUint8*>(
+            const_cast<TUint16*>((*iDesArray)[i].Ptr())), uriSize, uriSize);
+
+        bufPtr.Append(intPckg);
+        bufPtr.Append(uriPtr);
+        }
+
+    if (LmServerGlobal::Write(
+            aMessage, KPosLmServerBufferArg, *buffer) == KErrNone)
+        {
+        LmServerGlobal::Complete(aMessage, KErrNone);
+        iDesArray->Reset();
+        delete iDesArray;
+        iDesArray = NULL;
+        }
+    CleanupStack::PopAndDestroy(buffer);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::ListDatabaseInfoL(const RMessage2& aMessage)
+    {
+    TInt protocolLength = aMessage.GetDesLength(KPosLmServerProtocolArg);
+    TInt bufferLength = aMessage.GetDesMaxLength(KPosLmServerBufferArg);
+
+    if (protocolLength < 0 || bufferLength < 0)
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    HBufC* protocol = HBufC::NewLC(protocolLength);
+    TPtr protPtr = protocol->Des();
+
+    if (LmServerGlobal::Read(
+        aMessage, KPosLmServerProtocolArg, protPtr) != KErrNone)
+        {
+        CleanupStack::PopAndDestroy(protocol);
+        return;
+        }
+
+    HBufC8* buffer = HBufC8::NewLC(bufferLength);
+    TPtr8 bufPtr = buffer->Des();
+
+    TInt allocLength = 0;
+    TInt sumInfoSize = 0;
+    TDriveList driveList;
+
+    User::LeaveIfError(iLmServer.FileSession().DriveList(driveList));
+    for (TInt driveNumber = EDriveA; driveNumber <= EDriveZ; driveNumber++)
+        {
+        if ( driveList[driveNumber] && !( driveList[driveNumber] & KDriveAttRemote ) ) // avoid remote drives
+            {
+            TDriveInfo drvInfo;
+            TInt err = iLmServer.FileSession().Drive( drvInfo, driveNumber );
+
+            if ( !err && drvInfo.iType != EMediaNotPresent )
+                {
+                TDriveUnit unit(driveNumber);
+                TChar drive((unit.Name())[0]);
+                CPosLmDbRegistry* reg = iLmServer.GetRegistryL(drive);
+                if (reg)
+                    {
+                    CPosLmDatabaseIterator* iter = reg->ListDatabasesL(*protocol);
+                    CleanupStack::PushL(iter);
+
+                    while (iter->NextItemL())
+                        {
+                        HPosLmDatabaseInfo* dbInfo =
+                            HPosLmDatabaseInfo::NewLC(iter->UriL());
+                        iter->GetSettingsL(dbInfo->Settings());
+
+                        sumInfoSize += dbInfo->Size();
+                        if (sumInfoSize > bufPtr.MaxLength())
+                            {
+                            iDbInfoArray.AppendL(dbInfo);
+                            allocLength += dbInfo->Size();
+                            CleanupStack::Pop(dbInfo);
+                            }
+                        else
+                            {
+                            TUint8* pointer = reinterpret_cast<TUint8*>(dbInfo);
+                            bufPtr.Append(pointer, dbInfo->Size());
+                            CleanupStack::PopAndDestroy(dbInfo);
+                            }
+                        }
+                    CleanupStack::PopAndDestroy(iter);
+                    }
+                }
+            }
+        }
+
+    TPckg<TInt> allocPckg(allocLength);
+    if (LmServerGlobal::Write(
+            aMessage, KPosLmServerBufferArg, *buffer) == KErrNone &&
+        LmServerGlobal::Write(
+            aMessage, KPosLmServerAllocLengthArg, allocPckg) == KErrNone)
+        {
+        LmServerGlobal::Complete(aMessage, KErrNone);
+        }
+
+    CleanupStack::PopAndDestroy(2, protocol); //buffer
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::RemainingDatabaseInfoL(const RMessage2& aMessage)
+    {
+    if (iDbInfoArray.Count() == 0)
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    TInt bufferLength = aMessage.GetDesMaxLength(KPosLmServerBufferArg);
+
+    if (bufferLength < 0)
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    HBufC8* buffer = HBufC8::NewLC(bufferLength);
+
+    TInt infoLength = 0;
+    for (TInt i = 0; i < iDbInfoArray.Count(); i++)
+        {
+        HPosLmDatabaseInfo* dbInfo = iDbInfoArray[i];
+        TUint8* pointer = reinterpret_cast<TUint8*>(dbInfo);
+
+        infoLength += dbInfo->Size();
+        if (infoLength > bufferLength)
+            {
+            iDbInfoArray.ResetAndDestroy();
+            CleanupStack::PopAndDestroy(buffer);
+            PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+            return;
+            }
+
+        buffer->Des().Append(pointer, dbInfo->Size());
+        }
+
+    if (LmServerGlobal::Write(
+            aMessage, KPosLmServerBufferArg, *buffer) == KErrNone)
+        {
+        LmServerGlobal::Complete(aMessage, KErrNone);
+        }
+
+    iDbInfoArray.ResetAndDestroy();
+    CleanupStack::PopAndDestroy(buffer);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::ReportEventL(const RMessage2& aMessage)
+    {
+    TInt uriLength = aMessage.GetDesLength(KPosLmServerUriArg);
+    TInt dbEventLength = aMessage.GetDesLength(KPosLmServerDbEventArg);
+
+    if (uriLength < 0 || dbEventLength < 0)
+        {
+        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
+        return;
+        }
+
+    HBufC* uri = HBufC::NewLC(uriLength);
+    TPtr uriPtr = uri->Des();
+
+    TPckgBuf<TPosLmDatabaseEvent> event;
+
+    if (LmServerGlobal::Read(
+            aMessage, KPosLmServerUriArg, uriPtr) == KErrNone &&
+        LmServerGlobal::Read(
+            aMessage, KPosLmServerDbEventArg, event) == KErrNone)
+        {
+        iLmServer.ForwardEventToAllSessionsL(event(), uri->Des());
+        LmServerGlobal::Complete(aMessage, KErrNone);
+        }
+    CleanupStack::PopAndDestroy(uri);
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CPosLmServerSession::FreeResources(const RMessage2& aMessage)
+    {
+    delete iDesArray;
+    iDesArray = NULL;
+    iDbInfoArray.ResetAndDestroy();
+    LmServerGlobal::Complete(aMessage, KErrNone);
+    }
+
+TChar CPosLmServerSession::GetSystemDriveChar()
+{
+	return 'A' + RFs::GetSystemDrive();
+	
+}