Мне нужно напрямую написать на какое-то физическое устройство. Я следую указаниям, приведенным в приведенных ниже сообщениях и на странице 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 */
}