我正在编写一个后台应用程序,通过“优化快速删除”策略集将文件循环复制到USB记忆棒。但是,如果在此过程中部分删除了操纵杆(特别是在下面的WriteFile()调用中,它返回ERROR FILE NOT FOUND)应用程序挂起,则驱动器将永久无法从任何其他应用程序访问,并且PC无法关闭/已注销/重新启动等。所有正在运行的Windows资源管理器实例也会因此而挂起。
我已将问题追溯到删除操纵杆后发生的CloseHandle()调用,并发生上述错误。几乎就像CloseHandle()在驱动程序中无限期地阻塞因为棒不再存在?无论如何,如果WriteFile()返回ERROR FILE NOT FOUND,我已经设法通过简单地跳过CloseHandle()调用来解决这个问题。然而,这导致了另一个问题,即每隔一段时间,文件就会被无法恢复,并且修复它的唯一方法是使用chkdsk,或重新格式化棒。
请注意,这只发生在XP(SP2和3)上,Vista似乎没有遇到这个问题。代码片段如下:
HANDLE hFile = CreateFile(szFile,
GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
NULL,
CREATE_ALWAYS,
FILE_FLAG_WRITE_THROUGH,
NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
if (!WriteFile(hFile, pBuffer, dwBufferSize, &dwWritten))
{
int nLastError = GetLastError();
}
// If usb stick is removed during WriteFile(), ERROR_FILE_NOT_FOUND usually results.
// If handle is closed at this point then drive is inaccessible.
// If CloseHandle() is skipped, then file corruption occurs instead
if (nLastError != ERROR_FILE_NOT_FOUND)
{
CloseHandle(hFile);
}
}
我几乎尝试过CreateFile()的每个标志组合都无济于事。有没有人见过这个或者有任何好的想法如何避免出现这两个问题。我看到的驱动程序问题是在vista下默默修复的吗?
感谢您的帮助。
答案 0 :(得分:2)
它几乎就像是CloseHandle()在驱动程序中无限期地阻塞因为 棒不再存在?
听起来很合理。 CloseHandle()最终将发出一个文件系统IRP并且您没有使用非阻塞I / O,因此IRP将是同步的,但它看起来像实际文件系统突然从文件系统驱动程序下面消失, IRP永远不会完成。这意味着你被填充 - 导致文件系统IRP被发出的用户模式函数调用永远不会返回。
尝试使用非阻塞I / O - 这将极大地解决这个问题,至少从不挂起的角度来看。你仍然会遇到资源损失等问题,因为IRP仍会传递下来,几乎肯定还没有恢复,但至少你不会阻止它。
BTW,“优化快速删除”是我想说的,旨在减少正在进行的缓存量,并可能影响对文件系统的写入顺序,以减少损坏的可能性;我非常怀疑它是为了在写入期间文件系统离开时保留文件系统!你不应该对这会杀死文件系统感到惊讶。
答案 1 :(得分:1)
这似乎是一个驱动程序问题。
您必须释放驱动程序的所有句柄,让它自行清理,然后卸载窗口。当你不这样做时,驱动程序认为它仍然对设备负责,即使它已经改变了。
您无法在用户模式下解决此问题。
放弃句柄只会将问题转移到稍后阶段(例如,退出程序,以便Windows尝试关闭所有已放弃的打开句柄。)
答案 2 :(得分:0)
关于悬挂问题:你可以生成一个单独的线程进行编写,监督主线程的写入过程,如果它花费了很长时间就中止写入线程。换句话说:异步实现写入并查找超时。
答案 3 :(得分:0)
文件系统驱动程序而不是硬件驱动程序是否有问题?您可能会发现,如果使用NTFS,问题就会消失。