Blog. Just Blog

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

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

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, оно пригодится чуть позже.

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

Отключение кнопки "Свернуть все окна" в 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 успеха тоже не принесли.

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

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

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

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

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

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

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

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

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

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

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

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

Восстановление иконки в трее после сбоя системы

02.03.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Если ваше приложение создает и использует свою иконку в трее, то в обязательном порядке надо обрабатывать ситуацию, когда по какой-либо причине произошел сбой и перезапуск Explorer'а. В этом случае перерисовывается панель задач, рабочий стол, системный трей со значками и т.д., и если вы не вернете свою иконку в трей, то она "потеряется". При аварийном перезапуске Explorer'а всем окнам (HWND_BROADCAST) системой отсылается сообщение TaskbarCreated. Особенность этого сообщения в том, что оно не имеет постоянного значения идентификатора, и его значение должно быть получено функцией RegisterWindowMessage. В описаниях этой функции сказано, что она используется для регистрации уникального системного сообщения, но почему-то нигде не указано, что если такое сообщение уже зарегистрировано в системе, то функцией возвращается его существующий идентификатор. Это полезное свойство мы и будем использовать.
  1. ; Сегмент данных
  2. ...
  3. szTBC        db 'TaskbarCreated',0 ; Имя сообщения
  4. restore_msg  dd ?                  ; Идентификатор сообщения TaskbarCreated
  5. ...
Значение идентификатора лучше всего получать на этапе инициализации окна или при запуске приложения, но в любом случае до того, как будет выполняться его обработка.
  1. ; Сегмент кода
  2.         ...
  3.         ; Зарегистрировать сообщение TaskbarCreated
  4.         invoke  RegisterWindowMessage,szTBC
  5.         mov     [restore_msg],eax
  6.         ...
После того, как у вас есть идентификатор сообщения, его можно использовать в обработчике сообщений окна вашего приложения. И, как только оно будет получено, следует просто обновить иконку вашего приложения в трее и выполнить какие-нибудь другие действия по восстановлению работоспособности после перезапуска Explorer'а.
  1.         ...
  2.         ; Сообщение TaskbarCreated?
  3.         mov     eax,[msg]
  4.         cmp     eax,[restore_msg]
  5.         je      .wmrestore
  6.         ...
  7. .wmrestore:
  8.         ; Восстановить иконку в трее
  9.         invoke  Shell_NotifyIcon, NIM_ADD, node
  10.         jmp     .processed
  11.         ...
В этом коде подразумевается, что структура node (NOTIFYICONDATA) была заполнена ранее и содержит всю необходимую информацию об иконке в трее.

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

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