delphi - 有没有办法确定 NTFS 以外的文件系统(如 FAT16、exFAT...)的可移动驱动器的物理扇区大小?

标签 delphi filesystems disk

我需要一个函数来获取 Win7 或更高版本中所有类型系统驱动器的物理扇区大小。

这是我直到今天才使用的代码,当时我发现它无法与我的外部 USB HDD(exFAT 文件系统)和 USB MP3 播放器 (FAT16) 配合使用。在这些情况下,函数 DeviceIoControl 失败,并且出现异常:“系统错误。代码 50。不支持该请求”。但它与 NTFS 卷配合得很好。

function GetSectorSize(Drive:Char):DWORD;
var h:THandle;
    junk:DWORD;
    Query:STORAGE_PROPERTY_QUERY;
    Alignment:STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR;
begin
 result:=0;
 h:=CreateFileW(PWideChar('\\.\'+UpperCase(Drive)+':'),0,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
 if h=INVALID_HANDLE_VALUE then RaiseLastOSError;
 try
  FillChar(Query,SizeOf(Query),0);
  Query.PropertyId:=StorageAccessAlignmentProperty;
  Query.QueryType:=PropertyStandardQuery;
  if not DeviceIoControl(h,IOCTL_STORAGE_QUERY_PROPERTY,@Query,SizeOf(Query),@Alignment,SizeOf(Alignment),junk,nil) then RaiseLastOSError;
  result:=Alignment.BytesPerPhysicalSector;
 finally
  CloseHandle(h);
 end;
end;

最佳答案

根据 MSDN:

File Buffering

Most current Windows APIs, such as IOCTL_DISK_GET_DRIVE_GEOMETRY and GetDiskFreeSpace, will return the logical sector size, but the physical sector size can be retrieved through the IOCTL_STORAGE_QUERY_PROPERTY control code, with the relevant information contained in the BytesPerPhysicalSector member in the STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR structure. For an example, see the sample code at STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR. Microsoft strongly recommends that developers align unbuffered I/O to the physical sector size as reported by the IOCTL_STORAGE_QUERY_PROPERTY control code to help ensure their applications are prepared for this sector size transition.

同样的引用也出现在以下 MSDN 文档中:

Advanced format (4K) disk compatibility update

其中包括以下附加信息:

The below list summarizes the new features delivered as part of Windows 8 and Windows Server 2012 to help improve customer and developer experience with large sector disks. More detailed description for each item follow.
...
•Provides a new API to query for physical sector size (FileFsSectorSizeInformation)
...

Here’s how you can query for the physical sector size:
Preferred method for Windows 8

With Windows 8, Microsoft has introduced a new API that enables developers to easily integrate 4K support within their apps. This new API supports even greater numbers of scenarios than the legacy method for Windows Vista and Windows 7 discussed below. This API enables these calling scenarios:

•Calling from an unprivileged app
•Calling to any valid file handle
•Calling to a file handle on a remote volume over SMB2
•Simplified programming model

The API is in the form of a new info class, FileFsSectorSizeInformation, with associated structure FILE_FS_SECTOR_SIZE_INFORMATION

FILE_FS_SECTOR_SIZE_INFORMATION structure

This information can be queried in either of the following ways:

•Call FltQueryVolumeInformation or ZwQueryVolumeInformationFile, passing FileFsSectorSizeInformation as the value of FileInformationClass and passing a caller-allocated, FILE_FS_SECTOR_SIZE_INFORMATION-structured buffer as the value of FileInformation.

•Create an IRP with major function code IRP_MJ_QUERY_VOLUME_INFORMATION.

•Call FsRtlGetSectorSizeInformation with a pointer to a FILE_FS_SECTOR_SIZE_INFORMATION-structured buffer. The FileSystemEffectivePhysicalBytesPerSectorForAtomicity member will not have a value initialized by the file system when this structure is returned from FsRtlGetSectorSizeInformation. A file system driver will typically call this function and then set its own value for FileSystemEffectivePhysicalBytesPerSectorForAtomicity.

关于delphi - 有没有办法确定 NTFS 以外的文件系统(如 FAT16、exFAT...)的可移动驱动器的物理扇区大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26149623/

相关文章:

delphi - 如何从 Rich Edit 控件导出未格式化的文本?

c# - 如何在 C# 中找到包含给定分区的磁盘?

delphi - 存在哪些库可以在delphi中创建 "moving/living"UI?

delphi - 如何加载JPE图像文件?

linux - 如何配置 lxc 2.0 配置文件以使用多个 overlayfs 下层?

python - 监视文件系统中发生的事件

linux - 命令在终端提示符下可用,但无处可寻

mysql - 将 mysql 数据分布到多个磁盘

filesystems - 反向/跨步/扩展和pwrite的典型应用程序有哪些用途?

delphi - 提示指令的语法规范