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

标签 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

我做错了什么?

最佳答案

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

Application developers should take note of new types of storage devices being introduced into the market with a physical media sector size of 4,096 bytes. The industry name for these devices is "Advanced Format". As there may be compatibility issues with directly introducing 4,096 bytes as the unit of addressing for the media, a temporary compatibility solution is to introduce devices that emulate a regular 512-byte sector storage device but make available information about the true sector size through standard ATA and SCSI commands. As a result of this emulation, there are in essence two sector sizes that developers will need to understand:

  • Logical Sector: The unit that is used for logical block addressing for the media. We can also think of it as the smallest unit of write
    that the storage can accept. This is the "emulation".
  • Physical Sector: The unit for which read and write operations to the device are completed in a single operation. This is the unit of atomic write, and what unbuffered I/O will need to be aligned to in
    order to have optimal performance and reliability characteristics.

关于c++ - DeviceIoControl 返回意外的物理扇区大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23445074/

相关文章:

C++ - 数组数学

c# - 找出当前用户的用户名-当多个用户登录时

c++ - 如何使应用程序具有大地址感知能力?

c++ - DirectWrite 文本位置因字体大小而异

c++ - 尝试用 C++ 编写 ppm 图像

c++ - 这是 g++ bug、libc bug,还是我疯了(或者也许这三个)?

windows - 尝试授予 IIS 7.5 中特定应用程序池标识的权限 - "object cannot be found"

Python,试图打开一个命令

c++ - 使用 Visual C++ 设计器在主窗口上进行控制?

c++ - 在声明和类名的定义中使用不同的类键是否合法?