Обход защиты Microsoft Office Outlook 2003 - окно "#32770"
От: Vadimir  
Дата: 02.08.05 09:09
Оценка:
Здравствуйте, Вопрос на тему защиты Microsoft Office Outlook 2003.
Проблема: при отправлении письма с помощью InfoPath outlook выдает запрос на подтверждение – это диалоговое окно класса = "#32770" с заголовком "Microsoft Office Outlook", особенность его в слежующем: не возможно програмно нажать на кнопку Yes пока окно не будет активировано с помощью клавиатуры или мыши. При наличии GUI эта проблема решается легко: эмулируем ввод с клавиатуры
byte VK_TAB = 0x09;
const int KEYEVENTF_KEYUP = 0x2;
const int KEYEVENTF_EXTENDEDKEY = 0x1;
user32.keybd_event(VK_TAB,
0x45,
KEYEVENTF_EXTENDEDKEY | 0,
0);
user32.keybd_event(VK_TAB,
0x45,
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
0);
Табом переходим до нужного места и «нажимаем ввод». так же есть топик http://rsdn.ru/Forum/?mid=948725
Автор: Time
Дата: 15.12.04

А при работе из под сервиса (автоматический запуск юнит тестов) или в залоченном компе этот метод не подходит – в window XP без наличия GUI сообщения система не пересылает.
Получаю кнопку Yes как IAccessible объект и вызываю метод accDoDefaultAction, но это не срабатывает (пока не выполнится условие описанное выше), также могу получить к примеру WndProc = GetClassLong(HWND, GCL_WNDPROC); а потом CallWindowProc(WndProc, HWND, WM_ACTIVATE, MA_ACTIVATE, 0); — но у этого метода пока не получилось работоспособность наладить
Если кто знает решение этой задачи или имеет соображения как это обойти просьба написать ответ, за ранее благодарен.
Re: Обход защиты Microsoft Office Outlook 2003 - окно "#3277
От: EqWu Россия  
Дата: 02.08.05 13:49
Оценка:
Здравствуйте, Vadimir, Вы писали:

V>Здравствуйте, Вопрос на тему защиты Microsoft Office Outlook 2003.

V>Проблема: при отправлении письма с помощью InfoPath outlook выдает запрос на подтверждение – это диалоговое окно класса = "#32770" с заголовком "Microsoft Office Outlook", особенность его в слежующем: не возможно програмно нажать на кнопку Yes пока окно не будет активировано с помощью клавиатуры или мыши.

Так это ж диалог.
Узнай ID кнопки Yes и пошли окну BN_CLICKED через WM_COMMAND.
Re[2]: Обход защиты Microsoft Office Outlook 2003 - окно "#3
От: EqWu Россия  
Дата: 02.08.05 13:53
Оценка:
Здравствуйте, EqWu, Вы писали:

EW>Здравствуйте, Vadimir, Вы писали:


V>>Здравствуйте, Вопрос на тему защиты Microsoft Office Outlook 2003.

V>>Проблема: при отправлении письма с помощью InfoPath outlook выдает запрос на подтверждение – это диалоговое окно класса = "#32770" с заголовком "Microsoft Office Outlook", особенность его в слежующем: не возможно програмно нажать на кнопку Yes пока окно не будет активировано с помощью клавиатуры или мыши.

EW>Так это ж диалог.

EW>Узнай ID кнопки Yes и пошли окну BN_CLICKED через WM_COMMAND.

Вдогонку: а можно и через CallWindowProc

