Заметил очень странную вещь: если для пустого, свежеотформатированного диска сделать
DeviceIoControl(Handle, IOCTL_DISK_GET_DRIVE_GEOMETRY, ...), то DISK_GEOMETRY.Cylinders*DISK_GEOMETRY.TracksPerCylinder*DISK_GEOMETRY.SectorsPerTrack*DISK_GEOMETRY.BytesPerSector оказывается меньше, чем то, что GetDiskFreeSpaceEx(...) записывает в FreeAvailable.
То есть полный, обусловленный логической геометрией, объем устройства получается меньше, чем свободное пространство на его единственном разделе! Как это объяснить?
Re: DeviceIoControl and IOCTL_DISK_GET_DRIVE_GEOMETRY
Здравствуйте, misha_irpen, Вы писали:
_>Заметил очень странную вещь: если для пустого, свежеотформатированного диска сделать _>DeviceIoControl(Handle, IOCTL_DISK_GET_DRIVE_GEOMETRY, ...), то DISK_GEOMETRY.Cylinders*DISK_GEOMETRY.TracksPerCylinder*DISK_GEOMETRY.SectorsPerTrack*DISK_GEOMETRY.BytesPerSector оказывается меньше, чем то, что GetDiskFreeSpaceEx(...) записывает в FreeAvailable.
_>То есть полный, обусловленный логической геометрией, объем устройства получается меньше, чем свободное пространство на его единственном разделе! Как это объяснить?
Для получения размера диска надо пользоваться IOCTL_DISK_GET_PARTITION_INFO указывая handle диска.
Работает в Win2K+
Разница между этим значением и значением полученным из IOCTL_DISK_GET_DRIVE_GEOMETRY до 8 Мб.
Дело в том, что DISK_GEOMETRY это фикция. Чтобы заполнить эту структуру Windows берет настоящий размер (см выше) выставляет в DISK_GEOMETRY все числа кроме Cylinders, а цилиндры считает обычным целочисленным делением.
Происходит округление в меньшую строну. А поскольку один цилиндр это обычно ~8Мбг, то и разница может достигать этого значения как угодно близко.
Re[2]: DeviceIoControl and IOCTL_DISK_GET_DRIVE_GEOMETRY
Здравствуйте, MShura, Вы писали:
MS>Для получения размера диска надо пользоваться IOCTL_DISK_GET_PARTITION_INFO указывая handle диска. MS>Работает в Win2K+
Секунду, о каком PARTITION_INFO вообще может идти речь в том случае когда Handle указывает на RAW-device без разделов, файловых систем и вообще корректного MBR?
Ранее приведенный мной случай — частный, в общем же случае необходимо определить полный размер неразмеченного устройства.
Re[3]: DeviceIoControl and IOCTL_DISK_GET_DRIVE_GEOMETRY
Здравствуйте, misha_irpen, Вы писали:
_>Здравствуйте, MShura, Вы писали:
MS>>Для получения размера диска надо пользоваться IOCTL_DISK_GET_PARTITION_INFO указывая handle диска. MS>>Работает в Win2K+ _>Секунду, о каком PARTITION_INFO вообще может идти речь в том случае когда Handle указывает на RAW-device без разделов, файловых систем и вообще корректного MBR?
_>Ранее приведенный мной случай — частный, в общем же случае необходимо определить полный размер неразмеченного устройства.
Вот о каком handle идет речь.
И пусть слова PARTITION_INFORMATION Вас не смущают
MS>Вот о каком handle идет речь.
Хорошо... Глянул тыт в help, и остался в догадках. Если IOCTL_DISK_GET_PARTITION_INFO умеет возвращать размер неразмеченного диска, то как она поведет себя с размеченным? Что вообще она записывает в буфер? Сейчас проверить не могу, но мне сама идея непонятна: она заполняет одну структуру или несколько? Если несколько, то почему в MSDN-е нигде не написано что pOutBuffer должен указывать на массив из PARTITION_INFORMATION. А если на одну, то что он записывает в этот екземпляр и как получить информацию об остальных разделах? (ведь закос идет именно под PartitionTable)
Re[5]: DeviceIoControl and IOCTL_DISK_GET_DRIVE_GEOMETRY
Здравствуйте, misha_irpen, Вы писали:
MS>>Вот о каком handle идет речь. _>Хорошо... Глянул тыт в help, и остался в догадках. Если IOCTL_DISK_GET_PARTITION_INFO умеет возвращать размер неразмеченного диска, то как она поведет себя с размеченным? Что вообще она записывает в буфер? Сейчас проверить не могу, но мне сама идея непонятна: она заполняет одну структуру или несколько? Если несколько, то почему в MSDN-е нигде не написано что pOutBuffer должен указывать на массив из PARTITION_INFORMATION. А если на одну, то что он записывает в этот екземпляр и как получить информацию об остальных разделах? (ведь закос идет именно под PartitionTable)
Заполняется одна структура.
Если на входе handle диска, то его размер
Если на входе handle basic тома, то его размер положение и прочее.
Чтобы получить массив структур надо юзать IOCTL_DISK_GET_DRIVE_LAYOUT.
Re[6]: DeviceIoControl and IOCTL_DISK_GET_DRIVE_GEOMETRY
Здравствуйте, MShura, Вы писали:
MS>Заполняется одна структура. MS>Если на входе handle диска, то его размер MS>Если на входе handle basic тома, то его размер положение и прочее. MS>Чтобы получить массив структур надо юзать IOCTL_DISK_GET_DRIVE_LAYOUT.
В общем проверил. Для жесткого диска возвращает "неверная функция", для съемных носителей — "такой запрос не поддерживается". Вот такая фигня
Re[7]: DeviceIoControl and IOCTL_DISK_GET_DRIVE_GEOMETRY
Здравствуйте, misha_irpen, Вы писали:
_>Здравствуйте, MShura, Вы писали:
MS>>Заполняется одна структура. MS>>Если на входе handle диска, то его размер MS>>Если на входе handle basic тома, то его размер положение и прочее. MS>>Чтобы получить массив структур надо юзать IOCTL_DISK_GET_DRIVE_LAYOUT. _>В общем проверил. Для жесткого диска возвращает "неверная функция", для съемных носителей — "такой запрос не поддерживается". Вот такая фигня
Работает в Win2K/XP и выше.
#include <stdio.h>
#include <windows.h>
#include <winioctl.h>
int main ( int argc, char** argv )
{
HANDLE hDisk;
UNREFERENCED_PARAMETER( argc );
UNREFERENCED_PARAMETER( argv );
hDisk = CreateFileW( L"\\\\.\\PhysicalDrive0", GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( INVALID_HANDLE_VALUE != hDisk )
{
PARTITION_INFORMATION PartInfo;
DWORD Ret;
if ( DeviceIoControl( hDisk, IOCTL_DISK_GET_PARTITION_INFO,
NULL, 0,
&PartInfo, sizeof(PartInfo),
&Ret, NULL )
&& Ret == sizeof(PartInfo) )
{
unsigned long Gb, Mb;
PartInfo.PartitionLength.QuadPart /= 512;
// Do simple right 21 bit shift of 64 bit value
Gb = (PartInfo.PartitionLength.LowPart >> 21) | (PartInfo.PartitionLength.HighPart << 11);
Mb = PartInfo.PartitionLength.LowPart & 0x1FFFFF;
printf( "Disk 0: (%lu.%02lu Gb)\n", Gb, (Mb * 100) >> 21 );
}
CloseHandle( hDisk );
}
return 0;
}
Re[8]: DeviceIoControl and IOCTL_DISK_GET_DRIVE_GEOMETRY
Здравствуйте, MShura, Вы писали:
MS>Работает в Win2K/XP и выше.
Прошу прощения, все правильно, это просто я криворукий. Забыл что Delphi многострочный if при отладке считает одной строкой
Re[8]: DeviceIoControl and IOCTL_DISK_GET_DRIVE_GEOMETRY
Здравствуйте, misha_irpen, Вы писали:
_>Здравствуйте, MShura, Вы писали:
MS>>Работает в Win2K/XP и выше. _>И еще одно: это не работает для флоппика. Говорит что неверная функция...
Ну дык, если ошибка, то пробуем "старый" способ IOCTL_DISK_GET_DRIVE_GEOMETRY.
Re[10]: DeviceIoControl and IOCTL_DISK_GET_DRIVE_GEOMETRY
Здравствуйте, MShura, Вы писали:
MS>Здравствуйте, misha_irpen, Вы писали:
_>>Здравствуйте, MShura, Вы писали:
MS>>>Работает в Win2K/XP и выше. _>>И еще одно: это не работает для флоппика. Говорит что неверная функция... MS>Ну дык, если ошибка, то пробуем "старый" способ IOCTL_DISK_GET_DRIVE_GEOMETRY.
Пришлось Причем в этом случае остается вероятность что размер определится неточно. Хотя для дискет это вроде всегда правильно, но как поведет себя например USB-флоп — непонятно.