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