Получаем информацию о геометрии диска
В одной из моих программ необходимо было получать информацию геометрии диска (неважно, жесткий ли это диск, CD/DVD, или флешка). Может кому пригодятся куски кода.
Код Delphi:
// Пробуем открыть hDevice := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(Drive)),GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0); if hDevice = INVALID_HANDLE_VALUE then begin ToLog('Ошибка выбора диска'); inWork:=false; ListBox1.Enabled:=true; ButtonStart.Caption:='Start'; Exit; end; // Читаем геометрию диска if not(GetDiskGeometry(hDevice,DiskGeometry)) then begin ToLog('Ошибка получения геометрии диска'); inWork:=false; ListBox1.Enabled:=true; ButtonStart.Caption:='Start'; Exit; end else begin ToLog('Цилиндров: '+IntToStr(DiskGeometry.Cylinders)); ToLog('Тип носителя: '+IntToStr(DiskGeometry.MediaType)+' ('+DecodeMediaType(DiskGeometry.MediaType)+')'); ToLog('Дорожек на цилиндр: '+IntToStr(DiskGeometry.TracksPerCylinder)); ToLog('Секторов на дорожку: '+IntToStr(DiskGeometry.SectorsPerTrack)); ToLog('Байтов на сектор: '+IntToStr(DiskGeometry.BytesPerSector)); end; CloseHandle(hDevice);
Функция DecodeMediaType выдает описание типа носителя в строковом виде
Код Delphi:
function TForm1.DecodeMediaType(mt: byte):string; var s: string; begin case mt of $00: s:='Неизвестный тип носителя'; $01: s:='A 5.25" floppy, with 1.2MB and 512 bytes/sector'; $02: s:='A 3.5" floppy, with 1.44MB and 512 bytes/sector'; $03: s:='A 3.5" floppy, with 2.88MB and 512 bytes/sector'; $04: s:='A 3.5" floppy, with 20.8MB and 512 bytes/sector'; $05: s:='A 3.5" floppy, with 720KB and 512 bytes/sector'; $06: s:='A 5.25" floppy, with 360KB and 512 bytes/sector'; $07: s:='A 5.25" floppy, with 320KB and 512 bytes/sector'; $08: s:='A 5.25" floppy, with 320KB and 1024 bytes/sector'; $09: s:='A 5.25" floppy, with 180KB and 512 bytes/sector'; $0A: s:='A 5.25" floppy, with 160KB and 512 bytes/sector'; $0B: s:='Removable media other than floppy'; $0C: s:='Fixed hard disk media'; $0D: s:='A 3.5" floppy, with 120MB and 512 bytes/sector'; $0E: s:='A 3.5" floppy, with 640KB and 512 bytes/sector'; $0F: s:='A 5.25" floppy, with 640KB and 512 bytes/sector'; $10: s:='A 5.25" floppy, with 720KB and 512 bytes/sector'; $11: s:='A 3.5" floppy, with 1.2MB and 512 bytes/sector'; $12: s:='A 3.5" floppy, with 1.23MB and 1024 bytes/sector'; $13: s:='A 5.25" floppy, with 1.23MB and 1024 bytes/sector'; $14: s:='A 3.5" floppy, with 128MB and 512 bytes/sector'; $15: s:='A 3.5" floppy, with 230MB and 512 bytes/sector'; $16: s:='An 8" floppy, with 256KB and 128 bytes/sector'; $17: s:='A 3.5" floppy, with 200MB and 512 bytes/sector. (HiFD)'; $18: s:='A 3.5" floppy, with 240MB and 512 bytes/sector. (HiFD)'; $19: s:='A 3.5" floppy, with 32MB and 512 bytes/sector'; end; DecodeMediaType:=s; end;
Переменная Drive тут берется из ListBox
Код Delphi:Drive:= ListBox1.ItemIndex;
Функция GetDiskGeometry
Код Delphi:
interface // ... const IOCTL_DISK_GET_DRIVE_GEOMETRY = $70000; type TDiskGeometry = packed record Cylinders: Int64; // количество цилиндров MediaType: DWORD; // тип носителя TracksPerCylinder: DWORD; // дорожек на цилиндре SectorsPerTrack: DWORD; // секторов на дорожке BytesPerSector: DWORD; // байт в секторе end; // ... implementation // ... function TForm1.GetDiskGeometry(hDisk: Cardinal; var DiskGeometry: TDiskGeometry): boolean; var BytesReturned: DWORD; Res: boolean; begin Res := DeviceIoControl(hDisk,IOCTL_DISK_GET_DRIVE_GEOMETRY,nil,0, @DiskGeometry,SizeOf(TDiskGeometry),BytesReturned,nil); Res := Res and (BytesReturned = SizeOf(TDiskGeometry)); GetDiskGeometry:=Res; end;
Список в ListBox я обновлял в лоб
Код Delphi:
procedure TForm1.UpdateList; var Drive: byte; hD: Cardinal; DG:TDiskGeometry; begin Drive:= 0; ListBox1.Items.Clear; repeat hD := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(Drive)),GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0); if (hD=INVALID_HANDLE_VALUE) then break; GetDiskGeometry(hD,DG); CloseHandle(hD); ListBox1.Items.Add('\\.\PhysicalDrive'+IntToStr(Drive)+' - '+DecodeMediaType(DG.MediaType)); if ((DG.MediaType=11) or (Drive=0)) then ListBox1.ItemIndex:=Drive; Drive:=Drive+1; until (Drive=255); end;
А сам вызов UpdateList производил по изменению состава устройств (соответственно, подключения, или извлечения флешки)
Код Delphi:
procedure TForm1.ChangeDevice(var Msg: TMessage); begin UpdateList; end;
Для чего в uses нужно вписать модуль Messages, а в описании класса формы - указать, на какое сообщение реагировать.
Код Delphi:
TForm1 = class(TForm) // ... procedure ChangeDevice(var Msg: TMessage); message WM_DEVICECHANGE; // ...
Оставьте свой комментарий
Войдите, чтобы оставлять комментарии
Оставить комментарий как гость