您的位置:首页 > 其它

win7 writefile写磁盘失败解决

2016-03-21 16:32 375 查看
引用链接: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: