在线/离线获取磁盘

时间:2011-09-23 16:01:38

标签: c# winapi deviceiocontrol

我有一个程序正在为Windows中的磁盘执行原始IO。

如果目标磁盘在线,则一切正常。但是,某些Windows操作系统中的默认行为是让新磁盘最初脱机。

我很难在Windows上找到正确的API来执行此操作。等效的命令行类似于:

"select disk 2", "online disk" | diskpart

但是我需要能够在代码中执行此操作。我查看了DeviceIoControl Win32 API(我认为是正确的)但无法确定要使用的控件代码。我无法找到它的事实让我觉得我可能错过了一个更好的API来使用。

4 个答案:

答案 0 :(得分:4)

对于后代,答案(在Win 2k3 / Vista及更高版本上)是虚拟磁盘服务(VDS)。有一些工作可以将它们整合在一起,特别是如果你不在.NET中使用COM对象那么多。

使用IVdsDrive::SetStatus完成在线/离线磁盘。至少它应该;我发现只需禁用磁盘上的只读状态就可以解决我的问题。我能够使用IVdsDisk::SetFlags和适当的标志值来执行此操作。

答案 1 :(得分:2)

This question有一些指向Windows API的有用链接,包括DeviceIOControl方法。

查看了所有枚举后,我找不到与将磁盘联机相关的任何内容,或者在格式化/分区之外对磁盘进行任何有趣的更改。这可能是因为此功能仅支持热插拔硬盘驱动器。热插拔硬盘的市场非常小,绝大多数情况下都有支持任何所需操作的驱动程序。最后,剩余部分应该能够使用diskpart工具进行必要的操作。

我认为您需要再次查看您的要求。您正在运行具有联机硬盘所需权限的进程,但无法访问命令行程序?以下是一些不使用命令行程序的常见原因的建议:

  • 不能弹出黑屏 - 在线提供大量解决此问题的方案
  • 安全团队不会允许它 - 您已经以管理员身份运行该流程,因此您信任它,为什么您不相信内置的Windows功能
  • 技术问题阻止调用其他进程 - 如果进程以管理员身份运行,我会对如何管理这些进程感兴趣
  • 编码指南,例如“始终使用API​​” - 由于缺乏需要而没有

答案 2 :(得分:2)

不确定C#,但我在C ++中使用它: 尝试使用DeviceIoControl()致电IOCTL_DISK_SET_DISK_ATTRIBUTES。文件句柄必须具有读写访问权限。我认为它至少需要Windows 7.它不适用于Windows 2003 x64。 Windows 8成功使磁盘脱机,然后您可以从备份中重写它。

BOOL disk_offline(HANDLE h_file, bool enable){
DWORD bytes_returned = 0;
BOOL b_offline = 0;
if(get_size_volume_disk(h_file)){
    SET_DISK_ATTRIBUTES disk_attr;
    ZeroMemory(&disk_attr, sizeof(disk_attr));
    disk_attr.Version = sizeof(SET_DISK_ATTRIBUTES);
    disk_attr.Attributes = enable? DISK_ATTRIBUTE_OFFLINE: 0;
    disk_attr.AttributesMask = DISK_ATTRIBUTE_OFFLINE;
    b_offline = DeviceIoControl(h_file, IOCTL_DISK_SET_DISK_ATTRIBUTES, &disk_attr, disk_attr.Version, NULL, 0, &bytes_returned, NULL);
    // Invalidates the cached partition table and re-enumerates the device.
    if(!enable) BOOL b_update = DeviceIoControl(h_file, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &bytes_returned, NULL);
}
return b_offline;
}

答案 3 :(得分:0)

使用DeviceIoControl和IOCTL_DISK_IS_WRITABLE控制代码,可以检查磁盘是否可写。如果磁盘处于脱机状态,则返回false。这意味着可以确定磁盘是否处于脱机状态,并且可以在Windows 2003及之后正常运行。但是,我找不到任何有用的IOCTL来使磁盘在Windows 2003上联机.IOCTL_DISK_SET_DISK_ATTRIBUTES仅适用于Windows 2008及之后。