#include "ms_tool.h"
#define REAL_TEST
//===========================================================================
BOOL LockDiskDevice( HANDLE hDevice )
{
DWORD dwBytesReturned;
if( !DeviceIoControl( hDevice, // handle to a volume
FSCTL_LOCK_VOLUME, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
NULL, // lpOutBuffer
0, // nOutBufferSize
&dwBytesReturned, // number of bytes returned
NULL ) )
{
printf( "Lock volume failed ! \n" );
return FALSE;
}
return TRUE;
}
BOOL FindDiskWithSpecifiedLabel( UINT drvType, const char *szVolLabel, char *pLogicDrvName )
{
char szDrvName[16];
char szDrvRootPath[32];
char szVolNameBuf[128];
char szFileSystemName[32];
DWORD dwVolSerial, dwMaxFileNameLen, dwFileSystemFlags;
DWORD dwDrvMask;
unsigned int dt;
dwDrvMask = GetLogicalDrives();
strcpy( szDrvName, "A:" );
for (int m = 0; dwDrvMask != 0; m++, dwDrvMask>>=1 )
{
if ( (dwDrvMask & 1) != 0 )
{
szDrvName[0] = 'A' + m;
dt = GetDriveType( szDrvName );
/* DRIVE_UNKNOWN
DRIVE_NO_ROOT_DIR
DRIVE_REMOVABLE
DRIVE_FIXED
DRIVE_REMOTE
DRIVE_CDROM
DRIVE_RAMDISK
*/
if( dt != drvType )
continue;
// GetVolumeNameForVolumeMountPoint();
sprintf( szDrvRootPath, "%s\\", szDrvName );
if ( GetVolumeInformation( szDrvRootPath, // in : root directory
szVolNameBuf, // out: volume name buffer
sizeof(szVolNameBuf), // in : length of name buffer
&dwVolSerial, // out: volume serial number
&dwMaxFileNameLen, // out: maximum file name length supported
&dwFileSystemFlags, // out: file system options
szFileSystemName, // out: file system name buffer
sizeof(szFileSystemName) // in : size of file system name buffer
) )
{
if( strcmp( szVolLabel, szVolNameBuf ) == 0 )
{
strcpy( pLogicDrvName, szDrvName );
return TRUE;
}
}
}
}
return FALSE;
}
DWORD GetDiskDeviceSectorSize( HANDLE hDevice )
{
DISK_GEOMETRY dg;
DWORD dwDiscarded;
//LONGLONG llDiskSize;
if( ! DeviceIoControl( hDevice, // device we are querying
IOCTL_DISK_GET_DRIVE_GEOMETRY, // operation
NULL, 0, // input buffer and it's size
&dg, sizeof(dg), // output buffer
&dwDiscarded, // discard count of bytes returned
NULL ) // synchronous I/O
)
{
printf( "Get disk geomtry error !\n" );
return 0;
}
/*
if( dg.MediaType != RemovableMedia )
{
printf( "The device is not removable disk !\n" );
return;
}
llDiskSize = dg.Cylinders.QuadPart * dg.TracksPerCylinder *
dg.SectorsPerTrack * dg.BytesPerSector;
*/
return dg.BytesPerSector;
}
/* To enumerate the volumes:
GetVolumeNameForVolumeMountPoint()
Then use volume name as device name to open the volume or partition.
*/
/*-------------------------------------------------------------------------------------*
* *
*-------------------------------------------------------------------------------------*/
#define U8 BYTE
U8 Memory[ MS_IMAGE_SIZE ];
BYTE gv_recvBuff[MS_BLOCK_SIZE];
void HostTestMassStorageIO( HANDLE hDevice, int nBlockSize )
{
int blk_sent = FIRST_DATA_BLOCK; // begins from this block, to find a idle block to sent data.
int blk_recv = FIRST_DATA_BLOCK; // begins from this block, to find a ACK data block.
U8 *pHostCtrlBlock = &Memory[BLOCK_OFF(HOST_CTRL_BLOCK)];
U8 *pDeviCtrlBlock = &Memory[BLOCK_OFF(DEVI_CTRL_BLOCK)];
unsigned int nAckCount = 0;
time_t tm_start, tm_end;
assert( nBlockSize == MS_BLOCK_SIZE );
assert( ( MS_BLOCK_NUM * CTRL_FLAG_BITS / 8 ) <= MS_BLOCK_SIZE );
time( &tm_start );
// Write communication start flag ( to notify the device )
memset( pHostCtrlBlock, 0, MS_BLOCK_SIZE );
memset( pDeviCtrlBlock, 0, MS_BLOCK_SIZE );
pHostCtrlBlock[0] = 0xFF;
pHostCtrlBlock[1] = 0xFF;
pDeviCtrlBlock[0] = 0xFF;
pDeviCtrlBlock[1] = 0xFF;
if( !WriteDiskMemory( hDevice, BLOCK_OFF(HOST_CTRL_BLOCK), pHostCtrlBlock, 2*MS_BLOCK_SIZE ) )
{
printf( "WriteDiskMemory() failed ! \n" );
return;
}
/* //temp code for testing
if( ! ReadDiskMemory( hDevice, BLOCK_OFF(HOST_CTRL_BLOCK), gv_recvBuff, MS_BLOCK_SIZE ) )
{ printf( "ReadDiskMemory() failed ! \n" );
return;
}
*/
srand( (unsigned)time( NULL ) );
while( 1 )
{
int b;
if( ! ReadDiskMemory( hDevice, BLOCK_OFF(DEVI_CTRL_BLOCK), pDeviCtrlBlock, MS_BLOCK_SIZE ) )
goto on_read_fail;
// find a block for sending data
for( b = 0; b < MS_BLOCK_NUM - CTRL_BLOCK_NUM; b++ )
{
if( pHostCtrlBlock[blk_sent] == FLAG_IDLE && pDeviCtrlBlock[blk_sent] == FLAG_IDLE )
{
BYTE *pBlock = Memory + BLOCK_OFF(blk_sent);
// prepare data to be sent
for( int i = 0; i < MS_BLOCK_SIZE/sizeof(short); i++ )
((short *)pBlock)[i] = (short)rand(); // RAND_MAX
HEX_PRINTF(( (const char *)pBlock, MS_BLOCK_SIZE, "[Host-SEND %02d] ", blk_sent ));
// write data
if( !WriteDiskMemory( hDevice, BLOCK_OFF(blk_sent), pBlock, MS_BLOCK_SIZE ) )
goto on_write_fail;
// Set sent flag
pHostCtrlBlock[blk_sent] = FLAG_SENT;
}
if( ++blk_sent >= MS_BLOCK_NUM )
blk_sent = FIRST_DATA_BLOCK;
}
if( !WriteDiskMemory( hDevice, BLOCK_OFF(HOST_CTRL_BLOCK), pHostCtrlBlock, MS_BLOCK_SIZE ) )
goto on_write_fail;
if( ! ReadDiskMemory( hDevice, BLOCK_OFF(DEVI_CTRL_BLOCK), pDeviCtrlBlock, MS_BLOCK_SIZE ) )
goto on_read_fail;
// find a block contains ACK data
for( b = 0; b < MS_BLOCK_NUM - CTRL_BLOCK_NUM; b++ )
{
if( pHostCtrlBlock[blk_recv] == FLAG_SENT && pDeviCtrlBlock[blk_recv] == FLAG_ACK )
{
int i;
BYTE *pBlock = Memory + BLOCK_OFF(blk_recv);
// Read the ACK data
if( !ReadDiskMemory( hDevice, BLOCK_OFF(blk_recv), gv_recvBuff, MS_BLOCK_SIZE ) )
goto on_read_fail;
// Check the ACK data
for( i = 0; i < MS_BLOCK_SIZE; i++ )
gv_recvBuff[i] = ~gv_recvBuff[i];
HEX_PRINTF(( (const char *)gv_recvBuff, MS_BLOCK_SIZE, "[Host-RECV %02d] ", blk_recv ));
// Goto idle state
pHostCtrlBlock[blk_recv] = FLAG_IDLE;
// Check the ACK data
for( i = 0; i < MS_BLOCK_SIZE; i++ )
{
if( gv_recvBuff[i] != pBlock[i] )
break;
}
if( i < MS_BLOCK_SIZE )
{
printf( "ACK data error in block %d !\n", blk_recv );
}
++nAckCount;
printf( "%d\r", nAckCount );
// break; // Just check one ACK at a time
}
if( ++blk_recv >= MS_BLOCK_NUM )