Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Определение времени бездействия системы

05.08.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда приложениям требуется узнать время бездействия системы, то есть интервал времени, прошедший с момента когда пользователь последний раз пошевелил мышкой или нажал какую-нибудь кнопку на клавиатуре. Для определения время бездействия системы в системах Windows 2000 и старше используется функция API GetLastInputInfo. Она возвращает количество миллисекунд (тиков таймера), прошедшее от старта системы до момента последнего ввода. Время бездействия вычисляется как арифметическая разница между данными, возвращаемыми функцией GetTickCount и данными из GetLastInputInfo. В FASM, как обычно, ничего из нужных структур не определено, лезем в MSDN:
  1. section '.data' data readable writeable
  2.  
  3. struct  LASTINPUTINFO
  4.         cbSize   dd ?   ; Размер структуры
  5.         dwTime   dd ?   ; Время бездействия
  6. ends
  7.  
  8. lii     LASTINPUTINFO  
Получение времени бездействия системы:
  1.         ...
  2.         ; Получить время последнего ввода
  3.         mov     [lii.cbSize],sizeof.LASTINPUTINFO
  4.         invoke  GetLastInputInfo,lii
  5.  
  6.         ; Получить текущее время в миллисекундах
  7.         invoke  GetTickCount
  8.  
  9.         ; EAX - время бездействия системы в миллисекундах
  10.         sub     eax,[lii.dwTime]
  11.         ...
Это был самый простой способ, работающий на всех новых системах. В старых операционках типа Windows 9x функция GetLastInputInfo отсутствует, поэтому там придется использовать другой, более громоздкий способ с применением глобальных системных хуков.

Читать статью целиком »
Просмотров: 8337 | Комментариев: 11

Windows 7 Taskbar API на Ассемблере

30.06.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter

Progress Bars и Overlay Icons

Продолжаю потихоньку осваивать внутренности Windows 7. В новой системе появилась такая приятная фича интерфейса, как отображение прогресса выполнения какого-нибудь действия прямо на кнопке приложения в панели задач. Впервые я увидел это в программе Total Commander при копировании и переносе файлов, сразу очень захотелось узнать как это делается и научиться делать самому. К сожалению, во всех доступных мне интернетах были найдены только примеры для Delphi, .NET и прочих языков высокого уровня. Пришлось лезть в отладчик и запасаться железным терпением, зато в результате получилось вполне рабочее решение. Для управления элементами панели задач в Windows 7 используется COM-интерфейс ITaskBarList3. Как обычно, никаких описаний в FASM нет, и все необходимое нужно искать самому или портировать с других языков.
  1. ; GUID {56FDF344-FD6D-11D0-958A-006097C9A090}
  2. CLSID_TaskbarList       dd 056FDF344h
  3.                         dw 0FD6Dh
  4.                         dw 011D0h
  5.                         db 095h, 08Ah, 000h, 060h, 097h, 0C9h, 0A0h, 090h
  6.  
  7. ; GUID {EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}
  8. IID_ITaskbarList3       dd 0EA1AFB91h
  9.                         dw 09E28h
  10.                         dw 04B86h
  11.                         db 090h, 0E9h, 09Eh, 09Fh, 08Ah, 05Eh, 0EFh, 0AFh
  12.  
  13. ; ITaskbarList3 Interface
  14. SetProgressValue        = 4*09
  15. SetProgressState        = 4*10
  16. RegisterTab             = 4*11
  17. UnregisterTab           = 4*12
  18. SetTabOrder             = 4*13
  19. SetTabActive            = 4*14
  20. ThumbBarAddButtons      = 4*15
  21. ThumbBarUpdateButtons   = 4*16
  22. ThumbBarSetImageList    = 4*17
  23. SetOverlayIcon          = 4*18
  24. SetThumbnailTooltip     = 4*19
  25. SetThumbnailClip        = 4*20
  26.  
  27. ; Типы прогрессбаров на панели задач
  28. TBPF_NOPROGRESS         = 0
  29. TBPF_INDETERMINATE      = 1
  30. TBPF_NORMAL             = 2
  31. TBPF_ERROR              = 4
  32. TBPF_PAUSED             = 8
  33.  
  34. ; Константы для работы с объектом
  35. CLSCTX_INPROC_SERVER    = 1
  36. S_OK                    = 0
Хотя сейчас будут использоваться только три функции, я привел полное описание методов COM-интерфейса ITaskbarList3, оно пригодится чуть позже.

Читать статью целиком »
Просмотров: 8143 | Комментариев: 11

Отключение кнопки "Свернуть все окна" в Windows 7

