1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/f32test/ext/t_rawext.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,771 @@
1.4 +/*
1.5 +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +//
1.21 +// RAWEXT.CPP
1.22 +//
1.23 +// This file system extension provides a way to access a drive on the local windows system in "raw format".
1.24 +// It can be used to test large files / drives
1.25 +//
1.26 +// NB This should be used WITH CARE to avoid unintentionally overwriting or formatting a windows disk
1.27 +//
1.28 +
1.29 +#include <f32fsys.h>
1.30 +
1.31 +#include <emulator.h>
1.32 +
1.33 +#include <windows.h>
1.34 +
1.35 +#define WIN32_LEAN_AND_MEAN
1.36 +#pragma warning (disable:4201) // warning C4201: nonstandard extension used : nameless struct/union
1.37 +
1.38 +#include <winioctl.h>
1.39 +
1.40 +// Enable this macro to find the last REMOVABLE drive (e.g. a card reader drive)
1.41 +// (to minimise the chance of doing any damage !
1.42 +// Doesn't even try any drive letters below E (again for safety):
1.43 +#define __LOOK_FOR_DRIVE__
1.44 +
1.45 +// Otherwise the windows drive letter can be hard-coded here:
1.46 +#ifndef __LOOK_FOR_DRIVE__
1.47 + char diskName[] = "\\\\.\\Y:";
1.48 +#endif
1.49 +
1.50 +
1.51 +const TInt KSectorSize = 512;
1.52 +
1.53 +class CRawWinDiskExtProxyDrive : public CBaseExtProxyDrive
1.54 + {
1.55 +public:
1.56 + static CRawWinDiskExtProxyDrive* NewL(CProxyDrive* aProxyDrive, CMountCB* aMount);
1.57 + ~CRawWinDiskExtProxyDrive();
1.58 +public:
1.59 + virtual TInt Initialise();
1.60 + virtual TInt Dismounted();
1.61 + virtual TInt Enlarge(TInt aLength);
1.62 + virtual TInt ReduceSize(TInt aPos, TInt aLength);
1.63 + virtual TInt Read(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt aThreadHandle,TInt anOffset);
1.64 + virtual TInt Read(TInt64 aPos,TInt aLength,TDes8& aTrg);
1.65 + virtual TInt Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aThreadHandle,TInt anOffset);
1.66 + virtual TInt Write(TInt64 aPos,const TDesC8& aSrc);
1.67 + virtual TInt Caps(TDes8& anInfo);
1.68 + virtual TInt Format(TFormatInfo& anInfo);
1.69 +private:
1.70 + CRawWinDiskExtProxyDrive(CProxyDrive* aProxyDrive, CMountCB* aMount);
1.71 +private:
1.72 + HANDLE iDeviceHandle;
1.73 + };
1.74 +
1.75 +class CRawWinDiskProxyDriveFactory : public CProxyDriveFactory
1.76 + {
1.77 +public:
1.78 + CRawWinDiskProxyDriveFactory();
1.79 + virtual TInt Install();
1.80 + virtual CProxyDrive* NewProxyDriveL(CProxyDrive* aProxy,CMountCB* aMount);
1.81 + };
1.82 +
1.83 +
1.84 +
1.85 +CRawWinDiskExtProxyDrive* CRawWinDiskExtProxyDrive::NewL(CProxyDrive* aProxyDrive, CMountCB* aMount)
1.86 +//
1.87 +//
1.88 +//
1.89 + {
1.90 + CRawWinDiskExtProxyDrive* temp=new(ELeave) CRawWinDiskExtProxyDrive(aProxyDrive,aMount);
1.91 + return(temp);
1.92 + }
1.93 +
1.94 +
1.95 +CRawWinDiskExtProxyDrive::CRawWinDiskExtProxyDrive(CProxyDrive* aProxyDrive, CMountCB* aMount):CBaseExtProxyDrive(aProxyDrive,aMount)
1.96 + {
1.97 + RDebug::Print(_L("CRawWinDiskExtProxyDrive::CRawWinDiskExtProxyDrive"));
1.98 + }
1.99 +
1.100 +CRawWinDiskExtProxyDrive::~CRawWinDiskExtProxyDrive()
1.101 +//
1.102 +//
1.103 +//
1.104 + {
1.105 + CloseHandle(iDeviceHandle);
1.106 + }
1.107 +
1.108 +TInt CRawWinDiskExtProxyDrive::Initialise()
1.109 +//
1.110 +//
1.111 +//
1.112 + {
1.113 + RDebug::Print(_L("CRawWinDiskExtProxyDrive::Initialise()"));
1.114 +
1.115 +
1.116 +#ifdef __LOOK_FOR_DRIVE__
1.117 + // Find the last REMOVABLE drive (to minimise the chance of doing any damage !
1.118 + // Don't even try any drive letters below E (agai for safety):
1.119 + char diskName[] = "\\\\.\\?:";
1.120 + char driveLetter;
1.121 + for (driveLetter = 'Z'; driveLetter > 'D'; driveLetter--)
1.122 + {
1.123 + diskName[4] = driveLetter;
1.124 +
1.125 + DISK_GEOMETRY geometry;
1.126 + DWORD dummy;
1.127 +
1.128 + iDeviceHandle = CreateFileA(diskName,
1.129 + GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
1.130 + NULL, OPEN_EXISTING, 0, NULL);
1.131 +
1.132 + if (iDeviceHandle == INVALID_HANDLE_VALUE)
1.133 + {
1.134 + continue;
1.135 + }
1.136 +
1.137 + if(DeviceIoControl(iDeviceHandle,
1.138 + IOCTL_DISK_GET_DRIVE_GEOMETRY,
1.139 + NULL,
1.140 + 0,
1.141 + &geometry,
1.142 + sizeof(geometry),
1.143 + &dummy,
1.144 + (LPOVERLAPPED)NULL))
1.145 + {
1.146 + RDebug::Print(_L("Drive %c MediaType %d removable %s"),
1.147 + driveLetter,
1.148 + geometry.MediaType,
1.149 + geometry.MediaType==RemovableMedia ? _S16("True") : _S16("False"));
1.150 +
1.151 + }
1.152 +
1.153 + CloseHandle(iDeviceHandle);
1.154 + if (geometry.MediaType==RemovableMedia)
1.155 + break;
1.156 + }
1.157 + if (driveLetter == 'D')
1.158 + return KErrNotFound;
1.159 +#endif
1.160 +
1.161 + // Creating a handle to drive a: using CreateFile () function ..
1.162 + TPtrC8 diskName8((const TUint8*) diskName);
1.163 + TBuf16<16> diskName16;
1.164 + diskName16.Copy(diskName8);
1.165 + RDebug::Print(_L("RAWEXT: Opening drive %S"), &diskName16);
1.166 +
1.167 + iDeviceHandle = CreateFileA(
1.168 +// "\\\\.\\H:",
1.169 + diskName,
1.170 + GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
1.171 + NULL, OPEN_EXISTING, 0, NULL);
1.172 +
1.173 + if (iDeviceHandle == INVALID_HANDLE_VALUE)
1.174 + {
1.175 + return Emulator::LastError();
1.176 + }
1.177 +
1.178 + return KErrNone;
1.179 + }
1.180 +
1.181 +TInt CRawWinDiskExtProxyDrive::Dismounted()
1.182 +//
1.183 +//
1.184 +//
1.185 + {
1.186 + RDebug::Print(_L("CRawWinDiskExtProxyDrive::Dismounted()"));
1.187 + return(KErrNone);
1.188 + }
1.189 +
1.190 +TInt CRawWinDiskExtProxyDrive::Enlarge(TInt /*aLength*/)
1.191 +//
1.192 +//
1.193 +//
1.194 + {
1.195 + return(KErrNotSupported);
1.196 + }
1.197 +
1.198 +
1.199 +TInt CRawWinDiskExtProxyDrive::ReduceSize(TInt /*aPos*/, TInt /*aLength*/)
1.200 +//
1.201 +//
1.202 +//
1.203 + {
1.204 + return(KErrNotSupported);
1.205 + }
1.206 +
1.207 +LOCAL_C TInt ParameterNum(const TInt aMessageHandle, const TAny* aAddress)
1.208 + {
1.209 + RMessage2 tmpMessage(*(RMessagePtr2 *) &aMessageHandle);
1.210 +
1.211 + if (tmpMessage.Ptr0() == aAddress)
1.212 + {
1.213 + return 0;
1.214 + }
1.215 + if (tmpMessage.Ptr1() == aAddress)
1.216 + {
1.217 + return 1;
1.218 + }
1.219 + if (tmpMessage.Ptr2() == aAddress)
1.220 + {
1.221 + return 2;
1.222 + }
1.223 + if (tmpMessage.Ptr3() == aAddress)
1.224 + {
1.225 + return 3;
1.226 + }
1.227 + User::Panic(_L("RAWEXT"),KErrBadHandle);
1.228 + return -1;
1.229 + }
1.230 +
1.231 +
1.232 +
1.233 +TInt CRawWinDiskExtProxyDrive::Read(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt aThreadHandle,TInt aOffset)
1.234 +//
1.235 +//
1.236 +//
1.237 + {
1.238 +
1.239 + //
1.240 + // Set file position to where we want to read...
1.241 + //
1.242 + LARGE_INTEGER li;
1.243 + li.QuadPart = aPos;
1.244 +
1.245 + long posH = I64HIGH(aPos);
1.246 + long posL = I64LOW(aPos);
1.247 +
1.248 + TInt off = posL & 0x1FF;
1.249 + posL &= ~0x1FF;
1.250 +
1.251 + if(SetFilePointer (iDeviceHandle, posL, &posH, FILE_BEGIN) == 0xFFFFFFFF)
1.252 + {
1.253 + return Emulator::LastError();
1.254 + }
1.255 +
1.256 + const TInt KLocalBufferSize = 256*1024;
1.257 + char buffer[KLocalBufferSize];
1.258 +
1.259 + const TInt param = ParameterNum(aThreadHandle, aTrg);
1.260 +
1.261 + TInt totalBytesRead = 0;
1.262 +
1.263 + //
1.264 + // Read first sector if start of data is offset from 512 bytes...
1.265 + //
1.266 + if(off)
1.267 + {
1.268 + // read 1st sector if offset
1.269 + DWORD bytesRead;
1.270 + if (!ReadFile (iDeviceHandle, buffer, KSectorSize, &bytesRead, NULL) )
1.271 + {
1.272 + return Emulator::LastError();
1.273 + }
1.274 +
1.275 + if(bytesRead != KSectorSize)
1.276 + {
1.277 + return KErrNotReady;
1.278 + }
1.279 +
1.280 + bytesRead-= off;
1.281 + TInt copyLen = Min(aLength, bytesRead);;
1.282 +
1.283 + totalBytesRead += copyLen;
1.284 + aLength -= copyLen;
1.285 +
1.286 + TPtrC8 des((TUint8*) buffer+off, copyLen);
1.287 + ((RMessagePtr2 *) &aThreadHandle)->Write(param, des, aOffset);
1.288 + }
1.289 +
1.290 + //
1.291 + // Read the remainder of the data, accounting for partial last sector...
1.292 + //
1.293 + while(aLength > 0)
1.294 + {
1.295 + TUint32 bytesThisTime = min(KLocalBufferSize, (TUint32)aLength);
1.296 +
1.297 + bytesThisTime = (bytesThisTime + KSectorSize-1) & ~(KSectorSize-1);
1.298 +
1.299 + DWORD bytesread;
1.300 + if (!ReadFile (iDeviceHandle, buffer, bytesThisTime, &bytesread, NULL) )
1.301 + {
1.302 + return Emulator::LastError();
1.303 + }
1.304 +
1.305 + if(bytesread != (TUint32)bytesThisTime)
1.306 + {
1.307 + return KErrNotReady;
1.308 + }
1.309 +
1.310 + TPtrC8 des((TUint8*)buffer, min((TUint32)aLength, bytesThisTime));
1.311 + ((RMessagePtr2 *) &aThreadHandle)->Write(param, des, aOffset + totalBytesRead);
1.312 + totalBytesRead += bytesThisTime;
1.313 + aLength -= bytesThisTime;
1.314 + }
1.315 +
1.316 + return KErrNone;
1.317 + }
1.318 +
1.319 +//////
1.320 +
1.321 +GLDEF_C void DumpBuffer( const TDesC8& aBuffer )
1.322 + /**
1.323 + * Dump the content of aBuffer in hex
1.324 + */
1.325 + {
1.326 + static const TText hextab[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
1.327 + 'A', 'B', 'C', 'D', 'E', 'F' };
1.328 + const TInt KBytesPerLine = 32;
1.329 + const TInt KCharsPerLine = KBytesPerLine * 2;
1.330 +
1.331 + TInt remaining = aBuffer.Length();
1.332 + TUint8* pSrc = const_cast<TUint8*>(aBuffer.Ptr());
1.333 +
1.334 + TBuf<KCharsPerLine> line;
1.335 + line.SetLength( KCharsPerLine ); // don't need to print trailing space
1.336 + TInt bytesPerLine = KBytesPerLine;
1.337 + TInt lineOffs = 0;
1.338 + while( remaining )
1.339 + {
1.340 + if( remaining < KBytesPerLine )
1.341 + {
1.342 + bytesPerLine = remaining;
1.343 + line.SetLength( (bytesPerLine*2) );
1.344 + }
1.345 + TUint16* pDest = const_cast<TUint16*>(line.Ptr());
1.346 + remaining -= bytesPerLine;
1.347 + for( TInt i = bytesPerLine; i > 0; --i )
1.348 + {
1.349 + TUint8 c = *pSrc++;
1.350 + *pDest++ = hextab[c >> 4];
1.351 + *pDest++ = hextab[c & 0xF];
1.352 + }
1.353 + _LIT( KFmt, "%06x: %S\n\r" );
1.354 + RDebug::Print( KFmt, lineOffs, &line );
1.355 + lineOffs += bytesPerLine;
1.356 + }
1.357 + }
1.358 +
1.359 +
1.360 +
1.361 +TInt CRawWinDiskExtProxyDrive::Read(TInt64 aPos,TInt aLength,TDes8& aTrg)
1.362 +//
1.363 +//
1.364 +//
1.365 + {
1.366 +
1.367 + //
1.368 + // Set file position to where we want to read...
1.369 + //
1.370 + LARGE_INTEGER li;
1.371 + li.QuadPart = aPos;
1.372 +
1.373 + long posH = I64HIGH(aPos);
1.374 + long posL = I64LOW(aPos);
1.375 +
1.376 + TInt off = posL & 0x1FF;
1.377 + posL &= ~0x1FF;
1.378 +
1.379 + if(SetFilePointer (iDeviceHandle, posL, &posH, FILE_BEGIN) == 0xFFFFFFFF)
1.380 + {
1.381 + return Emulator::LastError();
1.382 + }
1.383 +
1.384 + const TInt KLocalBufferSize = 256*1024;
1.385 + char buffer[KLocalBufferSize];
1.386 +
1.387 + TInt totalBytesRead = 0;
1.388 +
1.389 + aTrg.SetLength(aLength);
1.390 +
1.391 + //
1.392 + // Read first sector if start of data is offset from 512 bytes...
1.393 + //
1.394 + if(off)
1.395 + {
1.396 + // read 1st sector if offset
1.397 + DWORD bytesRead;
1.398 + if (!ReadFile (iDeviceHandle, buffer, KSectorSize, &bytesRead, NULL) )
1.399 + {
1.400 + return Emulator::LastError();
1.401 + }
1.402 +
1.403 + if(bytesRead != KSectorSize)
1.404 + {
1.405 + return KErrNotReady;
1.406 + }
1.407 +
1.408 + bytesRead-= off;
1.409 + TInt copyLen = Min(aLength, bytesRead);;
1.410 +
1.411 + totalBytesRead += copyLen;
1.412 + aLength -= copyLen;
1.413 +
1.414 + memcpy(&aTrg[0], &buffer[off], copyLen);
1.415 + }
1.416 +
1.417 + //
1.418 + // Read the remainder of the data, accounting for partial last sector...
1.419 + //
1.420 + while(aLength > 0)
1.421 + {
1.422 + TInt bytesThisTime = (aLength > KLocalBufferSize) ? KLocalBufferSize : aLength;
1.423 +
1.424 + bytesThisTime = (bytesThisTime + KSectorSize-1) & ~(KSectorSize-1);
1.425 +
1.426 + DWORD bytesread;
1.427 + if (!ReadFile (iDeviceHandle, buffer, bytesThisTime, &bytesread, NULL) )
1.428 + {
1.429 + return Emulator::LastError();
1.430 + }
1.431 +
1.432 + if(bytesread != (TUint32)bytesThisTime)
1.433 + return KErrNotReady;
1.434 +
1.435 + TInt copyLen = aLength < bytesThisTime ? aLength : bytesThisTime;
1.436 +
1.437 + memcpy(&aTrg[totalBytesRead], buffer, copyLen);
1.438 +
1.439 + totalBytesRead += bytesThisTime;
1.440 + aLength -= bytesThisTime;
1.441 + }
1.442 +
1.443 +// DumpBuffer(aTrg);
1.444 +
1.445 + return KErrNone;
1.446 + }
1.447 +
1.448 +TInt CRawWinDiskExtProxyDrive::Write(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt aThreadHandle,TInt aOffset)
1.449 +//
1.450 +//
1.451 +//
1.452 + {
1.453 + //
1.454 + // Set file position to where we want to write...
1.455 + //
1.456 + long posStartH = I64HIGH(aPos);
1.457 + long posStartL = I64LOW(aPos);
1.458 +
1.459 + TInt offStart = posStartL & 0x1FF;
1.460 + posStartL &= ~0x1FF;
1.461 +
1.462 + if(SetFilePointer (iDeviceHandle, posStartL, &posStartH, FILE_BEGIN) == 0xFFFFFFFF)
1.463 + {
1.464 + return Emulator::LastError();
1.465 + }
1.466 +
1.467 + const TInt KLocalBufferSize = 256*1024;
1.468 + char buffer[KLocalBufferSize];
1.469 +
1.470 + const TInt param = ParameterNum(aThreadHandle, aSrc);
1.471 +
1.472 + TInt totalBytesRead = 0;
1.473 +
1.474 + //
1.475 + // Read-Modify-Write on first sector if start of data is offset from 512 bytes
1.476 + // or if this is a partial write...
1.477 + //
1.478 + if(offStart || aLength < KSectorSize)
1.479 + {
1.480 + DWORD bytesread;
1.481 + if (!ReadFile (iDeviceHandle, buffer, KSectorSize, &bytesread, NULL) )
1.482 + {
1.483 + return Emulator::LastError();
1.484 + }
1.485 +
1.486 + if(bytesread != KSectorSize)
1.487 + {
1.488 + return KErrNotReady;
1.489 + }
1.490 +
1.491 + totalBytesRead = min(KSectorSize-offStart, aLength);
1.492 + aLength -= totalBytesRead;
1.493 +
1.494 + TPtr8 des((TUint8*)&buffer[offStart], totalBytesRead);
1.495 + ((RMessagePtr2 *) &aThreadHandle)->Read(param, des, aOffset);
1.496 +
1.497 + if(SetFilePointer (iDeviceHandle, posStartL, &posStartH, FILE_BEGIN) == 0xFFFFFFFF)
1.498 + {
1.499 + return Emulator::LastError();
1.500 + }
1.501 +
1.502 + if (!WriteFile (iDeviceHandle, buffer, KSectorSize, &bytesread, NULL) )
1.503 + {
1.504 + return Emulator::LastError();
1.505 + }
1.506 + }
1.507 +
1.508 + //
1.509 + // Write the remainder of the aligned data
1.510 + //
1.511 + while(aLength >= KSectorSize)
1.512 + {
1.513 + TInt alignedLength = aLength & ~0x1FF;
1.514 +
1.515 + TInt bytesThisTime = (alignedLength > KLocalBufferSize) ? KLocalBufferSize : alignedLength;
1.516 +
1.517 + TPtr8 des((TUint8*)buffer, bytesThisTime);
1.518 + ((RMessagePtr2 *) &aThreadHandle)->Read(param, des, aOffset + totalBytesRead);
1.519 +
1.520 + DWORD bytesWritten;
1.521 + if (!WriteFile (iDeviceHandle, buffer, bytesThisTime, &bytesWritten, NULL) )
1.522 + {
1.523 + return Emulator::LastError();
1.524 + }
1.525 +
1.526 + if(bytesWritten != (TUint32)bytesThisTime)
1.527 + {
1.528 + return KErrNotReady;
1.529 + }
1.530 +
1.531 + totalBytesRead += bytesThisTime;
1.532 + aLength -= bytesThisTime;
1.533 + }
1.534 +
1.535 + //
1.536 + // Read-Modify-Write on the last block if a partial write...
1.537 + //
1.538 + if(aLength > 0)
1.539 + {
1.540 + DWORD curPos = SetFilePointer(iDeviceHandle, 0, NULL, FILE_CURRENT);
1.541 +
1.542 + // RMW last sector if offset
1.543 + DWORD bytesread;
1.544 + if (!ReadFile (iDeviceHandle, buffer, KSectorSize, &bytesread, NULL) )
1.545 + {
1.546 + return Emulator::LastError();
1.547 + }
1.548 +
1.549 + if(bytesread != KSectorSize)
1.550 + return KErrNotReady;
1.551 +
1.552 + TPtr8 des((TUint8*)buffer, aLength);
1.553 + ((RMessagePtr2 *) &aThreadHandle)->Read(param, des, aOffset + totalBytesRead);
1.554 +
1.555 + if(SetFilePointer (iDeviceHandle, curPos, &posStartH, FILE_BEGIN) == 0xFFFFFFFF)
1.556 + {
1.557 + return Emulator::LastError();
1.558 + }
1.559 +
1.560 + if (!WriteFile (iDeviceHandle, buffer, KSectorSize, &bytesread, NULL) )
1.561 + {
1.562 + return Emulator::LastError();
1.563 + }
1.564 + }
1.565 +
1.566 + return KErrNone;
1.567 + }
1.568 +
1.569 +TInt CRawWinDiskExtProxyDrive::Write(TInt64 aPos,const TDesC8& aSrc)
1.570 +//
1.571 +//
1.572 +//
1.573 + {
1.574 + //
1.575 + // Set file position to where we want to write...
1.576 + //
1.577 + TInt length = aSrc.Length();
1.578 +
1.579 + long posStartH = I64HIGH(aPos);
1.580 + long posStartL = I64LOW(aPos);
1.581 +
1.582 + TInt offStart = posStartL & 0x1FF;
1.583 + posStartL &= ~0x1FF;
1.584 +
1.585 + if(SetFilePointer (iDeviceHandle, posStartL, &posStartH, FILE_BEGIN) == 0xFFFFFFFF)
1.586 + {
1.587 + return Emulator::LastError();
1.588 + }
1.589 +
1.590 + const TInt KLocalBufferSize = 256*1024;
1.591 + char buffer[KLocalBufferSize];
1.592 +
1.593 + TInt totalBytesRead = 0;
1.594 +
1.595 + //
1.596 + // Read-Modify-Write on first sector if start of data is offset from 512 bytes
1.597 + // or if this is a partial write...
1.598 + //
1.599 + if(offStart || length < KSectorSize)
1.600 + {
1.601 + DWORD bytesread;
1.602 + if (!ReadFile (iDeviceHandle, buffer, KSectorSize, &bytesread, NULL) )
1.603 + {
1.604 + return Emulator::LastError();
1.605 + }
1.606 +
1.607 + if(bytesread != KSectorSize)
1.608 + {
1.609 + return KErrNotReady;
1.610 + }
1.611 +
1.612 + totalBytesRead = min(KSectorSize-offStart, length);
1.613 + length -= totalBytesRead;
1.614 +
1.615 + memcpy(&buffer[offStart], &aSrc[0], totalBytesRead);
1.616 +
1.617 + if(SetFilePointer (iDeviceHandle, posStartL, &posStartH, FILE_BEGIN) == 0xFFFFFFFF)
1.618 + {
1.619 + return Emulator::LastError();
1.620 + }
1.621 +
1.622 + if (!WriteFile (iDeviceHandle, buffer, KSectorSize, &bytesread, NULL) )
1.623 + {
1.624 + return Emulator::LastError();
1.625 + }
1.626 + }
1.627 +
1.628 + //
1.629 + // Write the remainder of the aligned data
1.630 + //
1.631 + while(length >= KSectorSize)
1.632 + {
1.633 + TInt alignedLength = length & ~0x1FF;
1.634 +
1.635 + TInt bytesThisTime = (alignedLength > KLocalBufferSize) ? KLocalBufferSize : alignedLength;
1.636 +
1.637 + memcpy(buffer, &aSrc[totalBytesRead], bytesThisTime);
1.638 +
1.639 + DWORD bytesWritten;
1.640 + if (!WriteFile (iDeviceHandle, buffer, bytesThisTime, &bytesWritten, NULL) )
1.641 + {
1.642 + return Emulator::LastError();
1.643 + }
1.644 +
1.645 + if(bytesWritten != (TUint32)bytesThisTime)
1.646 + {
1.647 + return KErrNotReady;
1.648 + }
1.649 +
1.650 + totalBytesRead += bytesThisTime;
1.651 + length -= bytesThisTime;
1.652 + }
1.653 +
1.654 + //
1.655 + // Read-Modify-Write on the last block if a partial write...
1.656 + //
1.657 + if(length > 0)
1.658 + {
1.659 + DWORD curPos = SetFilePointer(iDeviceHandle, 0, NULL, FILE_CURRENT);
1.660 +
1.661 + // RMW last sector if offset
1.662 + DWORD bytesread;
1.663 + if (!ReadFile (iDeviceHandle, buffer, KSectorSize, &bytesread, NULL) )
1.664 + {
1.665 + return Emulator::LastError();
1.666 + }
1.667 +
1.668 + if(bytesread != KSectorSize)
1.669 + return KErrNotReady;
1.670 +
1.671 + memcpy(&buffer[0], &aSrc[totalBytesRead], length);
1.672 +
1.673 + if(SetFilePointer (iDeviceHandle, curPos, &posStartH, FILE_BEGIN) == 0xFFFFFFFF)
1.674 + {
1.675 + return Emulator::LastError();
1.676 + }
1.677 +
1.678 + if (!WriteFile (iDeviceHandle, buffer, KSectorSize, &bytesread, NULL) )
1.679 + {
1.680 + return Emulator::LastError();
1.681 + }
1.682 + }
1.683 +
1.684 +
1.685 + return KErrNone;
1.686 + }
1.687 +
1.688 +TInt CRawWinDiskExtProxyDrive::Caps(TDes8& anInfo)
1.689 +//
1.690 +//
1.691 +//
1.692 + {
1.693 + TLocalDriveCapsV3Buf caps;
1.694 + TInt err = CBaseExtProxyDrive::Caps(caps);
1.695 + if(err == KErrNone)
1.696 + {
1.697 + DISK_GEOMETRY geometry;
1.698 + DWORD dummy;
1.699 +
1.700 + if(!DeviceIoControl(iDeviceHandle,
1.701 + IOCTL_DISK_GET_DRIVE_GEOMETRY,
1.702 + NULL,
1.703 + 0,
1.704 + &geometry,
1.705 + sizeof(geometry),
1.706 + &dummy,
1.707 + (LPOVERLAPPED)NULL))
1.708 + {
1.709 + return KErrNotReady;
1.710 + }
1.711 +
1.712 + caps().iExtraInfo = EFalse;
1.713 +
1.714 + // NB This seems to be incorrect:If the disk is formatted by Windows, then the
1.715 + // number of sectors reported in the Boot Sector is slightly greater than
1.716 + // the number of sectors calculated here ... resulting in CheckDisk failures.
1.717 + // One solution is to ensure the disk is formatted by the emulator.
1.718 + caps().iSize = MAKE_TINT64(geometry.Cylinders.HighPart, geometry.Cylinders.LowPart) *
1.719 + geometry.TracksPerCylinder *
1.720 + geometry.SectorsPerTrack *
1.721 + geometry.BytesPerSector;
1.722 +
1.723 + anInfo = caps.Left(Min(caps.Length(),anInfo.MaxLength()));
1.724 + }
1.725 +
1.726 + return(err);
1.727 + }
1.728 +
1.729 +TInt CRawWinDiskExtProxyDrive::Format(TFormatInfo& /*anInfo*/)
1.730 +//
1.731 +//
1.732 +//
1.733 + {
1.734 + return(KErrEof);
1.735 + }
1.736 +
1.737 +
1.738 +CRawWinDiskProxyDriveFactory::CRawWinDiskProxyDriveFactory()
1.739 +//
1.740 +//
1.741 +//
1.742 + {
1.743 + RDebug::Print(_L("CRawWinDiskProxyDriveFactory::CRawWinDiskProxyDriveFactory"));
1.744 + }
1.745 +
1.746 +TInt CRawWinDiskProxyDriveFactory::Install()
1.747 +//
1.748 +//
1.749 +//
1.750 + {
1.751 + _LIT(KLoggerName,"RAWEXT");
1.752 + return(SetName(&KLoggerName));
1.753 + }
1.754 +
1.755 +
1.756 +CProxyDrive* CRawWinDiskProxyDriveFactory::NewProxyDriveL(CProxyDrive* aProxy,CMountCB* aMount)
1.757 +//
1.758 +//
1.759 +//
1.760 + {
1.761 + return(CRawWinDiskExtProxyDrive::NewL(aProxy,aMount));
1.762 + }
1.763 +
1.764 +extern "C" {
1.765 +
1.766 +EXPORT_C CProxyDriveFactory* CreateFileSystem()
1.767 +//
1.768 +// Create a new file system
1.769 +//
1.770 + {
1.771 + return(new CRawWinDiskProxyDriveFactory());
1.772 + }
1.773 +}
1.774 +