os/boardsupport/emulator/emulatorbsp/win_drive/generic_block_media.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 // Implementaion of the media abstraction classs.
    15 // 
    16 //
    17 
    18 /**
    19  @file
    20 */
    21 
    22 #include "win_media.h"
    23 #include "win_media_device.h"
    24 
    25 
    26 //#########################################################################################################################
    27 //##        CMediaBase abstract base class implementation
    28 //#########################################################################################################################
    29 
    30 
    31 CMediaBase::CMediaBase(TInt aEpocDrvNumber)
    32            :iEpocDrvNumber((TDriveNumber)aEpocDrvNumber), iReadOnly(0), ipDevice(NULL)
    33 {
    34     ASSERT(iEpocDrvNumber >= EDriveA && iEpocDrvNumber <= EDriveZ);
    35     ipSettingsManager = NULL;
    36 }
    37 
    38 CMediaBase::~CMediaBase()
    39 {
    40     Disconnect();    
    41     delete ipDevice;
    42     delete ipSettingsManager;
    43 }
    44 
    45 /**
    46     This method is called in order to disconnect from the media (on dismount)
    47 */
    48 void CMediaBase::Disconnect()
    49 {
    50     if(ipDevice)
    51         ipDevice->Disconnect();
    52 }
    53 
    54 //-----------------------------------------------------------------------------
    55 /**
    56     Get EPOC-style drive capabilities
    57     @param aCaps - some fields of this structure will be filled with the information from the WinMediaDevice
    58     @return standard EPOC code
    59 */
    60 TInt CMediaBase::GetEpocCaps(TLocalDriveCaps& aCaps)
    61 {
    62     //-- get real drive geometry from the windows device we are using and 
    63     //-- override the native media driver's data
    64     TDriveGeometry dg;
    65     ipDevice->GetDriveGeometry(dg);
    66     aCaps.iSize = dg.TotalSizeInBytes();
    67 
    68     //-- here we can also override other information, like drive and media attributes etc..
    69 
    70     //-- media type
    71     TUint32 val = ipSettingsManager->TMediaType_Override();
    72     if(val)
    73         aCaps.iType = (TMediaType)val;
    74          
    75     //-- media attributes
    76     TUint32 andMask, orMask;
    77     ipSettingsManager->MediaAtt_OverrideMasks(andMask, orMask);
    78     aCaps.iMediaAtt &= andMask;
    79     aCaps.iMediaAtt |= orMask;
    80 
    81     //-- drive attributes
    82     ipSettingsManager->DriveAtt_OverrideMasks(andMask, orMask);
    83     aCaps.iDriveAtt &= andMask;
    84     aCaps.iDriveAtt |= orMask;
    85 
    86     return KErrNone;
    87 }
    88 
    89 //#########################################################################################################################
    90 //##        CGenericBlockMedia class implementation
    91 //#########################################################################################################################
    92 
    93 
    94 
    95 CGenericBlockMedia::CGenericBlockMedia(TInt aEpocDrvNumber)
    96                    :CMediaBase(aEpocDrvNumber)
    97 {
    98 }
    99 
   100 CGenericBlockMedia::~CGenericBlockMedia()
   101 {
   102 }
   103 
   104 //-----------------------------------------------------------------------------
   105 
   106 /**
   107     Connect to the media, i.e. do mounting job. 
   108     Read settings from the ini file, instantiate "windows device" class..
   109 */    
   110 TInt CGenericBlockMedia::Connect()
   111 {
   112     __LOG1(_L("#-- CGenericBlockMedia::Connect(), epocDrv:%d"), iEpocDrvNumber);
   113 
   114     if(ipDevice)
   115     {
   116         ASSERT(0);
   117         return KErrInUse;
   118     }
   119 
   120     //-- initialise an object to work with settings from ini file
   121     if(!ipSettingsManager)
   122     {
   123         ipSettingsManager = TSettingsManager::Create(iEpocDrvNumber);
   124         if(!ipSettingsManager)
   125         {
   126             __LOG(_L("#-- Can not create TSettingsManager!"));
   127             return KErrGeneral;
   128         }
   129     }
   130 
   131 
   132     //-- 1. obtain and process windows device name
   133     char szDevName[KMaxFileName];
   134     Settings().WinDeviceName(szDevName, sizeof(szDevName));
   135     
   136     if(strlen(szDevName) < 4)
   137     {
   138         __LOG(_L("#-- CGenericBlockMedia::Connect() Bad device name!"));
   139         __LOGF(szDevName);
   140         return KErrBadName;
   141     }
   142 
   143     //-- 1.1 find out if it is the physical volume or image file
   144     TBool bImageFile = ETrue;
   145     const char szDevPrefix[] = "\\\\.\\";
   146     if( memcmp(szDevName, szDevPrefix, strlen(szDevPrefix)) == 0)
   147     {//-- this is a physical device
   148         bImageFile = EFalse;    
   149     }
   150 
   151     
   152     //-- 2. instantinate an interface to the Windows media device
   153     TInt nRes;
   154 
   155     if(bImageFile)
   156     {//-- device name corresponds to the image file
   157         ipDevice = new CWinImgFileDevice;
   158     }
   159     else
   160     {//-- device name corresponds to the physical volume file
   161         ipDevice = new CWinVolumeDevice;
   162     }
   163     
   164     ASSERT(ipDevice);
   165 
   166 
   167     //-- 3. other parameters
   168     iReadOnly = Settings().IsReadOnly();
   169 
   170     //-- set and validate parameters
   171     TMediaDeviceParams connectParams;
   172     
   173     const TUint32 bps = Settings().MediaSectorSize();
   174     if(bps > 0) 
   175     {//-- some value is provided in the ini file.
   176         if(!IsPowerOf2(bps) ||  bps < KDefaultSectorSz || bps > 4096)
   177         {
   178         __LOG1(_L("#-- 'BytesPerSector' value is incorrect! :%d"), bps);
   179         return KErrArgument;
   180         }
   181     }
   182 
   183     connectParams.iDrvGeometry.iBytesPerSector = bps;
   184     
   185     //-- !!! chech size here!!
   186     connectParams.iDrvGeometry.iSizeInSectors  = Settings().MediaSizeInSectors();
   187     connectParams.ipDevName = szDevName;
   188     connectParams.iReadOnly = iReadOnly;
   189     
   190     //-- connect to the device driver
   191     nRes = ipDevice->Connect(connectParams);
   192     
   193 
   194     return nRes;
   195     
   196 }
   197 
   198 //-----------------------------------------------------------------------------
   199 /**
   200     Disconnect from the media, dismounting.
   201 */
   202 void CGenericBlockMedia::Disconnect()
   203 {
   204     __PRINT1(_L("#-- CGenericBlockMedia::Disconnect(), epocDrv:%d"), iEpocDrvNumber);
   205     ASSERT(ipDevice);
   206     CMediaBase::Disconnect();
   207 }
   208 
   209 //-----------------------------------------------------------------------------
   210 /**
   211     Read from the media. See corresponding CWinDrvProxyDrive:: method
   212 */
   213 TInt CGenericBlockMedia::Read(TInt64 aPos, TInt aLength, TDes8& aDataDes)
   214 {
   215     //__PRINT3(_L("#-- CGenericBlockMedia::Read(), epocDrv:%d, pos:%LU, len:%u"), iEpocDrvNumber, aPos, aLength);
   216     ASSERT(ipDevice);
   217     return ipDevice->Read(aPos, aLength, aDataDes);
   218 }
   219 
   220 //-----------------------------------------------------------------------------
   221 
   222 /**
   223     Write to the media. See corresponding CWinDrvProxyDrive:: method
   224 */
   225 TInt CGenericBlockMedia::Write(TInt64 aPos,TInt aLength, const TDesC8& aDataDes)
   226 {
   227     //__PRINT3(_L("#-- CGenericBlockMedia::Write(), epocDrv:%d, pos:%LU, len:%u"), iEpocDrvNumber, aPos, aLength);
   228 
   229     ASSERT(ipDevice);
   230 
   231     if(iReadOnly)
   232         return KErrAccessDenied;
   233 
   234     return ipDevice->Write(aPos, aLength, aDataDes);
   235 }
   236 
   237 
   238 //-----------------------------------------------------------------------------
   239 
   240 /**
   241     Format the media. 
   242     For "formatting" called CWinMediaDeviceBase::Erase(...) method that fills required media region with zeroes (see its implementation).
   243     As soon as the number of erased sectors becomes >= max. number of sectors on this media, KErrEof is reurned indicationg the last
   244     formatting step done.
   245 */
   246 TInt CGenericBlockMedia::Format(TFormatInfo& anInfo)
   247 {
   248     if(iReadOnly)
   249         return KErrAccessDenied;
   250 
   251     TInt nRes;
   252 
   253     const TUint32 KMaxFmtSteps = 100; //-- max. number of formatting steps.
   254 
   255     TDriveGeometry dg;
   256     ipDevice->GetDriveGeometry(dg);
   257     const TUint32 KFmtSectors = (dg.iSizeInSectors + (KMaxFmtSteps-1))/ KMaxFmtSteps; //-- how many sectors format during one step
   258 
   259     if(anInfo.iFormatIsCurrent == 0)
   260     {//-- this is a first entry, prepare format data
   261         iSectorsFormatted = 0;
   262         anInfo.iFormatIsCurrent = 1;
   263     }
   264     
   265     //-- erase block of the media 
   266     TUint32 sectorsToErase = KFmtSectors;
   267     if(iSectorsFormatted+KFmtSectors > dg.iSizeInSectors)
   268     {
   269         sectorsToErase -= (iSectorsFormatted+KFmtSectors-dg.iSizeInSectors);
   270     }
   271 
   272     nRes = ipDevice->Erase(iSectorsFormatted*dg.iBytesPerSector, sectorsToErase*dg.iBytesPerSector, 0);
   273     
   274     if(nRes != KErrNone)
   275     {
   276         ASSERT(0);
   277         return nRes;
   278     }
   279 
   280     iSectorsFormatted+=KFmtSectors;
   281     anInfo.i512ByteSectorsFormatted = iSectorsFormatted;
   282 
   283     if(iSectorsFormatted >= dg.iSizeInSectors)
   284         return KErrEof; //-- formatted has finished
   285 
   286     return KErrNone;
   287 
   288 }
   289 
   290 
   291 //-----------------------------------------------------------------------------
   292 
   293 /**
   294     "format" the specified region on the media. See corresponding CWinDrvProxyDrive:: method.
   295 */
   296 TInt CGenericBlockMedia::Format(TInt64 aPos, TInt aLength)
   297 {
   298     TInt nRes = ipDevice->Erase(aPos, aLength, 0);
   299     
   300     return nRes; //-- shall it be KErrEof ?
   301 }
   302 
   303 
   304 
   305 
   306 
   307 
   308 
   309 
   310 
   311 
   312 
   313 
   314 
   315 
   316 
   317 
   318 
   319 
   320 
   321 
   322 
   323 
   324 
   325