воскресенье, 4 марта 2007 г.

LooxLight 2007-03-04

Подробнее о Looxlight (утилита для Fujitsu-Siemens Loox N560/C550) смотрите здесь.

Сделал новую версию LooxLight. Изменения:
  • Полная поддержка GPS светодиода.
  • Поддержка bluetooth стека от Broadcom.
  • Полная поддержка индиктора питания.
  • Лучше реализована поддержка индикатора клавиатуры (теперь переживает изменение яркости).
  • LooxLight теперь не EXE, а DLL. Это лучше тем, что в wince есть ограничение в 32 процесса.
  • В два раза меньшее потребление памяти, чем раньше

  • CAB архив в ZIP'е: тут.
    Исходные коды (GPL): тут.

    Будущие версии программы можно будет найти здесь.
    Другая программа для уменьшения расхода заряда батареи описана здесь.

    понедельник, 19 февраля 2007 г.

    Вирус для WinCE

    Конкретно так изучил внутренности WM5. Может вспомнить детство и написать под него вирус? Надо перейти в режим ядра? Нет проблем, есть ф-ия SetKMode. Надо прочитать память какого-то прилажения? Нет проблем, бери да читай. Надо перехватит системный вызов, обращение к драйверу или прерывание? И это можно. :)

    воскресенье, 11 февраля 2007 г.

    WM5EventSpy

    Сегодня очень продуктивный день. Сегодня я реализовал утилиту для мониторига системных событий в Windows Mobile 2005. Если вы запустите WM5EventSpy, оно создаст файл с именем \SD-MMCard\WM5EventSpy.log. Туда утилита запишет имена всех зарегестрированных приложениями событий. Затем утилита будет ожидать срабатывания какого либо события и писать об этом в лог, когда одно из событий сработает. Тут зип архив с исполняемым файлом WM5EventSpy внутри. А тут его исходные коды. При написании утилиты были использованы недокументированные структуры ядра WM5, поэтому оно врятли заработает на какой-то другой версии ОС.

    Пример лога:
    2007.02.11 22:28:36: Started ------------------------------------------------------
    2007.02.11 22:28:36: - - - - Start of event list - - - -
    2007.02.11 22:28:36: 1: 'WM5EventSpy/SomeEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 2: '50650_ConnMgr', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 3: 'PluginInitialized', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 4: 'HistoryMappingsClosedEvent', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 5: 'CookiesMappingsClosedEvent', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 6: 'ContentMappingsClosedEvent', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 7: 'HistoryCloseMappingsEvent', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 8: 'CookiesCloseMappingsEvent', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 9: 'ContentCloseMappingsEvent', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 10: 'ActiveSync:Started', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 11: 'CE2STATEEVENT1', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 12: 'CE2COMMANDDONEEVENT', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 13: 'CE2COMMANDEVENT', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 14: '__SD_CARD_INOUT', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 15: 'tiacwlnControlReady', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 16: 'tiacwlnResponseToControlReady', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 17: '_LEAP_LIST_CHANGE', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 18: '_BT_STATE_OFF', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 19: '_BT_STATE_ON', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 20: 'WLANStateNotified', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 21: 'LooxLight/FlashlightEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 22: 'LooxLight/SetupEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 23: 'LooxLight/ExitEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 24: 'SYSTEM\netui-TNETWLN1', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 25: 'WLANStatusHasChanged', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 26: 'ProfileStatusEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 27: 'ConnMgrApiReady', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 28: 'DTPT_SRV_STARTED', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 29: 'BindingMapSharedMemoryEvent', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 30: 'All_Awake', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 31: 'BT_EVENT_SECURITY', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 32: '_KeyPress', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 33: 'Shell_Ready', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 34: '$*@DBChanged#%&', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 35: '$*@RegChanged#%&', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 36: 'SSTimeChange', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 37: 'SSUpdatePower', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 38: '$*EventInboxEnableSound*$', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 39: '$*EventInboxDisableSound*$', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 40: 'SSUpdateRecalc', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 41: 'SYSTEM\SipTimerActive', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 42: 'EventSounds_GlobalStopEvent', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 43: 'MS_GWE_TPC_cont_startup', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 44: 'MS_GWE_TPC_startup', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 45: 'TouchPanelCommandEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 46: 'CgrTabletInnerEvent', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 47: 'CgrTabletEvent', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 48: '_SSP_INIT_OK_EVENT3', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 49: 'WatsonUploadClientReady', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 50: 'WALNStatusChangeEvent', manualreset=0, pIntrProxy=8f9fba3c
    2007.02.11 22:28:36: 50: 'system/events/bluetooth/PairingChange', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 51: 'system/events/bluetooth/HardwareChange', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 52: 'system/events/bluetooth/DeviceIdChange', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 53: 'system/events/bluetooth/ConnectivityChange', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 54: 'system/events/bluetooth/SecurityChange', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 55: 'system/events/bluetooth/ConnectionsChange', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 56: 'system/events/bluetooth/BasebandChange', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 57: 'system/events/bluetooth/StackInitialized', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 58: 'IP6_ROUTE_CHANGE_EVENT', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 59: 'IP6_ADDR_CHANGE_EVENT', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 60: 'TAPILINE00000000', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 61: 'IP_ROUTE_CHANGE_EVENT', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 62: 'IP_ADDR_CHANGE_EVENT', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 63: 'BTWCEShimShutdownThread', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 64: 'BTWCEShimFreeLibs', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 65: 'BTWCEShimLoadLibs', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 66: '_SSP_INIT_OK_EVENT2', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 67: 'Event_HS_PTT_Down', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 68: 'Event_HS_PTT_Up', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 69: 'CPUSpeed4lter', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 70: '_SSP_INIT_OK_EVENT', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 71: '_hLedChangeEvent_Name_', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 72: 'BackLightOverTempEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 73: 'BackLightNormTempEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 74: 'BackLightHighTempEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 75: 'BackLightChangeEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 76: 'BackLightActiveEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 77: 'BackLightNotifyEvent', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 78: 'PowerManager/SystemIdleTimerReset', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 79: 'PowerManager/ReloadActivityTimeouts', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 80: 'PowerManager/UserActivity_Inactive', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 81: 'PowerManager/UserActivity_Active', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 82: 'PowerManager/ActivityTimer/UserActivity', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 83: 'SYSTEM/SystemStarted', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 84: 'system/events/notify/APIReady', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 85: 'SYSTEM/ShellAPIReady', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 86: 'SYSTEM/BatteryAPIsReady', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 87: 'SYSTEM/NLedAPIsReady', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 88: 'SYSTEM/CertChange', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: 89: 'SYSTEM/BootPhase2', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 90: 'SYSTEM/DevMgrApiSetReady', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 91: 'SYSTEM/PowerManagerReady', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 92: 'SYSTEM/GweApiSetReady', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 93: 'LASS_SRV_STARTED', manualreset=1, pIntrProxy=00000000
    2007.02.11 22:28:36: 94: 'WatsonEventDumpFileReady', manualreset=0, pIntrProxy=00000000
    2007.02.11 22:28:36: - - - - End of event list - --- - - -
    2007.02.11 22:28:37: We are going to monitor 63 events!
    2007.02.11 22:28:37: We are going to monitor 31 events!
    [...]
    2007.02.11 22:28:56: Event 'PowerManager/ActivityTimer/UserActivity' is signaled, avgDelay = 54, count=10!
    2007.02.11 22:28:56: Event 'PowerManager/ActivityTimer/UserActivity' is signaled, avgDelay = 46, count=11!
    2007.02.11 22:28:56: Monitoring of 'PowerManager/ActivityTimer/UserActivity' is disabled, current count of monitoring events=69!
    2007.02.11 22:29:16: Event '$*@RegChanged#%&' is signaled, avgDelay = 0, count=1!
    2007.02.11 22:29:17: Event '$*@RegChanged#%&' is signaled, avgDelay = 24, count=2!

    пятница, 9 февраля 2007 г.

    Synce & Linux & WM5 & Password

    Когда я разрабатывал для WM5 под linux'ом мне показалось, что копировать файлы для тестирования на КПК весьма напряжно. Файлы копировались на КПК либо через MMC карточку, либо с помощью монтирования КПК как USB флешки. Оба способа совершенно не удобны, когда эти действия приходится делать каждые 5 минут. В добавок, исполняемый файл надо было запускать, чтобы увидеть как он работает. Я запускал файлы руками. Вобщем-то нет особого смысла говорить, как меня это раздражало после того как я в свое время поразрабатывал под виндой, где все эти действия выполнялись одним батничком. Тогда когда я попробовал найти что-то типа того я наткнулся на проект synce. Сначало мне показалось, что надо поставить драйвер usb-rndis. Я попытался, но оно обломалось на этапе компиляции. После небольшого изучения сайта synce я все-таки обнаружил существование новой версии драйвера "usb-rndis-lite". На этот раз получилось без проблем. После установки драйвера появилось новое сетевое устройство: rndis0. Затем надо было поставить synce утилиты и библиотеки. Это была самая жостка часть. Первым делом я попробовал следовать инструкциям с вики. Но odccm вывавал мне ошибки о d-ubs, hal и т.д.. Ошибки были откровенно тупыми, т.е. по ним нельзя никак было сказать о причине... ну это было что-то типа "d-bus error" или типа того. Тогда я попробовал vdccm.. и мне показалось, что уже лучше. Появилось что-то первое и хорошее - программа запустилась без ошибок :). В остальном все было тихо и грустно. Я начал искать в гугле слово 'vdccm' и через какое-то время нашел, что некто пользовался утилитой triggerconnection, чтобы уведомить ActiveSync. Но в моих руках triggerconnection не производила никакого эффекта ни на vdccm, ни на ActiveSync. Я прошелся по исходникам triggerconnection, было походе, что оно (утилито) отсылает пакет на порт 5679 нашего PPC. Тогда я посканил КПК с помощью nmap. Но nmap сказал мне, что портов открытых немає. У меня не было никаких идей почему порт 5679 закрыт в том время, как сам ActiveSync запущен. Я устал и заколебался. Увы, я потратил кучу времени пытаясь понять почему порт 5679 закрыт, пока в конце-концов, не предположил, что порт может оставаться открытым только несколько секунд после того как мы воткнули КПК в кроватку. И действительно, vdcomm обнаружил КПК, когда я запустил tirggerconnection сразу после того, как воткнул КПК в крэдл. В этот раз стало ясно, что одна проблема закрывала собой другую. Теперь, vdccm мог обнаруживать КПК, но он не мог держать соединение с КПК больше нескольких секунд. И снова я стал гуглить. Где-то кто-то написал, что vdccm не работает с устройствами защищенными паролями. "@!#%@#%*#$!!!" воскликнул я. Я не хотел держать КПК не защищенным или снимать пароль каждый раз как я вставляю КПК в крэдл. Короче я сделал патч для vdccm, сразу как только отреверсинженирил протокол авторизации и разобрался в коде synce. И тогда наше время пришло, пропатченный vdccm разарботал как надо! Вии! Итак вкратце, что я сделал:
    1. Поставил usb-rndis-lite.
    2. Поставил библиотеки: librapi2, libsynce.
    3. Пропатчил vdccm.
    4. Установил ifplugd. Он запускает ifup/ifdown для rndis0 когда это нужно.
    5. Добавил следующее в /etc/network/interfaces:

    iface rndis0 inet static
    address 169.254.2.2
    netmask 255.255.255.0
    post-up /usr/local/bin/triggerconnection-delayed local-pda

    6. Добавил строку '169.254.2.1 local-pda' в /etc/hosts.
    7. Написал /usr/local/bin/triggerconnection-delayed:

    #!/bin/sh

    sleep 2
    exec /usr/local/bin/triggerconnection $@

    8. Следующее я добавил в ~/.xsession:
    vdccm -d 3 -f -t -p `cat ~/.pda-pwd` 1>>~/logs/vdccm 2>>~/logs/vdccm &

    9. Записал секретный пароль в ~/.pda-pwd file (chmod 0600).

    Теперь могу наслаждаться использованием утилит: pls, pstatus... ставить кабы и тд.

    Любые комменты приветствуются.

    P.S. Патч собственно не совсем полный. Я написал его очень прямолинейно. Он не поддерживает ожидание ввода пароля откуда-то, вместо этого вы должны указать пароль через ключ -p. К сожалению, у меня нет времени это реализовывать.

    воскресенье, 4 февраля 2007 г.

    LooxLight-2007-02-03

    Подробнее о Looxlight (утилита для Fujitsu-Siemens Loox N560/C550) смотрите здесь.

    Обновление. Надеюсь исправил проблему из-за которой владельцы локализованных версий WM5 не могли поставить программу. Сообщение об ошибке сделал более детальным - если проблема все-таки не исчезла можно будет хоть понять причину более точно.

    Зазипованный каб файл (2007-02-03),

    Будущие версии программы можно будет найти здесь.
    Другая программа для уменьшения расхода заряда батареи описана здесь.

    пятница, 2 февраля 2007 г.

    GoodWavPower

    Третья программа. Смотрел форум firstloox и нашел, что после того как КПК Fujitsu-Siemens Loox N560 или C550 просыпается из спящего режима, она вдруг начинает потреблять на 40мА больше, чем до сна. Советуют нажимать на кнопку Start - помогает. Попытался определить почему помогает и предположил, что проблема в аудио драйвере. Вобщем, поставив это программу забудите про эту багу, как если бы вы о ней не знали вообще. Вы сможете читать книги на 3 часа дольше на той же батарее.

    Зазипованный cab архив (3k).
    Сырцы (GPL, 11k).

    Следить за обновлением программы можно по ссылке.

    (другая программа, чтобы сэкономить эл-энэргию (где-то 15 ... 40мА) тут)

    четверг, 1 февраля 2007 г.

    LooxLight


    Я сделал это! Я написал свое второе приложение для PPC. LooxLight - это крошечное приложение, которое позволяет контролировать встроенные светодиоды на вашем FSC Pocket PC.

    Фичи:

  • LooxLight позволяет управлять светодиодами: клавиатуры, wifi, bluetooth, gps, питания. Каждый светодиод может быть установлен в свое состояние. LooxLight может поддерживать любой светодиод в заданном состоянии или просто временно переключать из одного состояния в другое.
  • Сервис LooxLight занимает всего 3.5k памяти, когда загружен (можно и не загружать). LooxLight не грузит процессор: сервис делает только то, что требуется в те моменты, когда оно требуется и не более того (реагирует на изменение состояний светодиодов). LooxLight не разряжает батарею.
  • Работа из командной строки. Вы можете контролировать светодиоды из скриптов. Резидентная часть для этого не нужна. Например, "LooxLightCtrl +keyb sleep100 -keyb sleep100 +keyb" подмигнет вам подсветкой клавиатуры.
  • Протестировано на Fujitsu-Siemens Loox N560 и Fujitsu-Siemens Loox C550. Но ЕМНИП должно работать и на Loox 720 / Loox 718 .
  • Выложу исходники под GPL как только реализую все что хотел..

    ZIP архив с CAB'ом (17k).

    Что к чему в диалоге настройки.
    KBD озанчает KEYBOARD т.е. клавиатура, BTH сокращение от BLUETOOTH, PWR это POWER т.е. питание как вы догадались уже. Каждая строка с элементами управления озаглавлена названием светодиода.
    "On" кнопка просто включает светодиод, а "off" выключает. Blink означает мигать.
    "KEEP ON"/"KEEP OFF" подразумевает, что LooxLight будет восстанавливать состояние светодиода после того как какая либо другая программа установит его в ненужное состояние.

    Некоторые элементы управления отключены сейчас, потому, что еще не реализованы.

    Опции командной строки:
    LooxLightCtrl.exe ... , где opN:
  • stop - выключает резидентную часть
  • setup - говорит резидентной части прочитать настройки из registry
  • sleep123 - спать 123 миллисекунд (где 123 это любое положительное число)
  • flashlight - включает все светодиоды
  • +wifi - включает светодиод wifi
  • -wifi - выключает светодиод wifi
  • +bluetooth - включает светодиод bluetooth
  • -bluetooth - выключает светодиод bluetooth
  • +gps - включает светодиод gps
  • -gps - выключает светодиод gps
  • +keyboard - включает светодиод клавиатуры
  • -keyboard - выключает светодиод клавиатуры
  • +power - включает светодиод питания
  • -power - выключает светодиод питания
  • =power - включает светодиод питания в режим мерцания

    История создания:
    Однажды я нашел KeyLightC. Это была полезная программа, но в ней нельзя было включать-выключать отдельные светодиоды (а только все вместе и только выключать). Также там нужно было заново запускать KeyLightC как только какая-то программа поменяла состояние светодиода или просто после включения КПК. Я написал письмо Phill McManus. Я попросил его добавить опции +keyboard или -keyboard. Также я попросил его открыть исходники KeyLightC, чтобы я сам мог добавить эти фичи, если у него нет времени или желания. Но он не ответил. Тогда я начал мои собственные исследования прошивки. Прошло порядка 20 вечеров, прежде чем я нашел как управлять светодиодами правильным образом. Потом ушло порядка 10 вечеров, чтобы разобраться как писать под КПК и как пользоваться WinCE API. Потом ушло 3 дня, чтобы избавится от ужасного MS Visual Studio и мигрировать на mingw32ce под линух. И вообще, я ненавижу Win32 API за тонну подводных камней и неожиданностей.

    Планы:
  • Реализовать режим фонарик (не всегда темнота друг молодежи).
  • Доделать контроль светодиодов питания и GPS..
  • Реализовать контроль уровня подсветки.

    О прошивке Loox N560/C550.
    Я уже устал от этого поста. Опишу в другом попозже.

    Обратная связь:
    Было б прикольно увидеть комменты с пожеланиями, замечаниями и информацией у кого заработало (и на чем), а у кого нет (и на чем).

  • Новые версии программы здесь.
    Другая программа для уменьшения расхода заряда батареи описана здесь.