Delphi - Using DeviceIoControl passing IOCTL_DISK_GET_LENGTH_INFO to get flash media physical size (Not Partition)

前端 未结 2 1814
-上瘾入骨i
-上瘾入骨i 2021-01-06 14:21

Alright this is the result of a couple of other questions. It appears I was doing something wrong with the suggestions and at this point have come up with an error when usi

相关标签:
2条回答
  • 2021-01-06 14:43

    The question is already answered. As an alternative you can use IOCTL_DISK_GET_DRIVE_GEOMETRY to obtain disk size. Here a working code that I used in my project:

    const
      IOCTL_DISK_GET_DRIVE_GEOMETRY  = $00070000;
    
    type
    {$MINENUMSIZE 4}
      TMediaType = (
        Unknown,                // Format is unknown
        F5_1Pt2_512,            // 5.25", 1.2MB,  512 bytes/sector
        F3_1Pt44_512,           // 3.5",  1.44MB, 512 bytes/sector
        F3_2Pt88_512,           // 3.5",  2.88MB, 512 bytes/sector
        F3_20Pt8_512,           // 3.5",  20.8MB, 512 bytes/sector
        F3_720_512,             // 3.5",  720KB,  512 bytes/sector
        F5_360_512,             // 5.25", 360KB,  512 bytes/sector
        F5_320_512,             // 5.25", 320KB,  512 bytes/sector
        F5_320_1024,            // 5.25", 320KB,  1024 bytes/sector
        F5_180_512,             // 5.25", 180KB,  512 bytes/sector
        F5_160_512,             // 5.25", 160KB,  512 bytes/sector
        RemovableMedia,         // Removable media other than floppy
        FixedMedia,             // Fixed hard disk media
        F3_120M_512             // 3.5", 120M Floppy
      );
    {$MINENUMSIZE 1}
      PDiskGeometry = ^TDiskGeometry;
      TDiskGeometry = packed record
        Cylinders: int64;
        MediaType: TMediaType;
        TracksPerCylinder: DWORD;
        SectorsPerTrack: DWORD;
        BytesPerSector: DWORD;
      end;
    
    var
      H: THandle;
      BytesReturned: DWORD;
      DG: TDiskGeometry;
      DSize: int64;
    
    begin
      H:= CreateFile(PChar('\\.\G:'), GENERIC_READ,
        FILE_SHARE_WRITE or FILE_SHARE_READ, nil,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
      if Handle = INVALID_HANDLE_VALUE then
        raise Exception.Create('OOps!');
      if not DeviceIOControl(H, IOCTL_DISK_GET_DRIVE_GEOMETRY, nil, 0,
        @DG, SizeOf(TDiskGeometry), BytesReturned, nil) then
          raise Exception.Create('OOps #2!');
      DSize:= DG.Cylinders * DG.TracksPerCylinder;
      DSize:= DSize * (DG.SectorsPerTrack * DG.BytesPerSector);
      ShowMessage(IntToStr(DSize));
    end;
    
    0 讨论(0)
  • 2021-01-06 14:53

    I see what might be happening here.

    Try this:

    For every "FILE_SHARE_READ", change it to "FILE_SHARE_WRITE Or FILE_SHARE_READ"

    From msdn:

    "If you want to open a volume using \.\X:, you must use FILE_SHARE_WRITE | FILE_SHARE_READ, not just FILE_SHARE_WRITE. If you omit FILE_SHARE_READ, you'll get ERROR_NOT_SUPPORTED on most volumes"

    http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx

    EDIT:

    Your going to hate this, but the real reason it's failing is because your define for IOCTL_DISK_GET_LENGTH_INFO is wrong. Replace it with this:

    ((IOCTL_DISK_BASE shl 16) or (FILE_READ_ACCESS shl 14) or ($0017 shl 2) or METHOD_BUFFERED);
    

    Which turns out to be 0x7405C not 0x80070017

    0 讨论(0)
提交回复
热议问题