First public contribution.
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Implementation of this File System extension
23 #include "win_drive_ext.h"
26 //#############################################################################
27 //# Proxy drive implementation
28 CWinDrvProxyDrive* CWinDrvProxyDrive::NewL(CProxyDrive* aProxyDrive, CMountCB* aMount)
30 CWinDrvProxyDrive* pSelf = new(ELeave) CWinDrvProxyDrive(aProxyDrive, aMount);
35 CWinDrvProxyDrive::CWinDrvProxyDrive(CProxyDrive* aProxyDrive, CMountCB* aMount)
36 :CBaseExtProxyDrive(aProxyDrive, aMount)
38 ASSERT(aProxyDrive && aMount);
41 iProxyDrive = aProxyDrive;
44 CWinDrvProxyDrive::~CWinDrvProxyDrive()
50 //-----------------------------------------------------------------------------
53 Initialise the proxy drive (this extension)
54 @return standard epoc error code.
56 TInt CWinDrvProxyDrive::Initialise()
58 __PRINT(_L("#-- CWinDrvProxyDriveFactory::Initialise()"));
63 //-- create a scratch buffer
64 nRes = iScratchBuf.CreateMax(65536);
68 //-- create media driver object, at present only generic block media supported
71 const TInt nEpocDrvNum = iMount->DriveNumber();
72 ipMedia = new CGenericBlockMedia(nEpocDrvNum);
77 //-- connect to the media device
78 nRes = ipMedia->Connect();
85 Dismount this extension.
86 @return standard epoc error code.
88 TInt CWinDrvProxyDrive::Dismounted()
90 __PRINT(_L("#-- CWinDrvProxyDriveFactory::Dismounted()"));
92 //-- disconnect from the media driver and delete it
95 ipMedia->Disconnect();
105 //-----------------------------------------------------------------------------
106 TInt CWinDrvProxyDrive::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
110 case ELocalBufferSupport:
114 return CBaseExtProxyDrive::GetInterface(aInterfaceId,aInterface,aInput);
118 //-----------------------------------------------------------------------------
121 Read data from the media.
122 @param aPos media position to start write with.
123 @param aLength number of bytes to read
124 @param destination data descriptor
126 @return standard epoc error code.
128 TInt CWinDrvProxyDrive::Read(TInt64 aPos, TInt aLength, TDes8& aTrg)
130 //__PRINT3(_L("#-- CWinDrvProxyDrive::Read()#0 pos:%LU, desLen:%d, desMaxLen:%d"),aPos, aTrg.Length(), aTrg.MaxLength());
132 if(aTrg.MaxLength() == 0)
133 return KErrNone; //-- nothing to do
136 TInt nRes = ipMedia->Read(aPos, aLength, aTrg);
141 //-- try to find a message slot containing the required address
142 #define GetIndex(msg, aAddress, aIndex) \
143 aIndex = msg.Ptr0() == aAddress ? 0 : \
144 msg.Ptr1() == aAddress ? 1 : \
145 msg.Ptr1() == aAddress ? 2 : \
146 msg.Ptr1() == aAddress ? 3 : -1;
151 Read data from the media.
152 @param aPos media position to start write with.
153 @param aLength number of bytes to be written
154 @param aTrg pointer to the destination data descriptor
155 @param aThreadHandle can specify remote thread where the data will be copied to.
156 @param aOffset an offset within the data descriptor to the real data to be written (see aTrg).
158 @return standard epoc error code.
160 TInt CWinDrvProxyDrive::Read(TInt64 aPos, TInt aLength, const TAny* aTrg, TInt aThreadHandle, TInt aOffset)
162 //__PRINT4(_L("#-- CWinDrvProxyDrive::Read()#1 pos:%LU, offset:%d, desLen:%d, desMaxLen:%d"),aPos, aOffset, desData.Length(), desData.MaxLength());
165 //-- N.B. aTrg is a pointer to the data descriptor TDes8 !
166 TDes8& orgDes = *((TDes8*)aTrg);
169 return KErrNone; //-- nothing to do
172 if(aOffset < 0 || aOffset+aLength > orgDes.MaxLength())
176 //-- check if we have local or remote message from a different process
178 TBool localMessage = (aThreadHandle == KLocalMessageHandle);
181 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle);
182 localMessage = (msg.Handle() == KLocalMessageHandle);
186 {//-- we can just copy data to the descriptor; it is the same process
187 TPtr8 desData((TUint8*)(orgDes.Ptr()+aOffset), orgDes.Length()-aOffset);
188 return ipMedia->Read(aPos, aLength, desData);
191 {//-- we have to read data to the local buffer first and then write to another process
193 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle);
195 GetIndex(msg, aTrg, msgSlotIdx); //-- find out message slot index containing the desctiptor data
200 TInt localOffset = 0;
204 const TInt bytesToRead = Min(rem, iScratchBuf.Size());
205 TPtr8 ptrBuf((TUint8*)iScratchBuf.Ptr(), bytesToRead);
207 //-- read chunk of data from the media to the local buffer
208 TInt nRes = ipMedia->Read(aPos + localOffset, bytesToRead, ptrBuf);
210 return nRes; //-- media read error
212 //-- write data from the local buffer to another process
213 nRes = msg.Write(msgSlotIdx, ptrBuf, aOffset+localOffset);
218 localOffset += bytesToRead;
227 /** the same as above */
228 TInt CWinDrvProxyDrive::Read(TInt64 aPos,TInt aLength, const TAny* aTrg,TInt aThreadHandle, TInt aOffset,TInt /*aFlags*/)
230 //__PRINT4(_L("#-- CWinDrvProxyDrive::Read()#2 pos:%LU, offset:%d, desLen:%d, desMaxLen:%d"),aPos, aOffset, desData.Length(), desData.MaxLength());
231 return Read(aPos, aLength, aTrg, aThreadHandle, aOffset);
235 //-----------------------------------------------------------------------------
238 Write data to the media.
239 @param aPos media position to start write with.
240 @param aSrc data descriptor
242 @return standard epoc error code.
244 TInt CWinDrvProxyDrive::Write(TInt64 aPos, const TDesC8& aSrc)
246 //__PRINT2(_L("#-- CWinDrvProxyDrive::Write()#0 pos:%LU, desLen:%d"),aPos, aSrc.Length());
248 if(aSrc.Length() == 0 )
249 return KErrNone; //-- nothing to do
251 TInt nRes = ipMedia->Write(aPos, aSrc.Size(), aSrc);
257 Write data to the media.
258 @param aPos media position to start write with.
259 @param aLength number of bytes to be written
260 @param aSrc pointer to the data descriptor
261 @param aThreadHandle can specify remote thread where the data will be got from.
262 @param aOffset an offset within the data descriptor to the real data to be written (see aSrc).
264 @return standard epoc error code.
266 TInt CWinDrvProxyDrive::Write(TInt64 aPos, TInt aLength, const TAny* aSrc, TInt aThreadHandle, TInt aOffset)
268 //__PRINT3(_L("#-- CWinDrvProxyDrive::Write()#1 pos:%LU, offset:%d, desLen:%d"),aPos, aOffset, orgDes.Length());
272 TDesC8& orgDes = *((TDesC8*)aSrc);
274 if(orgDes.Length() == 0 || aLength == 0)
275 return KErrNone; //-- nothing to do
277 if(aOffset < 0 || aOffset+aLength > orgDes.Length())
281 //-- check if we have local or remote message from a different process
283 TBool localMessage = (aThreadHandle == KLocalMessageHandle);
286 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle);
287 localMessage = (msg.Handle() == KLocalMessageHandle);
291 {//-- we can just copy data from the descriptor; it is the same process
292 TPtrC8 dataDes(orgDes.Ptr()+aOffset, orgDes.Length()-aOffset);
293 return ipMedia->Write(aPos, aLength, dataDes);
296 {//-- we have to copy data to the local buffer first and then write to the media.
299 RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle);
300 GetIndex(msg, aSrc, msgSlotIdx);
306 TInt localOffset = 0;
310 const TInt bytesToWrite = Min(rem, iScratchBuf.Size());
312 TInt nRes = msg.Read(msgSlotIdx, iScratchBuf, aOffset+localOffset);
316 nRes = ipMedia->Write(aPos+localOffset, bytesToWrite, iScratchBuf);
322 localOffset += bytesToWrite;
332 /** the same as above */
333 TInt CWinDrvProxyDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aThreadHandle, TInt aOffset,TInt /*aFlags*/)
335 //__PRINT3(_L("#-- CWinDrvProxyDrive::Write()#2 pos:%LU, offset:%d, desLen:%d"),aPos, aOffset, orgDes.Length());
336 return Write(aPos, aLength, aSrc, aThreadHandle, aOffset);
340 //-----------------------------------------------------------------------------
343 get drive capabilities
344 @param anInfo packed descriptor of TLocalDriveCaps
345 @return standard Epoc error code
347 TInt CWinDrvProxyDrive::Caps(TDes8& anInfo)
351 //-- get capabilities of the EPOC drive we are overriding
352 nRes = CBaseExtProxyDrive::Caps(anInfo);
356 TLocalDriveCaps& orgCaps = ((TLocalDriveCapsBuf&)anInfo)();
358 //-- override capabilities with the data from our device.
359 ipMedia->GetEpocCaps(orgCaps);
364 //-----------------------------------------------------------------------------
368 This method can be called many times, each call represents the formatting step.
370 @param anInfo specifies the formatting parameters.
371 @return KErrNone if the formatting step has gone OK.
372 KErrEof if the formatting has finished
373 standard epoc error code otherwise.
376 TInt CWinDrvProxyDrive::Format(TFormatInfo& anInfo)
378 return ipMedia->Format(anInfo);
382 format part of the media
383 @param aPos starting media position
384 @param aLength length of the media space to be formatted.
386 @return standard epoc error code
388 TInt CWinDrvProxyDrive::Format(TInt64 aPos, TInt aLength)
390 return ipMedia->Format(aPos, aLength);
394 //-----------------------------------------------------------------------------
397 //#############################################################################
398 //# Extension factory implementation
400 CWinDrvProxyDriveFactory::CWinDrvProxyDriveFactory()
404 TInt CWinDrvProxyDriveFactory::Install()
406 _LIT(KExtensionName,"Win_Drive"); //-- this extensoin name.
408 __PRINT(_L("#-- CWinDrvProxyDriveFactory::Install()"));
409 return(SetName(&KExtensionName));
412 CProxyDrive* CWinDrvProxyDriveFactory::NewProxyDriveL(CProxyDrive* aProxy, CMountCB* aMount)
414 __PRINT(_L("#-- CWinDrvProxyDriveFactory::NewProxyDriveL()"));
415 return (CWinDrvProxyDrive::NewL(aProxy, aMount));
419 /** DLL entrypoint */
422 EXPORT_C CProxyDriveFactory* CreateFileSystem()
424 __PRINT(_L("#-- Win_Drive extension CreateFileSystem()"));
425 return new CWinDrvProxyDriveFactory();