#include "precomp.h"
#include "pdrive95.h"
// RAW functions
LPFNResetDisk m_ResetDisk = NULL;
LPFNReadPhysicalSector m_ReadPhysicalSector = NULL;
LPFNWritePhysicalSector m_WritePhysicalSector = NULL;
LPFNReadDiskGeometry m_ReadDiskGeometry = NULL;
LPFNEI13GetDriveParameters m_EI13GetDriveParameters = NULL;
LPFNEI13ReadSector m_EI13ReadSector = NULL;
LPFNEI13WriteSector m_EI13WriteSector = NULL;
P9xPhysicalDrive::P9xPhysicalDrive()
{
}
P9xPhysicalDrive::~P9xPhysicalDrive()
{
}
BOOL P9xPhysicalDrive::ReadPartitionInfoRecursive(DWORD dwSector,INT64 TotalOffset )
{
BYTE mbr[512];
INT64 OffsetInBytes = dwSector;
OffsetInBytes *= 512;
if( ReadAbsolute(mbr,sizeof(mbr),OffsetInBytes) )
{
MBR* pMBR = (MBR*) &(mbr[446]);
if( pMBR->wSignature != 0xaa55 )
return FALSE;
INT64 ScheissOffset = 0;
for( int i = 0; i < 4; i++ )
{
PARTITIONINFO* source = &(pMBR->pi[i]);
if( !source->SIZE && !source->LBA )
continue;
PARTITION_INFORMATION pi;
ZeroMemory(&pi,sizeof(pi));
pi.PartitionLength.QuadPart = source->SIZE;
pi.PartitionLength.QuadPart *= 512L;
pi.PartitionType = source->Type;
if( i == 0 )
{
pi.StartingOffset.QuadPart = source->LBA;
pi.StartingOffset.QuadPart *= 512L;
pi.StartingOffset.QuadPart += TotalOffset;
ScheissOffset = pi.StartingOffset.QuadPart;
}
else
{
pi.StartingOffset.QuadPart = ScheissOffset;
}
ScheissOffset += pi.PartitionLength.QuadPart;
P9xPartitionInfo* p9pi = new P9xPartitionInfo(&pi);
m_PartitionInfo.AddTail( p9pi );
if( pi.PartitionType == PARTITION_TYPE_EXTENDED )
{
if( !ReadPartitionInfoRecursive(dwSector + source->LBA,pi.StartingOffset.QuadPart) )
{
p9pi->m_pi.StartingOffset.QuadPart += 63*512;
}
}
}
}
return TRUE;
}
BOOL P9xPhysicalDrive::Open( int iDrive )
{
if( m_ResetDisk == NULL )
{
HINSTANCE hLibrary = (HINSTANCE)LoadLibrary( "RAWIO32.DLL" );
if( !hLibrary )
{
printf("ERROR %s, unable to load RAWIO32.DLL.\n", (LPCSTR) GetLastErrorString() );
return FALSE;
}
#define GETPROC(__NAME__) \
m_##__NAME__ = (LPFN##__NAME__) GetProcAddress(hLibrary,#__NAME__); \
if( !m_##__NAME__ ) { \
printf("ERROR, missing export " #__NAME__ " IN DISKIO32.DLL\n" ); \
return FALSE; \
}
GETPROC( ResetDisk )
GETPROC( ReadPhysicalSector )
GETPROC( WritePhysicalSector )
GETPROC( ReadDiskGeometry )
GETPROC( EI13GetDriveParameters )
GETPROC( EI13ReadSector )
GETPROC( EI13WriteSector )
}
//printf("About to get geometry\n");
m_bDriveNumber = (BYTE)(128 + iDrive);
DISK_GEOMETRY dg;
if( GetDriveGeometry(&dg) )
{
//printf("Cylinders = %I64d\n", dg.Cylinders );
//printf("TracksPerCylinder = %d\n", dg.TracksPerCylinder );
//printf("SectorsPerTrack = %d\n", dg.SectorsPerTrack );
//printf("BytesPerSector = %d\n", dg.BytesPerSector );
INT64 TotalSize = dg.Cylinders.QuadPart;
TotalSize *= dg.TracksPerCylinder;
TotalSize *= dg.SectorsPerTrack;
TotalSize *= dg.BytesPerSector;
//printf( "Total Size In Bytes = %I64d\n", TotalSize );
TotalSize /= 1024L;
TotalSize /= 1024L;
//printf( "Total Size In Megabytes = %I64d\n", TotalSize );
ReadPartitionInfoRecursive(0,0);
/*int index = 0;
ENUMERATE( &m_PartitionInfo, P9xPartitionInfo, pI )
{
printf("PARTITION %d: --------------------\n", index++ );
printf(" StartingOffset = %" FMT_QWORD "\n", pI->m_pi.StartingOffset.QuadPart );
printf(" PartitionLength = %" FMT_QWORD " (%.2f MB)\n", pI->m_pi.PartitionLength.QuadPart, PBytesInMBytes(pI->m_pi.PartitionLength.QuadPart) );
printf(" PartitionType = %ld\n", (long) pI->m_pi.PartitionType );
}*/
return TRUE;
}
return FALSE;
}
void P9xPhysicalDrive::Close()
{
}
BOOL P9xPhysicalDrive::GetDriveGeometry( DISK_GEOMETRY* lpDG )
{
lpDG->MediaType = Unknown;
lpDG->BytesPerSector = 512;
ExtDriveInfo edi;
ZeroMemory(&edi,sizeof(edi));
edi.drive = m_bDriveNumber;
if( m_EI13GetDriveParameters(&edi) > 0 )
{
lpDG->Cylinders.QuadPart = *(INT64*)&(edi.sectorsLo);
lpDG->TracksPerCylinder = 1; //edi.heads;
lpDG->SectorsPerTrack = 1; //edi.cylinders;
return TRUE;
}
SectorInfo si;
ZeroMemory(&si,sizeof(si));
si.bDrive = m_bDriveNumber;
if( m_ReadDiskGeometry(&si) > 0 )
{
lpDG->Cylinders.QuadPart = si.wCylinder;
lpDG->TracksPerCylinder = si.bHead;
lpDG->SectorsPerTrack = si.bSector;
return TRUE;
}
return FALSE;
}
BOOL P9xPhysicalDrive::ReadAbsolute( LPBYTE lpbMemory, DWORD dwSize, INT64 OffsetInBytes )
{
BlockInfo bi;
bi.drive = m_bDriveNumber;
OffsetInBytes /= 512;
*((INT64*)&(bi.scheiss[0])) = OffsetInBytes;
bi.count = (WORD) (dwSize / 512);
if( m_EI13ReadSector (&bi, lpbMemory, dwSize) > 0 )
return TRUE;
// ***** NOT SUPPORTED *******
//struct SectorInfo
//{
// BYTE bDrive;
// WORD wCylinder;
// BYTE bHead;
// BYTE bSector;
// BYTE bCount;
//};
//
// if( ReadPhysicalSector(&bi, lpbMemory, dwSize) > 0 )
// return TRUE;
return FALSE;
}
#ifdef SUPPORT_WINDOWS_XP_PARTITIONS
BOOL P9xPhysicalDrive::GetDriveGeometryEx( DISK_GEOMETRY_EX* lpDG, DWORD dwSize )
{
return FALSE;
}
BOOL P9xPhysicalDrive::GetDriveLayoutEx( LPBYTE lpbMemory, DWORD dwSize )
{
return FALSE;
}
#endif
BOOL P9xPhysicalDrive::GetDriveLayout( LPBYTE lpbMemory, DWORD dwSize )
{
DWORD dwBytesRequired = sizeof(DRIVE_LAYOUT_INFORMATION) + sizeof(PARTITION_INFORMATION)*(m_PartitionInfo.m_lCount-1);
if( dwSize < dwBytesRequired )
return FALSE;
PDRIVE_LAYOUT_INFORMATION pli = (PDRIVE_LAYOUT_INFORMATION) lpbMemory;
pli->PartitionCount = m_PartitionInfo.m_lCount;
pli->Signature = 0;
int index = 0;
ENUMERATE( &m_PartitionInfo, P9xPartitionInfo, pI )
{
pli->PartitionEntry[index++] = pI->m_pi;
}
return TRUE;
}
syntax highlighted by Code2HTML, v. 0.9.1