CallWindowProc(WndProc, HWND, WM_COMMAND, MAKEWPARAM(yesButtonID, BN_CLICKED), (LPARAM)yesButtonHWND);
Re[3]: Обход защиты Microsoft Office Outlook 2003 - окно "#3
От: Vadimir  
Дата: 03.08.05 11:31
Оценка:
Здравствуйте, EqWu, Вы писали: CallWindowProc(WndProc, HWND, WM_COMMAND, MAKEWPARAM(yesButtonID, BN_CLICKED), (LPARAM)yesButtonHWND);
ID кнопки Yes = 4774
У меня стоит Window XP я вдоволь наэксперементировался с CallWindowProc со следующим результатом:
Написал сабклассинг для своего окна все замечательно работает (код на C#)
IntPtr mWndProc = user32.GetWindowLong(mainhwnd, GWL_WNDPROC); /* возвращает к примеру -62989 а вот GetClassLong(mainhwnd, GCL_WNDPROC); -64345 хм*/
user32.WinProcDelegate winProcDelegate = new user32.WinProcDelegate(WinProc); /* public delegate int WinProcDelegate(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); */
IntPtr OldProc = user32.SetWindowLong(mainhwnd, GWL_WNDPROC, winProcDelegate); /* подменяю обработчик на свою функцию */
...
user32.SetWindowLong(mainhwnd, GWL_WNDPROC, OldProc); /* востановил обработчик */

private int WinProc(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam)
{
Console.WriteLine("hwnd " + hWnd.ToString()); /* вывожу для наглядности */
Console.WriteLine("Msg " + Msg.ToString());
Console.WriteLine("wParam " + wParam.ToString());
Console.WriteLine("lParam " + lParam.ToString());
user32.CallWindowProc(OldProc, hWnd, Msg, wParam, lParam); /* транслирую сообщение дальше в старый обработчик */
return 0;
}
Эта схема не работает для окон находящихся в другом процессе
GetWindowLong возвращает: 0 (NULL)
GetClassLong(HWnd, GCL_WNDPROC)возвращает: к примеру 2010572111 но из сказанного выше видно что это не тот указатель
соответственно вызвать CallWindowProc не получается
В поиске по мсдн нашел: << для SetWindowLong
GWL_WNDPROC Sets a new address for the window procedure.
Windows NT/2000/XP: You cannot change this attribute if the window does not belong to the same process as the calling thread. >>
Я так понимаю что и для GetWindowLong будет справедливо ограничение: окно должно принадлежать томуже процессу что и вызывающий поток!?
Уточнение я немогу использовать sendmessage или keybd_event — они не работают при залоченной машине или когда идет запуск из сервиса с правами определенного пользователя (в Window XP только для локального сервиса можно разрешить работу с десктопом) вобщем я не хочу "городить огород" на сервере который управляется удаленно и держать его залогиненным под определенным пользователем....
Если есть идеи буду рад их прочесть, за ранее благодарен.
Re[4]: Обход защиты Microsoft Office Outlook 2003 - окно "#3
От: EqWu Россия  
Дата: 03.08.05 12:00
Оценка:
Здравствуйте, Vadimir, Вы писали:

V>Уточнение я немогу использовать sendmessage или keybd_event — они не работают при залоченной машине или когда идет запуск из сервиса с правами определенного пользователя (в Window XP только для локального сервиса можно разрешить работу с десктопом) вобщем я не хочу "городить огород" на сервере который управляется удаленно и держать его залогиненным под определенным пользователем....

V>Если есть идеи буду рад их прочесть, за ранее благодарен.

А что мешает использовать PostMessage?
В крайнем случае можно внедрить DLL в процесс Outlook и там уже делать, что угодно.
Наконец, можно написать Add-in для Outlook или Exchange Client Extension (в этом случае, кстати, можно избежать появления тех самых "вредных" окон, но это — отдельная темя).
Если задачей является именно беспроблемное выполнение Unit-тестов, то Add-in, как мне кажется, самое оптимальное решение.
Он будет выполняться в контексте того же юзера, что и сам Outlook.
И еще вопрос: при работе тестов из-под сервиса как Outlook запускается? У него GUI то появляется вообще?
Re[5]: Обход защиты Microsoft Office Outlook 2003 - окно "#3
От: Vadimir  
Дата: 04.08.05 03:16
Оценка:
Здравствуйте, EqWu, Вы писали:

EW>И еще вопрос: при работе тестов из-под сервиса как Outlook запускается? У него GUI то появляется вообще?


InfoPath (для тех кто не знает InfoPath входит в состав Microsoft Office 2003 и является довольно мощьным средством для сбора информации)
отправляет письма с помощью JavaScript
var outlookObject, outMail;
outlookObject = new ActiveXObject("Outlook.Application");

if (outlookObject == null)
{
Alert(GetText('CanNotCreateOutlookApplication'));
return;
}

outMail = outlookObject.CreateItem(0);

if (outMail == null)
{
Alert(GetText('CanNotCreateMail'));
return;
}

outMail.Recipients.Add(SendOptions['Recipients']);
outMail.Subject = SendOptions['Subject'];
outMail.Body = SendOptions['Body'];
outMail.Attachments.Add(filename);
outMail.Send;
Outlook при такой реализации показывает только окна защиты.
Я написал библиотеку для тестирования (еще сырая только обкатывается)
с помощью ее можно заполнять html формы в "Internet Explorer_Server" вызывать метод Click у тегов, так же получать и устанавливать проперти;
вызывать DefaultAction у элементов управления GUI — этого вполне хватает для GUI тестирования InfoPath form.
К примеру TestComplete довольно мощьное средсво для тестирования GUI, но на залоченной машине или из под сервиса — работать не будет.
Вот и изобретаю велосипед. Вобщем застрял только на Outlook-е.
Огромное спасибо за советы, буду дальше пробовать. (у меня еще есть 2-а дня если в них не уложусь то задача отложится на неопределенный срок)
Re: Обход защиты Microsoft Office Outlook 2003 - окно "#3277
От: Vadimir  
Дата: 04.08.05 11:01
Оценка:
Для тех кому интерестно
PostMessage действительно работает при залоченной машине (Win + L, для NT)
можно переместить фокусирование с кнопки "No" на кнопку "Yes" вот так
//C#

bool rez; 
rez = user32.PostMessage(NoBtn.HWND, WM_KEYDOWN, Keys.Tab, 1);
Thread.Sleep(300);
rez = user32.PostMessage(HelpBtn.HWND, WM_KEYUP, Keys.Tab, 1 | 2);
Thread.Sleep(300);

rez = user32.PostMessage(HelpBtn.HWND, WM_KEYDOWN, Keys.Tab, 1);
Thread.Sleep(300);
rez = user32.PostMessage(CheckBox.HWND, WM_KEYUP, Keys.Tab, 1 | 2);
Thread.Sleep(300);

rez = user32.PostMessage(CheckBox.HWND, WM_KEYDOWN, Keys.Tab, 1);
Thread.Sleep(300);
rez = user32.PostMessage(yesBtn.HWND, WM_KEYUP, Keys.Tab, 1 | 2);
Thread.Sleep(300);


Можно нажать на любую кнопку кроме "Yes" вот так
// C++
HRESULT WINAPI DialogButtonClick(HWND dialogHWND, HWND buttonHWND, WORD buttonId)
{
    BOOL rezClick = PostMessage(dialogHWND, WM_COMMAND, MAKEWPARAM(buttonId, BN_CLICKED), (LPARAM)buttonHWND);
    Sleep(300);

    return rezClick ? S_OK : S_FALSE;
}


или так C# кнопка на которой будет фокус нажмется

rez1 = user32.PostMessage(yesBtn.HWND, WM_KEYDOWN, Keys.Return, 1); // yesBtn.HWND - это не опечатка  
Thread.Sleep(300);
rez1 = user32.PostMessage(yesBtn.HWND, WM_KEYUP, Keys.Return, 1 | 2);
Thread.Sleep(300);



на кнопку "Yes" гарантированно можно нажать так:
// C# не работает когда машина залочена

const int KEYEVENTF_KEYUP = 0x2;
const int KEYEVENTF_EXTENDEDKEY = 0x1;
user32.keybd_event(Keys.Return, 
    0x45,
    KEYEVENTF_EXTENDEDKEY | 0,
    0);
user32.keybd_event(Keys.Return,
    0x45,
    KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
    0);


Замеченно если после появления окна защиты из другой программы запустить метод (нажать кнопку на форме) который
получет кнопку "Yes" как IAccessible объект и вызовет у нее метод accDoDefaultAction то она нажмется!
Следовательно они повесили хук (или ловят какие-то события по активированию/деактивированию)
Всего наилудшего. P.S. Если кто зает как этот тригер сбросить пишите.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.