下面这个程序首先用 CreateFile 打开 PhysicalDiskX 然后使用 CreateFile 向里面写入数据。
#include "stdafx.h" #include <windows.h> #include <stdio.h> #include <conio.h> int main(int argc, char *argv[]) { HANDLE hFile; BOOL fSuccess; char txchar[512]; DWORD iBytesWritten; hFile = CreateFile(L"\\\\.\\PhysicalDrive1", GENERIC_WRITE, FILE_SHARE_WRITE, // must be opened with exclusive-access NULL, // no security attributes OPEN_EXISTING, // must use OPEN_EXISTING 0, // not overlapped I/O NULL // hTemplate must be NULL for comm devices ); if (hFile == INVALID_HANDLE_VALUE) { // Handle the error. printf ("CreateFile failed with error %d.\n", GetLastError()); system("PAUSE"); return (1); } txchar[0]='l'; txchar[1]='a';txchar[2]='b';txchar[3]='z'; //有资料说用这个函数对磁盘写的最小值是 512 bytes 我实验了一下如果小于此会出现error fSuccess=WriteFile(hFile, &txchar, 512, &iBytesWritten,NULL); printf ("done send %d bytes.Status [%d] \n", iBytesWritten,fSuccess,iBytesWritten); printf ("Get lasterror %d\n", GetLastError()); system("PAUSE"); CloseHandle(hFile); return (0); }
我的实验是在虚拟机中进行的。特别提醒:本次实验可能会损害你的数据,请务必小心。如果系统有安装杀毒软件,有可能被判定为病毒行为。实验的目标盘是一个U盘,盘符为 G:
之后,先用 Winhex 打开,我们可以看到开始的几个字符是 abcd
运行我们的程序(可以看到发送 512 Bytes Status=1 表示 Success GetLastError=0 表示无错误)
我们需要重新打开一次硬盘(WinHex有磁盘修改感知功能,但是在这里不好用)
我们可以看到最开始的几个字符被修改了,这说明我们的程序是由效果的的。
完整的程序下载:
参考:
1.http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx MSDN WriteFile function
2.http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx MSDN System Error 对于确定 GetLastError 返回值很有用
3.http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx MSDN CreateFile function
不知道这么些为什么会成功,可能是编译器自动纠错,也可能是WriteFile会自动纠错
1.你命名注释了 FILE_SHARE_WRITE, // must be opened with exclusive-access
你却给共享了,
2.磁盘写的最小值是 512 bytes 这个的确没错,因为目前,估计今后也不会出现Sector小于 512B的磁盘
3.fSuccess=WriteFile(hFile, &txchar, 512, &iBytesWritten,NULL);
这里应该是 fSuccess=WriteFile(hFile, txchar, 512, &iBytesWritten,NULL); 吧?但写入结果居然正确,不太理解
4.你这样写,应该只能写入 512字节,如果你换成char txchar[1024]; 写入1024字节有可能会出错,这要看分区的位置。
原因是 你的磁盘 已经被windows mount为 G:了,你必须FSCTL_LOCK_VOLUME or FSCTL_DISMOUNT_VOLUME才能对其写入
谢谢哈 刚看到这个评论,后面我会试试。