10

How can I programatically determine if a hard drive is currently spinning or not (Windows 7 or later)?

I tried GetDevicePowerState() but it always returns TRUE (always 1, not another non-zero value) for drives that I know are currently not spinning (for both internal and USB drives). Immediately after GetDevicePowerState() returns TRUE, if I issue dir d: in a console, I hear the drive spin up and there is a several-second delay before the directory listing is generated.

My code needs to check if a directory on a drive exists. The check can be deferred or skipped if the drive is currently spun down. I want to avoid making the check on a spun down drive for 2 reasons: 1) the check is currently done synchronously and I don't want the user to have to wait for the drive to spin up 2) I don't want to cause the drive to spin up just to make my check (hopefully it is obvious why not).

Is there a way to do this?

Update based on comments:

It was suggested that GetDevicePowerState works with physical device names but I cannot get it to return anything other than 1 (again, for drives that I have verified are NOT spinning). The following is the code I am using. If GetDevicePowerState is indeed known to work with USB drives, is there perhaps something wrong with my arguments to CreateFile?

for (int DriveNumber = 0; DriveNumber < 128; ++DriveNumber) {
   TCHAR Drive[128];
   _stprintf (Drive, _T("\\\\.\\PHYSICALDRIVE%d"), DriveNumber);
   HANDLE hDevice = CreateFile(Drive, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
   if (hDevice != INVALID_HANDLE_VALUE) {
      BOOL DeviceIsOn = FALSE;
      if (GetDevicePowerState(hDevice, &DeviceIsOn) != 0) {
         _tprintf(_T("Physical Drive %d is Powered %s (DeviceIsOn=%d)\n"), DriveNumber, DeviceIsOn?_T("On"):_T("Off"), (int)DeviceIsOn);
      }
      CloseHandle(hDevice);
   }
}
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
Not Submitted
  • 653
  • 1
  • 7
  • 13
  • 9
    Listen for the "whirr" sound. – Hot Licks Mar 11 '14 at 18:36
  • 3
    That works, except I don't have the human brain interface API installed :-) – Not Submitted Mar 11 '14 at 18:38
  • Look at the source for hdparm, by sending the ATA_OP_CHECKPOWERMODE ioctl. – Damon Mar 11 '14 at 18:43
  • Damon-- Thanks. the DeviceIoControl method works nicely for ATA drives, but does not appear to work for USB drives. Any other ideas? – Not Submitted Mar 11 '14 at 19:21
  • `GetDevicePowerState` is the way to do it. Note that for a `DRIVE_FIXED` type drive, you have to use a handle to the physical drive (`"\\.\PhysicalDriveX"`) rather than the drive letter. – Jonathan Potter Mar 11 '14 at 20:02
  • What are you getting from your current code? Is `CreateFile` and/or `GetPowerState` failing (you skip output), or you're getting output for all drives indicating powered-up? – Ben Voigt Mar 11 '14 at 22:58
  • The documentation of `GetDevicePowerState` seems fairly clear, it lets you know whether the computer is providing power to the device or not, it's got nothing to do with the device's internal decision whether to spin the platters or not. I'm afraid that for USB devices it is entirely likely that there is no way of doing this. – Harry Johnston Mar 12 '14 at 01:12
  • If you **Desperately** want a solution on windows, then you might want to check this ( http://superuser.com/questions/173622/hdparm-checking-if-a-drive-is-spun-down ) and check how it woks on linux and **maybe** port it to windows. In the end , it may not work out, but atleast it will not be a wasted effort. – Prem May 09 '15 at 18:22
  • Note that the notion of "is drive currently spinning" is becoming more antiquated as each quarter goes by. A drive with a 4GB DRAM cache can do easily service the working set of an entire Windows client machine. And an SSD clearly never spins - also true of NVDIMMs. Hybrid drives are another case where the drive can be active without the platters spinning. Also note that a 25W NVMe SSD takes a lot more power than a lot of SATA drives. So if the question is related to power, "spinning" is not necessarily a good proxy for power use. – Χpẘ Jan 17 '16 at 23:49

1 Answers1

1

As I like to say, don't tell me about the bug - tell me about what you're trying to accomplish.

My code needs to check if a directory on a drive exists

OK, if that's the end goal, Windows provides an API for that called FindFirstChangeNotification. You can use the Change Notification APIs to spin up a thread and monitor when files or directories change.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365261(v=vs.85).aspx

Jason De Arte
  • 467
  • 1
  • 3
  • 14