Подробнее о Looxlight (утилита для Fujitsu-Siemens Loox N560/C550) смотрите
здесь.
Обновление!
Вот cab.Вот исходники.Добавил возможность блокрировать экран и клавиатуру. Раньше у меня стояло что-то-там-guard (screen guard или типа того). Но оно было глючное: иногда при разблокриовке весило кпк, при нажатии на кнопку suspend разблокировала экран, но при нажатии любой клавиши блокировало его обратно - выглядело это страшно, при нажатии на кнопки разблокировало экран и тутже блокировало обратно. Терпел. А вот недавно перепрошил КПК на новую версию WM5 (кстати стало побыстрее все рисоваться, а в каталог /windows так вообще мгновенно заходит (раньше 10сек)). После перепрошивки обнаружил, что жить без блокировки тяжело - батарея садится быстрее, кнопки нажимаются случайно, когда в кармане КПК лежит... И позавчера вечером не выдержал и решил написать сам. Ну как сказать, получилось вобщем-то. Отличается от прочих (
пукнт 1.42) тем, что заточено чисто под Fujitsu-Siemens Loox N560/C550 (может конечно и на 720 заработает, дрова у них похожие), поэтому выключает и экран и клавиатуру в том числе и кнопку suspend(!!). Кстати, выключенный экран (при прослушивании музыки или аудиокниги) экономит более 50мА. С выключенным экраном заряжаться с USB должно быстрее.
Как установить:Если КПК не Fujitsu-Siemens Loox N560/C550, то очень рекоменудю сделать backup! Если это Fujitsu-Siemens Loox N560/C550, то все равно рекомендую, хотя у меня и жены вроде ничего страшного не произошло пока. В любом случае, я ответственности никакой не несу. :) (
Добполнение: У меня работает уже больше чем 2 года без проблем)
Скачать cab. Закинуть на кпк. Запустить установку. Установить. Подождать минуту для верности. Перезагрузить КПК (софтресет). Запустить LooxLight Control и поставить галочку напротив "Permit blocking". Ниже, напротив "Unblock by" два выпадающих списка. В них задается какими кнопками будет происходить РАЗБЛОКИРОВКА. Когда КПК будет заблокирована, эти две кнопки надо будет последовательно нажать. У меня это 2 и 3 кнопки. А по умолчанию почему-то стоит 2 и 4, ну и фик с ним. Теперь идем в Settings/Buttons и там вешаем LooxLight Control на ту кнопку, которой КПК будет БЛОКИРОВАТЬСЯ. У меня это долгое нажатие на кнопку 2. Готово. Можно тестировать.
При нажатии на первую из кнопок разблокировки, следующую нужно зажать в течении одной секунды. Во время ожидания клавиатура КПК будет подмигивать.
Как реализовано (в общих чертах):С выключением экрана все просто. А вот с его блокировкой посложнее. LooxLight аттачит себя к gwes.exe. Находит в памяти keybddr.dll и правит в ней таблицу импортированных функций, а именно WaitForSingleObject. Эта функция вызывается нитями keybddr.dll для ожидания прерывания клавиатуры (0x10 и 0x2a), а также для ожидания срабатывания события suspend. Т.е. в таблице импорта keybddr.dll, LooxLight подменяет адрес WaitForSingleObject с адреса функции из библиотеки coredll.dll на собственную функцию. Получается, что в момент, когда keybddr инициирует ожидание нажатия, вызывается функция LooxLight'а, которая в свою очередь дергает оригинальную функцию. Если блокировка не включена, то результат сразу же возвращается в keybddr.dll. Иначе в результате проверяется пара адресов памяти на код нажатой клавиши. По нему решается, разблокировать ли экран или нет (грубо очень). Если нажатие нужно проигнорировать, то сообщаем OS о том, что мы обработали прерывание (InterruptDone) и вызываем оригинальный WaitForSingleObject - тоесть управление обратно в keybddr не передается, пока клавиатуру не разблокируется. Таким образом ни одной нажатие мимо нас в принципе не проходит. Ибо обработчик LooxLight находится первым в цепочке обработки прерывания клавиатуры.
Пока заметил, что если воткнуть КПК в крэдл, когда КПК заблокирована, то экран включается. Правда при этому клавиатура попрежнему заблокирована. Я думаю activesync что-то делает такое не хорошее, например вызывает ExtEscape - функция используемая для выключения/включения питания экрана. Или еще хуже. он дергает какое-то более общее API (варианты: вывести окно на передний план, послать уведомление, включить подсветку), которое как раз и и дергает ExtEscape. Вариантов лечения я вижу два:
1. Простой. Эпизодически запрашивать состояния питания на экран и если блокировка включена, а экран выключен - то выключать экран. Но я так не люблю по таймеру что-то делать. Да и мерцание будет, хоть и очень редко.
2. Сложный. Я уже попробовал пойти по этому пути - убил 3 часа и пока решил отложить. Смысл в том, что можно вклинится в какое-нибудь API какой-нибудь dll. Например можно было бы перехватить ExtEscape, но для этого нужно пробежаться по всем dll'кам в системе и каждую из них происнструментировать так же как и keybddr. Так я еще не пробовал, но есть подозрение, что может не сработать. Ибо у нас есть gwes.exe который и рулит GDI'ем. И если кто-то вызывает API у coredll, тот направляет его еще куда.. короче я к тому, что вызов ExtEscape из coredll может быть проскипан кодом, который напрямую работает с DeviceDriver'ом - а с ним напрямую, я так подозреваю, работает gwes. Было бы просто идиально вклинится в Display Driver. Когда кто-то дергает ExtEscape, тот в свою очередь вызывает DrvEscape callback у драйвера дисплея. Как это вообще работает. Когда gwes.exe грузит драйвер дисплея, он вызывает у него метод DrvDeviceEnable (или типа того). Передавая ему в качестве параметра структуру, которую драйвер должен заполнить. В этой структуре указатели на методы связаные с работой с дисплеем, в том числе и DrvEscape. После того, как драйвер заполнил эту структуру, далее gwes уже работает только с методами прописанными в этой структуре. Было бы клево, найти в памяти адрес этой структура и прописать свой DrvEscape туда. Но полазив по header'ам от wince я пока не нашел цепочку, чтобы добраться до туда. Может имея HDC можно по нему добраться? Но HDC - это указатель на C++ структуру и я этот путь пока не осилил. Другой вариант, изучать gwes.exe и посмотреть куда он копирует адрес заполненной структуры и плясать отсюда. Но блин, gwes.exe как-то криво разобрался IDA (или криво задампился). Все локальные переменные имеют совсем не те адреса, на какие ссылается код. Еще можно было бы посмотреть coredll.dll и как там работает ExtEscape и потыкаться оттуда, но coredll.dll у меня задамлпнного нет (это вообще вроде kernel сам). А дамп всей ОЗУ неплохо так разобранный во времена когда искал как управлять диодами я где-то посеял..
Вобщем я решил пока этот вопрос отложить. Посмотрим как оно будет анноить или нет.
--------
Будущие версии программы можно будет найти
здесь.
Другая программа для уменьшения расхода заряда батареи описана
здесь.