03.06.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Захотелось поэкспериментировать с новым интерфейсом Windows 7, а конкретно решил убрать кнопку "Свернуть все окна" из трея. Зачем мне это надо - вопрос другой, здесь важна сама реализация. Кнопка "Свернуть все окна", как в сказке про Кащея, находится внутри нескольких других окон. Вложенность и иерархию классов можно определить, например, при помощи программы WinDowzer или любой другой, показывающей дерево всех окон системы. Для поиска родительского окна системного трея с названием класса Shell_TrayWnd я использовал функцию FindWindow, а для определения хэндлов вложенных дочерних окон с классами TrayNotifyWnd (область уведомлений) и TrayShowDesktopButtonWClass (сама кнопка "Свернуть все окна") - функцию FindWindowEx.
  1.         ...
  2.         ; Найти окно трея
  3.         invoke  FindWindow,stw,NULL
  4.         or      eax,eax
  5.         jz      no_button
  6.  
  7.         ; Найти окно уведомлений в трее
  8.         invoke  FindWindowEx,eax,NULL,tnw,NULL
  9.         or      eax,eax
  10.         jz      no_button
  11.  
  12.         ; Найти кнопку "Свернуть все окна"
  13.         invoke  FindWindowEx,eax,NULL,tsc,NULL
  14.         or      eax,eax
  15.         jz      no_button
  16.  
  17.         ; Спрятать кнопку "Свернуть все окна"
  18.         ; Если надо показать кнопку, то замените флаг на SW_SHOW
  19.         invoke  ShowWindow,eax,SW_HIDE
  20.  
  21.         ; Кнопка не найдена
  22. no_button:
  23.         ...
  24.  
  25. ; Названия классов окон для поиска
  26. stw     db      'Shell_TrayWnd',0  ; Название класса окна трея
  27. tnw     db      'TrayNotifyWnd',0  ; Название класса окна области уведомлений
  28. tsc     db      'TrayShowDesktopButtonWClass',0  ; Название окна кнопки
К сожалению, мне не удалось полностью убрать кнопку из трея, даже когда она скрыта, на ее месте остается пустое пространство. Попытки изменить ширину кнопки перед ее скрытием при помощи функции SetWindowPos успеха тоже не принесли.

Читать статью целиком »
Просмотров: 24506 | Комментариев: 32

Альтернативная Панель управления в Windows 7

22.04.2010 | Категория: Software | Автор: ManHunter

Альтернативная Панель управления в Windows 7

Некоторое время назад исследователи системы Windows 7 нашли в ней очень интересную недокументированную фичу. Если создать, например, на Рабочем столе папку с хитрым именем любое_название.{ED7BA470-8E54-465E-825C-99712043E01C}, то открыв ее, можно попасть в альтернативную Панель управления. Новость выложили даже на развлекательных сайтах, где она мгновенно обросла слухами и домыслами, что это "режим Бога", что там есть все скрытые настройки Windows, и даже что на 64-битных системах само наличие этой папки может привести к фатальному краху системы.

Читать статью целиком »
Просмотров: 12166 | Комментариев: 11

Прямой доступ к диску для записи в Windows 7

05.03.2010 | Категория: Темная сторона Силы | Автор: ManHunter

Прямой доступ к диску для записи в Windows 7

При разработке программы для защиты флешек от вирусов возникла необходимость записи секторов напрямую на диск. Прямой доступ к диску осуществлялся через функцию CreateFile. Под Windows XP все работало нормально, а под Windows 7 при попытке записи сектора возвращалась ошибка Access Denied, при том, что при открытии диска на запись никаких ошибок не возникало. После длительных поисков причины было выяснено следующее: еще в самом начале разработки в Windows 7 была обнаружена критическая уязвимость. Если не вдаваться в нудные технические подробности, то смысл ее заключался в том, что злоумышленник мог открыть системный диск напрямую для записи и поместить любой злонамеренный код в файл подкачки. В Microsoft решили проблему с присущей им дубовой прямолинейностью - просто взяли и запретили прямую запись на диски. Но поскольку нельзя, но было очень нужно, то способ обхода защиты нашелся очень быстро. Оказывается, что запись на диски запрещена не полностью, система разрешает записывать данные в нулевую дорожку диска и в неразмеченные области. Такое поведение вполне объяснимо: надо же как-то форматировать диски штатными средствами без дополнительных танцев с бубнами. Значит для того, чтобы система разрешила запись в произвольное место диска, она сперва должна определить его как неразмеченный. А это достигается уничтожением нулевого сектора диска перед записью. Естественно, что перед уничтожением надо сохранить все данные из нулевого сектора в сухом прохладном месте, а потом вернуть их обратно.

Порядок действий следующий: открыть диск для чтения-записи, попробовать записать нужный сектор. Если произошла ошибка Access Denied, то надо прочитать нулевой сектор, записать вместо него нули, после этого обязательно закрыть диск. Это нужно, чтобы система при повторном обращении посчитала диск неразмеченным и разрешила запись в любой сектор. Затем снова открываем диск для чтения-записи. После записи нужных данных восстанавливаем нулевой сектор и закрываем диск. Все, наша задача выполнена, данные записаны, система спокойна. У этого способа есть и минусы. Так, если работа вашей программы по какой-то причине завершилась аварийно до момента, когда она восстановила нулевую дорожку, то данные на диске могут стать недоступны или вообще потеряться. Способ проверен и хорошо работает на съемных дисках с файловой системой FAT/FAT32, на стационарных жестких дисках и других файловых системах я его не проверял.

Читать статью целиком »
Просмотров: 16986 | Комментариев: 9

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2025
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 3 (0.0073 сек.) / Память: 4.5 Mb
Наверх