Непосредственная запись на физический диск (Windows - winapi) - PullRequest
0 голосов
/ 08 апреля 2019

Мне нужно напрямую написать на какое-то физическое устройство. Я следую указаниям, приведенным в приведенных ниже сообщениях и на странице MSDN ниже. Но мой код все еще не работает в функции writeDisk(HANDLE hDevice) с кодом ошибки:
[87] The parameter is incorrect.
Но корень проблемы, похоже, не в этом.

Рядом с этим. Когда я отключаю устройство, оно не работает (я все еще могу получить к нему доступ из системного обозревателя), то же самое происходит после его блокировки.

Я уже проверил следующие ссылки:
* Документы Microsoft: вызов DeviceIoControl
* StackOverflow: Как явно заблокировать смонтированную файловую систему?
* StackOverflow: CreateFile: операция прямой записи на необработанный диск "Доступ запрещен"
* StackOverflow: Могу ли я получить доступ на запись в секторы сырых дисков под Vista и Windows 7 в пользовательском режиме?

Но, к сожалению, ни один из них не работает для меня. Самые полезные темы - первые два.

Вот мой код. После компиляции вы должны запустить приложение с правами администратора, чтобы открыть устройство с доступом WRITE:

/* This program attempts to directly write to a device (without respecting the file system) */

#include <stdio.h>
#include <windows.h>

BOOL dismountDisk(HANDLE hDevice);
BOOL lockDisk(HANDLE hDevice);
BOOL writeDisk(HANDLE hDevice);
void getSystemMessageString(DWORD errorCode, char *decodedMessage, unsigned long size);

/* Main function
   * Access the device
   * Dismount the device
   * Lock the device explicitly
   * Write to the device
   * Close handler
*/
int main()
{
    /* Access the device */
    HANDLE hDevice = CreateFileA(
        "\\\\.\\PHYSICALDRIVE2", /* device id (get it with `$ wmic DISKDRIVE`) */
        FILE_READ_DATA | FILE_WRITE_DATA, /* read/write access */
        FILE_SHARE_READ | FILE_SHARE_WRITE, /* shared */
        NULL, /* default security attributes */
        OPEN_EXISTING, /* only open if the device exists */
        0, /* file attributes */
        NULL); /* do not copy file attributes */

    if (hDevice == INVALID_HANDLE_VALUE) { /* cannot open the physical drive */
        fprintf(stderr, "Cannot open the device\n");
    } else { /* dismount and lock */
        BOOL result = dismountDisk(hDevice) && lockDisk(hDevice); /* try to dismount and lock the device */
        if (!result) { /* device not dismounted/locked */
            abort(); /* abort the operation */
        } else { /* OK */
            fprintf(stderr, "All OK. Check if the device has been dismounted and locked and press return to write.\n");
            getchar();
            writeDisk(hDevice); /* write to the disk */
        }
        CloseHandle(hDevice); /* close the handler to the device */
    }

    return 0;
}

/* Dismount disk */
BOOL dismountDisk(HANDLE hDevice)
{
    DWORD unused;
    BOOL b = DeviceIoControl(hDevice, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &unused, NULL);
    if (!b) {
        DWORD errorCode = GetLastError();
        char strBuff[500] = {0}; /* save the error message here */
        getSystemMessageString(errorCode, strBuff, 500);
        fprintf(stderr, "Error dismounting the device: [%lu] %s\n", errorCode, strBuff); /* print the error code and message */
    }
    return b;
}

/* Lock disk */
BOOL lockDisk(HANDLE hDevice)
{
    DWORD unused;
    BOOL b = DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &unused, NULL);
    if (!b) {
        DWORD errorCode = GetLastError();
        char strBuff[500] = {0}; /* save the error message here */
        getSystemMessageString(errorCode, strBuff, 500);
        fprintf(stderr, "Error locking the device: [%lu] %s\n", errorCode, strBuff); /* print the error code and message */
    }
    return b;
}

/* Write disk */
BOOL writeDisk(HANDLE hDevice)
{
    BYTE buffer[1000]; /* write 100 bytes */
    DWORD bytesWritten; /* to get the total amount of bytes written */
    BOOL b = WriteFile(hDevice, buffer, sizeof (buffer), &bytesWritten, NULL);
    if (!b) {
        DWORD errorCode = GetLastError();
        char strBuff[500] = {0}; /* save the error message here */
        getSystemMessageString(errorCode, strBuff, 500);
        fprintf(stderr, "Error writting the device: [%lu] %s\n", errorCode, strBuff); /* print the error code and message */
    } else {
        fprintf(stderr, "%lu bytes written.\n", bytesWritten);
    }
    return b;
}

/* Convert the error code returned by GetLastError into a human-readable string */
void getSystemMessageString(DWORD errorCode, char *decodedMessage, unsigned long size)
{
    FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
                  NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                  decodedMessage, size + 1, NULL);
    SetLastError(0); /* clear the last error */
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...