Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Определение размера диска 
:(
    Опции темы
Riply
Дата 5.6.2007, 05:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Здравствуйте !
Допустим, мы берем диск ( например CD ) и тремя способами пробуем получить его "размер".
DeviceIoControl(..., IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, ...., PDISK_GEOMETRY_EX,.....
Size_Ex := PDISK_GEOMETRY_EX.DiskSize.QuadPart; // первый вариант
with PDISK_GEOMETRY_EX.Geometry do
 Size_Calc := Cylinders.QuadPart * TracksPerCylinder * SectorsPerTrack * BytesPerSector; // второй вариант
и
 GetDiskFreeSpaceEx(PChar('\\.\CdRom0\), ..., Size_Total, ...) // третий вариант
Сравниваем результаты:
Size_Calc = 725 614 592
Size_Total = 728 975 360
Size_Ex = 729 282 560
Объясните мне, пожалуйста, почему они различаются и что каждый из них под собой подразумевает ?
Почему отличается результат, полученный GetDiskFreeSpaceEx, еще, худо-бедно, 
предположить можно (служебная информация и все такое),
но почему различаются Size_Ex и Size_Calc, мне совсем непонятно :(
P.S. 
CD-диск взят как пример.
Для дискеты:
Size_Calc = 1 474 560
Size_Total = 1 457 664
Size_Ex = получить не удается из-за EX-кода.
Для флешки:
Size_Calc = 123 379 200
Size_Total = 124 559 360
Size_Ex = 125 829 120

PM MAIL   Вверх
Rennigth
Дата 7.6.2007, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 8
Всего: 76



Riply, 
Ну ты бы могла хоть структурки с константами описать... :( Ну это так, лирика, очень уж лениво было. smile

А так по сути топа,
накатал примерчик:
Код

const
  IOCTL_DISK_GET_DRIVE_GEOMETRY_EX = $000700A0;
type

  MEDIA_TYPE = (Unknown, F5_1Pt2_512, F3_1Pt44_512, F3_2Pt88_512, F3_20Pt8_512,
    F3_720_512, F5_360_512, F5_320_512, F5_320_1024, F5_180_512, F5_160_512,
    RemovableMedia, FixedMedia, F3_120M_512, F3_640_512, F5_640_512, F5_720_512,
    F3_1Pt2_512, F3_1Pt23_1024, F5_1Pt23_1024, F3_128Mb_512, F3_230Mb_512,
    F8_256_128, F3_200Mb_512, F3_240M_512, F3_32M_512);

  PDISK_GEOMETRY = ^DISK_GEOMETRY;
  DISK_GEOMETRY = record
    Cylinders: LARGE_INTEGER;
    MediaType: MEDIA_TYPE;
    TracksPerCylinder: DWORD;
    SectorsPerTrack: DWORD;
    BytesPerSector: DWORD;
  end;

  PDISK_GEOMETRY_EX = ^DISK_GEOMETRY_EX;
  DISK_GEOMETRY_EX = record
    Geometry: DISK_GEOMETRY;
    DiskSize: LARGE_INTEGER;
    Data: array [0..0] of Byte;
  end;

var
  hDrive: DWORD;
  pDiskGeometry: PDISK_GEOMETRY_EX;
  pOvrlppd: POVERLAPPED;
  nOutBufferSize: DWORD;
  lpBytesReturned: DWORD;
  lSize: Int64;
  lTotalFreeSize, lTotalSize, lAVSize: LARGE_INTEGER;
begin
  {$R-}
//  hDrive := CreateFile ('\\.\\PhysicalDrive0', GENERIC_READ,
  hDrive := CreateFile ('\\.\CdRom0', GENERIC_READ,
    FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  if hDrive <> INVALID_HANDLE_VALUE then
  begin
    DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, nil, 0,
      nil, 0, lpBytesReturned, nil); (* Get Size *)

    if (GetLastError = ERROR_INSUFFICIENT_BUFFER)then
    begin
      nOutBufferSize := lpBytesReturned;
      pDiskGeometry := GetMemory(nOutBufferSize);
      ZeroMemory(pDiskGeometry, nOutBufferSize);
      if DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, nil, 0,
        pDiskGeometry, nOutBufferSize, lpBytesReturned, nil) then
      begin
        (* Вариант 1*)
        lSize := pDiskGeometry^.DiskSize.QuadPart;
        lstSizes.Items.Add(IntToStr(lSize));
        (* Вариант 2*)
        lSize := pDiskGeometry^.Geometry.Cylinders.QuadPart *
          pDiskGeometry^.Geometry.TracksPerCylinder *
          pDiskGeometry^.Geometry.SectorsPerTrack *
          pDiskGeometry^.Geometry.BytesPerSector;
        lstSizes.Items.Add(IntToStr(lSize));
        FreeMemory(pDiskGeometry);
      end else
      begin
        FreeMemory(pDiskGeometry);
        RaiseLastOSError;
      end;
  end else
    RaiseLastOSError;
  end;


  (* Вариант 3 *)
  if not Windows.GetDiskFreeSpaceEx(PChar('\\.\CdRom0\'), lAVSize, lTotalSize, @lTotalFreeSize) then
    RaiseLastOSError;
  lstSizes.Items.Add(IntToStr(lTotalSize.QuadPart));
end;


1й и 3й вариант у меня одинаковы. Почему отличается 2й будем думать... p.s. уже завтра.  smile  smile

Добавлено через 6 минут и 4 секунды
PSS: Пример не совсем удачный, непинайте если что  smile 

Это сообщение отредактировал(а) Rennigth - 7.6.2007, 17:10


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
Rouse_
Дата 7.6.2007, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 469
Регистрация: 23.4.2005

Репутация: 18
Всего: 29



IOCTL_DISK_GET_DRIVE_GEOMETRY_EX для флопиков не перекрыт в драйвере. Ну а остальное очень хорошо описано в DDK в том-же месте откуда взяты сами константы DeviceIoControl запросов.


--------------------
 Vae Victis
(Горе побежденным (лат.))
Демо с открытым кодом: http://rouse.drkb.ru 
PM MAIL WWW ICQ   Вверх
Riply
Дата 8.6.2007, 08:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(Rennigth @  7.6.2007,  17:09 Найти цитируемый пост)
Ну ты бы могла хоть структурки с константами описать... 

Sorry.
Думала, если кто-то заинтересуется вопросом, то приведу.

Цитата(Rennigth @  7.6.2007,  17:09 Найти цитируемый пост)
1й и 3й вариант у меня одинаковы.

У меня на некоторых CD дисках, тоже совпадают, но не на всех. 

Цитата(Rouse_ @  7.6.2007,  23:40 Найти цитируемый пост)
Ну а остальное очень хорошо описано в DDK в том-же месте откуда взяты сами константы DeviceIoControl запросов. 

У мненя не получилось найти там пояснения, что подразумевается под "размером диска" smile 
 
И еще вопрос. Наблюдается такой эффект:
Иногда DeviceIoControl на Floppy (в основном на нем ставлю эксперименты) начинает выдавать 
ошибку: ERROR_MEDIA_CHANGED ( Media in drive may have changed. ) при любом Io - коде.
Лечится открыванием флоппика в Explorer-е. В чем может быть дело ?
P.S. Открываю с доступом только на чтение(ну и читаю, разумеется). 
Используемые команды в DeviceIoControl:
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
IOCTL_DISK_GET_PARTITION_INFO_EX, IOCTL_STORAGE_QUERY_PROPERTY, 
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS.



PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0491 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.