win7 writefile写磁盘失败解决
引用链接:http://msdn.microsoft.com/en-us/library/windows/desktop/aa364562.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364575(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364814(v=vs.85).aspx
1.在xp下,对磁盘的写是直接用writefile就可以,但对于win7(即Windows Vista),MicroSoft帮助与支持已MicroSoft官网上给出了变更说明,
2.此点引自MicroSoft帮助与支持[http://support.microsoft.com/kb/942448]:在 Windows Vista 和 Windows Server 2008 中对文件系统和存储堆栈进行的更改可限制对磁盘和卷的直接访问,
3.对于Windows Vista 和 Windows Server 2008以下情况,则存储驱动器可以写入磁盘句柄:
情况 1:正要写入的扇区不位于卷内(空隙块与分区表)。
注意:程序使用卷之外的扇区来存储元数据。分区表也位于卷之外的扇区中。由于这些扇区不受任何文件系 统的控制,因此没有理由阻止对这些扇区的访问。
情况 2:已经通过锁定请求或卸载请求显式锁定卷
情况 3:正要写入的扇区位于未安装或者无文件系统的卷内(这个是原生磁盘块,没有受操作系统的管理, 当然可以随便写)。
4.所以我们对于磁盘空隙块与分区表等磁盘位置是可以像xp那样写的,但对于盘的数据区的写入则应该采用情况2的方法,即 显式锁定的已安装卷[后面说的FSCTL_LOCK_VOLUME或FSCTL_DISMOUNT_VOLUME ],一般是采用FSCTL_DISMOUNT_VOLUME,FSCTL_LOCK_VOLUME的前提是没有程序占用该盘的文件,所以可能会失败,FSCTL_DISMOUNT_VOLUME是强制型的,当我们强制卸载请求显式锁定卷后,一些正在占用磁盘的程序会出现崩溃,原因是它不能读盘上资源,注:对于FSCTL_DISMOUNT_VOLUME, If the specified volume is a system volume or contains a page file, the operation fails.所以不能对C盘强制成功
5.通用步骤是如下,
To change a volume file system:
1)Open a volume.
2)Lock the volume.
3)Format the volume.
4)Dismount the volume.
5)Unlock the volume.
6)Close the volume handle.
6.代码:(这是mfc中测试通过的代码)
方案一:
/
HANDLE HDevice=CreateFile(
“\\.\D:”,//(注:这里名称不能为\\.\PHYSICALDRIVEn(n为0-256),即物理磁盘,只能对逻辑分区锁定与DISMOUNT操作)
GENERIC_READ|GENERIC_WRITE, //对资源的读写操作权限
FILE_SHARE_READ|FILE_SHARE_WRITE,//共享模式
0, //指向安全属性的指针
OPEN_EXISTING, // 如何操作,这里是打开存在的资源
FILE_ATTRIBUTE_NORMAL, // 文件属性
NULL //如果不为零,则指定一个文件句柄,新文件将从这个文件中复制扩展属性
);
if (HDevice==INVALID_HANDLE_VALUE)
{
MessageBox(“打开磁盘句柄失败”);
break;
}
//
DWORD dwByteReturned;
BOOL bLOCK=DeviceIoControl(
HDevice,
FSCTL_LOCK_VOLUME,
NULL,
0,
NULL,
0,
&dwByteReturned,
NULL
);
if (!bLOCK)
MessageBox(csPartition+” FSCTL_LOCK_VOLUME 失败”,”提示”,MB_ICONINFORMATION);
WriteFile(…操作)//这里可以是\\.\PHYSICALDRIVEn得到的句柄,但只限锁定的逻辑盘区写入
BOOL bUNLOCK=DeviceIoControl(
HDevice,
FSCTL_UNLOCK_VOLUME, //锁定后要解锁
NULL,
0,
NULL,
0,
&dwByteReturned,
NULL
);
if (!bUNLOCK)
MessageBox(csPartition+” FSCTL_UNLOCK_VOLUME 失败”,”提示”,MB_ICONINFORMATION);
CloseHandle(HDevice);
方案二:
/
HANDLE HDevice=CreateFile(
“\\.\D:”,//(注:这里名称不能为\\.\PHYSICALDRIVEn(n为0-256),即物理磁盘,只能对逻辑分区锁定与DISMOUNT操作)
GENERIC_READ|GENERIC_WRITE, //对资源的读写操作权限
FILE_SHARE_READ|FILE_SHARE_WRITE,//共享模式
0, //指向安全属性的指针
OPEN_EXISTING, // 如何操作,这里是打开存在的资源
FILE_ATTRIBUTE_NORMAL, // 文件属性
NULL //如果不为零,则指定一个文件句柄,新文件将从这个文件中复制扩展属性
);
if (HDevice==INVALID_HANDLE_VALUE)
{
MessageBox(“打开磁盘句柄失败”);
break;
}
BOOL bDISMOUT=DeviceIoControl(
HDevice,
FSCTL_DISMOUNT_VOLUME,
NULL,
0,
NULL,
0,
&dwByteReturned,
NULL
);
if (!bDISMOUT)
MessageBox(csPartition+” FSCTL_DISMOUNT_VOLUME 失败”,”提示”,MB_ICONINFORMATION);
WriteFile(…操作)//这里可以是\\.\PHYSICALDRIVEn得到的句柄,但只限锁定的逻辑盘区写入
CloseHandle(HDevice);
注:写磁盘的速度会比较慢,与读的无法比的,原因未知,msdn上的这个问题的求问:http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/2699870a-526c-4135-9068-4f49837fcc6d/writefile-and-locking-writing-sectors-in-windows-7?forum=windowscompatibility