开发者

Take disks online/offline

I have a program that is doing raw IO to disks within Windows.

All works fine if the target disk is online. However, the default behavior in some Windows OSes is to have new disks initially offline.

I am having a hard time finding the correct API to do this on Windows. The comman开发者_开发技巧d line equivalent would be something like:

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

However I need to be able to do this in code. I looked through the DeviceIoControl Win32 API (which I think is right) but cannot determine which control code to use. The fact that I can't find it makes me think I might be missing a better API to use.


For future generations, the answer (on Win 2k3/Vista and later) is the Virtual Disk Service (VDS). There's some work getting it all together, especially if you don't use COM objects within .NET that much.

Disk online/offline is done with IVdsDrive::SetStatus. At least it should; I found that I could solve my problem with simply disabling read-only status on my disk. I was able to do this with IVdsDisk::SetFlags with the appropriate flag value.


This question has a couple useful links to the Windows API, including the DeviceIOControl method.

After looking through all of the enumerations, I could not find anything related to bringing a disk online, or make any interesting change to the disk beyond formatting/partitions. This is likely because only hot-swappable hard drives are supported by this functionality. The market for hot-swappable hard drives is very small, and the vast majority of those situations there are drivers to support any needed operations. Finally the remainder should be able to use the diskpart tool for whatever is necessary.

You need to look again at your requirements I think. You are running a process that has the rights necessary to online a hard disk, but cannot access a command line program? Here are some suggestions for common reasons to not use a command line program:

  • Can't have a black screen pop up - tons of solutions to this problem available online
  • Security team won't allow it - you are already running the process as an administrator so you trust it, why wouldn't you trust the built in Windows function
  • Technical problems preclude calling other processes - I would be interested in how this was managed given the process is running as an administrator
  • Coding guidelines such as "Always use the API" - there isn't one due to lack of need


Not sure about C#, but I'm using this in C++: Try calling DeviceIoControl() with IOCTL_DISK_SET_DISK_ATTRIBUTES. The file handle must have read and write access. I think it requires at least Windows 7. It doesn't work on Windows 2003 x64. Windows 8 successfully takes the disk offline and then you can rewrite it from a backup.

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


Using DeviceIoControl and IOCTL_DISK_IS_WRITABLE control code, it is possible to check if disk is writable. If the disk is offline it returns false. This means that it is possible to determine if disk is offline and it works fine with Windows 2003 and after. However, I could not find any useful IOCTL to bring the disk online on Windows 2003. IOCTL_DISK_SET_DISK_ATTRIBUTES only works with Windows 2008 and after.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