1 1 1 1 1 1 1 1 1 1 Рейтинг 0.00 (0 Голоса(ов)

Получаем информацию о геометрии диска

В одной из моих программ необходимо было получать информацию геометрии диска (неважно, жесткий ли это диск, CD/DVD, или флешка). Может кому пригодятся куски кода.

Код Delphi:
  1. // Пробуем открыть
  2. hDevice := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(Drive)),GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
  3. if hDevice = INVALID_HANDLE_VALUE then
  4. begin
  5. ToLog('Ошибка выбора диска');
  6. inWork:=false;
  7. ListBox1.Enabled:=true;
  8. ButtonStart.Caption:='Start';
  9. Exit;
  10. end;
  11. // Читаем геометрию диска
  12. if not(GetDiskGeometry(hDevice,DiskGeometry)) then
  13. begin
  14. ToLog('Ошибка получения геометрии диска');
  15. inWork:=false;
  16. ListBox1.Enabled:=true;
  17. ButtonStart.Caption:='Start';
  18. Exit;
  19. end
  20. else
  21. begin
  22. ToLog('Цилиндров: '+IntToStr(DiskGeometry.Cylinders));
  23. ToLog('Тип носителя: '+IntToStr(DiskGeometry.MediaType)+' ('+DecodeMediaType(DiskGeometry.MediaType)+')');
  24. ToLog('Дорожек на цилиндр: '+IntToStr(DiskGeometry.TracksPerCylinder));
  25. ToLog('Секторов на дорожку: '+IntToStr(DiskGeometry.SectorsPerTrack));
  26. ToLog('Байтов на сектор: '+IntToStr(DiskGeometry.BytesPerSector));
  27. end;
  28. CloseHandle(hDevice);

Функция DecodeMediaType выдает описание типа носителя в строковом виде

Код Delphi:
  1. function TForm1.DecodeMediaType(mt: byte):string;
  2. var s: string;
  3. begin
  4. case mt of
  5. $00: s:='Неизвестный тип носителя';
  6. $01: s:='A 5.25" floppy, with 1.2MB and 512 bytes/sector';
  7. $02: s:='A 3.5" floppy, with 1.44MB and 512 bytes/sector';
  8. $03: s:='A 3.5" floppy, with 2.88MB and 512 bytes/sector';
  9. $04: s:='A 3.5" floppy, with 20.8MB and 512 bytes/sector';
  10. $05: s:='A 3.5" floppy, with 720KB and 512 bytes/sector';
  11. $06: s:='A 5.25" floppy, with 360KB and 512 bytes/sector';
  12. $07: s:='A 5.25" floppy, with 320KB and 512 bytes/sector';
  13. $08: s:='A 5.25" floppy, with 320KB and 1024 bytes/sector';
  14. $09: s:='A 5.25" floppy, with 180KB and 512 bytes/sector';
  15. $0A: s:='A 5.25" floppy, with 160KB and 512 bytes/sector';
  16. $0B: s:='Removable media other than floppy';
  17. $0C: s:='Fixed hard disk media';
  18. $0D: s:='A 3.5" floppy, with 120MB and 512 bytes/sector';
  19. $0E: s:='A 3.5" floppy, with 640KB and 512 bytes/sector';
  20. $0F: s:='A 5.25" floppy, with 640KB and 512 bytes/sector';
  21. $10: s:='A 5.25" floppy, with 720KB and 512 bytes/sector';
  22. $11: s:='A 3.5" floppy, with 1.2MB and 512 bytes/sector';
  23. $12: s:='A 3.5" floppy, with 1.23MB and 1024 bytes/sector';
  24. $13: s:='A 5.25" floppy, with 1.23MB and 1024 bytes/sector';
  25. $14: s:='A 3.5" floppy, with 128MB and 512 bytes/sector';
  26. $15: s:='A 3.5" floppy, with 230MB and 512 bytes/sector';
  27. $16: s:='An 8" floppy, with 256KB and 128 bytes/sector';
  28. $17: s:='A 3.5" floppy, with 200MB and 512 bytes/sector. (HiFD)';
  29. $18: s:='A 3.5" floppy, with 240MB and 512 bytes/sector. (HiFD)';
  30. $19: s:='A 3.5" floppy, with 32MB and 512 bytes/sector';
  31. end;
  32. DecodeMediaType:=s;
  33. end;

Переменная Drive тут берется из ListBox

Код Delphi:
Drive:= ListBox1.ItemIndex;

Функция GetDiskGeometry

Код Delphi:
  1. interface
  2. // ...
  3. const
  4. IOCTL_DISK_GET_DRIVE_GEOMETRY = $70000;
  5.  
  6. type
  7. TDiskGeometry = packed record
  8. Cylinders: Int64; // количество цилиндров
  9. MediaType: DWORD; // тип носителя
  10. TracksPerCylinder: DWORD; // дорожек на цилиндре
  11. SectorsPerTrack: DWORD; // секторов на дорожке
  12. BytesPerSector: DWORD; // байт в секторе
  13. end;
  14. // ...
  15. implementation
  16. // ...
  17. function TForm1.GetDiskGeometry(hDisk: Cardinal; var DiskGeometry: TDiskGeometry): boolean;
  18. var BytesReturned: DWORD;
  19. Res: boolean;
  20. begin
  21. Res := DeviceIoControl(hDisk,IOCTL_DISK_GET_DRIVE_GEOMETRY,nil,0,
  22. @DiskGeometry,SizeOf(TDiskGeometry),BytesReturned,nil);
  23. Res := Res and (BytesReturned = SizeOf(TDiskGeometry));
  24. GetDiskGeometry:=Res;
  25. end;

Список в ListBox я обновлял в лоб

Код Delphi:
  1. procedure TForm1.UpdateList;
  2. var Drive: byte;
  3. hD: Cardinal;
  4. DG:TDiskGeometry;
  5. begin
  6. Drive:= 0;
  7. ListBox1.Items.Clear;
  8. repeat
  9. hD := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(Drive)),GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
  10. if (hD=INVALID_HANDLE_VALUE) then
  11. break;
  12. GetDiskGeometry(hD,DG);
  13. CloseHandle(hD);
  14. ListBox1.Items.Add('\\.\PhysicalDrive'+IntToStr(Drive)+' - '+DecodeMediaType(DG.MediaType));
  15. if ((DG.MediaType=11) or (Drive=0)) then
  16. ListBox1.ItemIndex:=Drive;
  17. Drive:=Drive+1;
  18. until (Drive=255);
  19. end;

А сам вызов UpdateList производил по изменению состава устройств (соответственно, подключения, или извлечения флешки)

Код Delphi:
  1. procedure TForm1.ChangeDevice(var Msg: TMessage);
  2. begin
  3. UpdateList;
  4. end;

Для чего в uses нужно вписать модуль Messages, а в описании класса формы - указать, на какое сообщение реагировать.

Код Delphi:
  1. TForm1 = class(TForm)
  2. // ...
  3. procedure ChangeDevice(var Msg: TMessage); message WM_DEVICECHANGE;
  4. // ...

 

Оставьте свой комментарий

Оставить комментарий как гость

0
  • Комментариев нет