6

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 command 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.

Jon Egerton
  • 40,401
  • 11
  • 97
  • 129
Joe
  • 41,484
  • 20
  • 104
  • 125
  • why not just shell execute the command line from C#? – Neil N Sep 23 '11 at 16:02
  • 1
    For a number of reasons, but suffice to say that is not an option. If diskmgmt and diskpart can do it, there is a way. I want to know what that way is. – Joe Sep 23 '11 at 16:03
  • 1
    @joe - diskmgmt and diskpart are gui's to commands built into Windows they might use Win32 API. Considering they have been around for awhile thats unlikely. Everything you can do through those guis you can do through a command line. – Security Hound Sep 23 '11 at 16:11
  • 1
    @Ramhound: I understand that: there is a Win32 API *somewhere* that lets you do this. I cannot find it, thus my question. – Joe Sep 23 '11 at 16:12
  • 2
    How do you know it exists if you can't find it? – Neil N Sep 23 '11 at 16:14
  • You might use some kind of IRQ snooping driver and see what is it that diskpart does. – Anton Tykhyy Sep 23 '11 at 18:03

4 Answers4

4

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.

Joe
  • 41,484
  • 20
  • 104
  • 125
2

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;
}
Deanna
  • 23,876
  • 7
  • 71
  • 156
George Valkov
  • 1,217
  • 12
  • 10
2

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
Community
  • 1
  • 1
Guvante
  • 18,775
  • 1
  • 33
  • 64
  • There are actually a number of uses for dynamic disks outside of hot-swap. Thanks for the link, I saw that though as you note there's no real solutions in there. – Joe Sep 23 '11 at 17:28
  • @Joe: I meant the physical capability of the drive not the action – Guvante Sep 23 '11 at 18:05
1

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.

hagh
  • 507
  • 5
  • 13