Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ScreenShot окна UAC в win7, как сделать скрин UAC 
:(
    Опции темы
yogin
Дата 9.4.2012, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Есть приложение, делает скрины каждые 10 секунд и сохраняет их на диске(регистратор визуальных действий). Недавно заметил, что окно "Контроль учётных записей пользователей" совсем не фоткается - его нет на скринах.
А оно так часто появляется... почти при запуске каждой проги.
Как его запечатлить? 
Скрин делается обычным способом:
Код

  DeskDC := GetDC(0);
  try
    BitBlt(..., SRCCOPY);
  finally
    ReleaseDC(0, DeskDC);      
  end;

Может нужно скринить как-то по другому?
Или ещё есть мысль - может быть нужно проматывать все существующие окна, смотреть на их какие-нибудь идентификаторы и определять UAC это окно или нет и если да, то скринить само окно через его дескриптор?
И следующий вопрос, а даст ли система свободу на все эти действия или тоже увильнёт как и от скрина?...
PM MAIL   Вверх
kami
Дата 9.4.2012, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



UAC "выскакивает" на отдельном десктопе.
Порядок действия его, afair, следующий:
- скрин десктопа
- переключение на специфический десктоп
- отображение скрина
- создание окна "запустить/не запустить"

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

Afair, читал это в статьях Руссиновича.

Это сообщение отредактировал(а) kami - 9.4.2012, 22:28
PM MAIL WWW   Вверх
kami
Дата 9.4.2012, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата

The Winlogon desktop is active while a user logs on. The system switches to the default desktop when the shell indicates that it is ready to display something, or after thirty seconds, whichever comes first. During the user's session, the system switches to the Winlogon desktop when the user presses the CTRL+ALT+DEL key sequence, or when the User Account Control (UAC) dialog box is open.
MSDN

Это сообщение отредактировал(а) kami - 9.4.2012, 22:47
PM MAIL WWW   Вверх
yogin
Дата 10.4.2012, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Так... правильно ли я понял, 
что мне надо запомнить Handle текущего десктопа методом GetThreadDesktop(GetCurrentThreadId),
затем как-то узнать Handle десктопа, созданного UAC'ом, 
потом переключиться на него командой SwitchDesktop(), сделать скрин обычным методом через GetDC(0), а потом переключиться обратно тем же методом SwitchDesktop(OldDT) ?
Тогда вопрос, а как узнать хэндл окна UAC'а?

Или второй вариант: мне надо не GetDC(0) делать, а постоянно вызывать сначало GetThreadDesktop(GetCurrentThreadId), и уже относительно результата получать дескриптор?
Тогда вопрос, как получать дескриптор в этом случае? так: GetDC(GetThreadDesktop(GetCurrentThreadId)) ?
PM MAIL   Вверх
kami
Дата 11.4.2012, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



не совсем так.
Есть ряд проблем с этой задачей.
1. Я не нашел функцию, позволяющую отследить смену десктопа, наподобие WTSRegisterSessionNotification, без этого имхо придется постоянно отслеживать через OpenInputDesktop
2. C учетом того, что UAC показывается на Winlogon -десктопе. последний абзац по ссылке. Это печально. Вообще - читать Thread connection to desktop. Могу посоветовать обратиться к Eraser-у на форуме delphimaster.ru, он при создании своего RemoteOfficeManager как-то обошел это.
 
Если отбросить все сложности, то (имхо) должно выглядеть так:

1. Запоминаем текущий десктоп потока.
2. OpenInputDesktop
3. SetThreadDesktop
4. Снимок экрана
5. SetThreadDesktop(старый десктоп)
6. Освободить все полученные хендлы.

Кстати, не стоит забывать, что Winlogon - не единственный десктоп, отличный от winsta0\default. Есть куча программ (например, Марка Руссиновича), которые создают дополнительные десктопы и позволяют оперативно переключаться между ними. Иногда - очень полезная штука smile

Вечером еще пошукаю MSDN, но думаю нечего нового не скажу.
PM MAIL WWW   Вверх
yogin
Дата 11.4.2012, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Цитата(kami @ 11.4.2012,  13:13)
Могу посоветовать обратиться к Eraser-у на форуме delphimaster.ru, он при создании своего RemoteOfficeManager как-то обошел это.

В ROM'е используется драйвер стандартного MS'овского удалённого рабочего стола. Так что это не то...
PM MAIL   Вверх
yogin
Дата 18.5.2012, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Правильно ли я понял, что перед каждым снимком мне надо создавать новый десктоп(OpenInputDesktop), потом фоткать обычным методом(GetDC(0)), а потом возвращаться к предыдущему десктопу. 
При этом фоткаться будет всё, т.к. мой новый десктоп будет как бы поверх всех существующих?...
PM MAIL   Вверх
kami
Дата 18.5.2012, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(yogin @  18.5.2012,  20:30 Найти цитируемый пост)
перед каждым снимком мне надо создавать новый десктоп(OpenInputDesktop), потом фоткать обычным методом(GetDC(0)), а потом возвращаться к предыдущему десктопу. 

Ну, OpenInputDesktop - это не создание нового десктопа, а попытка "подключения" к существующему.
Емнип(было дело - разрабатывал программу удаленного администрирования), нет. Достаточно один раз открыть и потом делать снимки. 
Опять-таки емнип, если делать снимки через BitBlt, то когда десктоп, DC которого получен, становится неактивным, то BitBlt начинает возвращать ошибку. Вот тогда и понадобится повторение всей последовательности от OpenInputDesktop и далее. Хотя... снимок раз в 10 секунд... можно каждый раз и полную последовательность, это не куча снимков за секунду.

Цитата(yogin @  18.5.2012,  20:30 Найти цитируемый пост)
При этом фоткаться будет всё, т.к. мой новый десктоп будет как бы поверх всех существующих?...

Вряд ли. хочу еще раз обратить внимание на:
Цитата

The Winlogon desktop's security descriptor allows access to a very restricted set of accounts, including the LocalSystem account. Applications generally do not carry any of these accounts' SIDs in their tokens and therefore cannot access the Winlogon desktop or switch to a different desktop while the Winlogon desktop is active.

Имхо - получить доступ к UAC-окну, даже если использовать запуск "из-под админа" у десктопного приложения не получится.

PM MAIL WWW   Вверх
yogin
Дата 19.5.2012, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Кароч делаю так:
Код

var  
  bmp : TBitmap;
  DC  : HDC;
  olddesk, desk  : HDESK;
begin
  GetThreadDesktop(olddesk);
  desk := OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, False, MAXIMUM_ALLOWED);
  if desk > 0 then
  begin
    if SetThreadDesktop(desk) then
    begin
      DC := GetDC(0);
      if DC > 0 then
      begin
        bmp := TBitmap.Create;
        bmp.Height := Screen.Height;
        bmp.Width := Screen.Width;
        try
          bitblt(bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, DC, 0, 0, SRCCOPY);
          bmp.SaveToFile(fAppPath + c_PTH08 + DateTimeToStr(Now) + '.bmp');
        finally
          ReleaseDC(0, DC);
          FreeAndNil(bmp);
        end;
      end;
      SetThreadDesktop(olddesk);
    end;
    CloseDesktop(desk);
  end;
