Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spin Down Hard Disk Programmatically on Windows?

Tags:

How do you request Windows to spin down a hard disk programmatically? Is there any user-mode function I can call (or kernel-mode function to call or IRP to send) in order to make this happen?

I've tried making a program to send an ATA STANDBY command directly to the hard disk, but the problem is that this method doesn't inform the system, and hence whenever the system needs to flush the cache, it'll wake up the hard disk again. How do I tell the system to do this for me? (If the system does it, it'll save up the cache and "burst" the data when it gets too large, instead of writing in small increments.)

(The entire point here is to do this directly, not by changing the system-wide spin-down timeout to a 1-second period and waiting for the disk to spin down. I need a function I can call at a specific moment in time when I'm using my laptop, not something generic that doesn't suit 95% of situations.)


How far I've gotten so far:

I have a feeling that PoCallDriver and IRP_MJ_POWER might be useful for this, but I have very limited kernel-mode programming experience (and pretty much zero driver experience) so I really have no idea.


Please read:

Update:

People seem to be repeatedly mentioning the solutions that I have already mentioned do not work. Like I said above, I've already tried "hacky" solutions that change the timeout value or that directly issue the drive a command, and the entire reason I've asked this question here is that those did not do what I needed. Please read the entire question (especially paragraphs 2 and 3) before repeating what I've already said inside your answers -- that's the entire difficulty in the question.


More info:

I've found this document about Disk Idle Detection to be useful, but my answer isn't in there. It states that the Power Manager sends an IRP to the disk driver (hence why I suspect IRP_MJ_POWER to be useful), but I have no idea how to use the information.

like image 773
user541686 Avatar asked Mar 20 '11 06:03

user541686


People also ask

What is HDD Spinup time?

Spin-Up Time S.M.A.R.T. parameter indicates an average time (in milliseconds or seconds) of spindle spinup (from zero RPM (Revolutions Per Minute) to fully operational). The low value means it takes too long for the hard disk to a fully operational state.

How does Hdparm work?

hdparm will issue a low-level write (completely bypassing the usual block layer read/write mechanisms) to the specified sector. This can be used to force a drive to repair a bad sector (media error). -W Get/set the IDE/SATA drive´s write-caching feature. -X Set the IDE transfer mode for (E)IDE/ATA drives.

Can you recover data from a hard drive that won't spin?

Unfortunately, there's nothing you can do on your own when you have a hard drive that's not spinning up. This is because there's nothing you can do to repair your hard drive or replace whatever is broken inside it.


2 Answers

I hope this helps:

This: http://msdn.microsoft.com/en-us/library/aa394173%28VS.85%29.aspx

Leads to this: http://msdn.microsoft.com/en-us/library/aa394132%28VS.85%29.aspx#properties

Then, you can browse to this: http://msdn.microsoft.com/en-us/library/aa393485(v=VS.85).aspx

This documentation seems to outline what you are looking for I think.

P.S. Just trying to help, don't shoot the messanger.

like image 112
Dima Avatar answered Oct 07 '22 12:10

Dima


Have you tried WMI? Based on MSDN documentation, you should be able to send spindown command to HDD via WMI:

http://msdn.microsoft.com/en-us/library/aa393493%28v=VS.85%29.aspx

uint32 SetPowerState(
  [in]  uint16 PowerState,
  [in]  datetime Time
);

EDIT:

This code lists all drives in system and drives that support this API:

strServer = "."

Set objWMI = GetObject("winmgmts://" & strServer & "/root\cimv2")
rem Set objInstances = objWMI.InstancesOf("CIM_DiskDrive",48)
Set objInstances = objWMI.ExecQuery("Select * from CIM_DiskDrive",,48) 
On Error Resume Next
For Each objInstance in objInstances
    With objInstance
        WScript.Echo Join(.Capabilities, ", ")
        WScript.Echo Join(.CapabilityDescriptions, ", ")
        WScript.Echo .Caption
        WScript.Echo .PNPDeviceID
        WScript.Echo "PowerManagementCapabilities: "  & .PowerManagementCapabilities
        WScript.Echo "PowerManagement Supported: " & .PowerManagementSupported
        WScript.Echo .Status
        WScript.Echo .StatusInfo
    End With
On Error Goto 0
Next

Just save this code as a .vbs file and run that from command line.

like image 38
Shamit Verma Avatar answered Oct 07 '22 12:10

Shamit Verma