DeviceIoControl返回意外的物理扇区大小

DeviceIoControl returning unexpected physical sector size

本文关键字:扇区 返回 意外 DeviceIoControl      更新时间:2023-10-16

我使用DeviceIoControl返回物理磁盘扇区的大小。它一直返回512字节,直到最近才开始返回4096字节。检查结果STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR,我看到逻辑字节大小和物理字节大小交换了位置——磁盘扇区的逻辑字节大小不应该总是大于或等于物理扇区大小吗?

#include <Windows.h>
#include <iostream>
#include <Windows.h>
#pragma comment(lib, "Kernel32.lib")
int main()
{
    HANDLE hDevice;
    char cDisk = 'c';   // Get metadata about the C: disk
    // Build the logical drive path and get the drive device handle
    std::wstring logicalDrive = L"\\.\";
    wchar_t drive[3];
    drive[0] = cDisk;
    drive[1] = L':';
    drive[2] = L'';
    logicalDrive.append(drive);
    hDevice = CreateFile(
        logicalDrive.c_str(),
        0, 
        0,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);
    if (hDevice == INVALID_HANDLE_VALUE)
    {
        std::cerr << "Errorn";
        return -1;
    }   
    // Now that we have the device handle for the disk, let us get disk's metadata
    DWORD outsize;
    STORAGE_PROPERTY_QUERY storageQuery;
    memset(&storageQuery, 0, sizeof(STORAGE_PROPERTY_QUERY));
    storageQuery.PropertyId = StorageAccessAlignmentProperty;
    storageQuery.QueryType  = PropertyStandardQuery;
    STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR diskAlignment = {0};
    memset(&diskAlignment, 0, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR));
    if (!DeviceIoControl(hDevice, 
        IOCTL_STORAGE_QUERY_PROPERTY, 
        &storageQuery, 
        sizeof(STORAGE_PROPERTY_QUERY), 
        &diskAlignment,
        sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR), 
        &outsize,
        NULL)
        )
    {
        std::cerr << "Errorn";
        return -1;
    }
    std::cout << "Physical sector size: " diskAlignment.BytesPerPhysicalSector << std::endl;
    std::cout << "Logical sector size: " diskAlignment.BytesPerLogicalSector << std::endl;
    return 0;
}

运行上述代码的结果是:

Physical sector size: 4096
Logical sector size: 512

运行fsutil得到相同的意外结果。

C:WINDOWSsystem32>fsutil fsinfo ntfsinfo c:
NTFS Version   :                  3.1
LFS Version    :                  2.0
Number Sectors :                  0x000000001741afff
Total Clusters :                  0x0000000002e835ff
Free Clusters  :                  0x0000000000999d28
Total Reserved :                  0x0000000000003260
Bytes Per Sector  :               512
Bytes Per Physical Sector :       4096
Bytes Per Cluster :               4096
Bytes Per FileRecord Segment    : 1024
Clusters Per FileRecord Segment : 0

我做错了什么?

这里没有问题。摘自MSDN的"文件缓冲"文章:

应用程序开发人员应该注意新的存储类型与物理介质部门一起进入市场的设备大小为4,096字节。这些设备的行业名称是"Advanced"格式"。由于直接使用可能存在兼容性问题引入4096字节作为媒体的寻址单位,a临时兼容性解决方案是引入设备进行模拟一个常规的512字节扇区存储设备,但使其可用通过标准ATA和SCSI获取有关真实扇区大小的信息命令。作为这个模拟的结果,实际上有两个开发人员需要了解的扇区大小:

  • 逻辑扇区:用于媒体的逻辑块寻址的单元。我们也可以把它看作是write
    的最小单位。即存储可以接受。这是"仿真"。
  • 物理扇区:对设备的读和写操作在一次操作中完成的单元。这是单位原子写,以及在
    中需要对齐哪些未缓冲的I/O以获得最佳性能和可靠性特性。

4096字节是8个扇区,称为集群。当您保存文件时,您将保存到一个或多个集群中。如果文件的大小大于512字节,它将被保存到集群中。空的部分被称为松弛区。一些恶意软件将自己写入空扇区以隐藏在显眼的地方。FAT文件系统在一个集群中使用16或32个扇区