end;

SetThreadDesktop всегда False, т.к.:
<<MSDN - function SetThreadDesktop - Remarks>>
Цитата

The SetThreadDesktop function will fail if the calling thread has any windows or hooks on its current desktop (unless the hDesktop parameter is a handle to the current desktop).

Поэтому сдаётся мне процесс скрининга надо реализовывать сервисным приложением... И видимо надо интерактивный сервис, чтобы скрин как-то передават "нормальному" приложению с формой, которое уже будет выполнять сохранение куда надо или отображение на форме...
PM MAIL   Вверх
kami
Дата 19.5.2012, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(yogin @  19.5.2012,  14:06 Найти цитируемый пост)
Поэтому сдаётся мне процесс скрининга надо реализовывать сервисным приложением... 

к потоку в сервисе ведь точно такие же требования - отсутствие окон и хуков при переключении. Причем окно ведь не обязательно визуальное, хватит и таймера, в котором используется AllocateHwnd.

Цитата(yogin @  19.5.2012,  14:06 Найти цитируемый пост)
И видимо надо интерактивный сервис

В ОС, в которых появился UAC, интерактивные сервисы запрещены. В Vista была специализированная служба, которая отлавливала попытку отображения чего-то визуального интерактивным сервисом и предлагала показать "это" на специализированном десктопе, не имеющем никакого отношения к Winlogon-у. А вообще, интерактивные службы в Vista и 7 не являются такими, какими они задумывались изначально - они не имеют доступа даже к обычному десктопу обычного пользователя, так как находятся в отличной от пользовательской терминальной сессии. То есть - не являются интерактивными.
Цитата(yogin @  19.5.2012,  14:06 Найти цитируемый пост)
 чтобы скрин как-то передават "нормальному" приложению с формой, которое уже будет выполнять сохранение куда надо или отображение на форме...

