Blog. Just Blog

Мониторинг активности HDD на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
В качестве предисловия коротенький анекдот из времен MS-DOS: "- Висим... - Не висим. - Висим! - Не висим, говорю - диском дpыгает." И действительно, активность жесткого диска, выражавшаяся в моргании соответствующего индикатора на корпусе, говорила о работе процесса, просто надо было подождать. Но иногда такие индикаторы отсутствовали или системник стоял в таком месте, что их не было видно. В этих случаях приходилось решать задачу различными программами, которые отображали активность жесткого диска как-нибудь иначе, например, морганием светодиода ScrollLock на клавиатуре.

Вот и мне захотелось сделать что-нибудь подобное. Естественно, на Ассемблере. Для начала некоторые данные, о которых не знает FASM.
  1. struct DISK_PERFORMANCE
  2.     BytesRead     dq ?
  3.     BytesWritten  dq ?
  4.     ReadTime      dq ?
  5.     WriteTime     dq ?
  6.     IdleTime      dq ?
  7.     ReadCount     dd ?
  8.     WriteCount    dd ?
  9.     QueueDepth    dd ?
  10.     SplitCount    dd ?
  11.     QueryTime     dd ?
  12.     StorageDeviceNumber dd ?
  13.     StorageManagerName  rd 8
  14. ends
  15.  
  16. IOCTL_DISK_PERFORMANCE = 0x70020
Дальше немного теории. Текущее состояние жесткого диска можно узнать при помощи функции DeviceIoControl с параметром IOCTL_DISK_PERFORMANCE. При удачном выполнении операции будет возвращена заполненная структура DISK_PERFORMANCE. В документации написано, что в полях ReadTime и WriteTime передаются счетчики времени, необходимые для выполнения операций чтения или записи. Сохранив текущее значение этих счетчиков и периодически сравнивая текущие значения с сохраненными данными, можно смело утверждать о выполнении операции жестким диском. И, соответственно, каким-то образом оповещать об этом пользователя.

А вот и сам код. Он максимально упрощен и заточен на мониторинг самого первого диска в системе. В качестве индикаторов используются обычные текстовые поля.
  1. szDrive du '\\.\PhysicalDrive0',0
  2. ...
  3.         ; Открыть диск для работы
  4.         invoke  CreateFile,szDrive,0,0,0,OPEN_EXISTING,0,0
  5.         cmp     eax,-1
  6.         je      .wmclose
  7.  
  8.         mov     [hhd],eax
  9.  
  10.         ; Инициализация времени чтения и записи
  11.         mov     dword [read_time],0
  12.         mov     dword [read_time+4],0
  13.         mov     dword [write_time],0
  14.         mov     dword [write_time+4],0
После инициализации надо запустить периодический опрос состояния. Это можно сделать по таймеру в оконном приложении или в отдельном потоке, как вам привычнее.
  1.         ; Получить информацию о диске
  2.         invoke  DeviceIoControl,[hhd],IOCTL_DISK_PERFORMANCE,\
  3.                 0,0,perf,sizeof.DISK_PERFORMANCE,tmp,0
  4.  
  5. .chk_read:
  6.         ; Время последнего чтения отличается?
  7.         mov     eax,dword[perf.ReadTime]
  8.         cmp     dword[read_time],eax
  9.         jne     @f
  10.         mov     eax,dword[perf.ReadTime+4]
  11.         cmp     dword[read_time+4],eax
  12.         jne     @f
  13.         ; Выключить индикатор
  14.         mov     ebx,FALSE
  15.         jmp     .set_read
  16. @@:
  17.         ; Актуализировать время чтения
  18.         mov     eax,dword[perf.ReadTime]
  19.         mov     dword[read_time],eax
  20.         mov     eax,dword[perf.ReadTime+4]
  21.         mov     dword[read_time+4],eax
  22.         ; Включить индикатор
  23.         mov     ebx,TRUE
  24. .set_read:
  25.         ; Включить или выключить индикатор
  26.         invoke  GetDlgItem,[hwnddlg],ID_READ
  27.         invoke  EnableWindow,eax,ebx
  28.  
  29. .chk_write:
  30.         ; Время последней записи отличается?
  31.         mov     eax,dword[perf.WriteTime]
  32.         cmp     dword[write_time],eax
  33.         jne     @f
  34.         mov     eax,dword[perf.WriteTime+4]
  35.         cmp     dword[write_time+4],eax
  36.         jne     @f
  37.         ; Выключить индикатор
  38.         mov     ebx,FALSE
  39.         jmp     .set_write
  40. @@:
  41.         ; Актуализировать время записи
  42.         mov     eax,dword[perf.WriteTime]
  43.         mov     dword[write_time],eax
  44.         mov     eax,dword[perf.WriteTime+4]
  45.         mov     dword[write_time+4],eax
  46.         ; Включить индикатор
  47.         mov     ebx,TRUE
  48. .set_write:
  49.         ; Включить или выключить индикатор
  50.         invoke  GetDlgItem,[hwnddlg],ID_WRITE
  51.         invoke  EnableWindow,eax,ebx
Вместо включения-выключения текстовых полей можно моргать светодиодами клавиатуры, выводить иконку в трей или сообщать об активности диска любым другим удобным вам способом. Операции чтения и записи тоже не обязательно разделять, ведь обе они означают активность диска.

В приложении пример программы с исходным текстом, которая мониторит активность жесткого диска.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

HDD.Activity.Demo.zip (2,877 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 581 | Комментариев: 0

Метки: Assembler, HDD
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.11 сек. / MySQL: 2 (0.0079 сек.) / Память: 4.5 Mb
Наверх