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

时间:2014-05-03 13:29:24

标签: c++ windows winapi kernel

我使用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'\0';
    logicalDrive.append(drive);

    hDevice = CreateFile(
        logicalDrive.c_str(),
        0, 
        0,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);

    if (hDevice == INVALID_HANDLE_VALUE)
    {
        std::cerr << "Error\n";
        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 << "Error\n";
        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:\WINDOWS\system32>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

我做错了什么?

2 个答案:

答案 0 :(得分:0)

这里没有错。来自MSDN的“文件缓冲”文章:

  

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

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

答案 1 :(得分:0)

4096个字节是8个扇区,称为簇。保存文件时,将保存到一个或多个群集中。如果文件的大小大于512字节,它将被保存到群集中。空扇区称为松弛。一些恶意软件将自己写入空白区域以隐藏起来。 FAT文件系统对一个群集使用16或32个扇区。