Функция определения SSD или HDD диск - протестируйте

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Gasparini
Новичок
Новичок
 
Сообщения: 49
Зарегистрирован: 06.09.2012 (Чт) 14:42

Функция определения SSD или HDD диск - протестируйте

Сообщение Gasparini » 11.01.2017 (Ср) 1:00

По работе столкнулся с задачей надежного, быстрого и точного определения типа диска (HDD или SSD).
Увы, но в интернете не так много надежных реализаций.

Написал модуль DetectSSD.bas, который и прикрепляю к теме.
Для определения используется опрос устройства с помощью WinAPI функции DeviceIoControl.

Большая просьба к владельцам твердотельных накопителей - протестируйте работоспособность функции, в идеале она должна безошибочно определять какого типа диск используется.
Ну и заодно, может и вам в будущем пригодится данная функция.
Заранее благодарен!
Вложения
modDetectSSD.zip
(1.38 Кб) Скачиваний: 183

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение pronto » 11.01.2017 (Ср) 10:04

Для диска C: выдаёт "HDD", хотя должно быть "SSD"
O, sancta simplicitas!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение alibek » 11.01.2017 (Ср) 12:31

А зачем это вообще различать?
Lasciate ogni speranza, voi ch'entrate.

Gasparini
Новичок
Новичок
 
Сообщения: 49
Зарегистрирован: 06.09.2012 (Чт) 14:42

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Gasparini » 11.01.2017 (Ср) 13:26

pronto писал(а):Для диска C: выдаёт "HDD", хотя должно быть "SSD"

А не могли бы, вы пожалуйста, запустить еще раз новый прикрепленный пример, который пишет в ЛОГ-файл на рабочем столе ответ устройства и прикрепить полученный лог ответа от SSD или ссылку на него?
Это мне очень бы помогло, так как у меня нет знакомых с SSD-дисками.
Очень прошу.
Вложения
modDetectSSD.zip
(1.51 Кб) Скачиваний: 165

Gasparini
Новичок
Новичок
 
Сообщения: 49
Зарегистрирован: 06.09.2012 (Чт) 14:42

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Gasparini » 11.01.2017 (Ср) 13:28

alibek писал(а):А зачем это вообще различать?

Я занимаюсь разработкой системного ПО для Windows.
Необходимо, чтобы оно по разному себя вело на SSD и HDD диске, с целью снижения износа SSD диска от частых перезаписей.

Teranas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 224
Зарегистрирован: 13.12.2008 (Сб) 4:26
Откуда: Новосибирск

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Teranas » 11.01.2017 (Ср) 14:22

Я так понимаю SSD это новое поколение твердотельных накопителей с интерфейсом SATA постоиных на принципе микросхемы флеш-памяти
и тоже не пойму зачем их различать
С уважением, Андрей.

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение pronto » 11.01.2017 (Ср) 14:24

Пожалуйста
Вложения
DetectSSD_Log.rar
(262 байт) Скачиваний: 159
O, sancta simplicitas!

Gasparini
Новичок
Новичок
 
Сообщения: 49
Зарегистрирован: 06.09.2012 (Чт) 14:42

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Gasparini » 11.01.2017 (Ср) 22:19

Собственно рабочий вариант.
Тестировался на двух SSD и двух HDD - везде отрабатывает правильно.
Вложения
modDetectSSD.zip
(1.52 Кб) Скачиваний: 203

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение pronto » 12.01.2017 (Чт) 1:26

Да, теперь верно отрабатывает.
O, sancta simplicitas!

Proxy
Профессор VB наук
Профессор VB наук
Аватара пользователя
 
Сообщения: 2941
Зарегистрирован: 31.08.2007 (Пт) 4:41

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Proxy » 12.01.2017 (Чт) 3:12

А как сама ОС определяет тип накопителя? Например, в "оптимизации и дефрагментации дисков" можно наблюдать столбец "тип носителя".
Follow the white rabbit.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Хакер » 12.01.2017 (Чт) 7:37

Код, конечно, не радует. Сочетание ошибок, дурных манер и плохого английского.

Код: Выделить всё
    If IsSSDDrive(sDrive, False) = False Then
        MsgBox "Drive " & Chr(34) & sDrive & Chr(34) & " is HDD Disk."
    Else
        MsgBox "Drive " & Chr(34) & sDrive & Chr(34) & " is SSD Disk."
    End If


