Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

By code, how can I test if a hard disk drive is sleeping without waking it up

I'm building a small app that gives me the free space available on my disks.

I would like to add a feature displaying the status of the disk, if it is sleeping or not for example. The OS is Windows.

How can this be done? The code should not have to wake the disk to find out, of course ;)

A solution in C# would be nice but I guess any solution will do...

Thank you for you help.

like image 381
Jonx Avatar asked May 13 '09 15:05

Jonx


1 Answers

C++ solution (call GetDiskPowerState and it will iterate over physical drives until there are no more):

class AutoHandle
{
    HANDLE  mHandle;
public:
    AutoHandle() : mHandle(NULL) { }
    AutoHandle(HANDLE h) : mHandle(h) { }

    HANDLE * operator & ()
    {
        return &mHandle;
    }

    operator HANDLE() const
    {
        return mHandle;
    }

    ~AutoHandle()
    {
        if (mHandle && mHandle != INVALID_HANDLE_VALUE)
            ::CloseHandle(mHandle);
    }
};


bool
GetDiskPowerState(LPCTSTR disk, string & txt)
{
    AutoHandle hFile = CreateFile(disk, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (hFile && hFile != INVALID_HANDLE_VALUE)
    {
        BOOL powerState = FALSE;
        const BOOL result = GetDevicePowerState(hFile, &powerState);
        const DWORD err = GetLastError();

        if (result)
        {
            if (powerState)
            {
                txt += disk;
                txt += " : powered up\r\n";
            }
            else
            {
                txt += disk;
                txt += " : sleeping\r\n";
            }
            return true;
        }
        else
        {
            txt += "Cannot get drive ";
            txt += disk;
            txt += "status\r\n";
            return false;
        }
    }

    return false;
}

string 
GetDiskPowerState()
{
    string text;
    CString driveName;
    bool result = true;
    for (int idx= 0; result; idx++)
    {
        driveName.Format("\\\\.\\PhysicalDrive%d", idx);
        result = GetDiskPowerState(driveName, text);
    }
    return text;
}
like image 83
sean e Avatar answered Sep 20 '22 19:09

sean e