我需要直接写一些物理设备。我遵循下面列出的帖子和下面的MSDN页面中给出的指示。但是我的代码仍然在函数writeDisk(HANDLE hDevice)
中失败,错误代码为:
[87] The parameter is incorrect
。
但是问题的根源似乎并不存在。
除此之外。卸载设备后,它无法工作(我仍然可以从系统资源管理器中访问它),锁定设备后也会发生同样的情况。
我已经检查了以下链接:
* Microsoft Docs: Calling DeviceIoControl
* StackOverflow: How to explicitly lock a mounted file system?
* StackOverflow: CreateFile: direct write operation to raw disk "Access is denied"
* StackOverflow: Can I get write access to raw disk sectors under Vista and Windows 7 in user mode?
但可悲的是,它们都不适合我。最有用的线程是前两个。
这是我的代码。编译后,您必须在具有管理员权限的情况下运行该应用程序,以便以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 */
}