4

如何HANDLE在某些设备上获取文件*,并且阻止用户弹出设备?

我试过用我能想到的最自由的访问权限调用CreateFile(甚至是)——即访问权限和共享权限,但它仍然不起作用。NtCreateFileFILE_READ_ATTRIBUTESFILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE

FileTest是一个很好的测试工具,无需编写程序。)


*更新:

真的很喜欢这个解决方案,它也适用于驱动器的句柄(不仅仅是文件)——我的意思是喜欢\\.\D:\\.\PhysicalDrive0. 但如果没有这样的解决方案,那么文件句柄也会很有用。

4

2 回答 2

2

你不能。

但是您可以做的是观察弹出设备消息,然后关闭您拥有的所有句柄。

设备事件 (MSDN)

于 2012-07-02T08:01:03.780 回答
2

应该清楚的是,在安装卷时获取文件句柄是微不足道的。

当卷被强制卸载时会发生什么?所有文件句柄都变为无效。尝试使用它们会返回错误。

这些代码片段强制卸载卷,以便后续代码可以对其进行直接 i/o。这是我几年前写的一个磁盘清理实用程序(一种大众消费产品)的摘录。

char    fn [20];

sprintf (fn, "\\\\.\\%s:", vol -> GetVolName ());
vol_lock_handle = CreateFile (fn, GENERIC_READ,
                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                OPEN_EXISTING,
                FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS,
                NULL);

fprintf (stderr,
 "Warning:  volume dismount will disrupt or kill all processes with open files!\n"
 "Before confirming, verify no critical processes have open files on volume %s:\n"
 "   Are you sure you want to dismount this volume? ('YES' to proceed)? ",
         g_vol -> GetVolName ());

char    buf [30];
if (!fgets (buf, sizeof buf, stdin)  ||  stricmp (buf, "yes\n"))
{
    fprintf (stderr, " Volume dismount not confirmed--canceled.\n");
    continue;
}
DWORD   status;
if (!DeviceIoControl (vol_lock_handle, FSCTL_DISMOUNT_VOLUME,
                        NULL, 0, NULL, 0, &status, NULL))
{
    DWORD err = GetLastError ();
    fprintf (stderr, "Error %d attempting to dismount volume: %s\n",
            err, w32errtxt (err));
}

我完全知道这段代码看起来有多么错误。获取 GENERIC_READ 句柄用于卸载,然后获取卷锁,然后写入。有用!

于 2012-07-02T05:46:41.730 回答