Blog. Just Blog

Время непрерывной работы (Uptime) Windows

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Для получения времени непрерывной работы системы обычно используется функция API GetTickCount. Она возвращает количество миллисекунд, прошедших с момента последнего старта системы. Проблема в том, что счетчик имеет тип dword, и по прошествии примерно 50 дней (49,7 если быть точным) достигает предельного значения и обнуляется. Конечно, продержать систему без перезагрузки почти два месяца трудно, но не значит что невозможно. Поэтому для получения гарантированно точного времени работы системы воспользуемся функцией NtQuerySystemInformation. Достаточно долго эта функция относилась к разряду недокументированных, теперь же на MSDN по ней имеется описание с примечанием, что ее использование в прикладных программах все равно нежелательно.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. ; По умолчанию структура в FASM не определена, сделаем это самостоятельно
  5. ; Для получения необходимой информации нужны только два первых значения
  6. struct SYSTEM_TIME_INFORMATION
  7.        liKeBootTime       dq ?  ; Время старта системы
  8.        liKeSystemTime     dq ?  ; Текущее время
  9.        liExpTimeZoneBias  dq ?
  10.        uCurrentTimeZoneId dd ?
  11.        dwReserved         dw ?
  12. ends
  13.  
  14. SystemTime   SYSTEM_TIME_INFORMATION  ; Наша структура с данными
  15.  
  16. ; Константа нужного класса информации тоже не определена, сделаем это сами
  17. GET_SYSTEM_TIME_INFORMATION = 3 
  18.  
  19. ; Сегмент кода
  20. section '.code' code readable executable
  21. ...
  22.         invoke  NtQuerySystemInformation, GET_SYSTEM_TIME_INFORMATION,\
  23.                 SystemTime, sizeof.SYSTEM_TIME_INFORMATION, 0
  24.         ; Записать в регистры EDX:EAX текущее время в миллисекундах
  25.         mov     eax, dword [SystemTime.liKeSystemTime]
  26.         mov     edx, dword [SystemTime.liKeSystemTime+4]
  27.         ; Вычесть время старта системы
  28.         sub     eax, dword [SystemTime.liKeBootTime]
  29.         sbb     edx, dword [SystemTime.liKeBootTime+4]
  30.         ; Теперь в регистры EDX:EAX записано реальное количество миллисекунд,
  31.         ; прошедшее с момента старта системы
  32. ...
Преобразовать миллисекунды в обычный вид даты и времени можно при помощи пары стандартных функций FileTimeToLocalFileTime и FileTimeToSystemTime.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. ; По умолчанию структура в FASM не определена, сделаем это самостоятельно
  5. ; Для получения необходимой информации нужны только два первых значения
  6. struct SYSTEM_TIME_INFORMATION
  7.        liKeBootTime       dq ?  ; Время старта системы
  8.        liKeSystemTime     dq ?  ; Текущее время
  9.        liExpTimeZoneBias  dq ?
  10.        uCurrentTimeZoneId dd ?
  11.        dwReserved         dw ?
  12. ends
  13.  
  14. SystemTime   SYSTEM_TIME_INFORMATION  ; Наша структура с данными
  15.  
  16. ; Добавляются две стандартные структуры для работы с датой и временем
  17. ftSystemTime FILETIME
  18. stSystemTime SYSTEMTIME
  19.  
  20. ; Константа нужного класса информации тоже не определена, сделаем это сами
  21. GET_SYSTEM_TIME_INFORMATION = 3 
  22.  
  23. ; Сегмент кода
  24. section '.code' code readable executable
  25. ...
  26.         invoke  NtQuerySystemInformation, GET_SYSTEM_TIME_INFORMATION,\
  27.                 SystemTime, sizeof.SYSTEM_TIME_INFORMATION, 0
  28.         ; Получить текущее системное время. Для получения времени старта
  29.         ; системы замените в вызове SystemTime.liKeSystemTime на
  30.         ; SystemTime.liKeBootTime
  31.         invoke  FileTimeToLocalFileTime, SystemTime.liKeSystemTime,\
  32.                 ftSystemTime
  33.         ; Преобразовать в системный формат даты и времени
  34.         invoke  FileTimeToSystemTime, ftSystemTime, stSystemTime
  35.  
  36.         ; Теперь к элементам структуры stSystemTime можно обращаться
  37.         ; обычными способами: [stSystemTime.wDay], [stSystemTime.wMonth] и т.д.
  38. ...
После выполнения этого кода структура stSystemTime (стандартная структура SYSTEMTIME) содержит все значения в удобном для доступа и обработки виде.

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

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

System.Uptime.Demo.zip (1,672 bytes)


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

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

Комментарии

Отзывы посетителей сайта о статье
Tam-Tam (15.02.2012 в 15:16):
Мелкомягкие утилиту написали uptime, вполне пригодную для употребления, однако в дистрибутивы её не кладут, она где то в глубинах их сайта скрывается.

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

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

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