Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I detect if a hard drive is spinning (under Windows)?

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);
   }
}
like image 388
Not Submitted Avatar asked Mar 11 '14 18:03

Not Submitted


1 Answers

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

like image 173
Jason De Arte Avatar answered Oct 14 '22 23:10

Jason De Arte