判断SSD 获取转速

参考链接 c++ - Detecting SSD in Windows - Stack Overflow

#ifndef StorageDeviceTrimProperty
#define StorageDeviceTrimProperty 8
#endif

#ifndef DEVICE_TRIM_DESCRIPTOR
typedef struct _DEVICE_TRIM_DESCRIPTOR {
  DWORD   Version;
  DWORD   Size;
  BOOLEAN TrimEnabled;
} DEVICE_TRIM_DESCRIPTOR, *PDEVICE_TRIM_DESCRIPTOR;
#endif


#ifndef StorageDeviceSeekPenaltyProperty
#define StorageDeviceSeekPenaltyProperty 7
#endif

#ifndef DEVICE_SEEK_PENALTY_DESCRIPTOR
typedef struct _DEVICE_SEEK_PENALTY_DESCRIPTOR {
  DWORD   Version;
  DWORD   Size;
  BOOLEAN IncursSeekPenalty;
} DEVICE_SEEK_PENALTY_DESCRIPTOR, *PDEVICE_SEEK_PENALTY_DESCRIPTOR;
#endif


struct ATAIdentifyDeviceQuery
{
    ATA_PASS_THROUGH_EX header;
    WORD data[256];
};

//Open drive as such: "\\?\PhysicalDriveX" where X is the drive number
//INFO: To get drive number from a logical drive letter, check this method:
//      (But keep in mind that a single logical drive, or a volume,
//       can span across several physical drives, as a "spanned volume.")
//       http://stackoverflow.com/a/11683906/843732

#include <WinIoCtl.h>
#include <Ntddscsi.h>

DWORD bytesReturned;

//As an example, let's test 1st physical drive
HANDLE hDevice = ::CreateFile(L"\\\\?\\PhysicalDrive0",
    GENERIC_READ | GENERIC_WRITE,       //We need write access to send ATA command to read RPMs
    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    OPEN_EXISTING,  0, NULL);
if(hDevice != INVALID_HANDLE_VALUE)
{
    //Check TRIM -- should be Y for SSD
    _tprintf(L"TRIM=");

    STORAGE_PROPERTY_QUERY spqTrim;
    spqTrim.PropertyId = (STORAGE_PROPERTY_ID)StorageDeviceTrimProperty;
    spqTrim.QueryType = PropertyStandardQuery;

    bytesReturned = 0;
    DEVICE_TRIM_DESCRIPTOR dtd = {0};
    if(::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
        &spqTrim, sizeof(spqTrim), &dtd, sizeof(dtd), &bytesReturned, NULL) &&
        bytesReturned == sizeof(dtd))
    {
        //Got it
        _tprintf(L"%s", dtd.TrimEnabled ? L"Y" : L"N");
    }
    else
    {
        //Failed
        int err = ::GetLastError();
        _tprintf(L"?");
    }


    //Check the seek-penalty value -- should be N for SSD
    _tprintf(L", seekPenalty=");

    STORAGE_PROPERTY_QUERY spqSeekP;
    spqSeekP.PropertyId = (STORAGE_PROPERTY_ID)StorageDeviceSeekPenaltyProperty;
    spqSeekP.QueryType = PropertyStandardQuery;

    bytesReturned = 0;
    DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {0};
    if(::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
        &spqSeekP, sizeof(spqSeekP), &dspd, sizeof(dspd), &bytesReturned, NULL) &&
        bytesReturned == sizeof(dspd))
    {
        //Got it
        _tprintf(L"%s", dspd.IncursSeekPenalty ? L"Y" : L"N");
    }
    else
    {
        //Failed
        int err = ::GetLastError();
        _tprintf(L"?");
    }


    //Get drive's RPMs reading -- should be 1 for SSD
    //CODE SOURCE: https://emoacht.wordpress.com/2012/11/06/csharp-ssd/
    _tprintf(L", RPM=");

    ATAIdentifyDeviceQuery id_query;
    memset(&id_query, 0, sizeof(id_query));

    id_query.header.Length = sizeof(id_query.header);
    id_query.header.AtaFlags = ATA_FLAGS_DATA_IN;
    id_query.header.DataTransferLength = sizeof(id_query.data);
    id_query.header.TimeOutValue = 5;   //Timeout in seconds
    id_query.header.DataBufferOffset = offsetof(ATAIdentifyDeviceQuery, data[0]);
    id_query.header.CurrentTaskFile[6] = 0xec; // ATA IDENTIFY DEVICE

    bytesReturned = 0;
    if(::DeviceIoControl(hDevice, IOCTL_ATA_PASS_THROUGH,
        &id_query, sizeof(id_query), &id_query, sizeof(id_query), &bytesReturned, NULL) &&
        bytesReturned == sizeof(id_query))
    {
        //Got it

        //Index of nominal media rotation rate
        //SOURCE: http://www.t13.org/documents/UploadedDocuments/docs2009/d2015r1a-ATAATAPI_Command_Set_-_2_ACS-2.pdf
        //          7.18.7.81 Word 217
        //QUOTE: Word 217 indicates the nominal media rotation rate of the device and is defined in table:
        //          Value           Description
        //          --------------------------------
        //          0000h           Rate not reported
        //          0001h           Non-rotating media (e.g., solid state device)
        //          0002h-0400h     Reserved
        //          0401h-FFFEh     Nominal media rotation rate in rotations per minute (rpm)
        //                                  (e.g., 7 200 rpm = 1C20h)
        //          FFFFh           Reserved
        #define kNominalMediaRotRateWordIndex 217
        _tprintf(L"%d", (UINT)id_query.data[kNominalMediaRotRateWordIndex]);
    }
    else
    {
        //Failed
        int err = ::GetLastError();
        _tprintf(L"?");
    }


    _tprintf(L"\n");
    ::CloseHandle(hDevice);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值