HDD или SSD в VC++

Есть ли способ в VC++ узнать, является ли установленный на компьютере диск HDD или SSD? Кроме того, чтобы узнать, где находится определенный жесткий диск или твердотельный накопитель.

Буду признателен за любую помощь .. Спасибо!


person patlimosnero    schedule 20.04.2011    source источник
comment
Каковы именно ваши потребности? Во многих случаях даже ОС не знает, что диск является SSD.   -  person Gabe    schedule 20.04.2011
comment
Учитывая стоимость SSD, почему бы просто не спросить у владельца? Она узнает.   -  person Hans Passant    schedule 20.04.2011
comment
Считайте это невозможным. Важной особенностью SSD является то, что он ведет себя точно так же, как стандартный жесткий диск. Все, что относится к SSD, будет обрабатываться операционной системой и низкоуровневыми драйверами, а не вашим приложением.   -  person Cody Gray    schedule 20.04.2011
comment
@Gabe: В большинстве случаев это проблема.   -  person user541686    schedule 14.05.2012
comment
@CodyGray: это возможно, с хорошей точностью; см. мой ответ. Может быть даже есть 100% точный способ сделать это, хотя я не знаю ни одного лично. (Я только что наткнулся на это, что тоже может сработать, хотя я не пробовал.)   -  person user541686    schedule 14.05.2012
comment
@Mehrdad Да, это считалось невозможным, потому что смысл SSD в том, что он работает точно так же, как обычный вращающийся диск. Конечно, понюхать название продукта сработает (кроме тех случаев, когда это не так), суть в том, что разница не должна быть значимой, и если вы так думаете, вы с самого начала делаете что-то не так.   -  person Cody Gray    schedule 14.05.2012


Ответы (1)


Это не 100% защита от ошибок, но этот метод использует Linux.
Он проверяет, есть ли слово "SSD" в Product ID диска:

#include <tchar.h>
#include <windows.h>
#include <winioctl.h>

void Check(LPCTSTR file, LPCTSTR volPathWithLeadingPrefix)
{
    HANDLE hFile = CreateFile(
        volPathWithLeadingPrefix,
        FILE_READ_ATTRIBUTES,  // Just querying; don't mount
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
    STORAGE_PROPERTY_QUERY spq =
    { StorageDeviceProperty, PropertyStandardQuery };
    union
    {
        STORAGE_DEVICE_DESCRIPTOR StorageDeviceDescriptor;
        BYTE Data[1024];
    } output = {0};
    DWORD br;
    if (DeviceIoControl(
        hFile, IOCTL_STORAGE_QUERY_PROPERTY,
        &spq, sizeof(spq), &output, sizeof(output),
        &br, NULL))
    {
        STORAGE_DEVICE_DESCRIPTOR &sdd =
            output.StorageDeviceDescriptor;
        if (sdd.ProductIdOffset > 0)
        {
            LPCSTR productID = (LPCSTR)&((LPBYTE)&sdd)[sdd.ProductIdOffset];
            BOOL isSSD = strstr(productID, "SSD") != NULL;
            _tprintf(_T("\"%s\": %s\n"), file, isSSD ? _T("SSD") : _T("HDD"));
        }
        else { _ftprintf(stderr, _T("No product ID.")); }
    }
    else
    { _ftprintf(stderr, _T("Error %u querying storage.\n"), GetLastError()); }
}

int _tmain(int argc, TCHAR *argv[])
{
    for (int i = 1; i < argc; i++)
    {
        LPCTSTR file = argv[i];
        TCHAR volPath[MAX_PATH];
        if (GetVolumePathName(file, volPath, ARRAYSIZE(volPath)))
        {
            for (size_t cchVolPath = _tcslen(volPath);
                cchVolPath > 0 && volPath[cchVolPath - 1] == TEXT('\\');
                cchVolPath--)
            { volPath[cchVolPath - 1] = TEXT('\0'); }

            TCHAR volPathWithLeadingPrefix[ARRAYSIZE(volPath)];
            if (_sntprintf(
                volPathWithLeadingPrefix,
                ARRAYSIZE(volPathWithLeadingPrefix),
                volPath[0] == _T('\\') ? _T("%s") : _T("\\\\.\\%s"),
                volPath) < ARRAYSIZE(volPathWithLeadingPrefix))
            {
                Check(file, volPathWithLeadingPrefix);
            }
            else
            {
                SetLastError(ERROR_FILENAME_EXCED_RANGE);
                _ftprintf(stderr, _T("Path \"%s\" is too long.\n"), volPath);
            }
        }
        else
        {
            _ftprintf(
                stderr,
                _T("Error %u getting volume path.\n"),
                GetLastError());
        }
    }
}
person user541686    schedule 13.05.2012
comment
На моем SSD написано SAMSUNG MMCRE28G8MXP-0VB. - person Gabe; 14.05.2012
comment
@Gabe: Как я уже сказал, это не надежно. Но это является метод, используемый некоторыми программами, и он действительно иногда работает, так что это лучше, чем ничего. Возможно, это будет работать лучше, я не знаю. - person user541686; 14.05.2012