ПРО
граммист
СОДЕРЖАНИЕ
№10 (январь) 2011
Издается с марта 2010. Выходит ежемесячно №10, январь 2011 г.
Редакция: Выпускающий редактор Сергей Бадло Литературный редактор Utkin Редакторы JTG, Василий Мединцев, ZvEr_HaCkEr, Алексей Шульга, Егор Горохов Редактор-корректор Yan Liplavskiy
Дизайн и верстка: Сергей Бадло
Авторский состав:
Дарья Устюгова, Виталий Белик, Вячеслав Мовила, Павел Добряков, Руслан Аблязов, Анатолий Демидович, Сергей Бадло
Официальный сайт журнала: www.procoder.info
Контакты:
ТЕМА НОМЕРА
Новогодние подарки ............................................. с.3 НЕВЕРОЯТНО, НО ФАКТ
Любопытные факты ............................................... с.4 VIP ПЕРСОНА
Журнал VR-ONLINE. Интервью с Игорем Антоновым .................. с.9 ОБЩИЕ ВОПРОСЫ
О правильном составлении ТЗ. Часть 3 ........................... с.15 ОТДЕЛ ТЕСТИРОВАНИЯ
USBMaster. Рулим флешками в офисе .............................. с.17 АЛГОРИТМЫ
Шаблон класса односвязной очереди в STL ........................ с.29 ЛАБОРАТОРИЯ
Компилятор домашнего приготовления. Часть 3 .................... с.31
Авторские статьи направляйте на maindatacentr@gmail.com Вопросы и предложения для редакции reddatacentr@gmail.com Вопросы и предложения администратору info@procoder.info
АРХИВ
Информационная поддержка:
Чего только не бывает .......................................... с.52
Международная Академия Информатизации (МАИН) РК www.academy.kz Журнал «Радиолюбитель» www.radioliga.com V.K. сайт... www.kotoff.info Free Legal Soft Group www.flsoft.ru AirNet-Berdyansk www.airnet.sytes.net
Шифровка паролем. Улучшаем алгоритм ............................ с.44 Общение между копиями своих программ ........................... с.49 ЮМОР
Примечание:
Издание некоммерческое. Все материалы, товарные знаки, торговые марки и логотипы, упомянутые в журнале, принадлежат их владельцам. Статьи, поступающие в редакцию, рецензируются. Мнение авторов не всегда совпадает с мнением редакции. Перепечатка материалов журнала и использование их в любой форме, в том числе в электронных СМИ, возможны только с разрешения редакции. Тираж неограничен. Формат A4, 55 стр.
Идея создания журнала: Алексей Шульга
Обложка номера: Дизайн Сергея Бадло
архив номеров журнала ^
ПРО
НОВОГОДНИЕ ПОДАРКИ ЛЮБОПЫТНЫЕ ФАКТЫ
№10 (январь) 2011
граммист
Уважаемые читатели! Вот и наступил 2011 год. Первый месяц нового года разродился 10-м выпуском нашего проекта, к которому присоединились новые помощники: Savva-Paladin и Zver_Hacker. Надеемся, что свежий взгляд и дополнительные руки облегчат труд редакторов и поддержат проект в трудную минуту. А тем временем, в среде редакции зародилась идея выбрать лучшие публикации ушедшего года, с которыми познакомили нас наши авторы. Мы отобрали для голосования все статьи, выбор же лучших остается исключительно за вами – аудиторией журнала «ПРОграммист». Голосование проводится на сайте официального портала в разделе «Голосование» по адресу http://procoder.info. В этом выпуске...
Рубрики журнала (плавающие)
Новая рубрика «VIP персона». У нас в гостях,
•
Новости программирования
ONLINE, Игорь Антонов. Читаем интервью.
•
Общие вопросы (правовое использование)
главный редактор дружественного журнала VRДарья
Устюгова
продолжит
свой
рассказ
про
особенности и нюансы составления ТЗ. Читайте рубрику «Общие вопросы».
В рубрике «Отдел тестирования» дебютирует наш новый
автор,
Анатолий
Демидович.
Его
оригинальная реализация контроля USB флешек с помощью
Windows
Script
Host,
Windows
Management Instrumentation и VBScript не оставит равнодушными специалистов по информационной безопасности.
В рубрике «Алгоритмы» Вячеслав Мовила покажет
как создать шаблон односвязной очереди типа FIFO в библиотеке STL. Виталий
продолжит
Белик
в
шаманить
рубрике
над
• • • • • • • •
варевом
У
мы
подняли
шифрования мощью этом
другом
с
пароля.
и
тему
по-
•
А
Павел
Юмор (специфические хохмы программеров) нас
нет
категоричных
свободное
труда
требований
к
ПО
«SCRIBUS»)
и
редакторов,
есть
некоторый
статья должна иметь выраженную структуру с разделами
и
информацию разработки,
содержать
название
статьи,
авторах, экскурс или введение, об
используемых
теоретическую
средствах
и/или
практическую часть, заключение и ресурсы к •
расскажет
•
Добряков
Архив (по материалам клуба и форума)
сведения об
•
Руслан Аблязов.
Лаборатория
желательный минимум:
Об
многом
Wi-Fi сети
облегчения
из
«Архив»
Разработка (проекты от этапа ТЗ до сдачи)
(используется
ваши тарелки, ложки и... клавиатуры.
рубрике
Переводные материалы
оформлению, но в связи с особенностями верстки
опкодов для создания компилятора. Приготовьте В
Алгоритмы
Общие требования к материалам
«Лаборатория»
новым
Отдел тестирования
•
статье;
текст статьи без табуляции в формате MS Word, VK WordPad или обычным текстовым файлом, шрифт Arial 10;
все рисунки, таблицы должны быть подписаны и иметь упоминание в тексте;
рисунки к статье должны прилагаться в виде отдельных файлов в формате PNG, TIF;
разделы статьи отделять двумя <ENTER>.
поделится секретами
По
щенными
замечаниям. Шаблон для написания статьи можно
общения между запукопиями
своих программ.
присланным
рецензию
и
материалам
корректирует
автор
статью
получает
согласно
взять тут.
С уважением, Редакция
ТЕМА НОМЕРА
СОДЕРЖАНИЕ
3
ПРО
граммист
ЛЮБОПЫТНЫЕ ФАКТЫ
№10 (январь) 2011
Если помните, в прошлом выпуске мы вам рассказали о распределенном методе измерения температуры DTS, основанном на эффекте Рамана. Так вот, данный метод также чувствителен к изгибам оптоволокна. На основе чего, в США была создана уникальная подземная охранная система, которая будет контролировать всю американо-мексиканскую границу. Система непрерывного мониторинга, под названием Helios, состоит из зарытого в землю волоконно-оптического кабеля, по которому проходят лазерные импульсы. Она может обнаруживать движение по поверхности и немедленно передавать на пункт управления информацию о нарушении периметра. Но, это не все новости на сегодня. Рассмотрим подробнее, что же еще удивительного нам приготовили прошедший месяц и год грядущий… Сергей Бадло
by raxp http://raxp.radioliga.com Солнечный свет может плавить камни и металл. Именно
настолько
так.
Любители
мощную
линзу,
техники что
та
создали
способна
фокусировать солнечную энергию в количестве, достаточном
для
расплавления
металла
или
даже камня. Другими словами, температура в
точке фокусировки солнечного луча достигает 3482 градусов Цельсия! Это, вероятно, одна из наиболее мощных линз, созданных человеком*.
Твердотельная плазменная антенна ускорит
Старт второго ежегодного республиканского
Antennas
http://www.itawards.kz
беспроводную связь. Инженеры компании Plasma объявили
создании
плазменной
твердотельной антенны PSiAN (Plasma Silicon Antenna), которая сможет стать основой для миниатюрных
радаров
представляет
собой
поколений
и
даже
чип
с
энергетического
для
оружия.
новых
Антенна
несколькими
десятками тысяч диодов. В рабочем состоянии эти диоды окружают себя облаком электронов
размером в одну десятую миллиметра. Каждое такое облако представляет собой зеркало для СВЧ. Включая одни группы диодов и выключая
другие, можно фокусировать излучение в узкий луч и изменять его направление. Работать такая антенна будет в диапазоне 1-100 ГГц. Для таких
частот обыкновенные антенны уже не годятся, так как сигнал быстро затухает. Ее легко будет вмонтировать
в
мобильный
телефон
и
использовать
для
поколением
системы
боты
со
ра-
следующим
Wi-Fi – Wi-Gig, которая
сможет передавать не
54 Мбит в секунду, а от 1 до 7 Гбит.
НЕВЕРОЯТНО, НО ФАКТ
конкурса
IT
AWARDS
KAZAKHSTAN
объявило
частное
учреждение «Центр компетенций Orient Lab» поддержке
Казахстанской
Республики
Казахстан
Ассоциации
ИТ
Компаний, Министерства Индустрии и Торговли и
инфокоммуникационный Партнерами
конкурса
бренды
мирового
Microsoft,
Cisco,
информационный
АО
«Национальный
холдинг
«Зерде».
выступили
уровня
технологий:
Доктор
ведущие
в
Веб.
SAP,
области
Avaya,
Генеральный
спонсор проекта – «Fujitsu Technology Solutions GmbH»,
официальный
спонсор
–
«Orient
Telecom». В рамках учрежденной награды, будут отмечены лучшие казахстанские разработки и внедрения
в
области
информационно-
коммуникационных технологий, а также заслуги отдельных профессионалов в этой сфере. Для
участия в конкурсе, необходимо подать заявку на
участие на сайте конкурса от организации либо от имени автора проекта. * Комментарий редакции.
Видео с демонстрацией работы такой линзы приложено в виде ресурсов к журналу.
СОДЕРЖАНИЕ
4
ПРО
ЛЮБОПЫТНЫЕ ФАКТЫ
№10 (январь) 2011
граммист
Деление
изотопа
ртути
удивило
физиков.
Физики ЦЕРНа задумчиво чешут бороды: вместо
того чтобы распасться напополам, изотоп ртути180 разделился у них на рутений-100 и криптон80. Команда физиков ЦЕРНа под руководством
профессора Андрея Андреева (Andrei Andreyev) из Университета Западной Шотландии, которая
провела этот эксперимент в рамках проекта ISOLDE, находится по этому поводу в полном недоумении. Более того, другой изотоп ртути, как
Агентства NASA, ESA (Европа)
тели, тоже повел себя у
отправить
сообщают
исследова-
них не по правилам и тоже
проявил
ление
к
стрем-
ассиммет-
ричному делению. аттенюатор,
управ-
(VVA)
назна-
чения,
напряжением
общего
разработанный
для 50 Омных систем и работающий в диапазоне
частот от 250 МГц до 4000
МГц
и
температурном пазоне
от
-40°C
диадо
+85°C. Каждый аттенюатор
обеспечивает
диапазоне
22
ослабление
сигнала дБ
в
при
линейности регулировки ослабления 10 dБ/В. Прозрачные ные
JAXA
(Япония) в
грандиозный
из
Alamost
шестиугольников,
способствуют электропроводности. Ультра-тонкие
вопросы
о
что
непроницаемые
сото-
солнца
телефоны
водо-
черных дыр, поскольку только
ко водонепроницаемые
распространены.
ское излучение очень далеких
оно легко проходит сквозь космическую пыль, которая закрывает обзор в других диапазонах. Однако для поиска удаленных объектов
зеркало телескопа должно быть очень большим: IXO будет иметь
телефоны
весьма
Одна-
требуют
динамиков,
которые
качественный
звук
гигантское зеркало площадью 1300 м2, фокусное расстояние 20 м и
могли бы предоставить
30 угловых секунд для 30 кэВ. Вес телескопа составит около 6600 кг,
быть
угловое разрешение 4 угловые секунды для энергии больше 7 кэВ и он будет 10 м и в длину и 4 метра в диаметре. Стандартные оптические
приборы
не
работают
с
высокоэнергетическими
рентгеновскими лучами, поскольку последние отражаются только
мыми.
и
влагонепроницаеНовый
динамика
тип
характери-
при очень малых углах встречи с плоскостью зеркала. Зеркало
зуется толщиной в 0.9
каналами, которые собирают рентгеновское излучение от удаленных
водонепроницаемости
рентгеновского телескопа представляет собой стопку пластин с
объектов, переотражают лучи с помощью внутренних перегородокмикропор и собирают в точку. Поверхность зеркала планируется
изготовить из обычного кремния с отформованными при 600°C перегородками-микропорами, космическое
рентгеновское
которые
излучение.
покрытия
смогут
Для
синхротрон
Германии.
захватывать
оценки
будет
лаборатории
в
качества
использоваться
радиационной
BESSY
II
в
Монохроматический
полимер
с
молекул,
называемых фуллеренами. Молекулы фуллерена напоминают футбольные мячи, сложенные из (в
данном
молекулы
случае
фуллерена
содержащие 60 атомов углерода). У них есть самоорганизации
НЕВЕРОЯТНО, НО ФАКТ
в
IPX7.
имеет
класс
Известно,
что
водонепроницаемые устройства имеют отверстия
для
покрытые
динамиков,
пленкой,
несомненно,
тонкой
которая,
снижает
менее одной угловой секунды и
не требуют каких-либо
имеет
расхождение
зеркало
IXO
на
трех
уровнях энергии фотонов: на 1
специальных
и
лучей
рентгеновских
синхротрона
полупроводниковый
мм
качество звука. Тем не
пучок
Los
свойство
восхо-
вые
кэВ, 2.8 кэВ и 7.6 кэВ.
интересное
стране
дящего
телескоп
Laboratory.
использовались
в
сможет обнаружить рентгенов-
представляет
углерода
(Япо-
ния). Следует заметить,
Материал
атомов
Murata
Manufacturing
происхождении
National
использованием
дина-
представила
компания
многочисленные
Новый
пьезо-
электрические мики
Laboratory и Brookhaven собой
водонепроницаемые
рентгеновский
на
свободно
Плотно упакованные края поглощают свет и
проверит
National
оставшихся
упакованными и относительно тонкими в центре.
– изучение черных дыр и поиск ответов
формы.
прозрачным, при этом связывая вместе края
космос
создали
исследователи
гексагональной
планируют
солнеч-
батареи
узор
Полимерные цепочки в материале делают его
телескоп. Основная задача IXO
Вселенной.
MAX19790 – сдвоенный ляемый
и
повторяющийся
Технология
менее, новые динамики
пленок и обеспечивают качественный звук.
iCoupler или трансформаторы в
микросхемах. Многие из нас знакомы с одним из
способов гальванической развязки сигналов – опторазвязкой и соответственно, оптронами. Но
ведь есть и старый добрый трансформатор. Да, именно. Реализованные планарным способом на кремниевой
интегральный
подложке
обмотки
трансформатор
прямо
образуют в
ИМС.
СОДЕРЖАНИЕ
5
ПРО
ЛЮБОПЫТНЫЕ ФАКТЫ
№10 (январь) 2011
граммист
Пользователь
отдает
прикосновением
к
команды
поверхности
не
обычным
бумаги,
а
деформацией экрана, причем экрана можно не только коснуться рукой, но и подуть на него. Беспроводную
портативную
акустическую
систему SoundLink, с помощью которой можно
слушать музыку с компьютера как внутри дома, так и снаружи, представила компания Bose. Система
проста
подсоединить
в
установке:
достаточно
прилагающийся
USB
ключ
SoundLink к компьютеру и выбрать музыку (из iTunes,
интернет-радио
музыкального
ресурса).
или
любого
другого
SoundLink
начнет
воспроизведение через беспроводную сеть, для Функционирование
каждого
канала
подобных
которой даже стены и пол – не помеха.
ИМС аналогично работе оптрона, где вместо
Домашними
частотно-модулированный сигнал. Но, в отличие
Они работают на природном газе и генерируют 1
модулированного светового потока передается от
оптронных
схем,
имеет
особенности:
отсутствие интермодуляционных искажений, в десятки
раз
большая
меньшим
скорость
двунаправленного
обмена
микроТЭЦ на твердооксидных**
топливных ячейках обзаведутся датские семьи. кВт электрической мощности и 1 кВт тепла.
энергопотреблением,
В
настоящее
данными,
по
габаритам
и
возможность ведь
время
это
трансформатор. Реализованная фирмой SiLicon Labs
по
КМОП-технологии,
такая
сравнима
схема
шим
обеспечивает надежный изолированный канал передачи
данных
инициализации
без
ником.
необходимости
радиочастотной
части
Power
и
вает
подключения внешних элементов. Микросхемы Si84xx
разделенных
рассчиты-
иметь
ТЭЦ,
будут
семь
микро-
которые
работать
в
течение всего отопительного сезона, включая
сигналов или исключения паразитных контуров с
планирует выпустить 15 новых микроТЭЦ для
согласования
передачи
боль-
цифровых
сигналов,
каналов
с
холодиль-
Dantherm
опытных
http://www.efo.ru/doc/Silabs/Silabs.pl?2430
предназначены для реализации гальванически
микроТЭЦ
уровней
логических
замыканием через землю. Микросхемы Si84xx
обеспечивают от одного до шести гальванически разделенных канала передачи цифровых данных
весну 2011 года. В сентябре 2011 года компания частных домов, в конструкции которых будет учтен опыт эксплуатации прототипов.
со скоростью до 150 Мбит/с. Следует отметить,
В 2012 году в продажу поступят микроТЭЦ,
NVE
старые печи и системы отопления на микроТЭЦ
что подобные цифровые изоляторы выпускают Corporation
и
Analog
Devices
(серия
ADuMххх) http://www.compitech.ru/html.cgi/arhiv/ 03_07/stat_66.htm.
позволяющие обычным людям заменить свои на твердооксидных топливных элементах. ** Комментарий редакции.
Разработан вариант
сенсорного которой
экраном
еще один
гибкого
дисплея,
в
управляющим становится
простой бумажный лист.
НЕВЕРОЯТНО, НО ФАКТ
Твердооксидные топливных
топливные
элементов,
элементы
электролитом
(SOFC) в
–
разновидность
которых
является
керамический материал, проницаемый для ионов кислорода. Эти
элементы работают при очень высокой температуре (700...1000 °C)
и применяется для стационарных установок мощностью от 1 кВт. Их отработанные газы могут быть использованы для приведения в действия газовой турбины, чтобы повысить КПД до 70%.
СОДЕРЖАНИЕ
6
ПРО
граммист
ЛЮБОПЫТНЫЕ ФАКТЫ
№10 (январь) 2011
аккумуляторов, питания компьютеров, систем
связи и других устройств без необходимости установки генераторов на жидком топливе и опасных, дорогих его поставок. Новые палатки оснащены инверторами и имеют приемлемую для
военных
несколько
долговечность.
вариантов
различной
палаток
площадью,
Переломы будут лечить быстрозастывающей наножидкостью, который быстро застывает при
повышении температуры до 37°C. Наноматериал состоит из циклических молекул, каждая из которых посредством двух ковалентных связей соединяется
с
двумя
Образующиеся
при
другими
этом
молекулами.
шестимолекулярные
кольца формируют трубчатые структуры. При
повышении температуры до температуры тела
эти трубчатые структуры собираются в спирали, по форме напоминающие молекулы ДНК. Такой обладающий
природной
структурой
материал
легко интегрируется с костной тканью. Более того,
различные
получившего которых
в
варианты
название
настоящее
материала,
Arxis,
разработкой
время
занимается
компания Audax Medical, при застывании могут
быть твердыми как кость или мягкими как хрящ. Скорость
застывания
может
составлять
нескольких секунд до нескольких минут.
от
Гибкие солнечные батареи конечно не ново, но
армия
США
оценивает
возможность
легкими
солнечными
использования тентов и палаток, оснащенных такиеми
панелями.
гибкими Эта
экспедиционным производство
технология
войскам
электроэнергии
для
позволит
развернуть зарядки
тентов
вместимостью
мощностью до 3 киловатт. Тактильные
Предложены
и
ощущения
с
и
предлагают
использовать инженеры из Университета Юты, как еще один способ взаимодействия со сложной электроникой. приборов,
Большинство
вроде
информационных
телефонов,
компьютеров,
навигаторов, передают человеку информацию
через изображение и звук. Однако глаза и уши – это наши основные сенсорные системы, они всегда загружены и к тому же требуют больших ресурсов
мозга.
Отвлекаясь
на
подсказку
навигатора или разговор по сотовому, например во время вождения автомобиля, человек рискует попасть
в
неприятности.
сенсорного
устройства
TrackPoint,
Основа
–
имеющая
красная
своим
нового
кнопка
прообразом
ноутбучный тачпад IBM ThinkPad. Она может перемещаться в разные стороны, натягивая кожу на подушечке пальца и тем самым сообщая пользователю нужную информацию. Несмотря
на кажущуюся простоту, устройство открывает
совершенно новые возможности обратной связи. Подвижная кнопка способна, например, давать навигационные
подсказки
вроде
«поверни
налево», даже когда водитель занят разговором или
сосредоточенно
Перспективно безопасности,
следит
использование
например,
для
за
в
дорогой.
системах
оповещения
водителя о том, что он съезжает со своей полосы
движения и указания направления вращения рулевого
колеса
рефлексивно
–
иногда
человек
способен
генетический
модуль
реагировать
на
даже в полусонном состоянии. Программируемый
прикосновения
удалось сконструировать ученым. Встраиваясь в
геном клеток, он заставляет их реагировать на внешние сигналы, давая при этом возможность учитывать
и
внутреннее
состояние
клетки.
Общая идея заключается в том, чтобы получить возможность управлять поведением клеток и их
реакциями на любой выбранный белок. Для этой
НЕВЕРОЯТНО, НО ФАКТ
СОДЕРЖАНИЕ
7
ПРО
ЛЮБОПЫТНЫЕ ФАКТЫ
№10 (январь) 2011
граммист
цели был сконструирован участок ДНК, который
95-97% всех редких земель (празеодим, церий,
После встраивания в клетку с ДНК считывается
добывается в Китае.
работает
как
небольшая
генетическая
схема.
лантан,
РНК (все как обычно), но вот следующий шаг – синтез
белка,
произойдет
лишь
в
выбранного
экспериментов,
проведенных
создание
такого
генетического элемента, который делает клетки организма
чувствитель-
ными к антивирусному средству
ганцикловиру,
но только при наличии в них
белка
бета-
катенина,
который
в
клетках.
избыточно производится опухолевых
Таким
образом,
получаем вовать
клетки,
на
не
воздейст-
опухолевые
Одним
Тепловизоры для
то время как мир уже сегодня нуждается в
пятидесяти тысячах. Министерство коммерции
стало
Fluke
Китая заявило о том, что запасы редкоземельных
ограждающих
конструкций зданий, обнаружения мест проникновения дефектов,
влаги,
общей
обследования
кровли.
IR-
слитное
изображение
в
инфракрасном позволяет
и
видимом
быстрее
необходимую
и
информацию
традиционных
инфракрасных
ИК
компоненты
с
снимков.
возможными
неисправностями
в
сигнал,
нее
и
выделить
безошибочно
Обследование щитов
что
силовых
лению
образом,
бета-
отделяется
что
химического реактора
в
фундаменталь-
ной науки – им удалось
высокопрометаллди-
алюминия (MIM). Суть ноу-хау
зовании
расщеп-
–
в
исполь-
контакта
аморфного
таким
от
области
проблем
одов из меди, никеля и
Обследование
рецептора
РНК
из
штата
диэлектрик-металл
катенина. Срабатывание к
основных
изводительных
был встроен и особый
приводит
50 тыс.
создания
Помимо этого блокатора
этого
экспорт он идет по цене
найти дешевый способ
РНК
белка
меньше 5 тыс. долл., на
Орегон решили одну из
неактивной.
рецептор
Китае его тонна стоит
университета
стоп-
так
тонну,
Исследователи
При
синтезированная остается
легко
определить участки, нуждающиеся в ремонте в первую очередь.
разработке ДНК ученые добавили
позволяет
поведения
элемента.
Так,
смешнее с лантаном – в
(когда
изобра-
Любопытна
программа
они
40%.
в два раза выше. Еще
найти
IR-Fusion™
на
экспортная цена сейчас
жений уже недостаточно), что облегчает задачу идентификации и анализа
годом
1997-м
метрическую
диапазонах
легче
с
стоит 40 тыс. долл. за
Fusion – отображение объектов двумя способами:
исто-
неодим внутри страны
и
Технология
резко
упали
устранения
проверки
минералов
щаются. По сравнению
оптимизированы
обследования
гадолиний)
Квота этого года – 30.3 тыс. метрических тонн, в
их
командой,
и
Китай вот уже пять лет
затрагивая
здоровые. такого
мы
возможность
направленно
белка.
самарий
подряд снижает квоты на экспорт редких земель.
случае
наличия или отсутствия внутри клетки другого заранее
неодим,
из
металла.
MIM-диод может быть
нее
использован для выпол-
стоп-сигнал,
Обследование
что снимает блокировку
электропередач
и дает зеленый свет для
линий
нения тех же функций,
что и обычные электронные компоненты, но
синтеза белка. Поскольку рецепторов для разных
работает он принципиально иначе: электрону не
получаем
проскакивает по «тоннелю» MIM и мгновенно
белков можно встраивать несколько, в итоге мы генетического
довольно
продвинутый
программирования.
Если
язык все
пойдет успешно и клинические испытания (до которых
пока
еще
далеко)
не
выявят
отрицательных последствий, то, возможно, мы
получим исправим «баги» нашего организма.
НЕВЕРОЯТНО, НО ФАКТ
нужно
путешествовать
появляется
на
механический
по
другой
процесс
материалу
стороне.
–
он
Квантово-
туннелирования
возникает, когда частица с меньшей энергией становится
способной
преодолевать
теоретически непреодолимый барьер – изолятор.
СОДЕРЖАНИЕ
8
ПРО
ЖУРНАЛ VR-ONLINE. ИНТЕРВЬЮ С ИГОРЕМ АНТОНОВЫМ
№10 (январь) 2011
граммист
Доброго дня, уважаемые читатели журнала «ПРОграммист». Я надеюсь, что никому не нужно рассказывать о проекте VR-ONLINE, каждый, так или иначе, знает его создателя – Михаила Фленова. И хотя Михаил отдалился от проекта, но дело его продолжает развиваться. По обоюдной договоренности, сегодня в гостях у нашего журнала нынешний руководитель проекта – Игорь Антонов aka Spider_NET. Тематика некоммерческого журнала VR-ONLINE близка к нашему, поэтому вдвойне было интересно услышать о журнале «из первых рук». Впрочем, обо всем этом мы поговорили в интервью, не буду делать большую затравку, переходим сразу к вопросам и ответам... Сергей: Расскажите немного о себе? Кем
том виде, в каком он был на то время. Журнал
Игорь: Меня зовут Игорь Антонов. Мне 24 года, в
Решающей каплей стал уход Фленова Михаила*.
работаю
детище на произвол он не хотел, поэтому решил
работаете? Семья?
настоящее время живу в городе Хабаровск и руководителем
программного обеспечения
в
ховой
отдела
разработки
мы тогда практически перестали выпускать.
Он решил отдохнуть от проекта. Бросать свое
передать его кому-
стра-
то из команды. Я
компании.
Помимо
не
програмжурна-
рей
того,
чески пишу статьи личных
для
нат
компаний. в
суюсь
года). нет.
Детей
Сергей: стали
итоге
пока вы
с
но
в
всегда
Что
касается
стимула,
желание
развить
чить
тание. нию,
Остались
его К
немного
ли они сейчас?
лем проекта я стал
я
проект,
руково-
Руководите-
ту-
то им всегда было
Каковы были сти-
Игорь:
аж
возвращался.
дителем проекта? мулы?
и
жизни
проекта,
два
Как
там
участии
Семья
(женат
Дейст-
были передышки в
приятно,
платят.
–
2002 года. У меня
когда за хобби еще есть
VR.
VR-Online
Это – мое хобби и и
я
тически вырос на
основном для души. очень
что
вительно, я прак-
всегда нравилась, и занимаюсь
из-за
очень давний фа-
раз-
Журналистика мне ей
всего,
самый старожил и
в журнал «Хакер», также
отдали
именно мне. Ско-
листикой. Периодиа
почему
VR-Online
мирования активно занимаюсь
знаю,
обеспе-
процве-
сожале-
тогда не
я
рас-
считал свои силы,
и проект времен-
но
Журнал VR-ONLINE → Ответное интервью
погрузился
летаргический
в
совершенно случайно. В 2007 году проект застыл
сон. Журналы выходили очень редко. Однако в
натянутыми, некоторые из участников не видели
Совместными усилиями с обновленной командой
в
развитии.
Отношения
в
команде
были
будущего проекта, если он будет оставаться в
VIP ПЕРСОНА
один
прекрасный
день
все
изменилось.
нам удалось запустить новую версию проекта.
СОДЕРЖАНИЕ
9
ПРО
ЖУРНАЛ VR-ONLINE. ИНТЕРВЬЮ С ИГОРЕМ АНТОНОВЫМ
№10 (январь) 2011
граммист
Что касается нынешней ситуации, то главным
Изначально наш постоянный посетитель, а
людей, кто поверил в меня и последовал за мной.
просто креативный чел.
стимулом является
оправдание надежды тех
Пользуясь, случаем, хочу сказать всем этим ребятам большое спасибо! Сергей:
Чем
Вы
любите
реальной жизни?
заниматься
позже дизайнер, верстальщик, автор статей и •
музыкой. В настоящее время я хожу на курсы в будущем
собираюсь
ей,
увы,
не
суждено
•
музыки мне нравится изучать английский язык. Пока учу для себя, но возможно в будущем он
функциональные
каждого?
обязанности
Игорь: В настоящее время слово «команда» для нашего проекта несколько изменилось.
Раньше
это был определенный костяк пользователей. Сегодня под командой подразумеваются друзья проекта
–
люди,
готовые
его
развивать
и
помогать. Именно поэтому мы стали употреблять
слово «сообщество». Мы хотим, чтобы границ
между участниками проекта было как можно
мало.
Андрей
Васючков
aka
•
постоянно тусит. Он оперативно отвечает на вопросы
посетителей
Online: •
Роман Костенко aka Lord_of_Fear. Это мой лучший друг в реале и самый активный участник
проекта.
Он
пишет
статьи,
•
ZeroXor, Khusman, AnyKey, Sly, Ghost
Rider,
wwwnet
и
многие
Zanuda, другие
(извините, если кого забыл). Ребята вносят
свой вклад в развитие проекта: пишут статьи, постят в блог. Они
интересней и лучше. Сергей:
Есть
редакции?
неизменным?
ли
среди
Состав раз
помогают сделать его авторов
был
мы
-
все
пробовали
члены
время
выделять
редакторов рубрик, но потом идея заглохла. В редакторами
можно
считать меня и Lord_of_fear. Мы занимаемся отбором
материала,
его
вычиткой,
а
также
подготовкой к верстке. Само собой, мы также пишем статьи.
Сергей: Многие из наших читателей давно и
еще успевает всячески меня подбадривать.
ONLINE, скажите - есть ли сдвиги в выходе
Антон Козлов дизайнер,
aka JimmyJonezz. Наш мега
постоянный
автор
статей,
создатель шаблона верстки журнала и т.д. Антон внес и продолжает вносить огромный вклад •
также
администрирует сайт, модерирует форум и т.д. Он делает просто колоссальную работу и •
а
автора статей (см. ноябрьский номер).
полноценными
несколько
проекта,
недавно начал пробовать себя в качестве
итоге,
есть
Пожалуй,
меня возникает ощущение, что Va-bank там
людей, которые максимально близки для VR-
это,
Soffrick.
Va-Bank. Гроза нашего форума. Иногда у
Как-то
на
-
так как несет военную службу.
Игорь:
Несмотря
из
один из самых старых участников проекта.
меньше. По сути, все посетители – одна большая команды.
Он
он временно не участвует в жизни проекта,
ПМЖ за рубеж. каковы
один
Очень креативный человек, но, к сожалению,
мне пригодится. В планах есть миграция на Сергей: Кто входит в команду проекта и
VR-Online.
потом взял на себя верстку и всю графику.
сбыться.
Надеюсь, ее удастся реализовать сейчас. Кроме
JimmyJonezz
Сначала он стал писать для VR-Online, а
организовать
было
с
посетителей
интересных статей и думаю, напишет еще не
свою рок-группу. Это – мечта моего детства, но тогда
Наравне
сетей! По этой теме он уже написал много
музыкальную школу. Пытаюсь освоить вокал. В ближайшем
старых
настоящий гик в отношении беспроводных
в
Игорь: В реальной жизни я люблю заниматься
Kastor.
в
развитие
огромное спасибо! Дмитрий
VIP ПЕРСОНА
Редькин
проекта. aka
За
что
ему
zahod5277.
пристально следят за развитием проекта VRбумажной версии журнала? Мы слышали, что
вроде
как
намечалось что-то. Игорь:
под
Действительно,
посетители
очень
хотят
Новый наши
видеть
2011
Год
постоянные
бумажную
версию журнала, но пока мы не можем себе
СОДЕРЖАНИЕ
10
ПРО
ЖУРНАЛ VR-ONLINE. ИНТЕРВЬЮ С ИГОРЕМ АНТОНОВЫМ
№10 (январь) 2011
граммист
этого позволить. Во-первых, качественная печать
читателей
пагубно
критики? Чем обусловлена многоколоночная
в нашей стране стоит хороших денег. Это очень отразится
Согласитесь,
на
мало
общей
кому
цене
журнала.
захочется
покупать
журнал за рублей 200-300. Во-вторых, для того
желающие
одноколоночной
верстки? Почему на форуме VR-ONLINE нет верстка в вашем журнале?
чтобы выпускать печатную версию нужно много
Игорь: Количество колонок при верстке – одна из
Если в бесплатной электронной версии можно
одноколоночная
свободного времени, особенно на первых порах. позволить себе огрехи, то в печатной – нет (ИМХО).
В
настоящий
участников
проекта
момент
свободного
у
многих
времени
практически нет. Поэтому пока, увы, позволить
печатную версию мы не можем. Тем не менее, полностью отказываться от этой идеи мы не хотим. копий
Мы
попробуем
новогоднего
отпечатать
номера.
несколько
Он
будет
предназначен для постоянных посетителей (те, кто изъявит желание купить). Мы не будем
делать никаких наценок. Цена журнала будет равна себестоимости + затраты на доставку.
Сергей: Как много постоянных авторов в издании?
Игорь: Где-то 70% авторов по праву можно
самых
горячих
тем.
двухколоночная.
Мы
Одним
нравится
верстка,
другим
даже
устраивали
голосование по этому поводу и обсуждали в комментариях. победителем
По
стала
итогам
голосования
двухколоночная
верстка.
Хотя, споры не утихают до сих пор. Я сам
сначала не любил двухколоночную верстку, но потом привык. Сейчас нахожу двухколоночную верстку
удобной.
Сергей:
Если
нравится.
какие-либо
Во
кто-то
всяком
случае,
предлагает
мне
ввести
усовершенствования,
модернизацию в верстку, прилагает ли этот
«кто-то»
усилия
предложенного
или
словами?
для
все
реализации
ограничивается
считать постоянными. Это - участники нашего
Игорь: Внести изменения в верстку в основном
тридцать – сторонние. Их находим либо мы, либо
Lord_of_Fear и я (а также другие участники
проекта,
а
также
администрация.
Остальные
они нас.
Сергей: Как мы уже знаем из общения с
Вами и прошлому интервью, вы используете для
верстки,
так
же
как
и
мы,
Скрибус. Чем обусловлен выбор?
пакет
-
Игорь: Да, сейчас для верстки мы используем
Scribus. Изначально журнал верстали в Word’е, а потом
в
InDesign.
Когда
наш
постоянный
верстальщик ушел в армию, его дело подхватил JimmyJonezz. Он сделал свой вариант верстки и если мне не изменяет память, то именно он и предложил использовать Scribus. Возможности этого
продукта
верстальщика,
полностью
поэтому
устраивали
решено
было
использовать его. Я сам со Scribus ни разу
предлагает
JimmyJonezz
(автор
шаблона),
проекта). Все предложения мы обсуждаем с автором
шаблона
(JimmyJonezz)
и
пытаемся
прийти к консенсусу. Как правило, пока в этом направлении
мы
думаем
одинаково,
поэтому
автор шаблона вносит изменения. Тем самым шаблон
Вообще,
верстки я
постоянно
совершенствования
думаю,
совершенствуется.
верстки
что –
процесс
бесконечен.
Постоянно хочется чего-то нового. Я думаю, такое
положение
дел
присуще
многим
журналам. Взять тот же ][акер. В свое время
ребята частенько вносили изменения в верстку, пока не нашли идеальный вариант. Сергей:
журнала?
Какая
периодичность
выпуска
толком не работал, поэтому сказать ничего не
Игорь: В теории наш журнал ежемесячный. Но
продукт устраивает человека, который с ним
разные непредвиденные трудности, мешающие
могу. Да это в принципе и не важно. Главное, что работает. Сергей:
Появляются-ли
VIP ПЕРСОНА
среди
ваших
на практике все иначе. Постоянно возникают
выпустить номер в срок. Поэтому, бывает, что очередной номер выходит не через месяц, а через полтора.
СОДЕРЖАНИЕ
11
ПРО
граммист
ЖУРНАЛ VR-ONLINE. ИНТЕРВЬЮ С ИГОРЕМ АНТОНОВЫМ
№10 (январь) 2011
Сергей: Как вы ищете авторов?
авторами и по возможности немного меняем
Игорь: По-разному.
можем сами немного переделать статью (само
Сначала публикуем призыв
на главной странице, стараемся заинтересовать
постоянных посетителей. Этот способ хорошо работает, но иногда одним им не обойтись. В
таких случаях приходится прибегать к поиску сторонних авторов. Для этого я начинаю гуглить
блоги, соответствующие тематике нашего сайта. С
контентом
внимательно
каждого
найденного
знакомлюсь
и,
если
блога
я
нахожу
интересные посты, пытаюсь связаться с автором
и попросить у него разрешения на публикацию
статьи в нашем журнале. Несколько раз были
случаи, когда блоггеры, позволившие разместить их
заметки
в
журнале,
отдельные статьи.
начинали
писать
Сергей: Насколько часто автора находят вас
сами? Случается ли, что автора требуют
верстки своей статьи в одном номере, а вы
видите, что по объему она великовата для одного выпуска? Как вы поступаете?
Игорь: По-разному. Иногда от них отбоя нет, а порой не можешь найти ни одного. Что касается второго вопроса, то таких случаев не припомню.
Сергей: Каков процент соотношения статей
профуровня в журнале к статьям начального и общего уровня?
Игорь: Точно сказать не могу. Число таких
статей меняется от номера к номеру. Тут еще все зависит
о
того,
что
подразумевается
под
статьями профуровня. Я думаю, для каждого
читателя «профуровень» имеет свои критерии. Взять тот же журнал Хакер. К какому уровню
отнести статьи, публикуемые в нем? В целом, они
все профессионального уровня. Но так думают отнюдь не все читатели.
Сергей: Нашим редакторам интересно, по каким критериям идет отбор присланных статей в издание? Игорь:
Статья
случаи,
когда
в
первую
очередь
должна
подходить к одной из рубрик журнала. Бывают присылают
очень
интересные
работы, но они не совсем нашего формата. В таких
ситуациях,
VIP ПЕРСОНА
мы
отдельно
беседуем
с
направление. Если у автора нет желания, то мы
собой, с его разрешения). Одной из особенностей
VR-Online в том, что мы не ставим четких рамок. Когда-то, мы выпускали журналы определенной тематики (для программистов, для всех и т.д.) и
это многим не нравилось. Наши посетители – это
не только программисты, но и просто люди, интересующиеся ИТ. Мы хотим учесть интересы
большинства, поэтому в журнале есть рубрики, которые
Главное,
не
полезной.
относятся
чтобы
статья
к
программированию.
была
интересной
и
Сергей: Что лично для вас - хорошая статья? Игорь: Хорошая статья – интересная статья, которая
поднимает
вопросы
и
дает
на
ответы. Статья, которую хочется перечитать. Сергей:
Много-ли
корректировать
и
исправлять
них
приходиться
присланных материалах?
ошибок
в
Игорь: У всех авторов разные проблемы. Одни
допускают множество грамматических ошибок, другие ошибаются в построении приложений. Всегда хочется, чтобы ошибок было минимум (в
идеале не было вообще). Вот и приходится
править творения. Иногда сильно, иногда нет. Помню,
был
случай,
когда
автор
написал
замечательную статью, но в изначальном виде
она была совершенно нечитабельной. Пришлось усердно потрудиться и практически полностью
переделать текст автора. Тем немее, оно того стоило.
Сергей: Каковы требования к оформлению статей в ваш журнал?
Игорь: Особых требований нет. Лучше, когда авторы вообще не пытаются оформлять свои
работы, а просто присылают текст, разбитый на заголовки/абзацы в MS Word’e или текстовом
файле. Остальное ложится на плечи редакторов. Автор
должен
материала,
и
я
работать
считаю,
что
над
его
качеством
не
нужно
обременять ненужными действиями. Так что никаких требований в плане оформления мы не предъявляем.
СОДЕРЖАНИЕ
12
ПРО
ЖУРНАЛ VR-ONLINE. ИНТЕРВЬЮ С ИГОРЕМ АНТОНОВЫМ
№10 (январь) 2011
граммист
Сергей:
Что
вы
думаете
по
поводу
«распространенного мнения»: чтобы платить
ориентиром?
авторам – нужен спонсор журналу, чтобы
Игорь:
профдизайнеры,
администратор». Считаю их самыми удачными и
был спонсор - нужны профверстальщики и которые
не
будут
постоянно работать на чистом энтузиазме?
Игорь: Даже не знаю, что вам ответить. Отчасти
это действительно так. Любой проект требует личных Чтобы
вложений
заработать
на
первоначальном
больше,
нужно
этапе.
сначала
вложить свои средства (не всегда, конечно, но во многих случаях) или собрать друзей (которые в
теме), готовых работать на первых порах на голом энтузиазме. Второй
вариант,
на
мой
взгляд,
предпочтительней. Очень важно, чтобы друзья
были заинтересованы в развитии проекта. Если
результат деятельности не нужен самим авторам, то
проект
коммерческий
никогда
выстрелит
«IT
всегда
Спец»
и
нравились
«Системный
полезными. Больше всех нравится «Хакер». Не потому, что туда чаще всего пишу, а из-за стиля
издания. Мне нравится свобода в общении и отсутствие лишних почестей. В этом журнале
общение с читателем идет на «ты», и это играет огромную
роль.
Когда
читаешь
статьи,
появляется ощущение, что слушаешь рассказ хорошего
друга,
что
значительно
качество усвояемости материала.
влияет
на
Сергей: ТОП ваших ежедневных просмотров интернет-ресурсов? Игорь:
Каждый
или
заглядываю на:
почти
каждый
день
http://vr-online.ru – думаю, комментарии из-
высказываний может показаться, что выхода нет.
•
http://google.com – мой любимый поисковик,
Кстати,
же
считаю,
что
делать
одному,
но
на
всего,
«Хакер»,
мне
•
Я
скорей
как
журналы
печатных
просто
развалится.
и,
не
Из
основании
если
есть
подобных
желание,
то
попробовать стоит. Пусть вначале придется все интересная,
то
если
рано
идея
или
действительно
поздно
найдутся
помощники, готовые помогать бесплатно. Нужно изначально верить успех и не тормозить перед трудностями. Сергей:
Каков
процент
материалов
• • •
лишни; всю
информацию
помощью;
ищу
и
нахожу
с
его
http://securitylab.ru – хороший ресурс о безопасности, мне очень нравится их новостная лента;
http://habrahabr.ru – раньше читал часто, а теперь нет. Хороший проект, но в последнее время у меня пропал к нему интерес;
http://flenov.info – блог Михаила Фленова и т.д.
редакторов издания среди прочих статей?
Сергей: Не принято делить шкуру неубитого
Игорь: Опять-таки четкого ответа дать не могу.
солидный спонсор проекту VR-ONLINE, ваша
Все зависит от конкретного номера. Если статей от
авторов
набираем
мало,
то
пытаемся
закрывать дырки, и пишем их сами. Максимально
я писал четыре или пять статей для номера.
медведя, но задам вопрос: если найдется команда
и
читатели
готовы
выпускать
бумажный вариант журнала и платить за него?
Столько же писал мой коллега – Lord_Of_fear и
Игорь: Пока я не готов дать однозначный ответ
(например,
журнала – слишком серьезное дело и большая
другие
пришлось
постоянные
участники
JimmyJonezz).
на
сторонних
проекта
Процентов
авторов.
10%
Бывают
обратные ситуации, когда постоянные участники
проекта вообще ничего не пишут, так как хватает присланных статей. Сергей:
издания
Какие
печатные
являются
VIP ПЕРСОНА
для
и
электронные
вас
идеалом,
на
этот
вопрос.
ответственность.
Выпуск
Данное
печатной
дело
требует
версии
много
свободного времени. Лично у меня (и у многих других участников проекта) пока его нет.
К
тому же есть одно «НО». Журнал «VR-Online» – всегда был бесплатным, и это одна из его основных
фишек.
Переход
на
коммерческие
рельсы запросто может убить журнал. К тому же
СОДЕРЖАНИЕ
13
ПРО
№10 (январь) 2011
граммист
ЖУРНАЛ VR-ONLINE. ИНТЕРВЬЮ С ИГОРЕМ АНТОНОВЫМ печатные издания постепенно отходят на второй
* Справка из Википедии.
Фленов Михаил Евгеньевич (род. 11 августа 1976 года, Ростов-наДону, Россия) – известный российский программист и хакер.
Родился в городе
Ростове-на-
Дону. Учился и
закончил 101-ю
школу в северном
оне
микрорайгорода.
Поступил
в
учился
в
институт ВТУЗ,
РИСХМ, но закончил РГАСХМ (за время учебы Михаила, институт
дважды менял свое название). Во время учебы работал программистом
на
заводе
Ростсельмаш,
разрабатывал
программы
для
экономических отделов, финансовой отчетности в налоговые органы и персонифицированного учета.
По окончании института, в 1999 году, уволился с завода и в период с 2000—2004 гг. работал программистом в ООО ПКФ «Атлантис-Пак», в
отделе автоматизации производства, разрабатывал программы для
снятия показаний с производственного оборудования. В 2006 году переехал в Санкт-Петербург.
В 2009 году иммигрировал в Канаду. На данный момент проживает в
пригороде Торонто и занимается разработкой сайта электронного магазина одной из компании, входящей в Fortune 100.
Помимо профессиональной разработки программного обеспечения и сайтов, является техническим писателем, а также автором дюжины книг по программированию и работе на компьютере: •
Библия C#
•
Искусство программирования игр на С++
• • • • • • • • • •
Web-сервер глазами хакера. Безопасность в интернете DirectX и Delphi. Программирование графики DirectX и C++. Программирование графики Transact-SQL
PHP глазами хакера
Linux глазами хакера
Компьютер глазами хакера. Безопасность
Программирование на C++ глазами хакера
Программирование в Delphi глазами хакера Библия Delphi
Журналы, в которых публиковались статьи Михаила Флёнова: •
«CHIP»
•
«Хакер»
•
«Игромания»
Ссылки •
Официальный блог о программировании http://www.flenov.info
•
Сайт с программами Михаила Фленова http://www.cydsoft.com
•
Официальный блог о жизни http://www.funniestworld.com
VIP ПЕРСОНА
план. Рано или поздно электронные версии их
вытеснят (ИМХО), а раз так, то почему бы
заранее не начать изучать этот рынок? Тут тем более
есть,
где
оригинальностью.
разгуляться
и
блеснуть
Сергей: Пишете ли вы материалы в дороге? Чем пользуетесь?
Игорь: Вне дома я провожу достаточно много времени,
из-за
этого
частенько
приходится
поэтому
пользуюсь
писать статьи/заметки в дороге. Таскать нетбук я с
собой
не
люблю,
коммуникатором – Nokia E71. Пока меня этот аппарат полностью устраивает. Набирать текст
удобно и он не тормозит в отличие от моего предыдущего мобильного друга Toshiba G900.
Сергей: А как вы и ваша команда борется с плагиатом?
Игорь: Никак не боремся. Это бесполезно. Для
серьезной борьбы нужно время, а его нет. Когда выпадает сделать
свободная
что-то
минутка,
полезное
для
мы
стараемся
сайта,
а
не
поднимать бессмысленные войны. К тому же, если пираты распространяют наш журнал через
свои ресурсы, то это дает свои плюсы. Да, читатели качают результат нашего труда не с нашего сайта, но, читая журнал, они видят ссылки на наш ресурс. Если им понравился журнал, то они непременно зайдут на сайт
и
присоединяться к нашему сообществу. Так что пираты
в
какой-то
степени
нам
помогают.
Благодаря им, о «VR-Online» узнают новые люди.
Сергей: И резюмируя нашу встречу: чтобы Вы
хотели
пожелать
некоммерческим
проектам и нашим читателям в частности? Игорь:
Хочу
пожелать
удачи
и
веры
в
собственные силы. Не бойтесь затевать новые проекты
и
проводить
эксперименты.
Жизнь
коротка и слишком ценна, чтобы разбрасываться
временем направо и налево. Нужно действовать
и начинать прямо сейчас! Пусть вам сопутствует
удача, и Боги будут на вашей стороне. Также, пользуясь,
случаем,
хочу
наступающим Новым Годом!
всех
поздравить
с
СОДЕРЖАНИЕ
14
ПРО
О ПРАВИЛЬНОМ СОСТАВЛЕНИИ ТЗ. ЧАСТЬ 3
№10 (январь) 2011
граммист
В этом номере я с радостью готова представить вам третью часть моего письменного рассказа о премудростях составления ТЗ. В первых двух статьях я рассказала вам о ТЗ в общих чертах, привела примерное содержание и постаралась показать, что необходимо писать в первых четырех главах. Сегодня я постараюсь осветить еще несколько глав. Приятного чтения… Дарья Устюгова
качественной
by Sparky ustyugova90@mail.ru
ГОСТы.
начала
отмечу,
что
в
этом
номере
я
чтобы
сориентировать
вас
7.2 Этапы разработки
буду
касаться
вопросов
проведения контроля и приемки работ, а также корректировки сложные
и
их
ТЗ.
вынести в отдельную статью. мы
также
Это
вопросы
обсуждение
рассмотрим
стоит
довольно
серьезные и сложные вопросы. Чем же они
сложны? Все банально, именно в этих главах ТЗ определяются содержание
сроки
этих
выполнения
работ.
самом
деле
подобных
руководств
больших коробках с кучей руководств – это Это
идеал,
Именно
есть
к
которому
поэтому
должности
необходимо
в
крупных
технических
Технико-экономические показатели
7.3 Содержание работ по этапам не
На
много. Да, байка про программы приходящие в
писателей.
7.1 Стадии разработки
специально
далее.
компаниях
7. Стадии и этапы разработки
Сегодня
того
стремиться.
6. Технико-экономические показатели
довольно
Для
правда.
5. Требования к программной документации
порядка
и
«Руководство системного программиста» и так
расскажу о следующих главах:
Я
написанной
перечислю названия: «Руководство оператора»,
Введение Для
документации,
оформленной также по ГОСТам. Да, да и тут
И
еще
работ, один
немаловажный вопрос, вопрос финансовый. Но начнем мы с более банальных вещей.
Вот мы и добрались до финансовых вопросов. Сразу
же
хочу
действительно
крупных проектов у меня еще не было, поэтому этот пункт я опишу очень сжато, чтобы не ввести вас
в
заблуждение.
В
данном
пункте,
если
разработка по своей идее не уникальна, стоит произвести аналогами, выиграть
программы.
сравнение показать
за
счет
Если
стоимости
что
с
заказчик
другими
использования
разработка
сможет нашей
уникально
и
финансист из вас не очень можно отписать следующей
экономическая
фразой:
ориентировочная
эффективность
не
рассчитываются. Аналогия не проводится ввиду уникальности
Требования к программной документации
признаться,
разработке.
еще раз отметить, что ТЗ документ официальный.
наш заказчик получит, а также необходимо
данном
документации программой. Возможно, вообще
пункте
мы
будет
идти
некоторые
какая-то
описываем, вместе
возмутятся,
документация,
у
с
а
нас
какая
нашей зачем же
программный
таки
наличие
продукт
отличается
ОБЩИЕ ВОПРОСЫ
какие
разъяснить, за что заказчик будет платить нам деньги.
Стадии разработки В данном пункте необходимо указать, через
от
программа. Тут существует огромное количество
программы? Одним из отличий является как раз документации,
расписать,
преимущества именно с точки зрения ресурсов
в
программе есть help? Задам встречный вопрос, а чем
необходимо
к
Но
В
идеале
требований
Это один из самых простых пунктов ТЗ, хотя это недолжно уменьшать его значимости. Тут стоит
в
предъявляемых
причем
какие
стадии
разработки
пройдет
наша
всевозможных вариантов. Это объясняется тем, что существует не один способ создания ПО.
СОДЕРЖАНИЕ
15
ПРО
О ПРАВИЛЬНОМ СОСТАВЛЕНИИ ТЗ. ЧАСТЬ 3
№10 (январь) 2011
граммист
Например,
существуют
каскадная
и
Дела идут намного лучше, если разбить ее на
во
каждого маленького этапа. Мы, ориентируясь по
итерационная модели. Все будет зависеть, в первую
очередь,
от
специфики
проекта,
вторую очередь от разработчика. Но, если вы
разработчик не очень опытный, а быть может это ваш первый проект или вы пишите систему (скажем для наших госорганов), то для вас есть
ГОСТ. Называется этот ГОСТ: «ГОСТ 19.102-77 ЕСПД Стадии разработки». В этом документе и расписаны
все
стадия
стадии,
поясняется.
кроме
того,
Поэтому
каждая
советую
использовать поначалу именно этот ГОСТ. Но, если ваш проект не очень большой и вы не любите
изучать
ГОСТы,
предлагаю
вам
упрощенный вариант этого пункта ТЗ: 2. Рабочее проектирование
успеваем-ли
мы,
сколько
еще
времени
понадобится, чтобы завершить дело в целом, может нам стоит ускорить выполнение. В общем, плюсов уйма, а явных минусов не видно.
Именно этот прием стоит использовать и в разработки ПО, также благодаря этому мы в любой
момент
сможет
отчитаться
перед
заказчиком о том, как у нас идут дела. И он будет хоть сколько-то уверен в благоприятном
исходе, а мы сможем себя контролировать, и, Вместо заключения
3. Внедрение
Вот я и рассказала о еще ряде пунктов ТЗ. В этой
Этапы разработки
статье я не даю четких установок что делать, так
В данном пункте происходит разбиение стадий на более маленькие этапы, опять же данный будет
этим срокам, намного проще сможем определить
если что, подкорректировать свои действия.
1. Разработка технического задания
пункт
более маленькие и определить даты окончания
зависеть
непосредственно
от
конкретной ситуации. Но все, же необходимо не
как программы, которые мы пишем, зачастую могут
сильно
отличаться,
исполнители
тоже
разные. У всех есть свои пристрастия, методы и приемы, используемые в разработке.
забывать о ГОСТе, про который я упомянула
В данной статье я попыталась дать некий обзор
этапы.
открывших для себя ТЗ она послужит толчком к
выше, там все стадии как раз таки разбиты на И
все
же
рискну
посоветовать
вам
использовать именно данный ГОСТ. Криво на вас
после этого никто не посмотрит, ну, наверное, кроме иностранных заказчиков, и то, только
данных пунктов ТЗ. Думаю, для людей только что изучению ГОСТов и ответит на некоторые общие вопросы, возникающие при написании ТЗ.
потому, что в их странах разработаны подобные
ГОСТы, и им будет более понятно и приятно, если стадии и этапы будут совпадать с теми, которые описаны в ГОСТах их стран.
данном
пункте
необходимо
Источники •
Содержание работ по этапам В
Продолжение следует…
еще
более
детализировать стадии разработки. В ГОСТе это
•
тоже есть. Зачем же нам это нужно? В прошлой статье я говорила о том, что одной из самых
•
двумя пунктами?
•
Думаю, вы и в повседневной жизни замечали,
•
для
•
что если у нас есть большая задача, требующая своего
времени,
но
выполнения сроки
большого
выполнения
ОБЩИЕ ВОПРОСЫ
количества
ограниченны.
19.201-78.
Техническое
задание,
требования к содержанию и оформлению http://www.nist.ru/hr/doc/gost/19201-78.htm
ГОСТ 19.106-78 Требования к программным документам,
выполненным
печатным
способом http://www.nist.ru/hr/doc/gost/19106-
важных вещей в ТЗ является указание сроков
выполнения работ. Какая же связь между этими
ГОСТ
78.htm Н.
Дубова.
В
круге
http://citforum.ru/SE/project/circle
разработки
Единая система программной документации (ЕСПД) http://www.philosoft.ru/espd.zhtml Rational
Unified
Process.
Технологический
процесс разработки ПО http://www.rup-rus.ru Введение
в
управление
http://www.prjman.ru/theory/32
проектами
СОДЕРЖАНИЕ
16
ПРО
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
№10 (январь) 2011
граммист
В этой статье я расскажу Вам, как стать властелином USB-устройств хранения информации (далее флешек) используя: Windows Script Host, Windows Management Instrumentation и VBScript, – на мой взгляд, довольно несложные вещи, которые по умолчанию имеют место быть в операционных системах Windows, начиная с XP... Анатолий Демидович
by da440dil http://da440dil.narod.ru
«Нужное не сложно, сложное не нужно», – учил один персонаж, реальное существование, которого не вызывает сомнений…
Легенда приблизительно такая. В организации
поиска уязвимостей». Полагаю, разработчики
разрешенных к использованию, флешек. Кроме
считать
существует того,
список
есть
сертифицированных,
специалист
безопасности,
исключительно
по
отвечающий
информационной
за
использование
«правильных»
Каспера не зря едят свой хлеб, поэтому будем Сделаем Regshot.
их
способ
снимок При
наиболее
реестра
помощи
«правильным».
программой
Каспера
типа
запретим
флешек.
«автозапуск со съемных дисков». Сделаем еще
из организации, наименование которой здесь
Появился параметр NoDriveTypeAutoRun типа
Периодически приезжают «серьезные товарищи»
один снимок реестра и сравним его с первым.
даже страшно упоминать, и проверяют, каким
"REG_DWORD" со значением 4 раздела реестра
работу. Ниже я попробую помочь подобным
Windows\CurrentVersion\policies\Explorer".
образом местный специалист выполняет свою специалистам
в
флешек.
части
организации
оборота
управлять
•
извлекать
•
флешек;
автозапуском
и
информацию
использованием о
текущих
установленных в системе флешках; удалять
информацию
системе флешках.
Решение
об
перечисленных
следующим образом:
установленных
задач
и в
реализуем
1. Напишем скрипты для решения каждой отдельной задачи
2. Создадим VBA приложение
блокнот.
включенному
On Error Resume Next 'пропустим ошибки ошибки Dim keyNoAutoRunVal 'значение ключа Dim wshShell 'оболочка Dim a, b, c, d 'тексты сообщений Dim mesaga 'само сообщение 'ключ для проверки Const keyNoAutoRun = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ Windows\CurrentVersion\policies\Explorer\NoDriveTypeAutoRun" a = "__________________________________________" & vbCrLf & vbCrLf & "Включить?" & vbCrLf & "__________________________________________" b = "__________________________________________" & vbCrLf & vbCrLf & "Отключить?" & vbCrLf &
Set wshShell = CreateObject("WScript.Shell")'получаем оболочку keyNoAutoRunVal = wshShell.RegRead (keyNoAutoRun)'читаем ключ
автозапуску
в
If Err = 0 And keyNoAutoRunVal = 4 Then 'если ошибки нет - ключ существует и значение равно 4 - автозапуск запрещен
компьютер нередко попадают вирусы, поэтому не
'выкатываем сообщение
разные способы запрета автозапуска флешек.
'удаляем ключ
мешало бы уметь его отключать. Существуют антивирус
Касперского
предлагает запретить автозапуск через «окно
ОТДЕЛ ТЕСТИРОВАНИЯ
Notepad++.
d = "Автозапуск USB-устройств отключен"
1. Управление автозапуском
известный
использую
c = "Автозапуск USB-устройств включен"
Ready - Steady – Go.
Всем
Я
"__________________________________________"
3. Создадим HTA приложение
Благодаря
Откроем
Напишем нехитрый скрипт:
Обозначим задачи: •
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\
mesaga = MsgBox (a, vbYesNo + vbInformation, d) If mesaga = vbYes Then wshShell.RegDelete keyNoAutoRun Else 'если ключа не существует - ошибка - автозапуск разрешен
СОДЕРЖАНИЕ
17
ПРО
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
№10 (январь) 2011
граммист
'выкатываем сообщение
Скомбинируем возможные значения ключа реестра и имена наших
mesaga = MsgBox (b, vbYesNo + vbInformation, c)
файлов:
'пишем ключ
•
If mesaga = vbYes Then wshShell.RegWrite keyNoAutoRun, 4, "REG_DWORD"
Сохраним в формате VBS. Запускаем... I've got the power.
описано
использования в
статье
флешек
на
сайте
мелкомягких. Для запрета установки флешек нам предлагают присвоить пользователю, группе или
локальной
учетной
записи
SYSTEM
разрешение запретить для следующих файлов:
"%SystemRoot%\Inf\Usbstor.pnf и %SystemRoot%\ Inf\Usbstor.inf".
Скриптом
проблематично, переименуем
эти
поэтому файлы
в
это
сделать
сделаем
проще:
Usbstor.pnf.bak
и
Usbstor.inf.bak, соответственно. Можно, конечно, переместить
эти
файлы
•
разрешена);
и
разрешено),
Usbstor.inf
файлы:
(установка
комбинация №2: Ключ <> 4 (использование установленных
разрешено),
файлы:
Usbstor.pnf.bak и Usbstor.inf.bak (установка
2. Управление использованием подробно
установленных Usbstor.pnf
End If
Предотвращение
комбинация №1: Ключ <> 4 (использование
в
какое-нибудь
«секретное» место, или рандомизировать новые
•
запрещена);
комбинация №3: Ключ = 4 (использование установленных
запрещено),
файлы:
Usbstor.pnf.bak и Usbstor.inf.bak (установка запрещена). Напишем
функцию
проверки
использования флешек:
состояния
'функция проверки состояния использования флешек Function USBUseState() On Error Resume Next Dim fso, sfolder'файловая система и специальные папки Dim fUSBInf, fUsbPnf'файлы usbstor.inf и usbstor.PNF используются при установке новых USB-устройств
наименования (при этом придется вести список
Dim fUSBInfBak, fUsbPnfBak'переименованные файлы -
компьютера), однако мы оставим такие методы
Dim keyVal'значение ключа
установленных флешек в этой же статье нам
Const keyUsbstor = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
переименованных
файлов
для
каждого
для параноиков. Для запрета использования уже предлагают
установить
значение
4
типа
"REG_DWORD" параметра Start раздела реестра "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControl
Set\Services\USBSTOR". В этом случае ничего изобретать функцию реестра:
не
надо.
проверки
Для
начала
существования
напишем
ключа
Function KeyExists(key) 'ф-я проверки существ-я ключа реестра Dim wshShell Dim key2 On Error Resume Next'пропускаем ошибки Set wshShell = CreateObject("WScript.Shell") key2 = wshShell.RegRead(key) 'читаем ключ If Err.Number <> 0 Then 'если ошибка - ключа нет KeyExists = False Else 'значит есть KeyExists = True End If On Error GoTo 0'возвращаем ошибки в исходное положение
usbstor.inf.bak и usbstor.PNF.bak 'ключ реестра для уже установленных USB-устройств Services\USBSTOR\Start" 'сообщение об отсутствии файлов Const msgFile = "Файлы, необходимые для правильной работы USB-устройств отсутствуют" 'сообщение об отсутствии ключа Const msgKey = "Ключ реестра, необходимый для правильной работы USB-устройств отсутствует" 'файловая система Set fso = CreateObject("Scripting.FileSystemObject")
sfolder =
fso.GetSpecialFolder(0)'получаем путь к папке Windows fUSBInf = sfolder & "\inf\usbstor.inf"'полное наименование файла usbstor.inf fUsbPnf = sfolder & "\inf\usbstor.PNF"'полное наименование файла usbstor.PNF fUSBInfBak = fUSBInf & ".bak"'наименование переименованного файла usbstor.inf fUsbPnfBak = fUSBPnf & ".bak"'наименование переименованного файла usbstor.inf If KeyExists(keyUsbstor) Then'если ключ существует keyVal = wshShell.RegRead (keyUsbstor)'читаем ключ
End Function
ОТДЕЛ ТЕСТИРОВАНИЯ
СОДЕРЖАНИЕ
18
ПРО
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
№10 (январь) 2011
граммист
'2 - автоматически запускается, 3 - вручную (по умолчанию),
ElseIf stateVal = 2 Then
'4 - не запускается
stateValMsg = msgBan2
If keyVal <> 4 Then 'если файлы существуют
ElseIf stateVal = 3 Then
If fso.FileExists (fUSBInf) And fso.FileExists (fUSBPnf) Then
stateValMsg = msgBan3
USBUseState = 1'комбинация №1 - все разрешено
End If
Else If fso.FileExists (fUSBInfBak) And fso.FileExists
'выкатываем сообщение,
(fUsbPnfBak) Then'если файлы переименованы
'используем максимум возможных кнопок окна MsgBox - 3 :)
USBUseState = 2'комбинация №2 - запрещена установка
mesaga = MsgBox (msgText,vbAbortRetryIgnore +
Else'если нет ни тех, ни других файлов
vbQuestion,stateValMsg)
'сообщаем в вызвавшую программу об ошибке
'ошибок 100% нет, поэтому смело работаем с значением ключа
USBUseState = msgFile Exit Function'выходим из функции End If Else'значение ключа = 4
'реестра и файлами If
mesaga = vbAbort Then'если запрещаем использование и
USBUseState = 3'комбинация №3 - все запрещено
'выкатываем сообщение
End If Else'если ключа нет
USBUseBan(3)
USBUseState = msgKey'сообщаем об ошибке
MsgBox msgBan3, vbInformation
End If
Else If mesaga = vbRetry Then'если запрещаем установку
End Function
USBUseBan(2)
Хочу обратить ваше внимание на то, что в каждой
скриптов
отдельной мы
переменные.
будем
На
функции
или
использовать
первый
взгляд,
процедуре
локальные
это
может
показаться избыточным, однако в дальнейшем поможет нам просто копировать код из скриптов
в приложения. Далее напишем основной код скрипта:
MsgBox msgBan2, vbInformation Else If mesaga = vbIgnore Then'если разрешаем использование USBUseBan(1) MsgBox msgBan1, vbInformation End If Else 'если не число - строка - ошибка MsgBox stateVal, vbCritical, msgErr'полученное из функции 'сообщения об ошибке End If 'процедура запрета-разрешения использования флешек в зависимости
On Error Resume Next
'от полученного аргумента:
Dim stateVal'значение состояния использования флешек
Sub USBUseBan(ArgVal)'ArgVal - желаемое состояние
Dim stateValMsg'сообщение о состоянии
On Error Resume Next'пропустим ошибки, чтобы не париться в
Dim mesaga'сообщение
'очередной раз с проверкой существования файлов
Dim msgText'текст сообщения Const msgErr = "Ошибка"'заголовок сообщения об ошибке
Dim wshShell
Const msgBan1 = "Использование USB-устройств разрешено"
Dim fso, sfolder'файловая система и специальные папки
'заголовки сообщений о состоянии
Dim fUSBInf, fUsbPnf'файлы usbstor.inf и usbstor.PNF
Const msgBan2 = "Запрещена установка USB-устройств" Const msgBan3 = "Использование USB-устройств запрещено"
'используются при установке новых USB-устройств Dim fUSBInfBak, fUsbPnfBak'переименованные файлы -
msgText = "Выберите нужное состояние:" & vbCrLf & _
'usbstor.inf.bak и usbstor.PNF.bak
"________________________________________" & _
Dim keyVal'значение ключа
vbCrLf & vbCrLf & _
'ключ реестра для уже установленных USB-устройств
"ПРЕРВАТЬ - запретить использование" & vbCrLf &
Const keyUsbstor =
_
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR\
"ПОВТОР - запретить установку" & vbCrLf & _
Start"
"ПРОПУСТИТЬ - разрешить использование" & vbCrLf
Set wshShell = CreateObject("WScript.Shell")
& _
Set fso = CreateObject(
"________________________________________"
"Scripting.FileSystemObject")'файловая система sfolder = fso.GetSpecialFolder(0)'получаем путь к папке Windows
stateVal = USBUseState'получаем значение состояния
'полное наименование файла usbstor.inf
If IsNumeric(stateVal) Then 'если число - ошибки нет
fUSBInf = sfolder & "\inf\usbstor.inf"
If stateVal = 1 Then stateValMsg = msgBan1
ОТДЕЛ ТЕСТИРОВАНИЯ
'полное наименование файла usbstor.PNF fUsbPnf = sfolder & "\inf\usbstor.PNF"
fUSBInfBak = fUSBInf &
СОДЕРЖАНИЕ
19
ПРО
граммист
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
№10 (январь) 2011
Отсюда
".bak"'наименование переименованного файла usbstor.inf
поставленные
'файла usbstor.inf If ArgVal <> 1 Then'если запрещаем либо установку,
•
'либо использование fso.MoveFile fUSBInf, fUSBInfBak
'переименуем файлы, если
с
ее
задачи,
использования
помощью если
решить
количество
флешек переваливает за несколько сотен);
на мой взгляд самый основной недостаток: программа
«пляшет»
от
одного
раздела
реестра - "HKEY_LOCAL_MACHINE\SYSTEM\
'ошибка - файлы уже переименованы - едем дальше
CurrentControlSet\Enum\USB", таким образом
fso.MoveFile fUsbPnf, fUsbPnfBak
не
If ArgVal = 3 Then wshShell.RegWrite keyUsbstor, 4,
удаляет
Else: wshShell.RegWrite keyUsbstor, 3, "REG_DWORD"'в противном 'случае - комбинация №2 - пишем значение по умолчанию End If Else'если все разрешаем - комбинация №1 wshShell.RegWrite keyUsbstor, 3, "REG_DWORD"'пишем значение по 'умолчанию 'переименуем файлы обратно,
'если ошибка - файлы уже переименованы - едем дальше fso.MoveFile fUsbPnfBak, fUsbPnf
•
раздела;
информацию
необходимую
только
из
этого
Для извлечения информации как нельзя лучше подойдет
технология
Instrumentation.
Извлечение
флешках
End Sub
получает
прочие недостатки для себя найдете сами.
3.1.
End If
всегда
информацию о флешках, и, что крайне важно,
"REG_DWORD"'если запрещаем использование - комбинация №3
fso.MoveFile fUSBInfBak, fUSBInf
неудобство
(попробуйте
fUsbPnfBak = fUSBPnf & ".bak"'наименование переименованного
Windows
информации
Management
о
текущих
Собираем все в кучу (ниже добавляем наши
Используем классы WMI:
VBS. Запускаем... Things get better.
•
Win32_DiskDrive для работы с физическими
3. Управление информацией
•
Win32_USBHub для работы с USB [2];
функции) и сохраняем в файле с расширением
Для того чтобы эффективно рулить флешками в организации, нам необходимо: •
вести список разрешенных к использованию
•
извлекать информацию о текущих флешках;
• • • •
флешек;
сравнивать списком
полученную
и
добавлять
необходимости; извлекать
информацию
ее
информацию в
из
список
реестра
об
информацию
со
установленных в системе флешках; сравнивать списком; удалять
полученную
из
реестра
установленных флешках.
со
при
информацию
об
В сети интернет я нашел программу USBDeview, которая частично решает поставленные задачи. Ее недостатки: •
избыточность информации – нас интересуют только
флешки,
серийные
номера,
наименования, объем, VendorID и ProductID (на
случай
перепрошивки
ОТДЕЛ ТЕСТИРОВАНИЯ
не
помешает).
•
накопителями [1];
StdRegProv для работы с реестром [3];
Итак, откроем блокнот и напишем функцию извлечения информация о текущих флешках:
'функция извлечения информация о текущих флешках, возвращает 'двухмерный массив '1-я размерность: серийный номер, наименование, объем, VID и PID '2-я размерность: счетчик Function USBGetCur() On Error Resume Next Dim wmiDiskDrive, wmiDiskDrives 'диски Dim wmiUSBHub, wmiUSBHubs 'USB Dim PnPID, PnPID2 'идентификатор флешки Dim USBSNumb 'серийный номер Dim arrUSBInfo() 'массив для информации о каждой флешке Dim i'счетчик 'переменные для 2-го способа извлечения VID-PID Dim strComputer 'местный компьютер Dim strValueName 'название параметра Dim strKeyPath 'раздел с информацией об USB Dim objReg 'реестр Dim subkey, arrSubKeys, arrSubKeys1 'подключ и массивы подразд-в Dim ParIdPre' переменная для параметра ParentIdPrefix Const HKLM = &H80000002
СОДЕРЖАНИЕ
20
ПРО
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
№10 (январь) 2011
граммист
Set wmiDiskDrives = GetObject("winmgmts:").InstancesOf( "Win32_DiskDrive")'получаем диски
'серийным номером If UCase(ParIdPre) = USBSNumb Then
Set wmiUSBHubs = GetObject("winmgmts:").InstancesOf(
'вытаскиваем из строки VID и PID
"Win32_USBHub")'получаем USB
arrUSBInfo(3,i) = Mid(subkey,5,4)
'значения для 2-го способа извлечения VID-PID
arrUSBInfo(4,i) = Mid(subkey,14,4)
strComputer = "."'местный компьютер
End If
strValueName = "ParentIdPrefix"'название параметра
Next
strKeyPath = "SYSTEM\CurrentControlSet\Enum\USB"'раздел с
End If
'информацией об USB
End If
Set objReg = GetObject("winmgmts:\\" & strComputer &
Next
"\root\default:StdRegProv")'получаем провайдера реестра
End If
i = 0
End If
For Each wmiDiskDrive In wmiDiskDrives'побежали по дискам
i = i + 1
If wmiDiskDrive.InterfaceType = "USB" Then'если диск USB
End If
ReDim Preserve arrUSBInfo(4, i)'перебили размерность массива
Next
arrUSBInfo(1,i) = wmiDiskDrive.Model'модель диска
If i <>0 Then
arrUSBInfo(2,i) = wmiDiskDrive.Size'объем диска
USBGetCur = arrUSBInfo'если есть флешки
PnPID = wmiDiskDrive.PnPDeviceID'идент-р флешки из реестра
Else USBGetCur = i
'вытаскиваем серийный номер флешки
End If
'выбираем из строки-идентификатора серийник
End Function
USBSNumb = Mid(PnPID, InStrRev(PnPID, "\") + 1)
Далее, создадим еще один текстовый файл и
'удаляем последние 2 символа - типа &0 или &1
запишем в него следующую строку:
arrUSBInfo(0,i) = Left(USBSNumb, Len(USBSNumb)-2) For Each wmiUSBHub In wmiUSBHubs'побежали по USB PnPID2 = wmiUSBHub.PNPDeviceID
Серийный номер;Наименование;Объем;Владелец
'вытаскиваем серийник и сравниваем с серийником из
Назовем его < USBBase.csv > и сохраним. Это
'Win32_DiskDrive
будет
If Right(PnPID2,Len(PnPID2)-Instr(5,PnPID2,"\")) = arrUSBInfo(0,i) Then arrUSBInfo(3,i) = Mid(PnPID2,9,4)'вытаскиваем VID arrUSBInfo(4,i) = Mid(PnPID2,18,4)'вытаскиваем PID Exit For
наша
база
информации
о
данных
для
разрешенных
хранения
флешках.
Использование формата CSV обусловлено тем, что
пользователю
довольно
легко
вносить
изменения в базу вручную. При условии, что на компьютере установлен MS Excel, пользоваться
End If
такой
Next If IsEmpty(arrUSBInfo(3,i)) Then'если не прокатило получить 'VID, тогда попробуем 2-й способ - через реестр
базой
напишем
несложно.
функцию
нашего файла:
Следующим
чтения
шагом
информации
из
objReg.EnumKey HKLM, strKeyPath, arrSubKeys'пол-м подразд-ы
'функция чтения файла базы, возвращает двухмерный массив
If IsArray(arrSubKeys) Then'на всякий случай, если массив
'1-я размерность: серийный номер, наименование, объем, владелец
For Each subkey In arrSubKeys'для каждого подраздела If Left(subkey,3) = "Vid" Then'если название раздела 'начинается с Vid - пропускаем ROOT_HUB и пр. objReg.EnumKey HKLM, strKeyPath & "\" &
subkey,
arrSubKeys1'получаем подразделы подразделов If IsArray(arrSubKeys1) Then'снова если массив For Each subsubkey In arrSubKeys1'для кажд.подр-а подр-в 'получаем значение параметра ParentIdPrefix objReg.GetStringValue HKLM, strKeyPath & "\" & subkey & "\" & subsubkey, strValueName, ParIdPre 'поднимем в верхний регистр ParentIdPrefix и сравним с
ОТДЕЛ ТЕСТИРОВАНИЯ
'2-я размерность: счетчик Function ReadCSV() On Error Resume Next Dim wshShell 'оболочка Dim fso 'файловая система Dim baseFilePath 'полное имя файла базы Dim baseFile 'сам файл Dim dataArray() 'массив для строк из csv-файла Dim splitArray 'массив разбитых прочитанных строк Dim dataArray1() 'двухмерный массив для разбитых строк Dim i, j 'счетчики
СОДЕРЖАНИЕ
21
ПРО
№10 (январь) 2011
граммист
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
Const baseFileName = "USBBase.csv" 'имя файла базы
'строку не читаем - заголовки столбцов
Set wshShell = CreateObject("WScript.Shell")
'если флешка обнаружена в списке
Set fso = CreateObject("Scripting.FileSystemObject")
If USBCur(0,i) = CSVRead(0,j) Then
'получаем полный путь к файлу базы: текущий каталог скрипта +
MsgBox "________________________________________" & vbCrLf &
'имя файла базы
_vbCrLf & "Владелец: " & CSVRead(3,j) & vbCrLf &
baseFilePath = wshShell.CurrentDirectory & "\" & baseFileName
"________________________________________", _
If fso.FileExists(baseFilePath) Then 'если файл базы существует
vbOKOnly + vbInformation,
Set baseFile = fso.OpenTextFile(baseFilePath) 'открываем файл
"USB-устройство обнаружено в списке"
i = 0
y = y + 1
Do Until baseFile.AtEndOfStream'читаем
Exit For
ReDim Preserve dataArray(i)'перебили размерность массива
End If
dataArray(i) = baseFile.ReadLine 'читаем строку и в массив
Next
splitArray = Split(dataArray(i), ";") 'разбиваем и во 2 массив
If y = 0 Then 'если в списке нет такой флешки
ReDim Preserve dataArray1(3, i)'перебили разм. 3-го массива
mesaga = MsgBox ("__________________________________________" & vbCrLf & vbCrLf & _"Серийный номер: " &
For j = 0 To 3
USBCur(0,i) & vbCrLf & "Наименование: " &
dataArray1(j, i) = splitArray(j)'полученное в 3-й массив
USBCur(1,i) & vbCrLf & _
Next
"Объем: " & USBCur(2,i) & vbCrLf & i = i + 1
"__________________________________________"
Loop
& vbCrLf & _"Добавить в список?", vbYesNo +
baseFile.Close
vbInformation,
ReadCSV = dataArray1 End If
"USB-устройство отсутствует в списке") If mesaga = vbYes Then
End Function
vlad = InputBox("Пожалуйста, введите имя владельца")
Затем напишем основной код скрипта:
'открываем файл для добавления Set baseFile = fso.OpenTextFile(baseFilePath,8) baseFile.WriteLine USBCur(0,i) & ";" & USBCur(1,i) & ";" &
On Error Resume Next
USBCur(2,i) & ";" & vlad
Dim USBCur 'текущие флешки
baseFile.Close
Dim CSVRead 'прочитанные из списка флешки
End If
Dim mesaga, vlad 'сообщения
End If
Dim wshShell 'оболочка Dim fso 'файловая система
'если в списке несколько одинаковых серийных номеров
Dim baseFilePath 'полное имя файла базы
If y > 1 Then
Const baseFileName = "USBBase.csv" 'имя файла базы
MsgBox "Серийный номер USB-устройства в списке повторяется",
USBCur = USBGetCur()'получаем текущие
vbCritical, "В списке обнаружена ошибка"
CSVRead = ReadCSV()'получаем список
Next
Set fso = CreateObject("Scripting.FileSystemObject")
Else: MsgBox "Вставьте USB-устройство в USB-порт",
Set wshShell = CreateObject("WScript.Shell")
vbExclamation, "USB-устройств не обнаружено"
'получаем полный путь к файлу базы:
End If
'текущий каталог скрипта + имя файла базы
Else: MsgBox "Файл USBBase.csv отсутствует",
baseFilePath = wshShell.CurrentDirectory & "\" & baseFileName If fso.FileExists(baseFilePath) Then 'если файл существует ' сравним серийные номера - побежали по текущим If IsArray(USBCur) Then'если есть хоть одна флешка - массив, 'если нет - число 0 y = 0 'счетчик - на случай если в списке одинаковые серийники 'идем по размерности №2 For i = LBound(USBCur, 2) To UBound(USBCur, 2) 'побежали по списку For j = 1 To UBound(CSVRead, 2)'идем по размерности №2 - первую
ОТДЕЛ ТЕСТИРОВАНИЯ
vbCritical, "Ошибка"'если файл отсутствует End If
Собираем, сохраняем, запускаем... Voila. 3.2.
Извлечение
установленных флешках
информации
об
Информацию об установленных флешках будем сохранять в файл. Открываем блокнот и пишем
СОДЕРЖАНИЕ
22
ПРО
граммист
№10 (январь) 2011
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
процедуру извлечения информации из реестра: 'процедура получения информации о всех флешках и сохранения в 'файл с расширением в зависимости от полученного параметра:
If zn = 0 Then 'в формат .htm 'имя создаваемого файла в папке скрипта 'создаем файл, если уже существует - перезапишем repFileName = wshShell.CurrentDirectory & "\" & compName & "
'0 - .htm, 1 - .csv
-" & Date & ".htm"
Sub InfToFile(zn) On Error Resume Next
'пишем в файл начальные тэги и заголовок таблицы
Dim subkey, subsubkey 'ключ, подключ
Set repFile = fso.CreateTextFile(repFileName, True)
Dim arrSubKeys(), arrSubKeys1()
'массивы подключей
repFile.WriteLine "<html><title>USBMaster -
Dim objReg 'реестр
Report</title><body><table border=" & Chr(34) & _
Dim wshShell 'оболочка
1 & Chr(34) & " width = 90% align = center><tr><th colspan=" &
Dim strComputer 'компьютер
Chr(34) & 2 & Chr(34) & _">Список USB-устройств хранения
Dim compName 'имя компьютера
информации, установленных на компьютере " & compName & _
Dim repFile 'файл отчета
" " & Date & " г.</th></tr><tr><td>Серийный
Dim repFileName'имя файла отчета
номер</td><td>Наименование</td></tr>"
Dim USBMas() 'массив для полученных значений
'если массив - хоть что-нибудь есть
Const HKLM = &H80000002
If IsArray(USBMas) Then 'заполняем таблицу
Const strValueName = "FriendlyName" 'назв-е пар-а имени флешки
For i = LBound(USBMas, 2) To UBound(USBMas, 2)
'раздел с информацией об USB
repFile.WriteLine "<tr><td>" & USBMas(0, i) &
Const strKeyPath = "SYSTEM\CurrentControlSet\Enum\USBSTOR" strComputer = "." 'местный компьютер
"</td><td>" & USBMas(1, i) & "</td></tr>" Next End If
Set wshShell = CreateObject("WScript.Shell")
repFile.WriteLine "</table></body></html>"'закрываем тэги
'получаем имя компьютера
repFile.Close ' закрываем файл
compName = wshShell.ExpandEnvironmentStrings("%COMPUTERNAME%")
'открываем файл программой по умолчанию
Set objReg = GetObject("winmgmts:\\" & strComputer &
wshShell.Run (repFileName)
"\root\default:StdRegProv") 'получаем провайдера реестра
Else If zn = 1 Then 'в формат .csv
repFileName = wshShell.CurrentDirectory & "\" & compName & "-" &
objReg.EnumKey HKLM, strKeyPath, arrSubKeys 'получаем подразделы
Date & ".csv"'имя создаваемого файла в папке скрипта
i = 0 'счетчик
'создаем файл, если уже существует - перезапишем
If IsArray(arrSubKeys) Then'если массив - есть хоть один ключ
Set repFile = fso.CreateTextFile (repFileName, true)
For Each subkey In arrSubKeys 'для каждого подраздела objReg.EnumKey HKLM, strKeyPath & "\" & subkey, arrSubKeys1 'получаем подразделы подразделов If IsArray(arrSubKeys1) Then'снова если массив
'пишем заголовки столбцов repFile.WriteLine "Серийный номер;Наименование" If IsArray(USBMas) Then'если массив - хоть что-нибудь есть For i = LBound(USBMas,2) To UBound(USBMas,2)
'для каждого подраздела-подразделов
repFile.WriteLine USBMas(0,i) & ";" & USBMas(1,i)
For Each subsubkey In arrSubKeys1
Next
ReDim Preserve USBMas(1, i)
End If
'получаем название минус последние 2 символа -
repFile.Close' закрываем файл
'серийный номер флешки
wshShell.Run (repFileName)'откр.файл программой по умолчанию
USBMas(0, i) = UCase(Left(subsubkey,
End If
Len(subsubkey) - 2)) 'получаем название флешки objReg.GetStringValue HKLM, strKeyPath & "\" & subkey & "\" & subsubkey, strValueName, USBMas(1, i)
End Sub
Далее напишем основной код скрипта:
i = i + 1
On Error Resume Next
Next
Dim mesaga'сообщение
End If Next End If
Dim msgText'текст сообщения msgText = "Выберите формат файла для сохранения:" & vbCrLf & _ "________________________________________" & _ vbCrLf & vbCrLf & _
Set fso = CreateObject("Scripting.FileSystemObject")
ОТДЕЛ ТЕСТИРОВАНИЯ
"ДА - htm" & vbCrLf & _
СОДЕРЖАНИЕ
23
ПРО
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
№10 (январь) 2011
граммист
"НЕТ - csv" & vbCrLf & _
Const strUSB = "\Enum\USB\"
"________________________________________"
Const strUSBSTOR = "\Enum\USBSTOR\"
mesaga = MsgBox (msgText,vbYesNoCancel + vbQuestion, "Извлечение информации")
Const CCS = "CurrentControlSet" Const CSX = "ControlSet"
If mesaga = vbYes Then
Set objReg = GetObject("winmgmts:\\.\root\default:StdRegProv")
InfToFile(0)
Set wshShell = CreateObject("WScript.Shell")
ElseIf mesaga = vbNo Then
'проверяем аргументы
InfToFile(1)
If WScript.Arguments.Count = 0 Then'если нет аргументов
End If
mesaga = MsgBox ("Удалить информацию об установленных USB
Собираем, сохраняем, запускаем... Everything's
-устройствах?", vbYesNo + vbInformation, "Удаление информации")
gonna be allright.
If mesaga = vbYes Then MkTask 'создаем задание
4. Удаление информации об установленных
Else If WScript.Arguments(0) = "/d" Then
флешках
Информация хранится в следующих разделах реестра: •
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentCont
•
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentCont
•
"HKEY_LOCAL_MACHINE\SYSTEM\ControlSetХ
•
"HKEY_LOCAL_MACHINE\SYSTEM\ControlSetХ
rolSet\Enum\USBSTOR" rolSet\Enum\USB"
ХХ\Enum\USBSTOR" ХХ\Enum\USB"
где Х = цифра (ControlSet001, ControlSet002 и т.д.)
По умолчанию полный доступ к перечисленным
'если аргумент /d - типа delete :) ChkNDel(0) End If Sub MkTask()'процедура создания задания Dim sched 'планировщик Dim compName 'имя компьютера 'получаем имя компьютера compName = wshShell.ExpandEnvironmentStrings("%COMPUTERNAME%") 'получаем службу планировщика заданий Set sched = GetObject("WinNT://" & compName & "/schedule, service") If sched.Status <> 4 Then 'если служба планировщика не запущена If sched.Status = 1 Then 'если служба планировщика не работает sched.Start 'запустить ElseIf sched.Status = 7 Then 'если приостановлена sched.Continue 'возобновить Else 'если или ошибка службы или пытается что-то сделать MsgBox "Планировщик заданий не работает",
разделам имеет только учетная запись SYSTEM. Следовательно, мы не сможем в цикле пробежать по всем подразделам и удалить ненужные (или нужные).
Изменить
разрешения,
заданий
Windows
vbCritical, "Ошибка" Exit Sub 'завершаем выполнение End If
используя
End If
запускает
'добавим задание - через 60 секунд запустить этот скрипт с
заявленные выше средства, тоже не получится. Планировщик
'удаляем информацию от имени системы
назначенные задания от имени системы. Его и
используем. Напишем скрипт, который будет создавать задание в планировщике, которое в
свою очередь будет запускать этот же скрипт с параметрами в начале следующей минуты:
'удаление из реестра информации об установленных флешках через
'параметром в пакетном режиме (без сообщений об ошибках) wshShell.Run "at " & DateAdd("s",61,Time) & " cscript.exe //b " & WScript.ScriptFullName & " /d", 0'окно консоли не отображаем keyCnt = ChkNDel(1)'считаем ключи MsgBox "Удаление начнется через " & 60 - Second(Now) & " сек." & vbCrLf & "Ключей реестра на удаление: " & _ keyCnt, vbInformation, "Пожалуйста, подождите"
'планировщик заданий и аргументы скрипта
'отдыхаем положенное количество миллисекунд - накинем еще 5,
On Error Resume Next
'чтобы правильно посчитал сколько ключей осталось
Dim objReg 'с переменными особо заморачиваться не будем
WScript.Sleep (66 - Second(Now))*1000
Dim wshShell
keyCnt = ChkNDel(1)'считаем ключи еще раз
Const HKLM = &H80000002
If keyCnt > 0 Then'если удалены не все ключи
Const strSys = "SYSTEM"
ОТДЕЛ ТЕСТИРОВАНИЯ
MsgBox "Не удалось удалить ключей: " & keyCnt,
СОДЕРЖАНИЕ
24
ПРО
граммист
№10 (январь) 2011
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
vbExclamation, "Удаление завершено"
'бывают варианты :)
Else: MsgBox "Все ключи успешно удалены",
objReg.EnumKey HKLM, strKeyPath, arrSubKeys1
vbInformation, "Удаление завершено"
'если существует хотя бы один подраздел - значит
End If
'arrSubKeys1 - массив
End Sub
If IsArray(arrSubKeys1) Then For Each strSubkey1 In arrSubKeys1
'функция обнаружения, подсчета или удаления ключей
'снова проверяем наличие имени - важно - чтобы
'если получает 0 - удаляет, если 1 - считает
'не вылететь с ошибкой
Function ChkNDel(delVal)
If strSubkey1 <> "" Then DelSubkeys strKeyPath &
cnt = 0 'счетчик
"\" & strSubkey1
'получаем подразделы HKEY_LOCAL_MACHINE\SYSTEM
Next
objReg.EnumKey HKLM, strSys, arrSubKeys
End If
'здесь проверять ничего не будем - подразделы есть - побежали
'если наконец-то мы не получили значения arrSubkeys1 -
For Each subkey In arrSubKeys
'значит подразделов нет, можно удалять раздел
'если CurrentControlSet или ControlSetХХХ If subkey = CCS Or Left(subkey, 10) = CSX Then keyUSB = strSys & "\" & subkey & strUSB keyUSBSTOR = strSys & "\" & subkey & strUSBSTOR 'получаем подразделы USB objReg.EnumKey HKLM, keyUSB, arrSubKeysUSB If IsArray(arrSubKeysUSB) Then'если массив - ключи есть For Each subkeyUSB In arrSubKeysUSB 'корневой концентратор оставим в покое - пригодится :) If Left(subkeyUSB,8) <> "ROOT_HUB" Then 'считаем ключи, если функция получила значение 1 If delVal = 1 Then cnt = cnt + 1 'зап-м процедуру удаления, если ф-я получила значение 0 If delVal = 0 Then DelSubkeys keyUSB & subkeyUSB End If Next End If 'получаем подразделы USBSTOR objReg.EnumKey HKLM, keyUSBSTOR, arrSubKeysUSBSTOR 'все то же самое, что и этажом выше If IsArray(arrSubKeysUSBSTOR) Then For Each subkeyUSBSTOR In arrSubKeysUSBSTOR If Left(subkeyUSBSTOR,8) <> "ROOT_HUB" Then If delVal = 1 Then cnt = cnt + 1 If delVal = 0 Then DelSubkeys keyUSBSTOR & subkeyUSBSTOR End If Next End If End If Next ChkNDel = cnt End Function 'рекурсивная процедура удаления подразделов реестра Sub DelSubkeys(strKeyPath) If strKeyPath <> "" Then 'проверяем наличие имени раздела -
ОТДЕЛ ТЕСТИРОВАНИЯ
objReg.DeleteKey HKLM, strKeyPath End If End Sub
Здесь следует сделать оговорку. С рекурсивной процедурой
objReg.EnumKey
бывают не
косяки:
может
иногда
прочитать
имя
раздела – вместо имени читает пустую строку и по
ходу
рекурсии
происходит
переполнение
памяти. В таком случае не спасает и вариант: wshShell.Run "reg.exe delete " & Chr(34) &
"имя_раздела или имя_родительского_раздела" & Chr(34) & " /f"
Только последовательное удаление подразделов
ручками*, либо через редактор реестра, либо через консоль. Так вот, на этот случай мы
установили проверки: If strKeyPath <> "" и If strSubkey1
<>
"".
Кроме
того,
по
этой
же
причине в ходе работы скрипта мы считаем
количество ключей, содержащих информацию о установленных
флешках
и
в
сообщении
об
окончании работы скрипта, в случае косяков, обозначаем количество ключей, удалить которые не удалось.
И еще. Скрипт удаляет информацию обо ВСЕХ установленных
USB-устройствах,
включая
встроенные устройства, такие как картридеры и т.п.
Для
Мы
не
повторной
установки
таких
USB-
устройств необходимо перезагрузить компьютер. стали
тратить
время
на
проверку
* Комментарий автора.
Если честно – не понял, почему так происходит. Смотришь через
regedit – все нормально: ключи как ключи, ничего особенного. А
objReg.EnumKey не читает. Кто знает причину – пожалуйста, сообщите. Буду очень рад.
СОДЕРЖАНИЕ
25
ПРО
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
№10 (январь) 2011
граммист
параметра Service каждого раздела реестра (disk
On Error Resume Next
USB),
Dim fso 'файловая система
– для раздела USBSTOR, usbstor – для раздела потому
что
этот
параметр
не
всегда
корректный (например, для какого-нибудь USBмодема с CD-ROM разделом параметр будет равен
cdrom,
а
информацию
о
таких
USB-
устройствах нам необходимо удалять в первую очередь), а иногда и вовсе отсутствует. Все.
Копипастим
текст
скрипта
в
блокнот.
Сохраняем. Запускаем... We are the champions 5. Резервирование
Dim wshShell 'оболочка Dim usrAppData 'папка Application Data текущего пользователя Dim fFullName 'полное имя файла резервной копии Dim objFile 'сам файл Const fName = "SysRegBack.reg" 'имя файла резервной копии Set wshShell = CreateObject("WScript.Shell") Set fso = CreateObject("Scripting.FileSystemObject") 'получаем путь к папке Application Data usrAppData = wshShell.ExpandEnvironmentStrings("%APPDATA%") 'собираем полное имя файла резервной копии fFullName = usrAppData & "\" & fName
Не секрет, что перед началом манипуляций с реестром неплохо сохранить резервную копию
If fso.FileExists(fFullName) Then 'если файл существует Set objFile = fso.GetFile(fFullName) 'получаем файл objFile.Delete 'удаляем
целевого раздела. Так как наши ключи находятся
End If
предлагаю
'экспортируем раздел
в разных подразделах раздела HKLM\SYSTEM, экспортировать
HKLM\SYSTEM,
так
будет
целиком
проще.
раздел
Сохранять
резервную копию будем в папке Application Data текущего пользователя. Напишем простенький скрипт,
при
помощи
которого
мы
сможем
«легким движением руки» создавать резервную
wshShell.Run "reg.exe EXPORT HKLM\SYSTEM " & Chr(34) & fFullName & Chr(34), 0, True'ждем завершения выполнения MsgBox "Создание резервной копии завершено", vbInformation End Sub
копию нашего раздела, восстанавливать раздел
'восстановление из резервной копии (если она существует)
резервной копии (для параноиков):
On Error Resume Next
из резервной копии, а также удалять файл
Sub USBRestore() Dim wshShell 'оболочка
'создание резервной копии, восстановление и удаление
Dim fso 'файловая система
On Error Resume Next
Dim usrAppData 'папка Application Data текущего пользователя
Dim mesaga'сообщение
Dim fFullName 'полное имя файла резервной копии
Dim msgText'текст сообщения
Const fName = "SysRegBack.reg" 'имя файла резервной копии
msgText = "Выберите задание:" & vbCrLf & _
Set wshShell = CreateObject("WScript.Shell")
"__________________________________________________" &
Set fso = CreateObject("Scripting.FileSystemObject")
_vbCrLf & vbCrLf & _
'получаем имя компьютера
"ПРЕРВАТЬ - сохранить резервную копию" & vbCrLf & _
compName = wshShell.ExpandEnvironmentStrings("%COMPUTERNAME%")
"ПОВТОР - восстановить из резервной копии" &vbCrLf & _
'получаем путь к папке Application Data
"ПРОПУСТИТЬ - удалить резервную копию" & vbCrLf & _
usrAppData = wshShell.ExpandEnvironmentStrings("%APPDATA%")
"__________________________________________________"
'собираем полное имя файла резервной копии fFullName = usrAppData & "\" & fName
'сообщение, используем макс.возм.кнопок окна MsgBox - 3 :)
If fso.FileExists(fFullName) Then 'если файл существует
mesaga = MsgBox (msgText,vbAbortRetryIgnore + vbQuestion,
'проверка запуска службы
"Резевирование") If
mesaga = vbAbort Then USBBackUp 'создаем резервную копию
ElseIf mesaga = vbRetry Then USBRestore 'восстанавливаем ElseIf mesaga = vbIgnore Then USBDelBackUp 'удаляем резервную копию End If Sub USBBackUp() 'создание копии раздела реестра "HKLM\SYSTEM"
ОТДЕЛ ТЕСТИРОВАНИЯ
Set sched = GetObject("WinNT://" & compName & "/schedule, service") If sched.Status <> 4 Then 'если служба планировщика не запущена If sched.Status = 1 Then 'если служба планировщика не работает sched.Start 'запустить ElseIf sched.Status = 7 Then 'если приостановлена sched.Continue 'возобновить Else 'если или ошибка службы или пытается что-то сделать MsgBox "Планировщик заданий не работает",
СОДЕРЖАНИЕ
26
ПРО
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
№10 (январь) 2011
граммист
vbCritical, "Ошибка"
On Error Resume Next
Exit Sub 'завершаем выполнение
Dim wshShell 'оболочка
End If
Dim fso 'файловая система
End If
Dim usrAppData 'папка Application Data текущего пользователя Dim fFullName 'полное имя файла резервной копии
'добавляем запуск восстановления в планировщик задач, чтобы
Dim objFile 'сам файл
'запустил от имени System
Const fName = "SysRegBack.reg" 'имя файла резервной копии
wshShell.Run "at " & DateAdd("s", 61, Time) & " reg.exe
Set wshShell = CreateObject("WScript.Shell")
IMPORT " & Chr(34) & fFullName & Chr(34), 0 MsgBox "Восстановление начнется через " & 60 - Second(Now) & " сек.", vbInformation, "Пожалуйста, подождите"
Set fso = CreateObject("Scripting.FileSystemObject") 'получаем путь к папке Application Data usrAppData = wshShell.ExpandEnvironmentStrings("%APPDATA%")
'отдыхаем положенное кол-во миллисекунд + накинем еще секунду
'собираем полное имя файла резервной копии
WScript.Sleep (62 - Second(Now))*1000
fFullName = usrAppData & "\" & fName
MsgBox "Восстановление завершено", vbInformation
If fso.FileExists(fFullName) Then 'если файл существует
Else
Set objFile = fso.GetFile(fFullName) 'получаем файл
MsgBox "Резервная копия отсутствует", vbExclamation End If
objFile.Delete 'удаляем MsgBox "Удаление резервной копии завершено", vbInformation
End Sub
Else: MsgBox "Резервная копия отсутствует", vbExclamation End If
Sub USBDelBackUp() 'удаление файла резервной копии, если он есть
End Sub
Рис. 1. Начальное меню
Рис. 2. Поиск и обнаружение USB устройств
ОТДЕЛ ТЕСТИРОВАНИЯ
СОДЕРЖАНИЕ
27
ПРО
граммист
USBMASTER. РУЛИМ ФЛЕШКАМИ В ОФИСЕ
№10 (январь) 2011
Рис. 3. Добавление в список «разрешенных» Последовательность не изменилась. Запускаем...
Ресурсы
информационной
•
I love rock'n'roll. В результате наш специалист по скрипты,
может
безопасности,
отработать
с
используя
подотчетными
компьютерами по следующему алгоритму (см. рисунки 1-3): •
удалить
•
перезагрузить компьютер;
• • •
флешках;
информацию
об
установленных
установить «разрешенные» флешки;
запретить последующую установку флешек;
• • •
немного расслабиться.
Win32_DiskDrive для работы с физическими накопителями
http://msdn.microsoft.com/en-
us/library/aa394132(VS.85).aspx Win32_USBHub
для
работы
с
http://msdn.microsoft.com/en-us/library/ aa394506(VS.85).aspx StdRegProv
для
работы
с
USB
реестром
http://msdn.microsoft.com/en-us/library/ aa393664(VS.85).aspx
Ресурс автора http://da440dil.narod.ru/ download.html
Заключение В этой статье я постарался, как можно более
подробно обозначить способы работы с USBустройствами хранения информации при помощи
«несложных» технологий. Это всего лишь мое решение
задачи.
решение поможет.
Надеюсь,
кому-нибудь
это
Для тех, кто совершил подвиг, и все таки дочитал текст до конца, выкладываю архив с созданными в
процессе
изложения
скриптами.
Скачать
слегка «кривые», но вполне работоспособные заявленные выше VBA и HTA приложения Вы
можете тут [4] или заглянуть в ресурсы к журналу. Для тех, кто внимательно прочитал статью,
не
«выпрямить».
составит
особого
труда
их
Пожалуйста, Ваши замечания по содержанию статьи отправляйте на e-mail: da440dil@ya.ru.
ОТДЕЛ ТЕСТИРОВАНИЯ
СОДЕРЖАНИЕ
28
ПРО
ШАБЛОН КЛАССА ОДНОСВЯЗНОЙ ОЧЕРЕДИ В STL
№10 (январь) 2011
граммист
В свое время, изучая все богатство возможностей библиотеки STL и, применяя эти возможности на практике, обнаружил, что основным необходимым мне контейнером является односвязная очередь типа FIFO: «первым зашел – первым вышел». В одной из своих программ насчитал 27-мь очередей под различные типы данных. Видимо это связано со спецификой разрабатываемых программ: взаимодействие с различными внешними устройствами, также разработанных нашей фирмой. Обмен ведется сообщениями через последовательные интерфейсы: COM, USB, протокол TCP/IP… Вячеслав Мовила
http://movila.site11.com
QueueNode * next; QueueNode() { next = 0; } };
Предпосылки реализации... Такого контейнера – односвязной очереди, типа FIFO, в библиотеке STL не существует. Есть удобный
адаптер
под
стандартные
типы
контейнеров STL. Но! Вот всегда это самое «Но» и
в
самых
научила,
что
неожиданных
использовать
местах!
Практика
библиотеку
STL
отличаются
в
следует с определенной долей осторожности. Реализации
библиотеки
зависимости
от
компилятора.
Например,
некоторые реализации подразумевают потоковую
безопасность, некоторые – нет. По мне, так потоковую
безопасность
легче
организовать
программисту на прикладном уровне. Тем более, если
в
ней
нет
необходимости,
а
в
вашей
реализации она существует, то это просто ведет к увеличению накладных расходов.
//-----------------------------------------------------------// Темплетный универсальный класс очереди. template <class Q> class TPQueue { private: QueueNode<Q> * BeginQ, * LastQ; // Счетчик объектов в очереди. long count; public: TPQueue(); ~TPQueue(); bool PutQueue(Q data); bool CheckQueue(); Q GetQueue(); bool ClearQueue(); long size() { return count; } };
В моем случае, пришла мысль о написании
//------------------------------------------------------------
очереди, что называется «без всяких затей».
template <class Q>
простого,
компактного
шаблона
односвязной
Листинг данного шаблона приводится ниже:
// Конструктор. TPQueue<Q> :: TPQueue() { BeginQ = 0;
/-------------------------------------------------------------
LastQ = 0;
#ifndef PQueueH
count = 0;
#define PQueueH
}
//-----------------------------------------------------------// Структура определяющая узел очереди.
//------------------------------------------------------------
template <class T>
// Деструктор - освобождаем очередь и память,
struct QueueNode {
// выделенную под объекты.
T data;
template <class Q> TPQueue<Q> :: ~TPQueue() { QueueNode<Q> * work;
* Комментарий автора.
Я могу привести еще много примеров подобного типа, но ни в коем
случае не отговариваю Вас от изучения и применения библиотеки STL.
Просто
при
использовании
следует
тщательно
изучить
реализацию библиотеки и обязательно протестировать фрагменты кода, где эта библиотека применяется.
АЛГОРИТМЫ
while(BeginQ) { work = BeginQ->next; delete BeginQ; BeginQ = work;
СОДЕРЖАНИЕ
29
ПРО
граммист
№10 (январь) 2011
ШАБЛОН КЛАССА ОДНОСВЯЗНОЙ ОЧЕРЕДИ В STL
}
}
BeginQ = 0; LastQ = 0;
//------------------------------------------------------------
count = 0;
// Очистить очередь.
}
template <class Q> bool TPQueue <Q> :: ClearQueue() {
//------------------------------------------------------------
QueueNode<Q> * link;
// Положить в очередь. template <class Q>
while(BeginQ) {
bool TPQueue <Q> :: PutQueue(Q data) {
link = BeginQ;
QueueNode<Q> * link = new QueueNode<Q>;
BeginQ = BeginQ->next; if(!BeginQ) LastQ = 0;
count++;
delete link;
if(!BeginQ) {
}
link->data = data;
count = 0;
BeginQ = link;
return true;
LastQ = link;
}
}
//------------------------------------------------------------
else {
#endif // PQueueH
link->data = data; LastQ->next = link; LastQ = LastQ->next; } return true; } //-----------------------------------------------------------// Проверить состояние очереди. template <class Q> bool TPQueue <Q> :: CheckQueue() { if(BeginQ) return true; else return false;
Посткриптум Текст листинга достаточно прост и не требует комментариев. Пример использует две очереди
(первая для типа int, вторая для AnsiString). Шаблон класса односвязной очереди содержится в файле < PQueue.h >.
Полные исходные тексты и компиляция проекта (файл
myFIFO.rar)
непосредственно в журнале.
}
Ресурсы
//------------------------------------------------------------
•
// Изъять из очереди. template <class Q> Q TPQueue <Q> :: GetQueue() { QueueNode<Q> * link; Q p;
приложены
•
Пример
использования
к
статье
шаблона
класса
односвязной очереди http://movila.site11.com/ attachments/015_myFIFO.rar
Компилятор Builder C++ 6 http://www.brothersoft.com/borland-c++-builder-118249.html
if(BeginQ) { count--; link = BeginQ; BeginQ = BeginQ->next; if(!BeginQ) LastQ = 0; p = link->data; delete link; return p; } else return 0;
АЛГОРИТМЫ
СОДЕРЖАНИЕ
30
ПРО
граммист
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
Всем доброго. В прошлой статье я описал как охладить в холодильнике квас, пока пишется ядро компилятора. Помните? Нет?! Странно... Впрочем, это не проблема. Наши журналы хранятся по адресу [1], так что освежить память – не проблема. Поскольку ядро, генерирующее PE файл готово (по минимуму, но готово) и его можно использовать для генерации исполняемого файла, то теперь вполне можно подумать более глобально (в общем, углубиться дальше в лес). Вообще, некоторым может понравиться писать прямо в опкодах, да еще в собственном компиляторе – это интересно и познавательно. Придется перелопатить кучу литературы, которая направит на путь над пропастью по тонкой нити, потому как опкоды не позволяют сосредоточиться на стратегических задачах, постоянно отвлекая на тактические мелочи: то учесть адрес переменной, то работа со стеком. Уже сама операция 2+2 подразумевает, как минимум: положить в переменную число, прибавить к ней второе число. Это две операции, плюс ко всему нужно еще знать адрес переменной. Конечно не абсолютный, а относительный, но при наличии, скажем сотни, переменных хранить в голове все их адреса – достаточно круто. К этому нужно привыкнуть... Виталий Белик
на
by Stilet http://www.programmersforum.ru
прием
информации
упростить себе жизнь…
Или переменная локальная – она лежит в стеке,
о
том,
как
можно
Good morning, Joаn
а потом же не забыть этот стек очистить от
Итак, давайте еще раз посмотрим, что
опкодах
свои программы на своем языке было проще. Мы
мусора – еще одна операция. Не получиться в записать
выражение
(2+2)*18/(32+sin(pi/3.4)) в одну строку вот так просто.
Придеться
думать
о
том,
какой
приоритет, какому оператору задать. Каждый оператор
имеет
свою
тут
еще
с
FPU
имеем, и что нам нужно для того, чтобы писать имеем
открытый
поток
серьезнее работать
–
Нам
строку,
нужно
программу
процедуру,
придеться
что
написать
(класс,
функцию...
удобнее),
будет
выражения,
сопроцессора
которая
переводить вроде
описанного
число, получить из него
выше,
операционные
синус, и выдернуть из стека в переменную
–
данные, с которыми эти коды будут работать.
командами: поместить в стек
байт
представляющую собой операционные коды и
команду, а если брать
«синус»,
мы
в
коды,
учитывая при этом все
–
зарезервированные
это уже три операции
как минимум. В общем, люди, которые по натуре
слова в выражении.
своей ленивы, естественно желают разгрузить
Что такое зарезервированное* слово? Зададим
Поэтому
которая должна говорить компилятору о том, что
себя, переложив рутинные операции на машину. высокоуровневые
языки
программирования всегда снабжаются модулями разбора и анализа написанного кода на более
понятном и близком к человеку языке. Машинето все равно: разбор текста – тоже вычисления, а уж
она
человека, важная
это
да
умеет еще
задача
–
делать
и
гораздо
надежнее.
разработка
быстрее
Следующая
механизма
трансляции исходного кода в операционный код. Именно этим и займемся в этой части. Так что, устраивайтесь поудобнее и включайте свой разум
ЛАБОРАТОРИЯ
этот вопрос Википедии [2]. Это часть языка, в операции участвует некий объект. Функция, представляющая собой вызов некого блока кода, и возвращающая результат, интерпретируемый вместо ее имени, и участвующий в дальнейших
операциях. Переменная, представляющая собой * Справка.
Зарезервированное программирования
слово
слово,
(или
ключевое
имеющее
слово)
–
специальное
http://ru.wikipedia.org/wiki/Язык_программирования
в
языках
значение
СОДЕРЖАНИЕ
31
ПРО
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
граммист
область памяти, которой человек дал имя. Как,
данный момент я говорю о байтовых операциях.
себе, если бы их не было, а вместо этого был бы
Хорошо, договорились: зарезервированное слово
скажем, названия улиц в городе. Представьте просто номер – удобно ли это было бы?
И, конечно же, нужно не забыть о константах. Вообще, константа в программировании – это способ адресации к данным, изменение которых запрещено,
предполагает значения
но
в
в
целом
нахождение
памяти
в
это
том
определение
же
константного месте,
где
располагаются и обычные переменные. Однако константой с таким же успехом можно считать
часть операции, одним из операндов команды. Например,
ассемблерная
команда
сложения
значения в регистре-аккумуляторе: ADD EAX, 6. Здесь 6 – это константа, но расположена она не в
секции данных, а непосредственно в команде. Это
тоже
нужно
учесть.
Никто
не
мешает
хранить это число в секции данных вместе с
другими, и это не будет ошибкой. Программа так же сложит и получится такой же результат, но это не оптимально. Зачем напрягать компьютер
лезть в память за каким-то числом, если это число
можно
прямо
командой
загрузить
в
процессор, уже не говоря о том, что размер такой команды будет меньше. Вот взгляните на
рисунок 1. Видите, что Оля показывает (Оля – это Olly
Debuger,
которая
будет
нам
помогать
анализировать сгенерированный код)? Команда
работы с ячейкой памяти занимает 6 байт, в то
время как команда с константой всего лишь 3. Это не только выглядит более логичным, но и занимает меньше места в памяти. Причем в
–
это
имя
переменной,
имя
функции,
имя
оператора, операции. Теперь нужно подумать о самом языке**. Из каких слов и конструкций он
будет состоять? Какие ключевые слова нужно заранее прописать в компиляторе?
Вот и я опишу семантику, так как я представляю
ее на самом простом уровне. Имеется в виду правила,
похожие
на
язык
ЛИСП.
Почему
именно ЛИСП? Его операции атомарны. Каждая операция внутри
предполагает
выражения,
а
не
смесь
набор
операторов
огражденных
блоками операций с параметрами, при чем эти операции могут быть сколь угодно вложены друг
в друга, и совершенно не помешают написать
достаточно сложное выражение. Таким образом, ** Комментарий автора.
Вообще языков и их разновидностей много. Очень много. Каждый
автор языка выбирает свою семантику, исходя из своих знаний, предпочтений. Например, кому-то
будет удобнее исходить из
правила, когда операторы и действия находятся между операндами. Общепринятый вид выражения в математике, и потому во многих
языках. Автор такого языка представляет, как написать механизм разбора текста кода эффективно. Но это не значит, что все должны
так поступать. Например, мне и представить не просто как вышеприведенную формулу разобрать. Если повозиться, то вполне
можно написать такой транслятор, но зачем, если можно выбрать удобный для себя путь. Так поступают при написании любой программы – программист, если ему не дали жесткое ТЗ, в котором описаны
четкие
механизмы
наиболее удобный путь.
реализации,
выбирает
для
себя
Рис. 1. Разница в командах
ЛАБОРАТОРИЯ
СОДЕРЖАНИЕ
32
ПРО
граммист
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
каждая операция будет окружена символамиограничителями операции, внутри которых будут между
операнд
разделителями –
сама
операнды.
команда.
Первый
В
качестве
ограничителей предлагаю взять круглые скобки, а в качестве разделителей операндов символы пробела и разделитель строки. Так
выражение
следующий вид:
описанное
выше
приобретет
Property Text:string read FText write SetText; // Свойство, позволяющее получать из массива операнд по номеру // Соответственно нулевой операнд - это операция // Свойство это я предлагаю по умолч., так будет удобнее // обращаться к параметрам объекта сканера Property Item[i:integer]:string read GetItem; default; // Функция возвращающая последний индекс в массиве операндов // Предназначена для циклов типа FOR. Я лично не люблю писать
(/ (* (+ 2 2) 18) (+ 32 (sin (/ pi 3.4))) )
// Count-1. Хотя никому не мешает не использовать эту функцию
Запутанно и непривычно немного. Правда? Да, те кто работал только с Си, Паскалем, Бейсиком
скажут: «Фу-у-у... Ну и где здесь удобства?». Отвечу.
// рассматриваемой как исходный код
Во-первых,
армада
специалистов,
пишущих на ЛИСП наберет достаточно много
Function High:Integer; Constructor Create; Destructor Free; end;
аргументов «За» и поймут меня. Во-вторых, не
Немного свойств. Ну, нам-то и нужно разорвать
запомнить
вложенными
так уж и сложно понять такую структуру, если и
разобрать
такую
структуру,
поскольку каждое ключевое слово находится
строго на своем месте. Операция на первом, операнды через пробел на остальных, и одна операция правило
окружена
не
сложно
круглыми
скобками.
объяснить
Это
компилятору.
Всего лишь, пройтись по строке от первой «(» до последней «)», учитывая вложенные скобочки. А
код
на
операнды.
Причем,
выражениями,
в
случае
с
соответствующий
операнд будет представлять такой же текст кода, который
образом,
тоже
нужно
рекурсивно
будет
парсить.
вызывая
Таким
функцию,
запускающую парсинг, передавая ей операнд, содержащий операцию можно пробежаться по дереву вложенных операций.
потом в цикле перебрать разделенное со второго
Теперь
итерации операцию по ключевому слову в первой
разделителя операндов считается пробел (по
по последний операнд. И применить к каждой позиции. Так.
С
семантикой
выражений
более-менее
понятно. Ну что, попробуем описать парсер, разбирающий
такое
выражение?
Тогда
предлагаю выделить этот механизм в особый
класс. Ему будет передаваться текст, а тот будет разбирать его по блокам:
// Класс, отвечающий за разбор выражений TAlisaScaner=class private // Массив операндов. Нулевой операнд - это операция Param:TStringList; FText: string; function GetItem(i: integer): string; procedure SetText(const Value: string); public // Свойство, которому будет идти присвоение строки,
ЛАБОРАТОРИЯ
дело
за
реализацией.
Сразу
хочу
оговорить один момент. Поскольку символом крайней
мере,
у
нас),
нам
придется
что-то
придумать для операндов-строк. Ведь в них могут быть
пробелы.
Как
строки
устроены
в
популярных ЯВУ? Строка – это набор символов, ограниченных
специальным
образом.
В
Си
символы ограничители*** – двойные кавычки:
“Это
строка
в
Си”.
В
Паскале
кавычки
одинарные, а например, в MySQL особый вид
кавычек:`. Честно даже не знаю, как этот символ называется. Поэтому нам придется пропускать пробелы или, поясню точнее, приписывать их операнду, не считаясь с
разделителями, если
встретится
символ
ограничитель
пробелов
непосредственно
строк,
при
условии, что его еще не было. И включить учет после
встречи
второго такого же символа, отделив полученное
между символами в операнд. Интересно кстатито, что обычно открытая строка в параметрах функций
или
выражениях
может
называться
константой. Ее тело, конечно, не может быть
СОДЕРЖАНИЕ
33
ПРО
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
граммист
*** Комментарий автора.
Да кстати, поднимите руки, кто сталкивался с проблемой, когда
нужно в строке использовать символ-ограничитель этой строки? Оо... Сколько рук. Ну, неудивительно. В Паскале очень неудобно в этом
плане,
одинарные
поскольку
кавычки
-
приходится
’’’,
либо
либо
писать
использовать
подряд
функцию
три
chr(),
передавая ей код кавычки, который, кстати, не всегда вспомнить удается. Не всегда это смотрится читабельно.
частью
слишком
операционного длинно
например),
кода
(может
поэтому
ей,
быть
2
оно
Гигабайта,
любом
случае,
отводится участок памяти (как правило, это местечко в секции данных или ресурсов), а уж в
самом опкоде участвует адрес на первый символ (байт) строки. В случае с юникодом, символ придется
трактовать
как
два
процессору «это до лампочки».
байта,
хотя
Си тоже не далеко ушел. Там перед символом
ставится «\», дабы компилятор не учитывал его как разделитель. Это все не сильно мешает, но все же не смотрится красиво. По-другому дела обстоят в Обероне, ПХП, Перле. Здесь я могу запросто
использовать
ограничителей
строк.
При
:integer; // Вспомогательные переменные, принимающие входной код // и распарсенные операнды // после того как очередной операнд получен // он поступает в список
процессора,
в
// дистигнута последняя закрывающая скобка
несколько этом,
видов
остальные
ограничители, входящие в строку, но не похожие
на первый ограничитель, будут считаться как
v,s:string; // Эти переменные необходимы для того, чтобы парсер, попав на // начало строки, не растерялся, а получив первый символ // ограничитель строки из указанных нами начал считать все // символы до следующего такого же как контент строки bs:char; BracketsOfString:boolean; begin // Итак. Получаем код, не забыв заменить все переносы // каретки на пробелы, а так же отрезаем граничные пробелы, // чтоб не мешали v:=trim(StringReplace(value,#13#10,' ',[rfreplaceall])); // Учтем что в начале кода есть первая открывающая скобка BracketsCount:=0; // Чтоб она не мешала циклу удаляем ее if v[1]='(' then delete(v,1,1);
символы строки.
// И закрывающую тоже, ибо текст
Например “Это строка ‘в одинарных’ кавычках”.
// считаться атомарным кодом
Здесь ограничителем выступает первый из трех
возможных символов – “. С таким же успехом я
напишу: ‘Это строка “в двойных” кавычках’ и ограничителем
будет
считаться
одинарная
кавычка. Достаточно редко используются строки со смешанными кавычками, а тем более для
нашего простенького языка, не претендующего (пока еще) на широкий спектр решения задач.
Не утомил я с теорией? В любом случае пора переходить к телу парсера. Перейдем к коду, где опишем тело этого парсера:
procedure TAlisaScaner.SetText(const Value: string);
// поступающий на парсинг все равно будет if v[length(v)]=')' then delete(v,length(v),1); // Приведем в готовность список операндов Param.Clear;
s:='';
// Если парсить нечего то выйдем if v='' then exit; // Уберем лишние граничащие пробелы v:=trim(v); i:=1;
bs:=#0;
BracketsOfString:=false;
// И в цикле до конца текста while (i<=length(v)) do begin
var i, // Перемнная для цикла. Будем посимвольно проходить
// Поскольку мы сочли пробел(ы) символом разделения операндов
BracketsCount // Переменная, счит-я кол-во вложенных скобочек
// пройдемся циклом до следующего пробела
// Если появляется открывающая скобка переменная увеличивается
// или же до следующего символа ограничителя строки
// если скобка закрывающая - уменьшается
while (i<=length(v))and(v[i]<>' ')or
// Когда переменная достигнет 0 - парсить больше нечего, ибо
ЛАБОРАТОРИЯ
(BracketsCount>0)or BracketsOfString do begin
СОДЕРЖАНИЕ
34
ПРО
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
граммист
// Если появилась открывающая скобочка
begin
// учтем ее, увеличив количество.
// Свойство получения конкретного
// Таким образом показывая что операнд может быть выражением,
// операнда по списку. Если индекс не указывает на
//
// элемент списка, возвращается просто пустая строка
и нужно захватить
// весь его текст
if (i>=0)and(i<Param.Count) then
if v[i]='(' then inc(BracketsCount);
Result:=Param[i] else Result:=''; end;
// вплоть до его закрывающей скобки if v[i]=')' then dec(BracketsCount);
function TAlisaScaner.High: Integer; begin
// Если
появился символ ограничитель строки
// Этот метод не обязателен
// Перейдем в режим сканирования строки
// как я и говорил можно обойтись без него
if v[i] in ['''','"','`'] then begin
// Но мне влом писать в циклах с -1'ой
if bs=#0 then begin bs:=v[i];BracketsOfString:=true;end else
Result:=Param.Count-1;
if bs=v[i] then begin bs:=#0;BracketsOfString:=false;end;
end;
end;
Так-с... класс описан. В принципе его можно опробовать.
// Пересадим по символу в перем-ю, отделив очередной операнд
предыдущих
статьях
были
примеры кода, предполагалось, что все они будут
s:=s+v[i];inc(i);
находиться в одном модуле, соответственно и эти
end;
листинги нужно кинуть туда же (в приложениях
к статье я прикреплю действующий пример).
// После отделения поместим его в список
Кстати, если любопытный читатель уже успел
Param.Add(s);
скопипастить
s:='';
откомпилировать, компилятор
// После того как получили очередной операнд отбросим
отсутствие
// копыта пробелам, что могут быть после него
sysutils.
while (i<=length(v))and(v[i]=' ') do begin inc(i);end; end;
в
код
и
не
ругается.
разделе
мог И
попытался
не
заметить,
прежде
uses
всего
модулей
его
что на
classes,
Какой вывод? Не спешить! А если не терпится
end;
Что,
В
кода
много?
Да
нет,
просто
я
комментариями его обильно полил. На самом
деле тут все просто. И простота эта сказалась благодаря Остается
функциями:
семантике
дополнить
языка
(привет
класс
сервисными
constructor TAlisaScaner.Create; begin // Создадим экземпляр списка для операндов Param:=TStringList.Create; end; destructor TAlisaScaner.Free; begin // Освободим его Param.Free;Param:=nil; end; function TAlisaScaner.GetItem(i: integer): string;
ЛАБОРАТОРИЯ
ЛИСПу).
попробовать, привыкайте к тому, что у авторов
статей, книг... что вы там читаете... могу быть
другие условия работы. Например, частенько описанные в книгах приемы просто-напросто
заточены под конкретную версию компилятора, и на других не то что не сработают, а просто требуют мелких поправок «там-сям».
Ладно, оставим лирику. Для проверки предлагаю
сделать форму (нам же понадобится редактор для кода), на которой будет красоваться. Для
начала компонент TMemo. Для начала, потому что в дальнейшем, возможно, захочется разными
цветами подсвечивать ключевые слова, а в Мемо это не столь удобно. Но, пока хватит и Мемо.
Кстати, для красоты Мемо можно выровнять на всю
форму,
задав
свойству
Aling
значение
alClient. Далее кинем на форму TActionManager. Кликнув
по
нему
правой
клавишей
мышки,
создадим новую акцию. Для ее свойства ShortCut
СОДЕРЖАНИЕ
35
ПРО
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
граммист
поставим
клавишу
F9
–
эта
акция
будет
срабатывать по нажатию на F9, дабы запускать
delete(ss,1,1); sc.Free;
компилятор. Рядом же кинем ListBox, задав ему
end;
будем выводить то, что нам парсер выделит из
begin
Align как alBottom. Пусть лежит внизу. Туда мы
выражения. Это для проверки, чтобы убедится, что парсер работает как надо.
Не забудем «привинтить» поле этого класса (или переменную,
кому
как
больше
Например, как в следующем листинге:
нравится).
TForm1 = class(TForm) Memo1: TMemo; ActionManager1: TActionManager; Action1: TAction; ListBox1: TListBox; procedure Action1Execute(Sender: TObject); private sc:TAlisaScaner; { Private declarations } public { Public declarations } end;
Это стандартный набор для приложения, я не
ss:=' '; parse(Memo1.Lines.Text); end;
Здесь
для
каждого
отдельный
сканнер,
операнды,
и,
выражения
выражение
если
создается
парсится
очередной
на
операнд
представляет собой вложенное выражение, идет рекурсивный вызов этой процедуры, передавая ей
операнд.
вложений
И
так
(ну,
почти
не
будем
на
на
любое
компилятору стека хватит). Пока
что
компилятор.
До
него
любое,
вводить еще
количество насколько
в
рано.
игру
сам
Запустим
программу и впишем в Мемо наше выражение
(для удобства можно прямо в дизайне вписать его в свойство Lines, чтоб не вписывать каждый раз.
Нажмем
F9
–
сработает
наш
парсер,
разобрав выражения на части (см. рисунок 2):
буду его описывать. Исключение составляет поле
класса парсера. В событии OnExecute() этой акции напишем следующий код:
procedure TForm1.Action1Execute(Sender: TObject); procedure parse(Atext:String); var i:integer; sc:TAlisaScaner; begin sc:=TAlisaScaner.Create; ss:=ss+' '; // Заряжаем текст на парсинг sc.Text:=aText; // Оператор помести сразу пометив его как команду ListBox1.Items.Add(ss+'Начало оператора '+sc[0]); // Отработав это свойство сформирует список, который // поэлементно пройдем, обратившись к предусмотрительно // оформленному полю сканера по умолчанию в цикле for i:=1 to sc.High do begin
Рис. 2. Парсинг выражения
// Если попался оператор рекурсивно вызовем процедуру // передав ей операнд-оператор. Пусть распарсит if sc[i][1]='(' then parse(sc[i]) else
ListBox1.Items.Add(ss+sc[i]);
end; ListBox1.Items.Add(ss+'Конец оператора '+sc[0]);
ЛАБОРАТОРИЯ
Как
видно,
парсер
справился
с
задачей.
Выражение разобрано, разобрано правильно, все
операнды на своих местах по вложенности. И ведь так можно разобрать достаточно сложное
СОДЕРЖАНИЕ
36
ПРО
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
граммист
выражение. А нам, на все про все, хватило всего
пока
обработчик нажатия F9). Следует отметить, что
операции, не так будет много кода для них. Это
лишь строк около 50-ти (сам механизм парсера и ЛИСПовские
операторы
запрограммировать, сложность.
Это
операторов
достаточно
несмотря
потому
выделяет
на
что
сам
просто
кажущуюся
при
Заменим
наше
Тут
выражение
четыре
на
основных
выражение будет выглядеть по-нашему вот так:
приоритеты
программист
что.
(2*2)+16/(10-(20/4)).
(/ (+ 16 (* 2 2)) (- 10 (/ 20 4)) )
написании выражения. Интересно, а чего будет
Это выражение будет равно четырем. Учтем, что
операции находятся между операндами? Как в
опкодами
стоить написать парсер для выражения, где Си или в паскале. Вполне
возможно,
рассчитывать для
этого
что
операторы
еще
их
и
придется
высшего
их
сначала
приоритета,
операнды
нужно
вычленить из выражения, это притом, что стоять они могут где угодно... Мы обошлись одним
проходом – от начала строки в ее конец. Это радует простотой и скоростью разбора. А что
деление
будет
производиться
процессора,
и
стандартными операнды
целочисленные, а значит, результат операции
деления будет целое без остатка. Остаток пока что не будем учитывать. То есть, это будет
аналог 20 div 4 в паскале. Самое главное, что это выражение
достаточно
простое.
Здесь,
во-
первых, задействованы все четыре оператора, а во-вторых, деления***** получаются без остатка – сейчас это нам важно.
будет при разборе выражения вроде нашего
Теперь самая главная задача – выяснить на
специально заменил знак умножения в формуле
вправляет мозги как хождение по своим же
(2+2)+18/(32+sin(pi/3.4))? Обратите внимание, я
на «+», дабы усложнить ситуацию, ведь в этом
случае рассчитав 2+2, нельзя сразу к результату прибавлять
18.
Значит,
придется
либо
запоминать в некий стек эту 18, либо сначала
пройтись по оператору деления и вычислять не с начала, а с конца. Ладно, допустим. А как такое
выражение****: 5+2*(4-1/3)^2*36^3+28. Что тут
вычислять сначала? Явно не с конца. Сначала придется
вычислить
(4-1/3)^2,
потом
36^3.
Запомнить результаты вычисления где-то, а уж
потом умножение и сложения. Уверен, что строк кода такого парсера будет поболее, чем в нашем случае.
собственных граблям),
Сразу
предлагаю
для
простоты
убрать
вычисление синуса. Оперировать будем с целыми
Выражения
в
обычной,
не
польской
нотации
(то
есть
с
приоритетом операций), вычисляются аналогично – рекурсивно. И в первом случае, Вы также сохраняете данные в стеке, но на другом уровне (виде вложенных вызовов). Расходование памяти
(под данные) примерно одинаково. Однако «лисповая» арифметика в реализации проще.
ЛАБОРАТОРИЯ
будет
эти
ничего
стоить
простейшие
так
не
механизм,
операторы.
работы с другими операторами, увидев какую методику
проще
будет
использовать.
Далее,
операндами.
Кроме
парсер, разбирая выражение, дает возможность оперировать того,
у
нас
отдельными несколько
операций.
описать примерно следующую схему: •
Попробуем
после разбора выражения в цикле пройтись по
выражению,
эта
процедура
передав
некой
процедуре
(назовем ее kernel) очередной операнд; должна
будет
определить,
операндом,
и
вызвать
какова операция должна быть проведена над данным
соответствующий код, который можно для •
числами, размера DWord, Этого вполне хватит **** Комментарий редакции.
(ибо
Именно отсюда можно будет развить стратегию
Теперь можно попробовать скомпилировать это
выражение в опкоды, и запихнуть в РЕ файл.
чего
использующий
•
Pull the trigger to start
ошибках
удобства выделить в отдельную процедурку;
эта отдельная процедурка будет заниматься конкретным действием.
операндом
и
конкретным
Получается, что нам нужно пять процедур – четыре действия и их менеджер. Прекрасненько. Начнем с того, что опишем kernel – процедуру посредник между циклом, который проходится по
разпарсенным
непосредственного
операндам
и
транслирования
Она может выглядеть так:
процедурой в
опкоды.
СОДЕРЖАНИЕ
37
ПРО
граммист
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
// разобранного procedure kernel(
(и поскольку тут рекурсия
// скомпилированного) выражения
NumOfOperand:integer; fromStack:boolean
// Номер операнда по счету
kernel(i,true);
// Указание, что работать нужно с
// Незабыть убрать в стеке после себя мусор.
// результатом вложенного выражения
// Все что посчитанно должно хранится в аккумуляторе EAX
);
cdata:=cdata+#$83#$C4#$04;// ADD
var o:integer;
ESP, 4
end else begin
begin
// Если же этот операнд - константа
// получение значения по номеру операнда из выражения
// то передать указания работать с ней
// Если идет работа с вложенным выражением его значение
kernel(i,false);
// предполагается либо в стеке либо в регистре-аккумуляторе if not fromStack then
o:=StrToInt(sc[NumOfOperand])
//**********************************************************
else o:=0;
ListBox1.Items.Add(ss+sc[i]); end;
// вызов процедур-трансляторов согласно операции
end;
// и передача им информации
ListBox1.Items.Add(ss+'Конец оператора '+sc[0]);
if sc[0]='+' then plus(o,NumOfOperand,fromStack);
delete(ss,1,1);
if sc[0]='-' then minus(o,NumOfOperand,fromStack);
sc.Free;
if sc[0]='*' then mul(o,NumOfOperand,fromStack);
end;
if sc[0]='/' then div_(o,NumOfOperand,fromStack);
Я
end;
Думаю
здесь
понятно
–
эта
процедура
распределяет по операциям операнды. Вызов ее
нужно «прикрутить» непосредственно в цикл, пробегающий
по
элементам
выражения
предыдущем листинге следующим образом:
в
begin
отделил
изменения
специально,
чтобы
показать, где они могут стоять в нашем случае. Теперь
остается
описать
трансляторы:
сами
процедуры-
//***** Сложение ********************************* procedure plus(Operand,num:integer;fromStack:boolean); begin if not fromStack then begin
sc:=TAlisaScaner.Create;
// Если работа идет с операндом-константой
ss:=ss+' ';
// Если это первый операнд, то подготовим регистр, кинув в
// Заряжаем текст на парсинг
// негo первый операнд
sc.Text:=aText;
if num=1 then cdata:=cdata+#$B8+DWordToStr(Operand)
// Оператор помести сразу пометив его как команду
else // Иначе прибавим к
ListBox1.Items.Add(ss+'Начало оператора '+sc[0]);
регистру очередной операнд
cdata:=cdata+#$05+DWordToStr(Operand);
// Отработав это св-во сформирует список, который поэлементно
end else
// пройдем, обратившись к предусмотрительно
// Если же работа должна идти с уже посчитанным результатом
// оформленному полю сканера по умолчанию в цикле
// то нужно прибавить его значение из стека
for i:=1 to sc.High do begin
cdata:=cdata+#$03#$04#$24;
// Если попался оператор рекурсивно вызовем процедуру // передав ей операнд-оператор. Пусть распарсит if sc[i][1]='(' then begin //********************************************************* // Если обнаружено вложенное выражение // запомнить предидущий результат в стеке cdata:=cdata+#$50;// PUSH
EAX
// Разобрать подвыражение parse(sc[i]); // и передать управление процедуре-распределителю // указав что работать нужно не с константой а с результатом
ЛАБОРАТОРИЯ
//ADD
EAX, DWORD PTR SS:[ESP]
end;
Тут все просто и понятно. Вообще процедура сложения
достаточно
транслирования. приходится,
Ее
потому,
***** Комментарий редакции. Дополнительно
арифметические
о
делении.
операции
в
двояко как
от
Стоит
Лиспе
неограниченное число параметров.
удобна
трактовать
не
перестановки
отметить,
имеют
для
право
что
все
содержать
В том числе и деление. В
таком случае подразумевается деление первого операнда на все остальные.
СОДЕРЖАНИЕ
38
ПРО
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
граммист
слагаемых
сумма-то
не
процедура вычитания:
меняется.
Теперь
//***** умножение ********************************* procedure mul(Operand,num:integer;fromStack:boolean); begin
//***** Вычитание *********************************
if not fromStack then begin
procedure minus(Operand,num:integer;fromStack:boolean);
if num=1 then
begin
// Если это первый операнд положим его в аккумулятор
if not fromStack then begin
cdata:=cdata+#$B8+DWordToStr(Operand)
if num=1 then
else begin
// Если это первый операнд положим его в регистр-аккумулятор
// иначе умножим. При этом нам придется задействовать
cdata:=cdata+#$B8+DWordToStr(Operand)
// дополнительный регистр потому как операция умножения
else
// и кстати деления не допускает указания в качестве
// иначе отнимем константу от значения в регистре
// операнда константу.
cdata:=cdata+#$2D+DWordToStr(Operand);
// Ну выберем регистр DX.
end else begin
cdata:=cdata+#$BA+DWordToStr(Operand); //MOV cdata:=cdata+#$F7#$E2; //MUL
// Если же это работа с результатом выражения
EDX, ...
ЕDХ
end;
// Придется вычитать значение от результата в стеке
end else begin
// А уж потом вложить полученное в аккумулятор
// Если же работать нужно с результатом подвыражения
cdata:=cdata+#$29#$04#$24; //SUB
DWORD PTR SS:[ESP], EAX
// умножим результат из стека на значение в аккумуляторе
cdata:=cdata+#$8B#$04#$24; //MOV
EAX, DWORD PTR SS:[ESP]
cdata:=cdata+#$F7#$24#$24; //MUL
end;
end;
end;
end;
Здесь
уже
четко
просматриваются
отличия.
Результат операции вычитания зависит от того, как расположены его операнды – это важно. Значит можно сделать вывод – на самом деле
трансляцию каждой операции стоит оформлять отдельно,
не
смешивая
в
кучу.
Можно,
безусловно, написать одну процедуру, которая в зависимости
от
нужный
опкод
операции
будет
в
проводить
результирующую
//***** деление ********************************* procedure div_(Operand,num:integer;fromStack:boolean); begin if num=1 then begin if not fromStack then // Если это первый операнд положим его в аккумулятор cdata:=cdata+#$B8+DWordToStr(Operand) end else begin if not fromStack then begin
последовательность для экзешника, но это будет нормально
при
четырех,
десяти
// иначе задействовав дополнительный регистр
простейших
// перемножим константу на значение в аккумуляторе
операциях, а если захочется дальше развить компилятор?
Такая
универсальная
cdata:=cdata+#$BB+DWordToStr(Operand); //MOV
процедура,
cdata:=cdata+#$F7#$F3; //DIV
скорее всего, разрастется в «мегазапутанный» а
даже
как
любят
// подвыражения придется делить на значение из стека.
выражаться
// предварительно не забыв поменять местами
программисты «гххх-код», то есть запутанный, неоптимальный,
бессмысленными
зачастую
операциями,
// поскольку операция деления как и вычитания тоже строга
наполненный
код.
// к положениям операндов
Любого
хакера будет рвать вдоль и поперек при виде такого
монстра.
Поэтому,
несмотря
на
кажущуюся выгодную позицию – упихнуть все в процедуру,
предлагаю
этого
не
делать.
Пусть каждая процедура, а еще лучше каждый
EВX
// Если же работа предстоит с уже посчитанным значением
навевать ужас. Тут не то что обфускация может получиться,
EВX, ...
end else begin
код, который потом на самого автора будет
одну
WORD PTR SS:[ESP]
cdata:=cdata+#$87#$04#$24; //XCHG
DWORD PTR SS:[ESP], EAX
cdata:=cdata+#$F7#$34#$24; //DIV
DWORD PTR SS:[ESP]
end; end; end;
класс, занимается своим и только своим делом.
Здесь тоже наметились грабли. С умножением
Далее следуют процедуры умножения и деления:
сложности на горизонте. Во-первых, физиология
ЛАБОРАТОРИЯ
еще
кое-как
нормально,
а
вот
с
делением
СОДЕРЖАНИЕ
39
ПРО
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
граммист
деления достаточно непроста, если заглянуть в
Хорошо, что у нас уже наготове РЕ генератор:
разного, м-м-м, размера чисел, задействуются
заморачиваясь о том, как устроен РЕ, и какие
мануалы.
В
них
сказано,
что
для
деления
разные механизмы. При делении на двойное слово,
как
часть
от
раз
наш
случай,
задействуются
регистры EDX (остаток от деления) и EAX (целая деления),
так
что,
если
EDX
предполагается задействовать для чего-либо, его предварительно стоит сохранить в стек. Пока не
будем на этом останавливаться, потому как при
делении на результат из стека его придется либо выбирать в регистр, скажем, тот же EBX, либо
делить на SS:[ESP+4]. Но все равно, на будущее, стоит это учесть.
как
просто
передать
ему
контент,
не
пертурбации в нем будут происходить. Кстати, этот код можно подкинуть в обработчик клика по кнопке, элемента меню... Да куда угодно, в целом.
Я
предлагаю
разместить
его
в
выше
в
обработчике нажатия клавиши F9, для чего и использовал
TActionManager.
Вот
процедуру TForm1.Action1Execute(), его и стоит вставить.
запустим
Если
все
программу,
сделано
введем
нажмем на F9 (см. рисунок 3):
правильно,
выражение
то и
А так, в целом, для работы с константами и вложенными выражениями этого должно вполне хватить. Предлагаю попробовать в действии. Для
этого «прикрутим» к проекту переменную типа TAlisaCompiler3. В прошлой статье я описал этот класс для генерации РЕ файла. В его поле
открытым тестом, для чего в листингах служит переменная cdata, описанная как String, будем передавать
отранслированный
операционный
код, и записывать скомпилированный с этим кодом
контент
выглядеть:
в
файл.
Вот
как
это
будет
var comp:TAlisaCompiler3;f:file of byte; begin // На всякий случай сохраним наш исходный код Memo1.Lines.SaveToFile(ExtractFilePath(ParamStr(0))+ 'file.source'); ss:=' ';
cdata:='';
// Переведем исходний код в операционный parse(Memo1.Lines.Text); // который будет передан обьекту-компилятору comp:=TAlisaCompiler3.Create; comp._Code._Data:=cdata; // и скомпилирован cdata:=comp.Compile; // после чего контент РЕ пойдет в пункт назначения AssignFile(f,'file.exe');rewrite(f); BlockWrite(f,cdata[1],length(cdata)); CloseFile(f); comp.Free; end;
ЛАБОРАТОРИЯ
Рис. 3. Редактор исходного кода Как все было, так и осталось. Единственное, что в папке с программой появится исполняемый файл с скомпилированным выражением. Давайте
посмотрим на него сквозь микроскоп отладчика (см. рисунок 4). Что-то записало... Если пройтись пошагово (F8 выражение,
в Оле), то можно увидеть как
оживая,
результирующего
дает
числа,
плоды для
в
виде
каждого
вложенного выражения, и для всего целиком. В
аккумуляторе в результате появляется заветная
4, что говорит о том, что выражение правильно посчитано. Это радует. А давайте попробуем
теперь проверить на другом выражении. Скажем, на вот таком:
1+3+5+(8-10)+(10/2)+(3*(8+2))
Вводим в редактор выражение «по-ЛИСПовски»:
(+ 1 3 5 (- 8 10) (/ 10 2) (* 3 (+ 8 2))). Жмем F9,
СОДЕРЖАНИЕ
40
ПРО
граммист
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
Рис. 4. Скомпилированное выражение открываем отладчик, проходимся по шагам и...
системе,
Видите внизу посказку Оли: «Integer overflow»?
затрагивает
жестоко****** «обламываемся» (см. рисунок 5). Так, теперь будем думать (предположим, что ассемблер
максимум)
мы
знаем...
почему
Проанализируем
ну
на
это
ситуацию
троечку
–
как
произошло. Деление.
Задействовано три регистра: EAX – туда будет помещено частное, EDX – для остатка, EBX – сам
операнд. Логика подсказывает, что копать нужно в сторону особенностей работы деления не с
исходными, а с получаемыми значениями. Как происходит сам механизм деления? Div делит
число из EBX (это 2 – посмотрите на рисунок 5) на число из пары регистров EAX:EDX. В ЕАХ
записано «А», что равно 10-ти в десятичной ****** Комментарий автора.
а
в
EDX
записан
какой-то
адрес.
Механизм деления, если делится двойное слово, должны
оба
этих
быть
проинициализированы
регистров
и
оба
они
предварительно
делимым,
но
делимое
наше не велико, и вполне умещается в АХ (или
даже в AL), MOV EAX, A0 занимает под двадцатку
весь регистр, все 32 бита. А что же происходит с EDX? А ничего. Мы забыли о нем, в нем остался
мусор после действия некой функции (какой-то
там, сейчас не важно), но команда деления, учитывая его, воспринимает его содержимое как число, участвующее в делении – старшую часть числа
из
ЕАХ,
2089878024.
а
Итого,
там
7C910208,
получается
2
что
равно
делим
на
20898780240000000020... Так что ли? О, ужас! Вот оно переполнение. О чем нам это говорит?
Кто сказал, что в статьях все описывается гладко и красиво?
1. Нужно обнулять EDX перед делением, ну или
в примерах. Хм... Первый блин. Хорошо, что всплыл сейчас. Лучше
нибудь.
Чепуха, о багах нужно писать, акцентируя на них особое внимание поздно, чем никогда.
ЛАБОРАТОРИЯ
если это важно запоминать его значение где2. Бегом читать умные книги по ассемблеру.
СОДЕРЖАНИЕ
41
ПРО
граммист
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
Рис. 5. Грабли Программу подкорректировать несложно: //***** деление *********************************
cdata:=cdata+#$87#$04#$24; //XCHG
DWORD PTR SS:[ESP], EAX
cdata:=cdata+#$33#$D2;
EDX, EDX
//XOR
cdata:=cdata+#$F7#$34#$24; //DIV
procedure div_(Operand,num:integer;fromStack:boolean);
WORD PTR SS:[ESP]
end;
begin
end;
if num=1 then begin
end;
if not fromStack then // Если это первый операнд положим его в аккумулятор cdata:=cdata+#$B8+DWordToStr(Operand)
// иначе задействовав дополнительный регистр // перемножим константу на значение в аккумуляторе EDX, EDX
cdata:=cdata+#$F7#$F3; //DIV
EBX
EBX, ...
end else begin // Если же работа предстоит с уже посчитанным значением // подвыражения придется делить на значение из стека. // предварительно не забыв поменять местами // поскольку операция деления как и вычитания тоже строга // к положениям операндов
ЛАБОРАТОРИЯ
проверим
на
деле
(см.
рисунок 6). Во. Теперь порядок 42 (2А в ЕАХ) – нужно.
if not fromStack then begin
cdata:=cdata+#$33#$D2; //XOR
Ну-ка,
тот самый результат выражения. Как раз то, что
end else begin
cdata:=cdata+#$BB+DWordToStr(Operand); //MOV
Исправили?
Post Scriptum Ну вот. Теперь можно спокойно фантазировать, придумывая самые замысловатые выражения с
многочисленными вложенными выражениями – эту возможность дарит нам рекурсия. Одно жаль –
не
удастся
малой
кровью
написать
универсальную процедуру, которая бы вмещала в
себя все операторы. У каждого оператора свои
особенности, и их все желательно... то есть, нет...
СОДЕРЖАНИЕ
42
ПРО
граммист
КОМПИЛЯТОР ДОМАШНЕГО ПРИГОТОВЛЕНИЯ. ЧАСТЬ 3
№10 (январь) 2011
Рис. 6. Исправленный баг не желательно, а просто необходимо учитывать.
унаследовать классы, обработчики операторов от
имею ввиду встроенные в язык операторы –
цикл, в котором будут вызываться стандартные
Именно поэтому стоит для каждого оператора (я
ключевые слова) описать свой отдельный класс. Дабы он занимался только им и никем более. Единственное,
что
более-менее
может
быть
общего у всех этих классов – цикл, проходящий
по операндам, передающий их классу. Это да. Опять-таки в этом цикле можно предусмотреть возможность определения типов операндов, если операнд-функция
–
вызова
этой
функции,
и
последующей работы с ее результатом, если это
переменная – определение ее типа, приведение к единому типу – типу выражения. Поправьте
меня,
по-моему,
умными
людьми
принято проводить тип по первому операнду.
одного родителя, в котором и будет заряжен этот методы для этих классов. Их там много не будет: метод обработки при константе-операнде, метод обработки, если операнд – переменная, метод
обработки при операнде-функции и метод при операнде-выражении. Для старта, по крайней мере,
хватит
с
головой.
Можно
конечно
описывать все процедурами, как выше, но мы то живем в век ООП. Поэтому в следующей части я
покажу свое видение все этой жуткой схемы с классами-обработчиками
операторов.
А
на
сегодня, все. Всем доброго времени суток, где бы вы ни находились. The Чтиво
Вполне можно взять и это на вооружение, и это
•
Официальный сайт журнала «ПРОграммист»
механизм
•
Ресурс Викпедии http://ru.wikipedia.org/wiki/
(думается
мне)
для
операторами.
А
тоже
всех
ЛАБОРАТОРИЯ
может
иметь
единый
стало
быть,
можно
классов,
так,
занимающихся
http://procoder.info
Зарезервированное_слово
СОДЕРЖАНИЕ
43
ПРО
ШИФРОВКА ПАРОЛЕМ. УЛУЧШАЕМ АЛГОРИТМ
№10 (январь) 2011
граммист
Доброго времени суток. Если не все читали мою предыдущую статью «Шифруем файл с помощью пароля» [1], то рекомендую ознакомиться перед прочтением данного материала. В ней я описал методику шифрования файлов с помощью пароля. Это, конечно, довольно-таки простая методика. В этой же статье, я расскажу про более сложную методику шифрования с помощью пароля. Итак, приступим… Руслан Аблязов
Довольно-таки
by rpy3uH http://www.programmersforum.ru
если
в файле будет некоторая последовательность
одинаковых байт. После шифрования будет видно
повторение одной и той же последовательности, которая имеет длину равную длине пароля. Будет видно, на сколько отличаются символы в пароле (например, второй символ на 3 «больше», чем
первый, третий на 20 «меньше», чем второй и так После
этого,
нам
только
этому
правилу,
правило. мы
Но,
получим
исходный пароль после N*(N-1) модификаций.
В чем уязвимость старого алгоритма? Допустим,
далее).
следовать
незамысловатое
останется
перебрать все 256 вариантов пароля, и, в итоге,
Если использовать пароль длиной 8 символов (средняя
длина
пароля),
то
количество
модификаций будет равно 56-ти. Подобрать слово такой же длины, у которого все 56 модификаций имеют такую же CRC32, почти невозможно. Если
длина файла не кратна четырем, то остаток (1, 2 или 3 байта), «ксорится» побайтово с CRC32 текущей модификации пароля. Практические занятия
файл будет расшифрован в считанные минуты.
Теория
файле
«данными»
шифровать некоторую область данных в памяти с
чистом
виде.
Отсюда вывод: не надо обрабатывать данные в шифровании
не
надо
пароля,
Один
то
использовать
из
есть
множества
при
пароль
в
выходов
заключается в том, что бы использовать при
шифровании некую контрольную сумму пароля. В
качестве
использовать урезанный
контрольной
CRC32
пароля.
вариант
«хеша»,
суммы
CRC32
который
будем
–
это
имеет
размер не 16 байт, а 4 байта. Следовательно, шаг
закончилась,
Сначала
напишем
FASM).
Тем,
(это
обратную только
логическую
мое
мнение,
возможно, она мне понравилась из-за того, что для нее не надо писать дешифратор, поскольку шифратор
также
является
дешифратором).
Использовать одну и ту CRC32 слишком просто, потому что можно подобрать такое слово, у
которого CRC32 будет такой же что и у пароля. Поэтому надо будет видоизменять пароль после
очередной операции XOR. У видоизмененного пароля CRC32 будет уже совсем другим. Правило изменения пароля будет таким: • •
текущее смещение в файле делится 4, и
делится на длину пароля – 1, остаток от деления будет числом K; символ
в
пароле,
который
находится
позиции K, перемещается в конец пароля.
АРХИВ
на
будет
кому
это
не
интересно,
могут
некоторого блока: GET_CRC32:
; EDI = block size
взаимно
которая
пропустить эту часть. Функция получения CRC32
использовать
XOR
практике.
включу в DLL-ку (будет использован компилятор
; IN>
операцию
функцию,
к
помощью пароля. Я реализую ее на ассемблере и
у нас будет на 1 байт как в прошлом случае, а 4
байта. Вместо прибавления/убавления, по-моему,
приступим
; ESI = block offset ; OUT ; EAX = CRC32 push esi push edi push ecx push ebx push edx cld xor ecx,ecx dec ecx mov edx,ecx .NextByteCRC: xor eax,eax xor ebx,ebx lodsb
СОДЕРЖАНИЕ
44
ПРО
граммист
№10 (январь) 2011
ШИФРОВКА ПАРОЛЕМ. УЛУЧШАЕМ АЛГОРИТМ
xor al,cl
loop .next
mov cl,ch
mov [esi], bh
mov ch,dl mov dl,dh
popad
mov dh,8
ret
.NextBitCRC:
Идем далее. Теперь сама функция:
shr bx,1 rcr ax,1 jnc .NoCRC
proc CSCA1 DataAddress, DataSize, Password
xor ax,08320h
; DataAddress – data offset
xor bx,0EDB8h
; DataSize – data size
.NoCRC:
; Password – offset ZS of password
dec dh
local PasswordCp:DWORD
jnz .NextBitCRC
local PasswordLength:DWORD
xor ecx,eax xor edx,ebx
pushad
dec edi
mov edi, [Password]
jnz .NextByteCRC
call GetZSLength
not edx
mov [PasswordLength], eax
not ecx mov eax,edx
stdcall [VirtualAlloc],0,eax, MEM_COMMIT+MEM_RESERVE,
rol eax,16
PAGE_READWRITE
mov ax,cx
mov edi, eax ; eax = password offset mov esi, [Password]
pop edx
mov ecx, [PasswordLength]
pop ebx
rep movsb
pop ecx
mov [PasswordCp], eax
pop edi
Мы получили длину пароля. Выделили память и
pop esi
скопировали туда пароль, чтобы можно было без
ret
Теперь
функция
NextPasswordMod:
модификации
пароля
всякого «страха» модифицировать пароль: xor ecx, ecx .next: ; ecx
;IN
mov esi, [PasswordCp]
; ESI offset ZS of password
mov edi, [PasswordLength]
; EAX ordinal number ((текущее смещение в файле)/4)
mov eax, ecx
; EDI password length
call NextPasswordMod
pushad dec edi
mov esi, [PasswordCp] mov edi, [PasswordLength]
xor edx, edx
call GET_CRC32 ;eax = CRC32 of current password mod
div edi
mov edi, [DataAddress]
add esi, edx
imul edx, ecx,4 ;edx = current position
mov bh, [esi]
add edi, edx ; edi = current offset
mov ecx, edi sub ecx, edx
mov ebx, [DataSize]
.next: mov bl, [esi+1]
sub ebx, edx
mov [esi], bl
cmp ebx, 0
inc esi
АРХИВ
jz .end
СОДЕРЖАНИЕ
45
ПРО
граммист
ШИФРОВКА ПАРОЛЕМ. УЛУЧШАЕМ АЛГОРИТМ
№10 (январь) 2011
cmp ebx, 4
CSCA1(DataAddr,FSize,pchar(Edit1.Text));
jl .not_full_xor
UnmapViewOfFile(DataAddr); CloseHandle(FMH);
Здесь мы модифицируем пароль, получаем его
CloseHandle(FH);
контрольную сумму CRC32, и смотрим в конце-ли
мы, если в конце, прыгаем в конец, если осталось меньше
чем
четыре
байта,
завершающую стадию шифрования:
прыгаем
в
end;
Запустим проект на компиляцию (см. рисунок 1). При первом нажатии на кнопку файл шифруется,
а при втором – файл дешифруется (см. рисунок 24). Вот, наверное, и все. Да, чуть не забыл.
.full_xor:
Почему
xor [edi], eax
функция
так
называется?
Я
назвал
алгоритм так – Control Sum Crypt Algorithm v1.0,
inc ecx
т.е. CSCA1. Качаем и пользуемся. В архиве [2]
jmp .next
исходник DLL (FASM), сама DLL и пример ее
.not_full_xor:
использования.
mov ecx, ebx .rep:
Модернизируем алгоритм
dec ecx add edi, ecx
В
mov dl, [edi]
первом
варианте
описан
довольно
эффективный (по-моему) алгоритм шифрования
xor dl, al
данных с помощью пароля. Но у него есть
mov [edi], dl
недостаток: если пароль состоит из одинаковых
sub edi, ecx
символов, то все модификации пароля сходят на
inc ecx
нет (как ни модифицируй, все равно та же
shr eax, 8
строка)!
loop .rep .end: stdcall [VirtualFree],[PasswordCp],0, MEM_RELEASE
избежать.
А
теперь
я
расскажу,
как
этого
Единственное, что приходит в голову – это
добавление к паролю дополнительных символов,
popad
чтобы при модифицировании пароля получалась
ret
другая
endp
Полностью исходник DLL-ки и сама DLL есть в
архиве с примером [1]. Как эту DLL можно использовать? Приведу пример на Delphi: procedure CSCA1(DataAddress:pointer; DataSize:DWORD; Password:PChar); stdcall; external ‘CSCA1.DLL‘; procedure TForm1.Button1Click(Sender: TObject); var FH,FMH:THandle; DataAddr:pointer; FSize:DWORD; begin if not OpenDialog1.Execute then exit; FH:=CreateFile(pchar(OpenDialog1.FileName), GENERIC_ALL, FILE_SHARE_READ,0, OPEN_EXISTING, 0, 0);
CRC32.
одновременно
Увеличение
увеличивает
пароля,
защищенность
алгоритма, так как количество модификаций увеличивается, а следовательно увеличивается и количество
CRC32
шифруются данные.
с
помощью
которых
Итак, мы решили, что надо увеличивать пароль. Но как? Вариант, с добавлением в конец одной и той
же
подходит,
последовательности
потому
что
символов
алгоритм
не
становится
предсказуемым. Следовательно, надо добавлять
последовательность символов в зависимости от
самого пароля. Неплохим будет такой способ: код каждого символа пароля уменьшается на
число равное его позиции в пароле, после чего получившаяся строка добавляется к искомому
FSize:=GetFileSize(FH,nil); FMH:=CreateFileMapping(FH,0,PAGE_READWRITE,0,FSize,”); DataAddr:=MapViewOfFile(FMH,FILE_MAP_WRITE,0,0,FSize);
АРХИВ
Рис. 1. Окно тестового проекта
СОДЕРЖАНИЕ
46
ПРО
граммист
№10 (январь) 2011
ШИФРОВКА ПАРОЛЕМ. УЛУЧШАЕМ АЛГОРИТМ увеличивается в
два
раза
уже
и
можно
быть на 100%
уверенным, что
в нем будет как минимум
2
разных
сим-
вола. По
расчетам,
моим в
результате кого
та-
преобра-
зования,
защи-
щенность алгоритма
растает
минимум
воз-
как
четыре раза.
в
Теперь, остает-
ся только реа-
Рис. 2. Диалог выбора файла
лизовать это.
все
Основной
паролю. В результате уменьшения кода символа
код алгоритма не изменится, изменится только
конец строки, чтобы не было нуля мы заменяем
функция для расширения пароля.
может получиться значение 0, а это обозначает его на код $7F.
В результате этого преобразования длина пароля
начальный код функции шифровки и добавится
Код функции расширения ExpandString будет выглядеть следующим образом:
Рис. 3. Содержимое файла. Шифровка
Рис. 4. Содержимое файла. Дешифровка
АРХИВ
СОДЕРЖАНИЕ
47
ПРО
;ESI
ШИФРОВКА ПАРОЛЕМ. УЛУЧШАЕМ АЛГОРИТМ
№10 (январь) 2011
граммист
- pointer to string
mov
[PasswordLength], eax
pushad
inc eax
mov ebx, esi
stdcall [VirtualAlloc],0,eax, MEM_COMMIT+MEM_RESERVE,
mov edi, esi
PAGE_READWRITE
call GetZSLength
mov edi, eax
add edi, eax
mov esi, [Password]
mov ecx, eax
mov ecx, ebx
rep movsb
rep movsb
mov byte [edi], 0
mov [PasswordCp], eax
add ebx, eax
mov esi, eax
mov ecx, 1
call ExpandString
.rep:
; eax = password offset
xor ecx, ecx
sub byte [ebx], cl
.next:
; ecx
cmp byte [ebx], 0
mov esi, [PasswordCp]
jnz @f
mov edi, [PasswordLength]
mov byte [ebx], 7Fh
mov eax, ecx
@@:
call NextPasswordMod
inc ecx
Заключение
inc ebx cmp byte [ebx],0
В первом варианте функцию шифровки я вынес в
jz .endrep
отдельную DLL-ку. Аргументирую свое решение
jmp .rep
тем,
.endrep:
Сначала мы создаем копию пароля сразу за ним, после чего уменьшаем код каждого символа в
копии пароля на число равное позиции символа. видно,
уменьшение,
можно
будет
производится
то
есть,
например,
беззнаковое
уменьшение
[3] есть также реализация этого алгоритма на Delphi
с
коды
и
уменьшение равно 255, так как уменьшение
•
чем
образом,
отметить,
на
даже
255
если
что
максимальное
нецелесообразно. искомая
длина
Таким
пароля
больше чем 255, то 256 символ пароля останется
неизменным, а 257 символ уменьшится на 1. Теперь
осталось
только
изменить
сам
код
шифрующей функции. Начальный код функции шифровки теперь будет таким:
ресурсы
приложены
непосредственно к журналу. Ресурсы
Следует
использованием
встроенного
ассемблера. Все упомянутые в статье исходные
кода символа 11 на 15 даст нам значение кода более
алгоритм
С/С++, так и на Delphi… В архиве с исходниками
ret
252.
этот
использовать в программах написанных как на
popad
Как
что
• •
в
виде
архива
Р.Аблязов. Шифруем файл с помощью пароля. –
Блог
программистов
club.ru/gruzin-shifr-fail
http://programmers-
Исходник алгоритма шифрования CSCA1 и пример
использования
content/uploads/csca1.zip
http://pblog.ru/wp-
CSCA v1.1 исходники на Assembler и Delphi http://pblog.ru/wp-content/uploads/csca-11.zip
proc CSCA1 DataAddress, DataSize, Password local PasswordCp:DWORD local PasswordLength:DWORD pushad mov
edi, [Password]
call GetZSLength mov ebx, eax shl eax, 1
АРХИВ
СОДЕРЖАНИЕ
48
ПРО
граммист
ОБЩЕНИЕ МЕЖДУ КОПИЯМИ СВОИХ ПРОГРАММ
№10 (январь) 2011
Рассматривать задачу будем на конкретном примере некоего приложения. Опишем предметную область и постановку задачи: необходимо, чтобы наше приложение, зарегистрировав себя как протокол в системе Windows, при нажатии на ссылку вида testproject:\\xxxxx запустило наше приложение (если оно не запущено) и передало ему параметры ссылки. Если же приложение уже запущено, то необходимо запущенной копии приложения сообщить параметры ссылки... Павел Добряков
использованием
by Квэнди http://kvendi.pp.ru
необходимо зарегистрироваться в реестре, чтобы
uses
Для
начала
нам
система воспринимала правильно наши ссылки, поэтому
в
uses
главной
модуль registry.
сейчас
проекта и пишем там: program testproject;
проект.
буду
использования. Итак, заходим в код нашего
Для примера я буду использовать BDS 2006. новый
Не
вдавать в подробности описания мьютексов и их
Что ж, задачу описали, приступим к реализации. Создадим
мьютексов*.
формы
дописываем
Forms,windows, Ustart in ‘Ustart.pas’ {fstart}; {$R *.res} var HM: THandle;
В событии Onactivate() главной формы пишем:
function Check: boolean; begin
procedure Tfstart.FormActivate(Sender: TObject);
HM := OpenMutex(MUTEX_ALL_ACCESS, false, ‘TestProjectMutex’);
var reg: tregistry;
Result := (HM <> 0);
begin
if HM = 0 then HM := CreateMutex(nil, false,
reg:=tregistry.Create;
‘TestProjectMutex’);
reg.RootKey:=HKEY_Classes_Root;
end;
if not(reg.KeyExists(‘testproject’)) then begin
begin
reg.OpenKey(‘testproject’,true);
Application.Initialize;
reg.WriteString(”,’URL:testproject Protocol’);
Application.CreateForm(Tfstart, fstart);
reg.WriteString(‘URL Protocol’,”);
Application.Run;
reg.OpenKey(‘DefaultIcon’,true);
end.
reg.WriteString(”,application.ExeName);
В результате у нас есть функция, возвращающая
reg.CloseKey;
true, если копия проекта запущена и false, если
reg.OpenKey(‘testproject\shell\open\command’,true);
это первая копия. Далее нам необходимо понять
reg.WriteString(”,application.ExeName+’ %1′);
запущено-ли приложение по ссылке или просто
reg.CloseKey;
кто-то
end; end;
Соответственно мы имеем зарегистрированный в системе
протокол
Проверить
это
под
можно
названием
достаточно
testproject. простым
способом: открываем любой браузер и в адресной
строке набираем “testproject:\\eee”, после чего запустится ваша программа.
Теперь продолжим. Нам необходимо определять запущена-ли
наша
программа
или
нет.
Для
решения подобной задачи существует множество способов,
АРХИВ
запустил
наш
exe-ник.
Проверяется
достаточно просто: при запуске по ссылке в
reg.Free;
но
я
предпочитаю
способ
с
* Справка.
Мьютекс (англ. mutex, взаимное исключение) – одноместный семафор,
служащий
одновременно
в
программировании
выполняющихся
потоков.
для
Они
синхронизации
реализованы
во
многих ОС, их основное назначение – организация взаимного исключения для потоков из одного и того же или из разных процессов.
Могут
находиться
в
одном
из
двух
состояний:
отмеченном или неотмеченном (открыт и закрыт соответственно). Когда
какой-либо
поток,
принадлежащий
любому
процессу,
становится владельцем объекта mutex, последний переводится в
неотмеченное состояние. Если задача освобождает мьютекс, его состояние
wiki/Мьютекс.
становится
отмеченным
http://ru.wikipedia.org/
СОДЕРЖАНИЕ
49
ПРО
наше
ОБЩЕНИЕ МЕЖДУ КОПИЯМИ СВОИХ ПРОГРАММ
№10 (январь) 2011
граммист
приложение
будет
передан
параметр
командной строки, в котором будет сдержаться полностью
строка
ссылки,
поэтому
необходимо обработать только одно условие:
нам
var reg: tregistry; begin reg:=tregistry.Create; reg.RootKey:=HKEY_current_user; reg.OpenKey(’software\testproject’, true);
if (check)and(paramcount>0) then
reg.WriteInteger(‘handle’,0);
begin
reg.CloseKey;
end;
reg.Free;
Итак, что же мы будем делать, если такой процесс
уже
необходимо
есть?
Нам,
каким-то
соответственно,
образом
сообщить
запущенному процессу те параметры, которые нам передали. Отсюда возникает вопрос: нам необходимо
знать
хэндл
нашего
уже
end;
Таким образом, при закрытии программы мы будем
обнулять
проверяем
program testproject;
это можно сколь угодно множеством способов. Я
uses
выберу далеко не лучший, но для примера: будем хранить
хэндл
модифицируем формы:
в
реестре.
Onactivate()
Для
нашей
этого
главной
хэндл.
копии
уже
После
приложения. Приведу сразу код:
запущенного приложения. Здесь все подвластно исключительно вашей фантазии, так как сделать
наш
наличие
чего,
запущенного
Forms,windows,registry,sysutils,messages, Ustart in ‘Ustart.pas’ {fstart};
{$R *.res} var HM,HForm: THandle; reg: tregistry;
procedure Tfstart.FormActivate(Sender: TObject);
ParamCmd:TCopyDataStruct;
var reg:tregistry;
function Check: boolean;
begin
begin
reg:= tregistry.Create;
HM := OpenMutex(MUTEX_ALL_ACCESS, false, ‘TestProjectMutex’);
reg.RootKey:=HKEY_Classes_Root;
Result := (HM <> 0);
if not(reg.KeyExists(‘testproject’)) then begin
if HM = 0 then HM := CreateMutex(nil, false,
reg.OpenKey(‘testproject’,true);
‘TestProjectMutex’);
reg.WriteString(”,’URL:testproject Protocol’);
end;
reg.WriteString(‘URL Protocol’,”);
begin
reg.OpenKey(‘DefaultIcon’,true);
if (check)and(paramcount>0) then begin
reg.WriteString(”,application.ExeName); reg.CloseKey;
{Читаем handle запущенного приложения}
reg.OpenKey(‘testproject\shell\open\command’,true);
reg:= tregistry.Create;
reg.WriteString(”,application.ExeName+’ %1′);
reg.RootKey:=HKEY_current_user;
reg.CloseKey;
reg.OpenKey(’software\testproject’,true);
end;
HForm:=reg.ReadInteger(‘handle’);
reg.RootKey:= HKEY_current_user;
reg.CloseKey;
reg.OpenKey(’software\testproject’,true);
reg.Free;
reg.WriteInteger(‘handle’,fstart.Handle); reg.CloseKey;
{Составляем структуру данных ParamCmd}
reg.Free;
with ParamCmd do begin
end;
dwData := 0;
Далее добавим обработчик события CloseQuery() нашей формы:
procedure Tfstart.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
АРХИВ
cbdata:=strlen(pchar(paramstr(1)))+1; lpData:=pchar(paramstr(1)); end; {Посылаем сообщение запущеной программе} SendMessage(HForm, WM_COPYDATA,application.Handle,
СОДЕРЖАНИЕ
50
ПРО
граммист
ОБЩЕНИЕ МЕЖДУ КОПИЯМИ СВОИХ ПРОГРАММ
№10 (январь) 2011
longint(@ParamCmd));
reg.OpenKey(‘DefaultIcon’,true);
Exit;
reg.WriteString(”,application.ExeName);
end;
reg.CloseKey;
Application.Initialize;
reg.OpenKey(‘testproject\shell\open\command’,true);
Application.CreateForm(Tfstart, fstart);
reg.WriteString(”,application.ExeName+’ %1′);
Application.Run;
reg.CloseKey;
end.
Вот
end;
собственно
приложение
и
почти
умеет
все.
уже
Сейчас
наше
обрабатывать
полученные данные и отправлять их запущенной
копии приложения. Но нам также необходимо, чтобы наша запущенная копия получила эти данные, поэтому дополним код модуля нашей основной формы:
reg.RootKey:=HKEY_current_user; reg.OpenKey(’software\testproject’,true); reg.WriteInteger(‘handle’,fstart.Handle); reg.CloseKey; reg.Free; // Если это первая копия программы, if paramcount>0 then // то мы можем сразу смело обрабатывать наши параметры label1.Caption:=paramstr(1);
unit Ustart;
end;
interface
procedure Tfstart.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
var reg: tregistry;
Controls, Forms, Dialogs,registry, StdCtrls;
begin reg:= tregistry.Create;
type
reg.RootKey:=HKEY_current_user;
Tfstart = class(TForm)
reg.OpenKey(’software\testproject’,true);
Label1: TLabel;
reg.WriteInteger(‘handle’,0);
procedure FormActivate(Sender: TObject);
reg.CloseKey;
procedure FormCloseQuery(Sender: TObject;
reg.Free;
var CanClose: Boolean);
end;
protected procedure Getmessage(var msg: TWMCopyData); message WM_COPYDATA;
procedure tfstart.Getmessage(var msg: TWMCopyData);
private
var sText: array[0..99] of Char;
{ Private declarations }
begin
public
StrLCopy(sText, Msg.CopyDataStruct.lpData, // Преобр-м данные
{ Public declarations } end;
Msg.CopyDataStruct.cbData);
// в строку
label1.Caption:=stext; end;
var
fstart: Tfstart; end.
implementation {$R *.dfm}
Послесловие
procedure Tfstart.FormActivate(Sender: TObject);
Вот
var reg: tregistry; begin reg:= tregistry.Create; reg.RootKey:=HKEY_Classes_Root; if not(reg.KeyExists(‘testproject’)) then begin reg.OpenKey(‘testproject’,true); reg.WriteString(”,’URL:testproject Protocol’); reg.WriteString(‘URL Protocol’,”);
АРХИВ
собственно
проверить.
и
Запустим
все.
Достаточно
первую
копию
приложения, а затем в браузере наберем:
просто
нашего
testproject:\\TEST
И увидим, как на нашей запущенной форме появится
этот
текст.
Надеюсь,
информация пригодится вам.
что
эта
СОДЕРЖАНИЕ
51
ПРО
ЧЕГО ТОЛЬКО НЕ БЫВАЕТ
№10 (январь) 2011
граммист
Из заключения: «Дефект утрачен в процессе транспортировки... ».
zloywolk: Как предсказали индейцы майя ipv4 адреса закончатся 21 декабря 2012 года
ovoshee: Последние адреса 4-й версии будут
выданы тем самым здоровенным НЛО которые гдето там летят в нашу сторону. У
меня
младшему
двое
детей:
пять.
Чады
три
старшей
сказочными героями сели пить чай, а мелкие в своей
комнате
принялись
Деду Морозу SMS, и позарез понадобился ему интернет. Я оба бука приволок – на каком-то из
них, говорю, может, и есть. Не было ни на одном, но Снегурочка проявила живейший интерес и попросила
посмотреть.
антенной,
года,
себя
раньше есть
Дед
вели,
реальная
что
и
интернет
Дедушка
похвалил
предложил
дети тем
внучка
этом
перед
еще до Нового года. В
ребята
вели
исключи-
вовремя
не
его
молодые
Новым
она
годом. же
безработный системный
обхо-дится
и
взять
Снегурочка, – временно
пораньше. И мне радость: дешевле,
ей
и
подрабатывают
Наталья,
тельно и заслужили дары старик
внучку
старым маньяком.
возмож-
просто
красном
обозвала
Оказалось,
себя
и
пирожок с полки, на что
приходит:
малые
раздает
появился.
в
ность получить подарки году
там,
прочие радости жизни,
дом старика с перегаром лучше
она
«Одноклассников»
третий год заказываю на Чем
Посмотрела
потыкала кнопочки сям, сходила к коробочке с
Деда Мороза, и я уже
красном.
железную
дорогу и попросили нас им не мешать. Пришла тут
уверены в существовании
в
собирать
администратор, Кирилл,
приходит
он
совсем
же
Дед
менеджер.
«напраздновавшийся».
живут
Почесав
в
Мороз,
–
Супруги
неподалеку.
затылке,
я
Есть дома вайфай и два ноутбука. Как все это
вспомнил, что у нас на предприятии должность
смутно. Налаживал сеть провайдер и сделал, в
процесс стоит) и на минуту сам стал Дедом
работает и взаимодействует, я представляю себе принципе,
все
неплохо,
если
больше
года
нареканий не было. Но вот, где-то за неделю, перед приходом Дедушки Мороза стал пропадать
сисадмина уже неделю как вакантна (сеть лежит, Морозом. Предложил через два дня выходить на работу – собеседование Снегурочка уже прошла.
инет на одном буке, а второй вообще невесть, что
Жена
приложения
если будут яйца, то купи десяток.
стал творить – предполагаю, что это последствия поколения.
шаловливых
ручек
младшего
После торжественного поздравления, стихов на табуретке и вручения заранее предоставленных
подарков (хотя на сам НГ дети, несомненно, на
что-нибудь дополнительно раскрутят) взрослые со
ЮМОР
посылает
программиста
в
магазин:
Дорогой, купи, пожалуйста, палку колбасы, и,
Через
полчаса
программист
десятью палками колбасы.
возвращается
с
Жена: Что это?! Зачем ты купил столько колбасы? Программист: Ну так яйца-то были...
СОДЕРЖАНИЕ
52
ПРО
граммист
ЧЕГО ТОЛЬКО НЕ БЫВАЕТ
№10 (январь) 2011
Глюки с точки зрения мировых религий: •
•
стремиться избавляться от них. Патчи лишь
умножают глюки. Hет никакой разницы между
Иудаизм (к чему спрашивать, почему глючат
хардом
программы? Hадо ждать патча); Католицизм
(первая
программа
Apple и заглючила. Все программы являются версиями первой и сохраняют глюки в целях
глюков,
Протестантизм
(программист
так
любит
программы, что позволяет им глючить, падать
•
Свидетели
Иеговы
(только
у
нас
•
на
неправильных
•
Еще немного, и мы узнаем, как их включить); •
глючат
все
результаты); •
программы,
дающие
другие
Индуизм (программы глючат потому, что в них
были глюки до инсталляции, когда они были другими
программами
и
на
других
компьютерах. После деинсталляции они снова станут другими программами и будут глючить из-за глюков, которые в них есть сейчас. Патчи тут
не
помогут,
предопределено); •
потому
что
все
Буддизм (программы глючат потому, что вы задаетесь
ЮМОР
этим
вопросом.
Hе
следует
(программы
глючат
из-за
неверного понимания порядка вещей. Попытки
упразднены.
Совершенно
мудрый
Коммунизм
вредительства!
(программы
глючат
Hадо
и,
из-за
расстрелять
на
всякий
случай,
зачем нам какие-то программы? У нас уже есть Программа партии); •
Фрейдизм (на самом деле все графические оболочки
предназначены
для
просмотра
порнокартинок. А все текстовые редакторы для
неверная. Hеверные программы надо стереть. верная программа выдает, что 2х2=5, значит,
Конфуцианство
производителей компьютеров. Да и вообще,
Ислам (если программа глючит, значит, она Безглючны только верные программы. Если
есть истинный глюк. Патч, который можно
программистов
компьютерах.
Правильные компьютеры есть только у нас.
в
глюков);
Мормоны (программы глючат потому, что их запускают
Программы
постигнет истинный смысл и необходимость
исчезли, значит вы не уверовали); •
нирвану.
Даосизм (глюк, который можно отловить, не
быть
И мы готовы предложить его всем практически
глюки. Если вы поставили патч, а глюки не
в
западные варвары, противны этикету и должны
настоящий патч, исправляющий любые глюки!
уверуете, что он действительно исправляет
впадает
исправить их с помощью патчей, как делают
есть
бесплатно. Hо он не будет работать, если вы не
и
написать, не есть истинный патч);
и вешаться); •
программой
нирване не глючат, но и не работают);
совместимости); •
софтом,
программистом. Программа, избавленная от
была
безглючной. Hо захотела идти на компьютере
и
печатанья порнотекстов); •
Православие (когда случается глюк, надобно, милая, перво-наперво покропить компьютер святой
водичкой,
угоднику
да
зажечь
кактус
перед
свечку ним
Николе-
поставить,
чтобы дьявольскую энергию-то из компьютера повытянул. А коли кактуса нету, то и рюмка водки сойдет. Потом читай три раза акафист
Богородице, три раза вокруг себя повернись, да не направо, милая, а налево, а то молитва-то силы лишится, и скажи: чур-чур-чур изыди
сила сатанинска в мать сыру землю, через подполицу,
через
подклетицу,
через
подребицу. Выключи потом компьютер на три
дня и три ночи, да раньше не включай, не то глюк весь винт съест).
СОДЕРЖАНИЕ
53
ПРО
ЧЕГО ТОЛЬКО НЕ БЫВАЕТ
№10 (январь) 2011
граммист
Говорят, что истинные айтишники могут при
Смеется в ответ. Надо приятеля проучить, но я
куда им до эмбеддеров! Те при необходимости
минуту нахожу DNS-запись в диапазоне одного из
необходимости подпоясать штаны витой парой. Но могут зашить штаны МГТФ-ом. Приятель
недавно
устроился
в
IT-отдел
дочерней конторы достаточно крупной компании. Контора серьезная, судя по обороту денежных
средств, на железо и ПО средств не жалеет. Сам
приятель пользуется продуктами MS, я поклонник линукса
—
случаются
между
нами
холивары
почище, чем на «ЛОРе». Сидим как-то, кидаемся в чате
айтишными
типа
VPN,
ссылками.
Он
мне
пишет:
знаю лишь название его конторы... Через пару местных провайдеров, зарегистрированную на его контору, еще через минуту убеждаюсь, что IP из
нашего города и вот Nmap уже сканит подсеть /24. Четыре включенных хоста: на одном SSH, на втором Cisco SSL VPN, на остальных filtered-порты
msrpc, netbios-ssn и microsoft-ds. Пишу приятелю о результатах поиска, подтверждаю ссылками. Он
сперва отнекивается – дескать, не его хосты, но потом соглашается и уходит в офлайн.
дескать, опробовал LogMeIn, бесплатный сервис
Написал, что брутнул веб-морду Cisco SSL VPN,
серваками. Смотрю. Похоже на OpenVPN, которым
коллега, тоже админ, и если он читает логи (а он
я
удобно
пользуюсь,
виртуальном
удаленно
решение
сетевом
тоже
наблюдать
за
базируется
на
интерфейсе
–
правда,
у
LogMeIn это проприетарный Hamachi, а у OpenVPN –
свободный
TUN/TAP-адаптер.
Вчитываюсь
в
подробности. Оказывается, версия бесплатна для некоммерческого
пользования
дома
и
в
только чтобы позлить приятеля. Он ведь мой их читает), то они будут чисты, как полы в микропроцессорных пользоваться надеюсь,
%name%?
он
краденой
все
А
проприетарщиной,
перестанет.
Не
номерок на дверь квартиры, и я просто написал
PPTP-сервер
поднять?»
–
в
общем,
оттягиваюсь по полной. Приятель не проявляет угрызений
совести,
убеждая,
что
пользуется
сервисом изредка, а на ссылку с лицензионным соглашением отвечает: «Упс, не заметил». В
атаку
идет
грозное
оружие:
«Ты
ставишь
безопасность корпоративной сети под угрозу!»
ЮМОР
банального
Правда,
Все
мог
с
равно
Intel.
некоммерческих организациях. Начинаю троллить
приятеля: «Как тебе не стыдно? К тебе уже едут.
началось
лабораториях
компакт-диска.
После переезда мне было лень искать в магазине
цифру на болванке. Дальше мне в руки попалась
однокнопочная мышь, вещь редкая и бесполезная. Вроде и показать раритет хочется, и повода нет, а место в ящике девайс занимает. В итоге хвостатая
поселилась рядом с компактом, исполняя роль
кнопки звонка. Свои, кстати, стали узнаваться по двойному щелчку.
СОДЕРЖАНИЕ
54
ПРО
ЧЕГО ТОЛЬКО НЕ БЫВАЕТ
№10 (январь) 2011
граммист
Получил номера на машину. Чем крепить? Все
болты либо коротки, либо толсты, либо к ним нет гаек. Выручили болты от серверной стойки – тоже коротки,
но
вкрутились
железном бампере, без гаек.
прямо
в
дырки
на
Ставлю акустику. Чем развести провода? Само собой,
витухой:
как
раз
четыре
пары
на
квадросистему. Обрезки, кстати, хорошо пошли в
качестве вязальной проволоки, чтобы аккуратно смотать буксировочный трос.
Скопилась кучка старых убитых винтов. Отдал
проблема... Из последнего: обратили внимание на
что внутри. Я посмотрел на магниты и отобрал
конфигурации.
сыну, тот их быстренько разобрал – интересно же, обратно. Прикрутил на работе к стенке (на каждом
магните есть ушко) – теперь болты, отвертки, ножницы и даже пассатижи висят на магнитах. Удобно: всегда под рукой, на виду и не катаются, как попало.
Попался старый винт на 20 МБ, еще в формфакторе 5.25". Двигатель 36 Вт – это не нынешние 8-12. Вместо блинов – абразивный круг. Для
неторопливой заточки ножей сойдет. Вот такой образ
жизни.
Это
зашивать.
вам
не
штаны
МГТФ-ом
неполадки зависло.
с
памятью
Запустили
Посмотрели
в
тест
стандартной
памяти
размер
–
все
адресного
пространства: 64 МБ, а на плате физически присутствуют только 32. Тут у нас возникли некоторые подозрения. Оказалось, что в примере от
производителя,
памяти,
еще
и
кроме
банки
неверного
памяти
размера
адресованы
вперемешку. Выходит, что тест памяти стирает из
нее сам себя, и процессор исполняет какие-то случайные инструкции.
Интересно, что будут писать о глюках через
десять лет, если подобная технология станет повсеместной?
...с форума радиосканнера:
– Народ, а здесь кто-то ковыряется в мелкой ряби
Коллега
пацаны, плавно покачивающихся в КВ диапазоне?
со втянувшимися внутрь стенками. Я долго гадал,
спутниковых волн? Или тут только серьезные
Ведем
разработку
компании.
С
на
ПЛИС
появлением
известной
встраиваемых
процессоров возможности построения цифровых
систем стали практически безграничными. Работа сложная и интересная.
Приходится совмещать изменения железа и софта: переконфигурировал процессор или шину памяти – переписывай программу. А уж насколько богатые возможности для глюков, когда не поймешь, где
ЮМОР
показал
ADSL-модем
с
дохлыми
конденсаторами, но не вздувшимися, а вогнутыми, как такое может быть. Все оказалось просто: клиент на нервах хорошенько потыкал в модем отверткой.
Реальный диалог на частоте VK0MМ... W?????: VK0MM! Пожалуйста, Ваш QTH! VK0MM: Мой QTH – остров Макуари. W?????: А где это – остров Макуари?
VK0MM: Это 3000 км от Новой Зеландии. W?????: А где это, Новая Зеландия?
СОДЕРЖАНИЕ
55