Как прочитать определенный сектор диска с помощью команды ATA?
Я хочу прочитать определенный сектор (MBR Sector) диска, используя команды ATA в vC++. Я новичок в VC++, поэтому я сталкиваюсь с проблемой при отправке команды на диск с помощью DeviceIoControl. Я предоставляю код, который я использую для считывания сектора с помощью команды Read Sector(s)(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).
3 ответа
Спасибо всем за вашу помощь. Я получил решение. Маленькая вещь, которую я не заметил. Это Ата Флаги. Я должен отправить несколько флагов. Например.
pATAData->ataFlags = ATA_FLAGS_48BIT_COMMAND | ATA_FLAGS_DRDY_REQUIRED | ATA_FLAGS_DATA_IN
а также отправить команду ATA Opcode в PreviousTaskFile[6] также. И несколько вещей, на которые стоит обратить внимание: каков размер блока жесткого диска? Это может быть больше, чем 512 байт, особенно если это большой диск (1 ТБ...4 ТБ). Таким образом, вам необходимо соответствующим образом настроить размеры. Вы можете увидеть, каков размер, выполнив команду EC идентифицировать ATA, а затем посмотреть на результирующую структуру данных.
Спасибо, ребята, за вашу помощь. После долгого обсуждения я обнаружил, что мне нужно отправить расширенные команды для большого диска. Но сейчас я отправляю команду Read Sector(s) 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 );
Но здесь та же проблема. Команда выполнена успешно, но она не читает ни одного сектора. Я не могу найти ни одной ошибки.
Спасибо за помощь ребята. Я получил решение. Я не назначал дескриптор устройства в CurrentTaskFile.
pATAData->CurrentTaskFile[5] = (UCHAR)hDevice;
Но команда IDENTIFY_DEVICE(ECh) успешно отправляла без этого. Я не знаю, правильно это или неправильно, но это работает.