воскресенье, 20 июня 2010 г.

Организация работы приложения соглассно настройкам

Сегодня вывел для себя правило, которое можно сформулировать так:

Если приложение работает соглассно настройкам пользователя, то наиболее удобная работа с настройками может быть достигнута при разработке класса конфигуратора приложения.


Довольно часто мне приходится разрабатывать приложение работающее соглассно заданными пользователями параметрами в различных конфигурационных файлах, реестре, через командную строку, окна GUI-интерфейса. Сегодня пришел, что для того, чтобы упростить работу с настройками мне куда удобней разрабатывать для приложений класс конфигуратор cConfigurator. Этот класс будет знать как прочитать из командной строки, конфигурационных файлов, реестра или еще как сохранить в них настройки выбранные пользователем в GUI интерфейсе.

Таким образом достигаю следующих целей:
1) Буду знать где читается\сохраняется настройка из реестра;
2) Аналогично для командной строки;
3) Аналогично для конфигурационных файлов;
4) Буду знать как прочитать\сохранить выбор сделанный пользователем через GUI-интерфейс;

Думаю, даже в случае многопрофильной работы, когда нужно будет задавать каждому профилю свои настройке, куда удобней написать классы умеющие работать с профилями и подчинить их классу конфигуратору, т.е. сделать доступными через интерфейс класса основного приложения.

ЗЫ:
Меня опять-таки выручает мой любимый вопрос "Чего ты Дима хочешь достигнуть используя это приложение?"

четверг, 17 июня 2010 г.

Куда приспособить, как опцию командной строки или все же в ini-файл?

Перед теми кто разрабатывает довольно серьезный проект приложения консольного типа, рано или поздно встает вопросы "А куда эту настройку приспобить? Может как аргумент командной строки? А может как параметр конфигурационного файла?"

Для того чтобы пояснить правило получения ответов на подобные вопросы, поясню вам, что все-таки является консольным приложением на практике?

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

Именно в п.2. и следует искать ответ на вопрос: "а куда мне это?".

Есть множество настроечных параметров для работы приложения и делятся они на две категории:
1) Которые быстро и часто меняются
2) И такие которые наверное один раз задал и можно больше не касаться, по крайней мере до следующего билда.

К первым можно отнести "введите число для перевода его в двоичную", вот число как раз попадает под первую категорию, потому что уже через секунду может понадобиться новый результат. Ко втором можно отнести указание файлового пути к драйверу, с которым работает приложение. Думаю в случае, если разработчики и поменяют чтото в драйвере, то довольно часто оставляют тоже самое место в структуре папок своего продукта и вы можете положить туда же последний билд драйвера.

Также к первым можно отнести указание URL-а по которому нужно что-то скачать, указание файла который нужно как-то обработать, указать название резултирующего файла куда ложить результат и многие другие.

Пример из жизни, системная утиллита по исследованию внутренних объектов режима ядра у операционной системы. Для нее нужно написать драйвер, т.к. работая в пользовательском режиме вы врядли чего продуктивного получите, так вот драйвер редко меняет свое место расположение и поэтому его можно задать в ini-файле. Зато запрос на показание объекта, а какого, вот это уже быстро и часто меняющийся параметр к программе! Следовательно это лучше задать как опцию командной строки!

Правило:
Быстро и часто меняется ? "Да", значит в это кандидат в аргументы командной строки, если нет,то занести в качестве параметра конфигурационного файла.

Замечу, что, довольно часто приложения консольного типа применяют в командных сценариях, где гибко формируются новые параметры и задаются приложениям в качестве опций. Многие системные администраторы не видят свою жизнь без приложений консольного типа, т.к. их легко прописать в командном сценарии, а последний указать в задании для планировщика операционной системы, которое периодически выполняется.

четверг, 10 июня 2010 г.

Windows 7 UAC whitelist

Вчера столкнулся с трудностью установки драйвера под эту систему, выполнив строчку:

hSCMngr = ::OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);

получил "Access is denied". Хотя ранее этот код под XP работал на УРА, оно и не удивительно, там ведь не было UAC. Ввиду того, что пишу драйвер для утиллиты своих собственных нужд, которая будет работать исключительно на моем компе, то мне очень хочется чтобы все работало без спрашивания паролей или UAC-диалога. Начав изучать эту тему столкнулся с интересной информацией. Оказывается есть белый список ;) Насколько сейчас обстоят дела, но это весьма весьма занятная тема для размышления.

