简体   繁体   English

如何防止设备弹出/安全移除?

[英]How do I NOT prevent a device from being eject/safely removed?

How do I get a HANDLE to a file* on some device, and not prevent the user from ejecting the device? 如何在某些设备上获取文件*的HANDLE ,而不是阻止用户弹出设备?

I've tried calling CreateFile (and even NtCreateFile ) with the most liberal access I can think of -- ie FILE_READ_ATTRIBUTES for access, and FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE 我试过用我能想到的最自由的访问来调用CreateFile (甚至是NtCreateFile ) - 即FILE_READ_ATTRIBUTES用于访问,而FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE for sharing permissions, but it still doesn't work. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE用于共享权限,但仍然无效。

( FileTest is a great tool for testing this, without writing a program.) FileTest是一个很好的测试工具,无需编写程序。)


*Update: *更新:

I'd really love the solution to work for handles to volumes or drives as well (not just files) -- I mean like \\\\.\\D: or \\\\.\\PhysicalDrive0 . 真的很喜欢解决方案来处理驱动器 (不仅仅是文件) - 我的意思是\\\\.\\D:\\\\.\\PhysicalDrive0 But if there's no such solution, then handles to files would also be useful. 但如果没有这样的解决方案,那么处理文件也会很有用。

It should be clear that obtaining a file handle while a volume is mounted is trivial. 应该清楚的是,在安装卷时获取文件句柄是微不足道的。

What happens when the volume is forcibly dismounted? 当卷被强行拆卸时会发生什么? All file handles become invalid. 所有文件句柄都无效。 Attempts to use them return errors. 尝试使用它们会返回错误。

These code snippets forcibly dismounts a volume so that subsequent code can do direct i/o on it. 这些代码段强制卸载卷,以便后续代码可以对其进行直接i / o操作。 This is excerpted from a disk cleaner utility (a mass consumer product) I wrote a few years back. 这是我几年前写的磁盘清洁工具(大众消费产品)的摘录。

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));
}

I am perfectly aware of how wrong this code looks. 我完全清楚这段代码有多么错误。 A GENERIC_READ handle is obtained for dismounting, then obtaining a volume lock, and then written to. 获取GENERIC_READ句柄,用于卸载,然后获取卷锁,然后写入。 It works! 有用!

You cannot. 你不能。

But what you can do is to watch for the eject device message and then close all the handles you have. 但您可以做的是观察弹出设备消息,然后关闭所有的手柄。

Device Events (MSDN) 设备事件(MSDN)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM