C++ 以随机访问模式C+访问原始磁盘+;

C++ 以随机访问模式C+访问原始磁盘+;,c++,winapi,ioctl,C++,Winapi,Ioctl,现在,我已经熟悉了DeviceIoControl(ioctl)过程,可以按顺序从磁盘读取数据,每次512字节 我从\.\PhysicalDrive列表中创建一个句柄,并通过IOCTL\u STORAGE\u QUERY\u PROPERTY命令对其进行标识。然后处理所需设备的数据 在此,我可以通过创建一个循环来逐步读取它,这个循环每次用这个代码(Qt+C++环境)来推进读区域1扇区。 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 ... 句柄devHandle=NULL; de

现在,我已经熟悉了DeviceIoControl(ioctl)过程,可以按顺序从磁盘读取数据,每次512字节

我从\.\PhysicalDrive列表中创建一个句柄,并通过IOCTL\u STORAGE\u QUERY\u PROPERTY命令对其进行标识。然后处理所需设备的数据

在此,我可以通过创建一个循环来逐步读取它,这个循环每次用这个代码(Qt+C++环境)

来推进读区域1扇区。
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
...
句柄devHandle=NULL;
devHandle=CreateFile(字符数组,通用读取,通用写入,文件共享读取,文件共享写入,0,打开,0,空);
无符号长secCount=0;
while(true)
{
bSuccess=ReadFile(devHandle,lpSecBuf,512,&dwRead,NULL);
if(b成功&(dwRead<512))
{
qDebug()
read函数仍然不允许我将任何参数作为
“目的地”之类的,据我所知

这不是真的-请再次阅读

lpOverlapped[输入、输出、可选]

对于支持字节偏移的hFile,如果使用此参数,则 必须指定从文件或文件开始读取的字节偏移量 设备。此偏移量通过设置偏移量和偏移高度来指定 重叠结构的构件

这是:

使用文件句柄的注意事项:

•如果lpOverlapped不为空,则读取操作从偏移开始 在重叠结构中指定的


I/O管理器维护当前文件位置。(查找的
LARGE\u INTEGER CurrentByteOffset
成员)。
ReadFile
WriteFile
通过添加完成操作时读取或写入的字节数来更新当前文件位置。我们也可以通过调用
SetFilePointer[Ex]来设置此位置

如果我们在同步模式下打开文件(没有
file\u标志\u重叠
FLAG),所有与文件相关的操作都是连续的-任何新操作都不会开始执行,直到上一个操作未完成

在这种情况下,我们有两种选择:

  • 我们可以指定使用当前文件位置偏移量。此 可以通过传递一个
    NULL
    指针为
    lpOverlapped
  • 我们可以通过传递显式的
    lpOverlapped
    值设置为
    ReadFile
    WriteFile
    。这样做会自动更改 将当前文件位置设置为该
    (偏移量,偏移高度)
    值, 执行读(写)操作,然后更新位置 根据实际读取(写入)的字节数 该技术为调用者提供原子查找和读(写)服务
  • 因此,根据代码,我们有两种变体:

    BOOL _ReadFile(HANDLE hFile, LARGE_INTEGER ByteOffset, PVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead)
    {
    #if 1
        OVERLAPPED ov = {};
        ov.Offset = ByteOffset.LowPart;
        ov.OffsetHigh = ByteOffset.HighPart;
    
        return ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, &ov);
    #else
        if (SetFilePointerEx(hFile, ByteOffset, 0, FILE_BEGIN))
        {
            return ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, 0);
        }
        return FALSE;
    #endif
    }
    
    当然,与使用
    SetFilePointer[Ex]
    (对内核的附加API调用)相比,原子查找和读取(写入)更加有效

    如果我们在异步模式下打开文件(使用
    file\u标志\u重叠
    标志)-可以同时执行文件的多个读/写操作。在这种情况下,I/O管理器无法使用
    file\u对象中的文件位置,因为此处未定义此行为

    因此,我们必须始终显式地传递带有有效偏移量的
    lpOverlapped
    。如果我们传递lpOverlapped的
    NULL
    指针,我们得到
    ERROR\u INVALID\u参数
    ERROR

    最后但很重要。来自MSDN(第页和第页)

    系统更新读取文件之前的重叠偏移量(写入文件) 返回

    这是不正确的,文档中存在错误-您可以检查自己的
    OVERLAPPED
    偏移量在操作后未更新。这可能意味着当前文件位置(
    file\u OBJECT
    中的
    CurrentByteOffset
    )已更新。但再次检查
    OVERLAPPED
    偏移量在操作后未更新

    read函数仍然不允许我将任何参数作为 “目的地”之类的,据我所知

    这不是真的-请再次阅读

    lpOverlapped[输入、输出、可选]

    对于支持字节偏移的hFile,如果使用此参数,则 必须指定从文件或文件开始读取的字节偏移量 设备。此偏移量通过设置偏移量和偏移高度来指定 重叠结构的构件

    这是:

    使用文件句柄的注意事项:

    •如果lpOverlapped不为空,则读取操作从偏移开始 在重叠结构中指定的


    I/O管理器维护当前文件位置。(查找的
    LARGE\u INTEGER CurrentByteOffset
    成员)。
    ReadFile
    WriteFile
    通过添加完成操作时读取或写入的字节数来更新当前文件位置。我们也可以通过调用
    SetFilePointer[Ex]来设置此位置

    如果我们在同步模式下打开文件(没有
    file\u标志\u重叠
    FLAG),所有与文件相关的操作都是连续的-任何新操作都不会开始执行,直到上一个操作未完成

    在这种情况下,我们有两种选择:

  • 我们可以指定使用当前文件位置偏移量。此 可以通过传递一个
    NULL
    指针为
    lpOverlapped
  • 我们可以通过传递显式的
    lpOverlapped
    值设置为
    ReadFile
    WriteFile
    。这样做会自动更改 将当前文件位置设置为该
    (偏移量,偏移高度)
    值, 执行读(写)操作,然后更新位置 根据实际读取(写入)的字节数 该技术为调用者提供原子查找和读(写)服务
  • 因此,根据代码,我们有两种变体:

    BOOL _ReadFile(HANDLE hFile, LARGE_INTEGER ByteOffset, PVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead)
    {
    #if 1
        OVERLAPPED ov = {};
        ov.Offset = ByteOffset.LowPart;
        ov.OffsetHigh = ByteOffset.HighPart;
    
        return ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, &ov);
    #else
        if (SetFilePointerEx(hFile, ByteOffset, 0, FILE_BEGIN))
        {
            return ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, 0);
        }
        return FALSE;
    #endif
    }
    
    c的