Обычно делают наоборот smile
PM MAIL WWW   Вверх
CodeMonkey
Дата 20.5.2012, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89





--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
yogin
Дата 22.5.2012, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Цитата(kami @  19.5.2012,  17:42 Найти цитируемый пост)
В ОС, в которых появился UAC, интерактивные сервисы запрещены.

Хорошо, тогда обычный сервис, но порядок действий-то будет в нём таким же?
Цитата(kami @  19.5.2012,  17:42 Найти цитируемый пост)
Обычно делают наоборот

Тогда просто самим сервисом сохранять файлы?

CodeMonkey, я сделал так как там написано(вручную отключил), но обычные методы скрининга всё равно не запечатлили окно UAC, лишь тень от него.
PM MAIL   Вверх
yogin
Дата 1.6.2012, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Опытным путём метода тыка выяснено:
1) что фотки UAC'а получаются в нормальном приложении, если это приложение запустить от имени системы...
2) а служба не может ничего сфоткать потому что ей в нормальном режиме десктопы не доступны(в 7-ке)...

Вытекающие вопросы:
1) как можно службой запустить приложение, чтобы у него были её права(или права системы), но при этом оно имело доступ к едсктопам?
2) можно ли как-то в винде назначить, чтобы прога автоматом запускалась с правами системы?
PM MAIL   Вверх
kami
Дата 1.6.2012, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(yogin @  1.6.2012,  09:56 Найти цитируемый пост)
а служба не может ничего сфоткать потому что ей в нормальном режиме десктопы не доступны(в 7-ке)...

Ага, у пользователя своя терминальная сессия, а у сервисов - своя. И у каждой своя WinSta и свой десктоп...

Цитата(yogin @  1.6.2012,  09:56 Найти цитируемый пост)
как можно службой запустить приложение, чтобы у него были её права(или права системы), но при этом оно имело доступ к едсктопам?

Единственное, что нашел - это Starting an interactive process. Но, хоть в community пишут, что она работает (только acl-ы нужно потом удалить, даже код есть как) у меня не получилось портировать это хозяйство на Delphi. Вернее, получилось (отрабатывает без ошибок), но процесс запускается не интерактивный, а непойми в какой WinSta...

До того, как увидел этот код, получалось запустить из сервиса десктопное приложение, но так как токену сессии, от которой запускался процесс, не давали права админа (было Deny), то ни о каких дополнительных плюшках речи не шло. К сожалению, Deny ни на что другое поменять нельзя...

На последний вопрос ничего не скажу - не знаю...

Добавлено @ 13:20
Кстати, не пробовал еще получать токен не через LogonUser, а через GetActiveConsoleSessionID и далее...

Это сообщение отредактировал(а) kami - 1.6.2012, 13:20
PM MAIL WWW   Вверх
drkot
Дата 1.6.2012, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: нет
Всего: 8



Цитата

1) как можно службой запустить приложение, чтобы у него были её права(или права системы), но при этом оно имело доступ к едсктопам?


Сразу оговорюсь... то что напишу не есть "правильно" с точки зрения системного подхода ОС, но значительно проще и гуманнее относительно программиста.
Принцип прост: любое приложение может посылать (создавать) записи в системном журнале событий. В системном планировщике есть возможность привязки задачи к журналу событий.
Для реализации такого механизма не нужно ковырять права и переключаться между сессиями... что значительно упростит задачу для начинающего.

Права на запуск задаются в том же планировщике


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0563 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.