在Windows上检测未安装的卷

时间:2012-01-12 17:36:28

标签: c++ windows

我希望能够检测到何时在Windows上卸载卷(它可能是外部USB / FireWire / eSATA驱动器,网络共享文件夹或任何其他类型的逻辑卷)。

我发现MSDN上的RegisterDeviceNotification()功能是检测USB驱动器连接/断开的常用功能。此功能是否也适用于所有类型的卷,或仅适用于外部物理设备? 如果没有,你是否知道我可以用它做什么(除了民意测验)?

最后一个问题,我是Windows上的C ++新手,RegisterDeviceNotification() doc说我的第一个参数应该是A handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter.

在我的情况下,我本来想在我的程序的main()函数中注册通知,并使用某种onNotificationReceived()方法来处理通知。我可以这样做(如果是,如何),还是我必须注册另一个在另一个进程中运行的窗口/服务?

3 个答案:

答案 0 :(得分:3)

WM_DEVICECHANGE通知应用程序已到达和删除卷,您甚至不必致电RegisterDeviceNotification()

寻找dbch_devicetype == DBT_DEVTYP_VOLUME

an example in the documentation

答案 1 :(得分:1)

获取已卸载驱动器的唯一卷名:http://help.lockergnome.com/windows2/unique-volume-unmounted-drive--ftopict477553.html

FSCTL_IS_VOLUME_MOUNTED确定是否已装入指定的卷,或者指定的文件或目录是否已装入卷:http://msdn.microsoft.com/en-us/library/windows/desktop/aa364574(v=vs.85).aspx

如何检测该驱动器号上是否装有卷。

bool DiskInDrive(
  std::wstring const& inDrive)
{
  std::wstring volume = std::wstring(L"\\\\.\\") + inDrive.substr(0, 2);

  HANDLE h = CreateFileW(
    volume.c_str(),
    GENERIC_READ,
    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    NULL,
    OPEN_EXISTING,
    0,
    NULL);

  if(h == INVALID_HANDLE_VALUE)
  {
    DWORD lastError = GetLastError();
    // 2 means "no disk", anything else means by inference "disk
    // in drive, but you do not have admin privs to do a
    // CreateFile on that volume".
    return lastError != 2;
  }

  DWORD bytesReturned; // ignored
  BOOL devSuccess = DeviceIoControl(h, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &bytesReturned, NULL);

  if(devSuccess == FALSE)
  {
    DWORD lastError = GetLastError();
    (void)lastError; // For debugging.
    // Presumably, any error means "no disk in drive", or more
    // accurately, "no volume mounted on that drive letter".
    CloseHandle(h);
    return false;
  }

  CloseHandle(h);
  return true;
}

答案 2 :(得分:0)

只是一个建议,但您可能需要考虑创建一个Windows Shell扩展,它可以接收有关系统各种更改的通知。

例如,实施IShellChangeNotify界面包含OnChange方法,该方法可以接收包括SHCNE_DRIVEREMOVED, SHCNE_MEDIAREMOVED, SHCNE_NETUNSHARE等在内的各种通知。

你必须创建并注册一个DLL(即它不是一个独立的exe),但我认为它会为你提供你正在寻找的各种通知。