Можно было бы ужать до
MsgBox "Drive """ & sDrive & """ is " & IIf(IsSSDDrive(sDrive), "SSD", "HDD") & " Disk."

_________________________

Код: Выделить всё
    'Is handle is not created exit function
    If lHandle = 0 Then
        MsgBox "Error with creating disk handle (WinAPI: CreateFile function ): #" & Err.LastDllError
        Exit Function
    End If


Вот это очень плохой блок. Во-первых, если CreateFile сбойнет, она вернёт INVALID_HANDLE_VALUE, а эта константа численно равна -1&, а не нулю. Так что же в этом месте код пойдёт исполняться дальше, вместо того, чтобы указать на место возникновения проблемы.

Во-вторых, комментарий очень мутный. Тут видимо должно было быть If вместо Is, но даже так это звучит неважно. Лучше поменять is not created на wasn't created или has not been created. А ещё лучше — поменять смысл. Привязываться не к факту создания(!) хендла, а к факту сбоя функции.

___________

Код: Выделить всё
    'Create ATA_PASS_THROUGH_EX structure
    DiskData.Length = Len(DiskData)
    DiskData.AtaFlags = 2 ' ATA_FLAGS_DATA_IN
    DiskData.DataTransferLength = 512 'The command returns a 512 byte package of info.
    DiskData.TimeOutValue = 3 '10 second timeout.
    DiskData.CurrentTaskFile(6) = 236 'the command "IDENTIFY DEVICE"
    DiskData.DataBufferOffset = Len(DiskData)


Почему здесь везде стоят просто числа вместо соответствующих констант? Особенно на фоне того, что константа ATA_FLAGS_DATA_IN объявлена выше, почему тут стоит двойка, а в комментарии даётся имя константы, вместо того, чтобы просто использовать константу?

Не делай так!

_____________________

«Error with» звучит диковато — обычно «Error while» или «Error when».


______________________

Вообще, идея вгонять в эту функцию «c:» или «k:» кажется противоречиво и неправильной с идеологической точки зрения.

Ведь «c:» и «k:» это тома, а деление на SSD/HDD относится к устройствам.

А том не тождественнен устройству.
И, вообще, тут всё сложнее, чем кажется.
  • Существующая философия, заложенная в код, построена исходя из позиции, что любой том — это либо HDD, либо SSD. А между тем, том может оказаться флешкой, компакт-диском или вообще флоппи-диском.
  • Более того, среди «томов» в стиле «X:» могут оказаться объекты, представляющие собой симлинки на объекты, вообще никак не относящиеся к физическим накопителям. Например, так называемые сетевые диски являются симлинками на \Device\LanmanRedirector с постфиксами. А, к примеру, в VirtualBox диски для шар с родительской системы — симлинки на \DeviceVBoxMniRdr (с постфиксом).
  • За большинством томов (A:, B:, C: и так далее) стоят какое-то устройство. Но всегда это диск (для которого уместно деление на HDD или SDD), и не всегда это физическое устройство — вполне может быть и виртуальное устройство.
  • Кроме того, вызовом встроенной в Windows команды subst можно заставить отдельный каталог с какого-то одного тома стать новым отдельным томом.
  • Сама архитектура Windows такова, что в ней существует дерево устройств, состоящее из узлов-устройств, и с каждым таким узлом ассоциирован определённый драйвер. И если пройтись по ветви в таком дереве от вершины к корню и посмотреть на драйверы, то цепочка из драйверов образовывает так называемый стек драйверов (driver stack) для устройства.

    Диски (как и всё остальное) подчиняется этой же схемой, поэтому сам накопитель представлен в дереве устройств отдельный объектом-устройством (олицетворяющем накопитель), а тома (существующие на накопителе) — это уже дочерние объекты-устройства в дереве.

    В объектом, олицетворяющих физические накопители — свой драйвер.
    А у объектов, олицетворяющих тома — совершенно другой.

    Когда ты вызываешь DeviceIoControl, то ты по сути шлёшь IRP соответствующему объекту-устройству в дереве, а обрабатывать этот IRP (с кодом типа IRP_MJ_DEVICE_CONTROL) будет Dispatch-процедура драйвера.

    И в том случае, когда ты шлёшь этот IRP объекту-тому, обрабатывать этот IRP придётся драйверу тома (файловой системы), а не драйверу диску. С какой вообще стати драйвер тома отвечает на IRP, суть которого в выполнении ATA-команды, ведь на уровне работы с томами и ФС никому нет дела до физического оборудования? По идее, корректно реагировать на этот IRP должен только объект-диск, а не объект-том, так почему же текущий код работает?

    Работает он по той причине, что драйвер устройства-тома перенаправляет этот IRP по стеку вниз, и IRP переадресовывается нижележащему (в дереве) объекту — устройству-диску, а уже его драйвер знает, как обработать этот запрос.

    Но в принципе существует вероятность, что драйвер тома не будет пересылать запрос (IRP) нижележащему драйверу, а обработает его сам как неизвестный непредполагаемый.

    Вывод: чем слать IRP к устройству-тому (например в адрес объекта \\.\c:, который является симлинком на \Device\HarddiskVolume1), лучше слать его устройству-диску.

    В твоём случае это означает, что вместо \\.\c:, \\.\d:, \\.\e: надо передавать \\.\PhysicalDrive0, \\.\PhysicalDrive1 и т.п. в CreateFile.

    То есть, с учётом вышесказанного, если тебя интересуют тома D:, N: и Z:, сперва выяснить, что это тома приемлемого типа, что они «дисковые», дальше выяснить имена устройств-дисков, которые скрываются за этими томами, а потом опросить эти диски.

  • Всё оказывается ещё сложнее, если вспомнить про NTFS Junction Points и NTFS Hardlinks.
    Если взять твои слова
    Gasparini писал(а):Необходимо, чтобы оно по разному себя вело на SSD и HDD диске, с целью снижения износа SSD диска от частых перезаписей.

    то получается, что допустим твой софт пишет лог или какую-то иную запись в папку, скажем, c:\mysoft\logs\2017\.

    Ты урезаешь этот путь до тома «c:». Допустим, ты определишь, что этот том относится к физическому диску \\?\PhysicalDrive6, который является HDD. Однако может оказать, что папка c:\mysoft\log лежит не на этом HDD, а на другом, который, возможно, SSD. Этот другой диск может иметь сколько-то томов, а сами эти тома могут вообще не иметь никакой собственной буквы. И не только отдельная директория, но и отдельный файл, который с виду хранится на одном томе, может в реальности храниться на другом.

    Взгляд на ту же ситуацию с другой стороны: в компьютере может быть установлена куча HDD и SDD, и при этом будет только том «c:», а все остальные диски и их тома будут смонтированы в иерархию ФС тома «C:», то есть примерно так же, как это обстоит в unix-подобных ОС, где букв дисков нет вообще. Без всяких там RAID-ов, чисто средствами NT.

Выводы, если кратко:
  1. Лучше работать с дисками, а не томами.
  2. Не за всякой буквенным томом скрывается хард.
  3. Иногда буквенный том — это всего-лишь отдельный каталог локального (результат subst) или удалённого (сетевой диск) хранилища.
  4. В иерархии одного тома могут попасться файлы и папки, живущие на другом томе того же самого или вообще совершенно другого диска.
  5. Могут быть отдельные тома (и значит целые диски, где все тома такие), которые не имеют собственной буквы.
  6. За разными буквами, олицетворяющими разные тома, может стоять один диск.
  7. За разными буквами может стоять один и тот же том.

Финальный вывод: работать с дисками, а не томами, идентифицируемыми буквой + помнить, что имея путь к файлу или папке, нельзя судить о томе и диске, на которых размещён этот объект, по первой букве пути.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Teranas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 224
Зарегистрирован: 13.12.2008 (Сб) 4:26
Откуда: Новосибирск

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Teranas » 12.01.2017 (Чт) 8:50

Хакер
Супер! прям как по нотам! +100
:!:
С уважением, Андрей.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Хакер » 12.01.2017 (Чт) 10:04

Кстати, забыл сказать, что определяет у меня правильно, но требует администраторских прав для открытия тома.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Gasparini
Новичок
Новичок
 
Сообщения: 49
Зарегистрирован: 06.09.2012 (Чт) 14:42

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Gasparini » 12.01.2017 (Чт) 11:06

Хакер, благодарю за подробную критику, со всем абсолютно согласен. Буду совершенствоваться и совершенствовать код.
Еще один вопрос: вы сказали, что у вас правильно определяет, хотелось бы уточнить - какой тип диска вы проверяли HDD или SSD?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16473
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Хакер » 12.01.2017 (Чт) 12:25

Gasparini писал(а):какой тип диска вы проверяли HDD или SSD?

Kingston SSDNow определяет как SSD. Остальные HDD определяет как HDD, хотя я не проверял с каждым HDD, только с одним.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Gasparini
Новичок
Новичок
 
Сообщения: 49
Зарегистрирован: 06.09.2012 (Чт) 14:42

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение Gasparini » 12.01.2017 (Чт) 12:35

Хакер, благодарю за информацию.

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Функция определения SSD или HDD диск - протестируйте

Сообщение pronto » 12.01.2017 (Чт) 14:59

Может быть, будет полезно
Если будет желание углубиться в эту тему, то для этого есть очень хорошая книга «Внутреннее устройство Microsoft Windows» за авторством Руссиновича и Соломона.
O, sancta simplicitas!


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

    TopList