userlibandfileserver/fileserver/shostmassstorage/server/transport/cbulkonlytransport.cpp
changeset 43 96e5fb8b040d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/transport/cbulkonlytransport.cpp	Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,728 @@
+// Copyright (c) 2008-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:
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#include <e32base.h>
+#include <d32usbdi_hubdriver.h>
+#include <d32usbdi.h>
+#include <d32otgdi.h>
+#include <d32usbdescriptors.h>
+#include <d32usbtransfers.h>
+#ifdef MASSSTORAGE_PUBLISHER
+#include <e32property.h>
+#endif
+#include "botmsctypes.h"
+#include "msctypes.h"
+#include "mscutils.h"
+#include "mtransport.h"
+#include "mprotocol.h"
+#include "cusbifacehandler.h"
+#include "cbulkonlytransport.h"
+#include "debug.h"
+#include "msdebug.h"
+
+CBulkOnlyTransport::CBulkOnlyTransport()
+:	iBulkOutCbwTd(KCbwPacketSize),
+	iBulkDataTd(KResponsePacketSize),
+	iBulkInCswTd(KCswPacketSize)
+	{
+    __MSFNLOG
+	}
+
+CBulkOnlyTransport::~CBulkOnlyTransport()
+	{
+    __MSFNLOG
+	delete iUsbInterfaceHandler;
+	UnInitialiseTransport();
+	iInterface.Close();
+	}
+
+/**
+Create CBulkOnlyTransport object.
+
+@param aInterfaceId The interface ID of the device
+
+@return CBulkOnlyTransport* Pointer to the created object
+*/
+CBulkOnlyTransport* CBulkOnlyTransport::NewL(TUint aInterfaceId)
+	{
+    __MSFNSLOG
+	CBulkOnlyTransport* transport = new (ELeave) CBulkOnlyTransport();
+	CleanupStack::PushL(transport);
+    transport->ConstructL(aInterfaceId);
+    CleanupStack::Pop(transport);
+	return transport;
+	}
+
+
+void CBulkOnlyTransport::ConstructL(TUint aInterfaceId)
+    {
+    __MSFNSLOG
+	User::LeaveIfError(iInterface.Open(aInterfaceId));
+	iUsbInterfaceHandler = CUsbInterfaceHandler::NewL(iInterface);
+	InitialiseTransport();
+    }
+
+
+void CBulkOnlyTransport::Resume()
+	{
+    __MSFNSLOG
+	__BOTPRINT(_L("BOT RESUME"));
+ 
+	iInterface.CancelPermitSuspend();
+	}
+
+void CBulkOnlyTransport::Suspend(TRequestStatus& aStatus)
+	{
+    __MSFNSLOG
+	__BOTPRINT(_L("BOT SUSPEND"));
+//	iInterface.PermitRemoteWakeup(ETrue);
+	iInterface.PermitSuspendAndWaitForResume(aStatus);
+	}
+
+TInt CBulkOnlyTransport::InitialiseTransport()
+	{
+    __MSFNLOG
+	TInt BulkOutEpAddr;
+	TInt BulkInEpAddr;
+	const TUint8 KEpDirectionIn = 0x80;
+	const TUint8 KEpDirectionOut = 0x00;
+	const TUint8 KTransferTypeBulk = 0x02;
+
+	GetEndpointAddress(iInterface,0,KTransferTypeBulk,KEpDirectionOut,BulkOutEpAddr);
+	GetEndpointAddress(iInterface,0,KTransferTypeBulk,KEpDirectionIn,BulkInEpAddr);
+	iInterface.OpenPipeForEndpoint(iBulkPipeOut, BulkOutEpAddr, EFalse);
+	iInterface.OpenPipeForEndpoint(iBulkPipeIn, BulkInEpAddr, EFalse);
+
+	if (iInterface.RegisterTransferDescriptor(iBulkOutCbwTd) != KErrNone ||
+			iInterface.RegisterTransferDescriptor(iBulkDataTd) != KErrNone ||
+					iInterface.RegisterTransferDescriptor(iBulkInCswTd) != KErrNone)
+        {
+		return KErrGeneral;
+        }
+
+	if (iInterface.InitialiseTransferDescriptors() != KErrNone)
+        {
+		return KErrGeneral;
+        }
+	return KErrNone;
+	}
+
+
+void CBulkOnlyTransport::UnInitialiseTransport()
+	{
+    __MSFNLOG
+	iBulkPipeOut.Close();
+	iBulkPipeIn.Close();
+	}
+
+TInt CBulkOnlyTransport::GetEndpointAddress(RUsbInterface& aUsbInterface,
+                                            TInt aInterfaceSetting,
+                                            TUint8 aTransferType,
+                                            TUint8 aDirection,
+                                            TInt& aEndpointAddress)
+	{
+    __MSFNLOG
+	TUsbInterfaceDescriptor alternateInterfaceDescriptor;
+
+	if (aUsbInterface.GetAlternateInterfaceDescriptor(aInterfaceSetting, alternateInterfaceDescriptor))
+		{
+		__BOTPRINT1(_L("GetEndpointAddress : <Error> Unable to get alternate interface (%x) descriptor"),aInterfaceSetting);
+		return KErrGeneral;
+		}
+
+	TUsbGenericDescriptor* descriptor = alternateInterfaceDescriptor.iFirstChild;
+
+	while (descriptor)
+		{
+		TUsbEndpointDescriptor* endpoint = TUsbEndpointDescriptor::Cast(descriptor);
+		if (endpoint)
+			{
+			if ((endpoint->Attributes() & aTransferType) == aTransferType)
+				{
+				// Found the endpoint address
+				if ( (endpoint->EndpointAddress() & 0x80) == aDirection)
+					{
+					aEndpointAddress = endpoint->EndpointAddress();
+					__BOTPRINT(_L("GetEndpointAddress : Endpoint address found"));
+					return KErrNone;
+					}
+				}
+			}
+		descriptor = descriptor->iNextPeer;
+		}
+
+	// Unable to find the endpoint address
+	__BOTPRINT(_L("GetEndpointAddress : Unable to find endpoint address matching the specified attributes"));
+	return KErrNotFound;
+	}
+
+void CBulkOnlyTransport::GetMaxLun(TLun* aMaxLun, const RMessage2& aMessage)
+	{
+    __MSFNLOG
+	iUsbInterfaceHandler->GetMaxLun(aMaxLun, aMessage);
+	}
+
+TInt CBulkOnlyTransport::Reset()
+	{
+    __MSFNLOG
+	RUsbInterface::TUsbTransferRequestDetails reqDetails;
+	_LIT8(KNullDesC8,"");
+
+	reqDetails.iRequestType = 0x21;
+	reqDetails.iRequest = 0xFF;
+	reqDetails.iValue = 0x0000;
+	reqDetails.iIndex = 0x0000;
+	reqDetails.iFlags = 0x04;		// Short transfer OK
+
+	iInterface.Ep0Transfer(reqDetails, KNullDesC8, (TDes8 &) KNullDesC8, iStatus);
+	User::WaitForRequest(iStatus);
+    __BOTPRINT1(_L("BOT RESET[%d]"), iStatus.Int());
+
+	if (iStatus.Int() != KErrNone)
+        {
+		return KErrGeneral;
+        }
+
+	return KErrNone;
+	}
+
+void CBulkOnlyTransport::DoResetRecovery()
+	{
+    __MSFNLOG
+
+    __BOTPRINT(_L("BOT RESET RECOVERY"));
+#ifdef MASSSTORAGE_PUBLISHER
+    TMsPublisher publisher(TMsPublisher::KBotResetProperty);
+#endif
+	Reset();
+	iBulkPipeIn.ClearRemoteStall();
+	iBulkPipeOut.ClearRemoteStall();
+	}
+
+
+void CBulkOnlyTransport::SendCbwL(const MClientCommandServiceReq* aReq,
+                                  TBotCbw::TCbwDirection aDirection,
+                                  TUint32 aTransferLength)
+	{
+    __MSFNLOG
+    __BOTPRINT1(_L("Cbw Tag=0x%x"), iCbwTag);
+
+	iCbw.SetTag(iCbwTag++);
+    iCbw.SetDataTransferLength(aTransferLength);
+    iCbw.SetDataTransferDirection(aDirection);
+    iCbw.SetLun(iLun);
+
+    TPtr8 buf = iBulkOutCbwTd.WritableBuffer();
+    iCbw.EncodeL(buf, aReq);
+
+    iBulkOutCbwTd.SaveData(buf.Length());
+    iBulkPipeOut.Transfer(iBulkOutCbwTd, iStatus);
+    User::WaitForRequest(iStatus);
+
+	TInt r = iStatus.Int();
+    if (r != KErrNone)
+        {
+		if (r == KErrUsbStalled)
+            {
+            __BOTPRINT(_L("Cbw: BulkOut stalled"));
+            DoResetRecovery();
+            }
+		__BOTPRINT1(_L("Usb transfer error %d"),r);
+		User::Leave(KErrGeneral);
+        }
+	}
+
+
+void CBulkOnlyTransport::ReceiveCswL()
+	{
+    __MSFNLOG
+	iBulkInCswTd.SaveData(KCswPacketSize);
+	iBulkPipeIn.Transfer(iBulkInCswTd, iStatus);
+	User::WaitForRequest(iStatus);
+
+	TInt r = iStatus.Int();
+	if (r != KErrNone)
+        {
+		if (r == KErrUsbStalled)
+			{
+            __BOTPRINT(_L("Csw: Clearing BulkIn stall"));
+			iBulkPipeIn.ClearRemoteStall();
+			iBulkInCswTd.SaveData(KCswPacketSize);
+			iBulkPipeIn.Transfer(iBulkInCswTd, iStatus);
+			User::WaitForRequest(iStatus);
+#ifdef MASSSTORAGE_PUBLISHER
+            TMsPublisher publisher(TMsPublisher::KStallProperty);
+#endif
+			r = iStatus.Int();
+			if (r == KErrUsbStalled)
+                {
+				__BOTPRINT(_L("Csw: BulkIn stalled"));
+				DoResetRecovery();
+                }
+			}
+		// Handle other usb error and retry failures
+		if (r != KErrNone)
+			{
+			__BOTPRINT1(_L("Usb transfer error %d"), r);
+			User::Leave(KErrGeneral);
+			}
+        }
+
+	TPtrC8 data = iBulkInCswTd.Buffer();
+	r = iCsw.Decode(data);
+    if (r != KErrNone)
+        {
+        __BOTPRINT(_L("Csw: Invalid"));
+        DoResetRecovery();
+        User::Leave(KErrGeneral);
+        }
+	}
+
+
+TInt CBulkOnlyTransport::SendControlCmdL(const MClientCommandServiceReq* aCommand)
+	{
+    __MSFNLOG
+    SendCbwL(aCommand, TBotCbw::EDataOut, 0);
+    ReceiveCswL();
+    return ProcessZeroTransferL();
+	}
+
+
+TInt CBulkOnlyTransport::SendControlCmdL(const MClientCommandServiceReq* aCommand,
+                                         MClientCommandServiceResp* aResp)
+	{
+    __MSFNLOG
+
+	SendCbwL(aCommand, TBotCbw::EDataIn, aResp->DataLength());
+
+	if (aResp->DataLength() > KResponsePacketSize)
+        {
+		__BOTPRINT(_L("Control command response length not supported"));
+		User::Leave(KErrGeneral);
+        }
+
+	iBulkDataTd.SaveData(KResponsePacketSize);
+	iBulkPipeIn.Transfer(iBulkDataTd, iStatus);
+	User::WaitForRequest(iStatus);
+	TInt r = iStatus.Int();
+	if (r != KErrNone)
+        {
+		if (r != KErrUsbStalled)
+			{
+			__BOTPRINT1(_L("Usb transfer error %d"),r);
+			User::Leave(KErrGeneral);
+			}
+		__BOTPRINT(_L("SendControlCmdL ClearRemoteStall"));
+		iBulkPipeIn.ClearRemoteStall();
+        ReceiveCswL();
+        return KErrCommandStalled;        
+        }
+	TPtrC8 data = iBulkDataTd.Buffer();
+
+	ReceiveCswL();
+
+    TUint32 dataReceived = 0;
+	r = ProcessInTransferL(dataReceived);
+    if (!r)
+        {
+
+        if (dataReceived == 0)
+            {
+            __BOTPRINT1(_L("Warning: No data received"), dataReceived);
+            return KErrCommandNotSupported;
+            }
+
+        TRAP(r, aResp->DecodeL(data));
+        }
+	return r;
+	}
+
+
+TInt CBulkOnlyTransport::SendDataRxCmdL(const MClientCommandServiceReq* aCommand,
+                                        TDes8& aCopyBuf,
+                                        TInt& aLen)
+	{
+    __MSFNLOG
+
+	TInt r = KErrNone;
+	SendCbwL(aCommand, TBotCbw::EDataIn, aLen);
+
+    // store initial length as data is appended to the buffer
+    TInt startPos = aCopyBuf.Length();
+
+	TInt len = aLen;
+
+	while (len)
+        {
+		if(len > KResponsePacketSize)
+			iBulkDataTd.SaveData(KResponsePacketSize);
+		else
+			iBulkDataTd.SaveData(len);
+		iBulkPipeIn.Transfer(iBulkDataTd, iStatus);
+		User::WaitForRequest(iStatus);
+
+		r = iStatus.Int();
+		if (r != KErrNone)
+			{
+			if (r == KErrUsbStalled)
+				{
+				__BOTPRINT(_L("SendDataRxCmdL ClearRemoteStall"));
+				iBulkPipeIn.ClearRemoteStall();
+#ifdef MASSSTORAGE_PUBLISHER
+                TMsPublisher publisher(TMsPublisher::KStallProperty);
+#endif
+				break;
+				}
+			DoResetRecovery();
+			__BOTPRINT1(_L("Usb transfer error %d"),r);
+			User::Leave(KErrGeneral);
+			}
+
+		TPtrC8 data = iBulkDataTd.Buffer();
+		aCopyBuf.Append(data.Ptr(), data.Length());
+		if(len > KResponsePacketSize)
+			len -= KResponsePacketSize;
+		else
+			len = 0;
+        }
+
+	ReceiveCswL();
+	TUint32 lenReceived = 0;
+
+	r = ProcessInTransferL(lenReceived);
+    aLen = lenReceived;
+    aCopyBuf.SetLength(startPos + lenReceived);
+
+	return r;
+	}
+
+TInt CBulkOnlyTransport::SendDataTxCmdL(const MClientCommandServiceReq* aCommand,
+                                        TDesC8& aData,
+                                        TUint aPos,
+                                        TInt& aLen)
+	{
+    __MSFNLOG
+   	TInt r = KErrNone;
+
+   	SendCbwL(aCommand, TBotCbw::EDataOut, aLen);
+
+   	TInt len = aLen;
+   	TInt length = 0;
+   	iBulkDataTd.SetZlpStatus(RUsbTransferDescriptor::ESuppressZlp);
+   	while (len)
+        {
+   		TPtr8 senddata = iBulkDataTd.WritableBuffer();
+		senddata.Append(aData.Ptr() + length + aPos, len > KResponsePacketSize? KResponsePacketSize : len);
+
+   		iBulkDataTd.SaveData(senddata.Length());
+   		iBulkPipeOut.Transfer(iBulkDataTd, iStatus);
+   		User::WaitForRequest(iStatus);
+
+		if (iStatus.Int() != KErrNone)
+   			{
+   			if (iStatus.Int() == KErrUsbStalled)
+   				{
+				__BOTPRINT(_L("SendDataTxCmdL ClearRemoteStall"));
+   				iBulkPipeOut.ClearRemoteStall();
+#ifdef MASSSTORAGE_PUBLISHER
+                TMsPublisher publisher(TMsPublisher::KStallProperty);
+#endif
+   				break;
+   				}
+   			DoResetRecovery();
+			__BOTPRINT1(_L("Usb transfer error %d"), r);
+   			User::Leave(KErrGeneral);
+   			}
+
+		if(len > KResponsePacketSize)
+			{
+   			len -= KResponsePacketSize;
+   			length += KResponsePacketSize;
+			}
+		else
+			{
+   			length += len;
+   			len = 0;
+			}
+        }
+
+   	ReceiveCswL();
+
+   	TUint32 lenSent = 0;
+   	r = ProcessOutTransferL(lenSent);
+   	aLen = lenSent;
+
+   	return r;
+	}
+
+
+TInt CBulkOnlyTransport::ProcessZeroTransferL()
+    {
+    __MSFNLOG
+    // process 13 cases
+
+	__ASSERT_DEBUG(iCbw.iDirection == TBotCbw::EDataOut, User::Invariant());
+	__ASSERT_DEBUG(iCbw.iDataTransferLength == 0, User::Invariant());
+
+    // Hn - Host expects no data transfers
+    if (!iCsw.IsValidCsw(iCbw.iTag))
+        {
+        __BOTPRINT(_L("BOT CSW Invalid"));
+        DoResetRecovery();
+		User::Leave(KErrGeneral);
+        }
+    if (!iCsw.IsMeaningfulCsw(iCbw.iDataTransferLength))
+        {
+        __BOTPRINT(_L("BOT CSW not meaningful"));
+        DoResetRecovery();
+		User::Leave(KErrGeneral);
+        }
+
+    if (iCsw.iStatus == TBotCsw::EPhaseError)
+        {
+        // Case (2) or (3)
+        __BOTPRINT(_L("BOT Phase Error"));
+        // Reset Recovery
+        DoResetRecovery();
+		User::Leave(KErrGeneral);
+        }
+
+    if (iCsw.iDataResidue != 0)
+        {
+        // should not happen
+        __BOTPRINT(_L("BOT Residue is invalid!"));
+        // Reset Recovery
+        DoResetRecovery();
+		User::Leave(KErrGeneral);
+        }
+
+    // all ok if here
+    return (iCsw.iStatus == TBotCsw::ECommandPassed) ? KErrNone : KErrCommandFailed;
+    }
+
+
+TInt CBulkOnlyTransport::ProcessInTransferL(TUint32& aDataReceived)
+    {
+    __MSFNLOG
+    aDataReceived = 0;
+    // process 13 cases
+
+	__ASSERT_DEBUG(iCbw.iDirection == TBotCbw::EDataIn, User::Invariant());
+
+    // Hi - Host expects to receive data from the device
+    if (!iCsw.IsValidCsw(iCbw.iTag))
+        {
+        __BOTPRINT(_L("BOT CSW Invalid"));
+        DoResetRecovery();
+        User::Leave(KErrGeneral);
+        }
+    if (!iCsw.IsMeaningfulCsw(iCbw.iDataTransferLength))
+        {
+        __BOTPRINT(_L("BOT CSW not meaningful"));
+        DoResetRecovery();
+        User::Leave(KErrGeneral);
+        }
+
+
+    if (iCsw.iStatus == TBotCsw::EPhaseError)
+        {
+        __BOTPRINT(_L("BOT Phase Error"));
+        // Case (7) or (8)
+        // Reset Recovery
+        DoResetRecovery();
+		User::Leave(KErrGeneral);
+        }
+
+    // all ok if here
+    // Case (4), (5) or (6)
+    aDataReceived = iCbw.iDataTransferLength - iCsw.iDataResidue;
+    return (iCsw.iStatus == TBotCsw::ECommandPassed) ? KErrNone : KErrCommandFailed;
+    }
+
+
+TInt CBulkOnlyTransport::ProcessOutTransferL(TUint32& aDataReceived)
+    {
+    __MSFNLOG
+    aDataReceived = 0;
+    // process 13 cases
+
+	__ASSERT_DEBUG(iCbw.iDirection == TBotCbw::EDataOut, User::Invariant());
+
+    // Ho - Host expects to send data to the device
+    if (!iCsw.IsValidCsw(iCbw.iTag))
+        {
+        __BOTPRINT(_L("BOT CSW Invalid"));
+        DoResetRecovery();
+        User::Leave(KErrGeneral);
+        }
+    if (!iCsw.IsMeaningfulCsw(iCbw.iDataTransferLength))
+        {
+        __BOTPRINT(_L("BOT CSW not meaningful"));
+        DoResetRecovery();
+        User::Leave(KErrGeneral);
+        }
+
+    if (iCsw.iStatus == TBotCsw::EPhaseError)
+        {
+        __BOTPRINT(_L("BOT Phase Error"));
+        // Case (10) or (13)
+        // Reset Recovery
+        DoResetRecovery();
+		User::Leave(KErrGeneral);
+        }
+
+    // all ok if here
+    // Case (9), (11) or (12)
+    aDataReceived = iCbw.iDataTransferLength - iCsw.iDataResidue;
+    return (iCsw.iStatus == TBotCsw::ECommandPassed) ? KErrNone : KErrCommandFailed;
+    }
+
+
+void CBulkOnlyTransport::SetLun(TLun aLun)
+    {
+    __MSFNLOG
+    iLun = aLun;
+    __BOTPRINT1(_L("CBulkOnlyTransport::SetLun(%d)"), aLun)
+    }
+
+
+/**
+Encode CBW into the supplied buffer. The command is also encoded using the
+supplied encoding method of MClientCommandServiceReq.
+
+@param aBuffer The buffer to copy the encoded stream in to
+@param aCommand The command to be encoded into the Command Block field
+*/
+void TBotCbw::EncodeL(TPtr8 &aBuffer, const MClientCommandServiceReq* aCommand) const
+    {
+    __MSFNSLOG
+	aBuffer.SetLength(KCbwLength);
+
+	TPtr8 commandBlock = aBuffer.MidTPtr(TBotCbw::KCbwCbOffset);
+
+	aBuffer.FillZ();
+
+    TInt cbLength = aCommand->EncodeRequestL(commandBlock);
+
+	TUint8* ptr = (TUint8 *) aBuffer.Ptr();
+    LittleEndian::Put32(&ptr[KCbwSignatureOffset], 0x43425355);
+    LittleEndian::Put32(&ptr[KCbwTagOffset], iTag);
+    LittleEndian::Put32(&ptr[KCbwDataTransferLengthOffset], iDataTransferLength);
+    aBuffer[KCbwFlagOffset] = (iDirection == EDataOut) ? 0x00 : 0x80;
+    aBuffer[KCbwLunOffset] = iLun;
+    aBuffer[KCbwCbLengthOffset] = cbLength;
+	__BOTPRINT1(_L("BOT TBotCbw::Encode Lun=%d"), iLun);
+    }
+
+
+/**
+Decode stream into TBotCsw.
+
+@param aPtr A buffer containing CSW stream
+*/
+TInt TBotCsw::Decode(const TDesC8& aPtr)
+    {
+    __MSFNLOG
+    if (aPtr.Length() != KCswLength)
+        {
+		__BOTPRINT1(_L("Invalid CSW length %d"), aPtr.Length());
+        return KErrGeneral;
+        }
+
+    iSignature = LittleEndian::Get32(&aPtr[KCswSignatureOffset]);
+    iTag = LittleEndian::Get32(&aPtr[KCswTagOffset]);
+    iDataResidue = LittleEndian::Get32(&aPtr[KCswDataResidueOffset]);
+
+    TInt status = aPtr[KCswStatusOffset];
+    iStatus = static_cast<TCswStatus>(status);
+    __BOTPRINT1(_L("BOT CSW Status = %d"), iStatus);
+    return KErrNone;
+    }
+
+
+/**
+Checks that CSW contents are valid, USB Mass Storage Class Bulk-Only
+Transport 6.3.
+
+@param aTag The tag value received from the device
+
+@return TBool Return ETrue if valid else EFalse
+*/
+TBool TBotCsw::IsValidCsw(TUint32 aTag) const
+    {
+    __MSFNSLOG
+    if (iSignature != 0x53425355)
+        {
+        return EFalse;
+        }
+    if (iTag != aTag)
+        {
+        return EFalse;
+        }
+    return ETrue;
+    }
+
+
+/**
+Checks that CSW contents are meaningful, USB Mass Storage Class Bulk-Only
+Transport 6.3.
+
+@param aTransferLength Number of bytes transferred
+
+@return TBool Return ETrue if meaningful else EFalse
+*/
+TBool TBotCsw::IsMeaningfulCsw(TUint32 aTransferLength) const
+    {
+    __MSFNSLOG
+    if (iStatus != EPhaseError)
+        {
+        if (iDataResidue > aTransferLength)
+            {
+            return EFalse;
+            }
+        }
+    return ETrue;
+    }
+
+#ifdef MASSSTORAGE_PUBLISHER
+TMsPublisher::TMsPublisher(TPropertyKeys aKey)
+    {
+	RProperty prop;
+
+    const TUid KUidHostMassStorageCategory = {KMyUid};
+
+	TInt ret = prop.Attach(KUidHostMassStorageCategory, aKey);
+    __BOTPRINT2(_L("Property Key[%d] attach ret=%d"), aKey, ret);
+	if (ret == KErrNone)
+        {
+        TInt flag;
+        ret = prop.Get(KUidHostMassStorageCategory, aKey, flag);
+        if (ret == KErrNone)
+            {
+            flag++;
+            ret = prop.Set(KUidHostMassStorageCategory, aKey, flag);
+            }
+	    __BOTPRINT3(_L("Property Set[%d] ret=%d Counter=%d"), aKey, ret, flag);
+		prop.Close();
+        }
+    }
+
+#endif
+