5

我有一个程序对 Windows 中的磁盘进行原始 IO。

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

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

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

但是我需要能够在代码中做到这一点。我查看了 DeviceIoControl Win32 API(我认为这是正确的),但无法确定要使用哪个控制代码。我找不到它的事实让我觉得我可能缺少更好的 API 来使用。

4

4 回答 4

4

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

磁盘在线/离线使用IVdsDrive::SetStatus完成。至少它应该;我发现我可以通过简单地禁用磁盘上的只读状态来解决我的问题。我能够使用具有适当标志值的IVdsDisk::SetFlags来做到这一点。

于 2011-09-24T11:04:09.257 回答
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;
}
于 2013-02-01T02:48:01.460 回答
2

这个问题有几个有用的 Windows API 链接,包括DeviceIOControl方法。

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

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

  • 无法弹出黑屏 - 可在线获得大量解决此问题的方法
  • 安全团队不允许 - 您已经以管理员身份运行该进程,所以您信任它,为什么不信任内置的 Windows 功能
  • 技术问题无法调用其他进程 - 我会对如何管理它感兴趣,因为该进程以管理员身份运行
  • 诸如“始终使用 API”之类的编码指南 - 由于缺乏需求,因此没有
于 2011-09-23T17:21:53.390 回答
0

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

于 2014-04-24T20:08:12.423 回答