Я написал справочную информацию утилиты и (потому что я, и люди, которых я написал это для сбора & использовать устаревшее аппаратное обеспечение), сделав его совместимым с DOS и Windows 9x, а также с 64-битной Windows XP / Vista / 7/8 (потому что мы также используем их). Проблема, с которой я сталкиваюсь, заключается в том, что в Windows 9x доступны отчеты дисковое пространство и общее дисковое пространство как 2G (хорошо 1,9997 G) даже на больших дисках. В Windows XP и более поздних версиях (32-разрядных или 64-разрядных) он правильно сообщает размеры дисков. В DOS, конечно, это не проблема, так как максимальный размер в DOS уже равен 2G.
Я использую код (DInfo.Path — это каталог, к которому осуществляется доступ, с [0] — буква диска — A, B, C и т. Д.):
_dos_getdiskfree(DInfo.Path[0] - 'A' + 1, &Free);
BlockSize = Free.sectors_per_cluster * Free.bytes_per_sector;
for (i = 0; i < BlockSize; i++) {
DriveBytes += Free.total_clusters;
if (DriveBytes < Free.total_clusters) ++DBOverflow;
FreeBytes += Free.avail_clusters;
if (FreeBytes < Free.avail_clusters) ++FBOverflow;
}
Единственное различие между кодом в заглушке DOS и частью исполняемого файла для Windows заключается в том, что вместо _dos_getdiskfree вместо _getdiskfree. Я использую беззнаковые переменные __int32 в приведенном выше коде (или беззнаковые длинные для кода DOS.) Я использовал 32-битную для совместимости и максимально сократить повторную запись кода при преобразовании кода DOS в код Windows. В Windows XP + я, возможно, мог бы упростить вещи, используя переменные __int64, но, опять же, я не был уверен, будет ли Windows 9x предоставлять их или нет. Я даже не был уверен, позволят ли это 32-разрядные версии Windows XP + или нет, и действительно не хотел исследовать это, просто немного упростил его. Даже на старых HW он работает достаточно быстро с циклом.
С переполнением & Байтовые переменные и 32-разрядные целые числа, максимальный размер должен составлять 8 эксабайт (килобайт, мегабайт, гигабайт, терабайт, петабайт, эксабайт, если вам интересно), и, поскольку самые большие доступные в настоящее время диски измеряются в однозначных терабайтах, это ограничение не должно вызывать проблем на некоторое время. По крайней мере, это сомнительно при моей жизни.
ответ предоставлен Раймондом Ченом в комментарии исправил проблему. Использование GetDiskFreeSpaceEx вместо GetDiskFreeSpace дало правильные результаты.