Интерисующимся читать белый лист .

Также рекомендовал поглядеть и High elevation can be bad for your application: How to start a non-elevated process at the end of the installation


Кстати, у кого какие мысли есть касательно запуска дров, прошу оставить коменты ниже ;)

понедельник, 7 июня 2010 г.

Полиморфные объекты от Microsoft

Решил сегодня поглядеть внутрь Win32k.sys через Hiew. Этот файл у меня располагается по пути:
c:\Windows\winsxs\amd64_microsoft-windows-win32k_31bf3856ad364e35_6.1.7600.16385_none_14e86b61b437d067\win32k.sys

Система win7 x64 и увидел:

.FF0C3761: 666666666666660F1F840000000000 nop [rax][rax][0]
.FF0C3770: 66666690 nop
.FF0C3774: 666690 nop

Удивлению нет предела )))

Причем здесь "полиморфизм"? А при том, что если вы детектили полиморфные объекты, то вы должны знать о способе детекта по мусору. Напомню, что суть детекта заключается в подсчете подозрительных(уникальных) инструкций и выдаче статуса "обнаружен", если их количество превысило допустимое значени. Думаю, теперь на лицо "подозрительная" инструкция nop :)

пятница, 4 июня 2010 г.

Lazy IRQL

У меня есть эл.версия книги:
М. Руссиновича, Д. Соломона, "Внутреннее устройство Microsoft Windows: Windows Server 2003, Windows XP и Windows 2000", 4 изд.

Читаю сейчас про очень интересный механизм оптимизации называемый "Lazy IRQL" и описываемый на стр. 100 в самом последнем абзаце.

Приведу абзац здесь:
"Поскольку доступ к PIC - операция довольно медленная, в HAL, использующих PIC, реализован механизм оптимизации "Отложоенный IRQL"(LazyIRQL), который избегает обращений к PIC. Когда IRQL повышается, HAL - вместо того чтобы изменять маску прерывания - просто отмечает новый IRQL. Если вслед за этим возникает прерываание с более низким приоритетом, HAL устанавливает маску прерывания в соответствии с первым и откладывает обработку прерывания с более низким приоритетом до понижения IRQL. Таким образом, если при повышенном IRQL не повзникает прерываний с более низким проритетом, HAL не потребуется обращаться к PIC."

Мне даже с n-ой итерации вдумчивого чтения не совсем стало понятны слова авторов. Уж больно туманно как-то все написано. Поэтому обратившись к Four-F получил более понятное пояснение:

"Если только в общих чертах. Т.к. запись в PIC относительно медленная операция, то ядро пытается избежать её таким образом. Когда IRQL повышается, то все все прерывания с этим и более низким уровнем д.б. замаскированы и обработка их должна быть отложена до понижения IRQL. Для этого раньше тупо прописывали маску в PIC. Но если во время обработки первого прерывания больше не произойдет прерываний того же или более низкого уровня, получается что мы зря писали в PIC. Поэтому современное ядро поступает так. Оно запоминают на IRQL первого прерывания, но в PIC не пишут. Если во время обработки этого прерывания действительно происходит прерывание того же или более низкого уровня, то тогда уже ядро записывает в PIC маску, соответствующую текущему обрабатываемому прерыванию. Т.е. в этом случае работает старая схема. Ну а если другого прерывания не случается, то и вообще в PIC ничего писать не нужно. Примерно так эта хрень работает. Более детально я не знаю, ибо нафиг не нужно :)"

Казалось бы вроде, слово в слово, но мне почему-то со слов Four-F более понятно стало, что же происходит?! ;)

четверг, 3 июня 2010 г.

Использование макросов при разработке на С\С++

Наверное каждый программист разрабатыващий ПО на С\С++ писал макросы сталкивался с некоторой хитростью, которая приводит к интересному и малопонятному багу, при попытке использовать их как функции. Приведу пример, допустим есть макрос возврата минимального числа из двух:

#define M_MIN(A,B) ( ((A) < (B)) ? (A) : (B) )

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

int a = 2, b = 4;
int c = M_MIN(a++, b);

мы почему-то получаем не то что ожидаем! Это связано с тем что подставится в проверку (2++) < 4 , и потом еще раз при подстановке наименьшего ? (3++) , то есть 4 !

Из этого вытекает только одно правило: не использовать макросы, а если без них никак, то не использовать их как функции!!!!