Dick,
The model Netware uses for large drives for calculating C/H/S addressed this problem years ago and
provides more useful output, since C/H/S is converted into a hieristic which acts almost like an MD5 hash
and for a given dimension, does provide unique output for even very large drives.
Code Attached.
Jeff
ULONG SetPartitionTableGeometry(BYTE *hd, BYTE *sec, BYTE *cyl,
ULONG LBA, ULONG TracksPerCylinder,
ULONG SectorsPerTrack)
{
ULONG offset, cylinders, head, sector;
if (!cyl || !hd || !sec)
return -1;
cylinders = (LBA / (TracksPerCylinder * SectorsPerTrack));
offset = LBA % (TracksPerCylinder * SectorsPerTrack);
head = (WORD)(offset / SectorsPerTrack);
sector = (WORD)(offset % SectorsPerTrack) + 1;
if (cylinders < 1023)
{
*sec = (BYTE)sector;
*hd = (BYTE)head;
*cyl = (BYTE)(cylinders & 0xff);
*sec |= (BYTE)((cylinders >> 2) & 0xC0);
}
else
{
*sec = (BYTE)(SectorsPerTrack | 0xC0);
*hd = (BYTE)(TracksPerCylinder - 1);
*cyl = (BYTE)0xFE;
}
return 0;
}
ULONG SetPartitionTableValues(struct PartitionTableEntry *Part,
ULONG Type,
ULONG StartingLBA,
ULONG EndingLBA,
ULONG Flag,
ULONG TracksPerCylinder,
ULONG SectorsPerTrack)
{
Part->SysFlag = (BYTE) Type;
Part->fBootable = (BYTE) Flag;
Part->StartLBA = StartingLBA;
Part->nSectorsTotal = (EndingLBA - StartingLBA) + 1;
SetPartitionTableGeometry(&Part->HeadStart, &Part->SecStart, &Part->CylStart,
StartingLBA, TracksPerCylinder, SectorsPerTrack);
SetPartitionTableGeometry(&Part->HeadEnd, &Part->SecEnd, &Part->CylEnd,
EndingLBA, TracksPerCylinder, SectorsPerTrack);
return 0;
}