WINAPI: невозможно прочитать с основного диска (PhysicalDrive0)

Решено: см. комментарии ниже. Должно быть прочитано количество байт, кратное 512 (или размеру сектора диска).

Я пытаюсь прочитать с моего основного диска (этот диск является SSD-диском, и операционная система хранится на этом диске), но функция продолжает давать сбой и считывает 0 байт. Я запускаю эту программу от имени администратора.

Вот мой код:

int main() {
    char a[100];

    HANDLE hMainDisk = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hMainDisk == INVALID_HANDLE_VALUE) {
        std::cout << "ERROR: Main disk could not be found.\n"; //This is not printed.
    }

    unsigned char data[1000];
    BOOL succeeded = ReadFile(hMainDisk, bootloaderData, 1000, &numBytesRead, 0);
    DWORD error = GetLastError();
    CloseHandle(hMainDisk);
    if (numBytesRead != 1000) {
        std::cout << "ERROR: Less than 1,000 bytes were read. Only " << numBytesRead << " bytes were read\n"; //This is printed.
    }
    if (succeeded == FALSE) {
        std::cout << "ERROR: Main disk read failed.\n"; //This is also printed
    }
    if (error == ERROR_INVALID_USER_BUFFER || error ==     ERROR_NOT_ENOUGH_MEMORY) {
        std::cout << "ERROR: Too many IO requests.\n"; //This is not printed
    }

    std::cin >> a;
    return 0;
 }

person A Programmer    schedule 13.06.2018    source источник
comment
И каков результат GetLastError?   -  person Adrian McCarthy    schedule 13.06.2018
comment
@AdrianMcCarthy 87   -  person A Programmer    schedule 13.06.2018
comment
Независимо от того, зачем идти в пропасть в этом коде, если файл createfile не удалось. Ваша ошибка указывает на неправильный параметр, кстати, но к тому времени уже слишком поздно. В чем ошибка сразу после сбоя создания файла? (или даже не получается? В вашем вопросе говорится, что функция продолжает давать сбой, но не говорит, какая именно).   -  person WhozCraig    schedule 13.06.2018
comment
это потому, что ваш файл (дисковый файл) имеет флаг FO_NO_INTERMEDIATE_BUFFERING. размер буфера - должен быть кратен размеру сектора тома. 1000 это плохая цена   -  person RbMm    schedule 13.06.2018
comment
@WhozCraig Значение кода ошибки после создания файла равно 0.   -  person A Programmer    schedule 13.06.2018
comment
@RbMm Спасибо. Изменение размера буфера на 512 заставило программу работать. Если вы опубликуете свой комментарий в качестве ответа, я приму его.   -  person A Programmer    schedule 13.06.2018
comment
Тогда я согласен с RbMm. Несмотря на то, что проверка GetLastError после успешного вызова API не имеет смысла, ограничения на чтение с физического тома довольно жесткие. Вы можете (и должны) использовать вызов ioctl для получения геометрии диска для расчета требуемого размера буфера. Угадывание такого значения, как 512, не всегда будет работать.   -  person WhozCraig    schedule 13.06.2018
comment
Я думаю, вам также может понадобиться выровнять буфер.   -  person David Heffernan    schedule 13.06.2018
comment
действительно вам нужно получить информацию о выравнивании через GetFileInformationByHandleEx(hMainDisk, FileAlignmentInfo, &fai, sizeof(fai)) или через NtQueryInformationFile с FileAlignmentInformation и размером сектора, скажем, IOCTL_DISK_GET_DRIVE_GEOMETRY - выровнять буфер и прочитать несколько секторов   -  person RbMm    schedule 13.06.2018