os/boardsupport/emulator/emulatorbsp/win_drive/win_drive_ext.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Implementation of this File System extension
    15 // 
    16 //
    17 
    18 /**
    19  @file
    20 */
    21 
    22 
    23 #include "win_drive_ext.h"
    24 
    25 
    26 //#############################################################################
    27 //# Proxy drive implementation
    28 CWinDrvProxyDrive* CWinDrvProxyDrive::NewL(CProxyDrive* aProxyDrive, CMountCB* aMount)
    29 {
    30     CWinDrvProxyDrive* pSelf = new(ELeave) CWinDrvProxyDrive(aProxyDrive, aMount);
    31     return pSelf;
    32 }
    33 
    34 
    35 CWinDrvProxyDrive::CWinDrvProxyDrive(CProxyDrive* aProxyDrive, CMountCB* aMount)
    36                   :CBaseExtProxyDrive(aProxyDrive, aMount)  
    37 {
    38     ASSERT(aProxyDrive && aMount);
    39 
    40     iMount = aMount;
    41     iProxyDrive = aProxyDrive;
    42 }
    43 
    44 CWinDrvProxyDrive::~CWinDrvProxyDrive()
    45 {
    46     Dismounted();
    47 }
    48 
    49 
    50 //-----------------------------------------------------------------------------
    51 
    52 /** 
    53     Initialise the proxy drive (this extension)
    54     @return standard epoc error code.
    55 */
    56 TInt CWinDrvProxyDrive::Initialise()
    57 {
    58     __PRINT(_L("#-- CWinDrvProxyDriveFactory::Initialise()"));
    59 
    60     TInt nRes;
    61     ASSERT(!ipMedia);
    62 
    63     //-- create a scratch buffer
    64     nRes = iScratchBuf.CreateMax(65536);
    65     if(nRes != KErrNone)
    66         return nRes;
    67 
    68     //-- create media driver object, at present only generic block media supported
    69     if(!ipMedia)
    70     {
    71         const TInt nEpocDrvNum = iMount->DriveNumber();
    72         ipMedia = new CGenericBlockMedia(nEpocDrvNum);
    73         if(!ipMedia)
    74             return KErrNoMemory;
    75     }
    76 
    77     //-- connect to the media device
    78     nRes = ipMedia->Connect();
    79     
    80     return  nRes;
    81 }
    82 
    83 
    84 /**
    85     Dismount this extension.
    86     @return standard epoc error code.
    87 */
    88 TInt CWinDrvProxyDrive::Dismounted()
    89 {
    90     __PRINT(_L("#-- CWinDrvProxyDriveFactory::Dismounted()"));
    91     
    92     //-- disconnect from the media driver and delete it
    93     if(ipMedia)
    94     {
    95         ipMedia->Disconnect();
    96         delete ipMedia;
    97         ipMedia = NULL;
    98     }
    99 
   100     iScratchBuf.Close();
   101 
   102     return KErrNone;
   103 }
   104 
   105 //-----------------------------------------------------------------------------
   106 TInt CWinDrvProxyDrive::GetInterface(TInt aInterfaceId,TAny*& aInterface,TAny* aInput)
   107 {
   108 	switch(aInterfaceId)
   109 		{
   110 		case ELocalBufferSupport:
   111 			return KErrNone;
   112 
   113 		default:
   114 			return CBaseExtProxyDrive::GetInterface(aInterfaceId,aInterface,aInput);
   115 		}
   116 }
   117 
   118 //-----------------------------------------------------------------------------
   119 
   120 /**
   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
   125 
   126     @return standard epoc error code.
   127 */
   128 TInt CWinDrvProxyDrive::Read(TInt64 aPos, TInt aLength, TDes8& aTrg)
   129 {
   130     //__PRINT3(_L("#-- CWinDrvProxyDrive::Read()#0 pos:%LU, desLen:%d, desMaxLen:%d"),aPos, aTrg.Length(), aTrg.MaxLength());
   131 
   132     if(aTrg.MaxLength() == 0)
   133         return KErrNone; //-- nothing to do
   134     
   135     aTrg.SetLength(0);
   136     TInt nRes = ipMedia->Read(aPos, aLength, aTrg);
   137     return nRes;
   138 }
   139 
   140 
   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;
   147 
   148 
   149 
   150 /**
   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).
   157     
   158     @return standard epoc error code.
   159 */
   160 TInt CWinDrvProxyDrive::Read(TInt64 aPos, TInt aLength, const TAny* aTrg, TInt aThreadHandle, TInt aOffset)
   161 {
   162     //__PRINT4(_L("#-- CWinDrvProxyDrive::Read()#1 pos:%LU, offset:%d, desLen:%d, desMaxLen:%d"),aPos, aOffset, desData.Length(), desData.MaxLength());
   163     ASSERT(aTrg);
   164 
   165     //-- N.B. aTrg is a pointer to the data descriptor TDes8 !
   166     TDes8& orgDes = *((TDes8*)aTrg);
   167 
   168     if(aLength == 0)
   169         return KErrNone; //-- nothing to do
   170 
   171 
   172     if(aOffset < 0 || aOffset+aLength > orgDes.MaxLength())
   173         return KErrArgument; 
   174 
   175     
   176     //-- check if we have local or remote message from a different process
   177     
   178     TBool localMessage = (aThreadHandle == KLocalMessageHandle);
   179 	if(!localMessage)
   180 	{
   181 		RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle);
   182 		localMessage = (msg.Handle() == KLocalMessageHandle);
   183 	}
   184 
   185     if(localMessage)
   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);
   189     }
   190     else
   191     {//-- we have to read data to the local buffer first and then write to another process 
   192         TInt  msgSlotIdx = 0;
   193         RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle);
   194 
   195 		GetIndex(msg, aTrg, msgSlotIdx); //-- find out message slot index containing the desctiptor data
   196 		if (msgSlotIdx < 0)
   197 			return KErrArgument;
   198    
   199         TInt  rem = aLength;
   200         TInt  localOffset = 0;
   201         
   202         while(rem)
   203         {
   204             const TInt bytesToRead = Min(rem, iScratchBuf.Size());
   205             TPtr8 ptrBuf((TUint8*)iScratchBuf.Ptr(), bytesToRead);
   206 
   207             //-- read chunk of data from the media to the local buffer
   208             TInt nRes = ipMedia->Read(aPos + localOffset, bytesToRead, ptrBuf);
   209             if(nRes != KErrNone)
   210                 return nRes; //-- media read error
   211 
   212             //-- write data from the local buffer to another process
   213             nRes = msg.Write(msgSlotIdx, ptrBuf, aOffset+localOffset);
   214             if(nRes != KErrNone)
   215                 return nRes; 
   216 
   217             rem -= bytesToRead;
   218             localOffset += bytesToRead;
   219         }
   220     
   221         return KErrNone;
   222     }
   223     
   224     
   225 }
   226 
   227 /** the same as above */
   228 TInt CWinDrvProxyDrive::Read(TInt64 aPos,TInt aLength, const TAny* aTrg,TInt aThreadHandle, TInt aOffset,TInt /*aFlags*/)
   229 {
   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);
   232 }
   233 
   234 
   235 //-----------------------------------------------------------------------------
   236 
   237 /**
   238     Write data to the media.
   239     @param  aPos    media position to start write with.
   240     @param  aSrc    data descriptor
   241 
   242     @return standard epoc error code.
   243 */
   244 TInt CWinDrvProxyDrive::Write(TInt64 aPos, const TDesC8& aSrc)
   245 {
   246     //__PRINT2(_L("#-- CWinDrvProxyDrive::Write()#0 pos:%LU, desLen:%d"),aPos, aSrc.Length());
   247 
   248     if(aSrc.Length() == 0 )
   249         return KErrNone; //-- nothing to do
   250 
   251     TInt nRes = ipMedia->Write(aPos, aSrc.Size(), aSrc);
   252 
   253     return nRes;
   254 }
   255 
   256 /**
   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).
   263     
   264     @return standard epoc error code.
   265 */
   266 TInt CWinDrvProxyDrive::Write(TInt64 aPos, TInt aLength, const TAny* aSrc, TInt aThreadHandle, TInt aOffset)
   267 {
   268     //__PRINT3(_L("#-- CWinDrvProxyDrive::Write()#1 pos:%LU, offset:%d, desLen:%d"),aPos, aOffset, orgDes.Length());
   269     
   270     ASSERT(aSrc);
   271         
   272     TDesC8& orgDes = *((TDesC8*)aSrc);
   273 
   274     if(orgDes.Length() == 0 || aLength == 0)
   275         return KErrNone; //-- nothing to do
   276 
   277     if(aOffset < 0 || aOffset+aLength > orgDes.Length())
   278         return KErrArgument; 
   279     
   280    
   281     //-- check if we have local or remote message from a different process
   282     
   283     TBool localMessage = (aThreadHandle == KLocalMessageHandle);
   284 	if(!localMessage)
   285 	{
   286 		RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle);
   287 		localMessage = (msg.Handle() == KLocalMessageHandle);
   288 	}
   289 
   290     if(localMessage)
   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);
   294 }
   295     else
   296     {//-- we have to copy data to the local buffer first and then write to the media.
   297         TInt  msgSlotIdx = 0;
   298         
   299         RMessage2 msg(*(RMessagePtr2 *) &aThreadHandle);
   300 		GetIndex(msg, aSrc, msgSlotIdx);
   301 
   302 		if (msgSlotIdx < 0)
   303 			return KErrArgument;
   304 
   305         TInt  rem = aLength;
   306         TInt  localOffset = 0;
   307 
   308         while(rem)
   309         {
   310             const TInt bytesToWrite = Min(rem, iScratchBuf.Size());
   311             
   312             TInt nRes = msg.Read(msgSlotIdx, iScratchBuf, aOffset+localOffset);
   313             if(nRes != KErrNone)
   314                 return nRes; 
   315 
   316             nRes = ipMedia->Write(aPos+localOffset, bytesToWrite, iScratchBuf);
   317             if(nRes != KErrNone)
   318                 return nRes; 
   319 
   320 
   321             rem -= bytesToWrite;
   322             localOffset += bytesToWrite;
   323         }
   324     
   325         return KErrNone;
   326     }
   327    
   328 }
   329 
   330 
   331 
   332 /** the same as above */
   333 TInt CWinDrvProxyDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aThreadHandle, TInt aOffset,TInt /*aFlags*/)
   334 {
   335     //__PRINT3(_L("#-- CWinDrvProxyDrive::Write()#2 pos:%LU, offset:%d, desLen:%d"),aPos, aOffset, orgDes.Length());
   336     return Write(aPos, aLength, aSrc, aThreadHandle, aOffset);
   337 }
   338 
   339 
   340 //-----------------------------------------------------------------------------
   341 
   342 /** 
   343     get drive capabilities 
   344     @param anInfo packed descriptor of TLocalDriveCaps
   345     @return standard Epoc error code
   346 */
   347 TInt CWinDrvProxyDrive::Caps(TDes8& anInfo)
   348 {
   349     TInt nRes;
   350     
   351     //-- get capabilities of the EPOC drive we are overriding
   352     nRes = CBaseExtProxyDrive::Caps(anInfo);
   353     if(nRes != KErrNone)
   354         return nRes;
   355 
   356     TLocalDriveCaps& orgCaps = ((TLocalDriveCapsBuf&)anInfo)();
   357 
   358     //-- override capabilities with the data from our device.
   359     ipMedia->GetEpocCaps(orgCaps);
   360     
   361     return KErrNone;
   362 }
   363 
   364 //-----------------------------------------------------------------------------
   365 
   366 /** 
   367     Format whole media.
   368     This method can be called many times, each call represents the formatting step.
   369 
   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.
   374 
   375 */
   376 TInt CWinDrvProxyDrive::Format(TFormatInfo& anInfo)
   377 {
   378     return ipMedia->Format(anInfo);
   379 }
   380 
   381 /** 
   382     format part of the media 
   383     @param  aPos    starting media position
   384     @param  aLength length of the media space to be formatted.
   385 
   386     @return standard epoc error code
   387 */
   388 TInt CWinDrvProxyDrive::Format(TInt64 aPos, TInt aLength)
   389 {
   390     return ipMedia->Format(aPos, aLength);
   391 }
   392 
   393 
   394 //-----------------------------------------------------------------------------
   395 
   396 
   397 //#############################################################################
   398 //# Extension factory implementation
   399 
   400 CWinDrvProxyDriveFactory::CWinDrvProxyDriveFactory()
   401 {
   402 }
   403 
   404 TInt CWinDrvProxyDriveFactory::Install()
   405 {
   406     _LIT(KExtensionName,"Win_Drive"); //-- this extensoin name.
   407 
   408     __PRINT(_L("#-- CWinDrvProxyDriveFactory::Install()"));
   409     return(SetName(&KExtensionName));
   410 }
   411 
   412 CProxyDrive* CWinDrvProxyDriveFactory::NewProxyDriveL(CProxyDrive* aProxy, CMountCB* aMount)
   413 {
   414     __PRINT(_L("#-- CWinDrvProxyDriveFactory::NewProxyDriveL()"));
   415     return (CWinDrvProxyDrive::NewL(aProxy, aMount));
   416 }
   417 
   418 
   419 /** DLL entrypoint */
   420 extern "C" 
   421 {
   422     EXPORT_C CProxyDriveFactory* CreateFileSystem()
   423     {
   424         __PRINT(_L("#-- Win_Drive extension CreateFileSystem()"));
   425         return new CWinDrvProxyDriveFactory();
   426     }
   427 }
   428 
   429 
   430 
   431 
   432 
   433 
   434 
   435 
   436 
   437 
   438 
   439 
   440 
   441 
   442 
   443 
   444 
   445 
   446 
   447