os/kernelhwsrv/kerneltest/f32test/ext/t_rawext.cpp
changeset 0 bde4ae8d615e
     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 +