如何使用ATA命令读取磁盘的特定扇区?

问题描述 投票:1回答:4

我想使用vc ++中的ATA命令读取磁盘的特定扇区(MBR扇区)。我是VC ++的新手,因此在使用DeviceIoControl向磁盘发送命令时遇到了问题。我正在提供一个代码,用于使用命令读取扇区(0x20)读出扇区。

  BOOL status = FALSE;
 PATA_PASS_THROUGH_EX pATAData;
DWORD dataSize = sizeof(ATA_PASS_THROUGH_EX) + 512;
BYTE Buffer[sizeof(ATA_PASS_THROUGH_EX) + 512];
DWORD bytescopied = 0;

    pATAData = (ATA_PASS_THROUGH_EX*)Buffer;

    ZeroMemory(pATAData,dataSize); // clears the buffer

    pATAData->Length = sizeof(ATA_PASS_THROUGH_EX);
    pATAData->DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX);
    pATAData->DataTransferLength = 512;
    pATAData->TimeOutValue = 2;

    pATAData->CurrentTaskFile[1] = 0x01;
    pATAData->CurrentTaskFile[2] = 0x00;
    pATAData->CurrentTaskFile[3] = 0x00;
    pATAData->CurrentTaskFile[4] = 0x00;
    pATAData->AtaFlags =ATA_FLAGS_DATA_IN;

    pATAData->CurrentTaskFile[6] = 0x20; // command Read Sector(s)(0x20)
    /* sends the command to the device, **hDevice** is device handle*/
    status = DeviceIoControl(hDevice, IOCTL_ATA_PASS_THROUGH, pATAData, dataSize,Buffer, dataSize, &bytescopied, NULL );

我不能低下这段代码中的错误以及我在这里缺少的内容,但是它不起作用。我在这里想念什么?如果PATA_PASS_THROUGH_EX结构的参数存在问题,请告诉如何读取第一个扇区(MBR)。

c++ winapi hard-drive sata
4个回答
1
投票

谢谢大家的帮助。我找到了解决方案。我没有注意到的一点东西。那就是阿塔旗。我必须发送多个标志。例如。

pATAData->ataFlags = ATA_FLAGS_48BIT_COMMAND | ATA_FLAGS_DRDY_REQUIRED | ATA_FLAGS_DATA_IN

并且还要在PreviousTaskFile [6]中发送ATA命令操作码。而要注意的几件事是HDD的块大小是多少?它可能超过512个字节,特别是如果它是一个大磁盘(如(1TB ... 4TB))。因此,您需要相应地调整大小。您可以通过执行EC Identification ATA命令来查看大小,然后查看生成的数据结构。


0
投票

感谢您的帮助。我找到了解决方案。我没有在CurrentTaskFile中分配设备句柄。

pATAData->CurrentTaskFile[5] = (UCHAR)hDevice;

但是IDENTIFY_DEVICE(ECh)命令在没有此命令的情况下成功发送。我不知道这是对还是错,但这是可行的。


0
投票

感谢大家的帮助。经过长时间的讨论,我发现我必须为大型磁盘发送扩展命令。但是现在我正在发送读取扇区Ext(0x24 oppcode)命令。

BOOL status = FALSE;
PATA_PASS_THROUGH_EX pATAData;
DWORD dataSize = sizeof(ATA_PASS_THROUGH_EX) + 512;
BYTE Buffer[sizeof(ATA_PASS_THROUGH_EX) + 512];
DWORD bytescopied = 0;

pATAData = (ATA_PASS_THROUGH_EX*)Buffer;

ZeroMemory(pATAData,dataSize); // clears the buffer

pATAData->Length = sizeof(ATA_PASS_THROUGH_EX);
pATAData->DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX);
pATAData->DataTransferLength = 512;
pATAData->TimeOutValue = 2;

pATAData->CurrentTaskFile[0] = 0x00;
pATAData->CurrentTaskFile[1] = 0x01;
pATAData->CurrentTaskFile[2] = 0x01;
pATAData->CurrentTaskFile[3] = 0x00;
pATAData->CurrentTaskFile[4] = 0x00;
pATAData->CurrentTaskFile[5] = 0x40;
pATAData->CurrentTaskFile[7]=  0x00;
pATAData->AtaFlags =ATA_FLAGS_48BIT_COMMAND;

pATAData->PreviousTaskFile[0] = 0x00;
pATAData->PreviousTaskFile[1] = 0x00;
pATAData->PreviousTaskFile[2] = 0x00;
pATAData->PreviousTaskFile[3] = 0x00;
pATAData->PreviousTaskFile[4] = 0x00;
pATAData->PreviousTaskFile[5] = 0x04;
pATAData->PreviousTaskFile[7]=  0x00;

pATAData->CurrentTaskFile[6] = 0x24; // command Read Sector(s) Ext(0x24)
/* sends the command to the device, **hDevice** is device handle*/
status = DeviceIoControl(hDevice, IOCTL_ATA_PASS_THROUGH, pATAData, dataSize,Buffer, dataSize, &bytescopied, NULL );

但是这里是同样的问题。命令执行成功,但不读取任何扇区。我找不到任何错误。


0
投票

我也遇到同样的问题。我正在尝试向SATA磁盘发出READ SECTOR命令。您可以分享您的解决方案吗?

© www.soinside.com 2019 - 2024. All rights reserved.