INF-файлы
Хотелось бы в этой главе описать некоторые возможности INF-файлов. Здесь не будет полностью рассмотрен язык INF-файлов и способы написания на нем сценариев, но тем не менее попробуем понять, как с помощью INF-файлов можно выполнять копирование и удаление файлов, создание и удаление параметров реестра, а также рассмотрим некоторые интересные возможности INF-файлов.
Основные сведения
INF-файлы предназначены для описания начального процесса установки новой программы или оборудования. Каждый INF-файл должен начинаться с заголовка. Этот заголовок определяет версию INF-файла, а также версию операционной системы, для которой этот INF-файл написан. От версии информационного файла (INF-файла) зависят те возможности, которые он поддерживает. Существует две версии INF-файлов — обычные и расширенные. В главе 1 уже рассматривались способы вызова обычных и расширенных INF-файлов. При этом расширенные INF-файлы поддерживают следующие новые возможности (это не все возможности, только основные): выполнение различных программ до или после выполнения INF-файла, архивирование изменяемых значений параметров реестра, а также вывод сообщений перед выполнением INF-файлов или после него.
ПРИМЕЧАНИЕ
Необходимость изучения INF-файлов во многом оправдана. Конечно, сейчас INF-файлы заменили пакетами установщика Windows и другими способами описания начальной установки программ. Тем не менее они обладают несколькими интересными возможностями, которые будут рассмотрены далее и которые довольно трудно выполнить без использования INF-файлов. С помощью INF-файлов можно также работать с реестром, даже когда возможность работы с программой regedit.exe и REG-файлами была отключена с помощью DWORD-параметра DisableRegistryTools, расположенного в ветви реестра HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\system. И не следует забывать, что INF-файлы могут использоваться системными процессами, то есть на их основе можно выполнить взлом операционной системы.
Обычные INF-файлы
Возможности обычных INF-файлов поддерживаются и расширенными, поэтому эти возможности будут рассмотрены первыми. Обычные INF-файлы начинаются со следующего заголовка:
[Version]
Signature="$WINDOWS NT$"
При этом после ключевого слова Signature идет описание версии операционной системы, которая будет поддерживать такие INF-файлы. Если после этого ключевого слова идет слово $WINDOWS NT$, то данный файл написан для операционных систем семейства NT и работать с ним в операционных системах семейства Windows 9x нельзя. Если же после ключевого слова идет слово $CHICAGO$, то данный INF-файл был написан для операционных систем семейства Windows 9x. При этом работать с этим файлом можно будет и в операционных системах семейства NT.
После заголовка должен идти начальный блок, с которого будет устанавливаться данный INF-файл. Стало традицией, что этот блок должен иметь название DefaultInstall. К тому же блок именно с таким заголовком ищет система при установке INF-файла с помощью команды Установить его контекстного меню. Если же предполагается, что создаваемый INF-файл не должен вызываться с помощью контекстного меню (а только с использованием команды rundll32.exe setupapi.dll, InstallHINFSection), то начальный блок можно указать любой.
В начальном блоке могут содержаться различные ключевые слова, указывающие на другие блоки INF-файла, с помощью которых выполняется работа с реестром и файловой системой Windows XP.
Создание ветвей реестра
Например, в начальном блоке может находиться ключевое слово AddReg, указывающее на блоки INF-файла, описывающие добавляемые или изменяемые параметры и ветви реестра. Рассмотрим формат этого ключевого слова на примере листинга 15.1. В данном листинге приведен пример редактирования DWORD-параметра AutoRun из ветви реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Cdrom. В примере этому параметру присваивается значение 0, то есть отключается возможность автоматического запуска дисков.
[version]
Signature="$CHICAGO$"
[DefaultInstall]
AddReg=AR_off
[AR_off]
HKLM, "SYSTEM\CurrentControlSet\Services\Cdrom","Autorun",0x10001,0
Как видно из листинга 15.1, в блоке для редактирования ветвей реестра (в ключевом слове AddReg можно через запятую указать несколько блоков для редактирования ветвей реестра) описываются сами ветви реестра и параметры, в них изменяемые. Формат их описания таков:
«корневой раздел», «ветвь реестра», «параметр», «флаг типа параметра», «новое значение параметра»
Рассмотрим этот формат подробнее.
■ Корневой раздел — здесь содержится ключевое слово, определяющее корневой раздел реестра, в котором расположен изменяемый параметр. Возможны следующие значения:
• HKCU — определяет корневой раздел HKEY_CURRENT_USER;
• HKLM — HKEY_LOCAL_MACHINE;
• HKU — HKEY_USERS;
• HKCR — HKEY_CLASSES_ROOT;
• HKCC — HKEY_CURRENT_CONFIG.
■ Ветвь реестра — определяет остальной путь к ветви реестра, включающей в себя изменяемый параметр. Если ветвь реестра содержит пробелы, то ее нужно взять в кавычки.
■ Параметр — указывает изменяемый параметр реестра. Если название параметра содержит пробелы, то его нужно взять в кавычки. Если название параметра указано не будет, то будет изменено значение параметра (По умолчанию).
■ Флаг — определяет как тип параметра, так и в некоторых случаях дополнительные сведения о том, что же нужно делать с аналогичным параметром в реестре, если он уже существует. Флаг представляет собой битовую маску. Рассмотрим некоторые состояния этой битовой маски.
• 0x00000000 — тип REG_SZ.
• 0x00000001 — REG_BINARY.
• 0x00010000 — REG_MULTI_SZ.
• 0x00020000 — REG_EXPAND_SZ.
• 0x00010001 — DWORD.
• 0x00020001 — NONE.
• 0x00000002 — если изменяемый параметр уже существует в реестре, то изменять его значение запрещено.
• 0x00000004 — удалить раздел или параметр из реестра. Иными словами, в INF-файле можно обойтись даже без специального ключевого слова для описания блока удаления, который будет рассмотрен далее. Удалить параметр можно и с помощью блока редактирования параметров.
• 0x00000008 — только для параметров REG_MULTI_SZ-типа. Указанное в строке редактирования параметра значение не заменяет существующее значение, а добавляется к существующему значению параметра.
• 0x00000010 — создать раздел, но игнорировать создание или редактирование указанного в строке параметра. Вообще, если посмотреть на возможные значения данного флага, то можно подумать, что Microsoft намеревается создать целый язык сценария с условными значениями и переменными для INF-файла. Иначе зачем вообще нужны два только что рассмотренных значения флага, если аналогичные действия можно выполнить и без их использования?
• 0x00000020 — изменить значение параметра, только если данный параметр уже существует в реестре.
■ Значение параметра — определяет новое значение параметра.
Теперь рассмотрим пример INF-файла, добавляющего в реестр значения параметров. Пример, отображенный в листинге 15.2, является частью стандартного INF-файла Windows XP, предназначенного для настройки отключения автозапуска дисков для разных типов приводов компакт-дисков. В примере параметру Autorun присваивается значение только в том случае, если он не существует в реестре. А значение параметра AutoRunAlwaysDisable, имеющего тип REG_MULTI_SZ, формируется в несколько приемов, чтобы обеспечить хранение значений параметра в разных строках.
[version]
Signature="$CHICAGO$"
[DefaultInstall]
AddReg=autorun_addreg
[autorun_addreg]
HKLM,"System\CurrentControlSet\Services\cdrom","AutoRun",0x00010003,1
HKLM,"System\CurrentControlSet\Services\cdrom","AutoRunAlwaysDisable", 0x00010008, "NEC MBR-7 "
HKLM,"System\CurrentControlSet\Services\cdrom","AutoRunAlwaysDisable", 0x00010008, "NEC MBR-7.4 "
HKLM,"System\CurrentControlSet\Services\cdrom","AutoRunAlwaysDisable", 0x00010008, "PIONEER CHANGR DRM-1804X"
HKLM,"System\CurrentControlSet\Services\cdrom","AutoRunAlwaysDisable", 0x00010008, "PIONEER CD-ROM DRM-6324X"
HKLM,"System\CurrentControlSet\Services\cdrom","AutoRunAlwaysDisable", 0x00010008, "PIONEER CD-ROM DRM-624X "
HKLM,"System\CurrentControlSet\Services\cdrom","AutoRunAlwaysDisable", 0x00010008, "TORiSAN CD-ROM CDR_C36"
Удаление ветвей реестра
Параметр или ветвь реестра можно не только добавить в реестр, но и удалить из него. Для этого применяется ключевое слово DelReg, указывающее на блок INF-файла, содержащий сведения о ветвях реестра и параметрах, которые нужно удалить. Несмотря на то, что флаг для редактирования параметров позволяет также и удалять параметры, для их удаления рекомендуется все-таки использовать ключевое слово, так как это более наглядно и позволяет легче понять принцип работы INF-файла.
Рассмотрим пример удаления параметра. В этом примере из реестра удаляется ветвь HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\Shares, чтобы отключить все пользовательские общедоступные папки. При этом сначала нужно удалить все расположенные в данной ветви разделы, чтобы можно было удалить саму ветвь реестра. Как правило, ветвь для хранения сведений об общедоступных папках содержит только один раздел — Security.
ПРИМЕЧАНИЕ
Вообще-то можно удалять и ветви реестра, хранящие другие разделы, но лучше перестраховаться. На памяти у автора были случаи, когда ветвь реестра не удалялась из-за того, что в ней содержались вложенные разделы.
[version]
Signature="$CHICAGO$"
[DefaultInstall]
DelReg=shared_del
[shared_del]
HKLM,"SYSTEM\CURRENTCONTROLSET\SERVICES\LANMANSERVER\SHARES\Security"
HKLM,"SYSTEM\CURRENTCONTROLSET\SERVICES\LANMANSERVER\SHARES"
Как можно заметить, содержимое блока для удаления ветвей и параметров реестра похоже на содержимое блока редактирования ветвей и параметров реестра. Строка для удаления ветви или параметра имеет следующий формат:
«корневой раздел», «ветвь реестра», «параметр», «флаг операции удаления», «пример для удаления»
■ Корневой раздел — указывает на корневой раздел, в котором расположен удаляемый параметр или ветвь реестра.
■ Ветвь реестра — определяет удаляемую ветвь реестра или ветвь, в которой хранится удаляемый параметр.
■ Параметр — определяет название удаляемого параметра. Если параметр отсутствует, то предполагается, что удаляться будет конечный раздел указанной ветви реестра.
■ Флаг операции удаления — может принимать следующие значения:
• 0x00002000 — удалить весь конечный раздел указанной ветви;
• 0x00004000 — произвести указанные изменения в 32-разрядном реестре;
• 0x00018002 — удаляет из параметра все строки, соответствующие примеру для удаления.
■ Пример для удаления — определяет строку значения параметра, имеющего REG_MULTI_SZ-тип, все соответствия которой должны быть удалены из параметра.
Редактирование отдельных битов значения параметра
Это довольно интересная и, можно сказать, уникальная возможность, с помощью которой можно изменить отдельный бит параметра, не изменяя другие его биты. Для реализации этой возможности применяется ключевое слово BitReg, указывающее на блок INF-файла, содержащий сведения об изменяемых битах параметров. При этом блок INF-файла должен включать в себя строки следующего формата:
«корневой раздел», «ветвь реестра», «параметр», «флаг операции», «маска операции», «номер байта параметра»
■ Корневой раздел, ветвь реестра и параметр были рассмотрены ранее.
■ Флаг операции — может принимать следующие значения:
• 0x00000000 — сбросить указанный бит;
• 0x00000001 — установить указанный бит;
• 0x00040000 — выполнить эти операции в 32-разрядном реестре.
■ Маска операции — определяет биты в значении параметра, которые должны быть модифицированы. Другими словами, маска должна состоять из восьми нулей или единиц (определяют 8 бит одного байта значения параметра). Все биты, на месте которых в маске указана единица, будут модифицироваться в зависимости от флага операции. Маска указывается в виде битовой маски.
■ Номер байта значения параметр — указывает на байт значения параметра, к которому будет применяться маска и биты которого будут модифицироваться. При этом номер байта зависит от типа параметра. Для параметров DWORD-типа самый старший байт имеет номер 0, а для параметров REG_BINARY-типа номер 0 имеет самый младший байт.
Для примера попробуем изменить отдельные биты параметра Attributes контекстного меню Корзины. После данной модификации в контекстном меню Корзины будут команды Переименовать, Свойства и Удалить. Такие команды, как Копировать, Вырезать, Вставить, будут удалены из контекстного меню Корзины (если они там присутствуют). В результате применения приведенного INF-файла значение DWORD-параметра Attributes станет равным 0x????0070.
ПРИМЕЧАНИЕ
Заметьте, что сначала желательно сбрасывать биты отдельного байта, а потом уже устанавливать другие биты этого байта.
Если в ветви реестра HKEY_CLASSES_ROOT\CLSID\645FF040-5081-101B-9F08-00AA002F954E}\ShellFolder присутствует параметр, имеющий DWORD-тип, CallForAttributes, то ему будет присвоено значение 0 (если в ветви данного параметра не существует, то он и не будет создан).
[version]
Signature="$CHICAGO$"
[DefaultInstall]
BitReg=RecicleBit
AddReg=CallAttrOff
[CallAttrOff]
HKCR,"CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\ShellFolder",CallForAttributes,0x00010021,0
[RecicleBit]
HKCR,"CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\ShellFolder",Attributes,0,0xff,0
HKCR,"CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\ShellFolder",Attributes,0,0xff,1
HKCR,"CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\ShellFolder",Attributes,1,0x70,0
Создание службы
Еще одной оригинальной возможностью, которой обладают INF-файлы, является упрощенное создание служб на компьютере. Для этого применяется не только ключевое слово AddService, но и специальный стандартный блок INF-файла [DefaultInstall.Services] (то есть к блоку по умолчанию добавляется строка .Services). При этом следует сказать, что этот блок не заменяет стандартный, а дополняет его. Иными словами, если в INF-файле будет два блока, то сначала выполнятся ключевые слова блока [DefaultInstall], а потом блока [DefaultInstall.Services].
Так как вам уже известно, как хранятся сведения о службе в реестре, то будет не сложно понять пример создания службы. По этой причине сначала посмотрим на листинг 15.5, который содержит часть INF-файла, регистрирующего в системе службу Восстановление системы.
[version]
Signature="$CHICAGO$"
[DefaultInstall.Services]
AddService=sr,,SRFlt_service,SRFlt_event
[SRFlt_service]
DisplayName = "Имяслужбы"
ServiceType = 2
StartType = 0
ErrorControl = 1
ServiceBinary = %12%\sr.sys
LoadOrderGroup = "FSFilter System Recovery"
[SRFlt_event]
AddReg=SRFlt_event_addreg
DelReg=SRFlt_event_delreg
Ключевое слово AddService, в отличие от большинства других, содержит не только название блока INFфайла, описывающего службу, но и некоторые другие сведения. Формат этого ключевого слова следующий:
«название службы»,«тип службы», «блок INF-файла»
■ Название службы — определяет название раздела в ветви системного реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services, в который будет заноситься информация о службе. Как известно, название этого раздела является и названием службы.
■ Тип службы — указывает, является ли данная служба самостоятельной. Может принимать значения 0x01, 0x2 и 0x3.
■ Блок INF-файла — определяет один или несколько блоков INFфайла (в этом случае они пишутся через запятую), в которых определены сведения о службе. В листинге 15.5 первый блок содержит информацию о службе, а второй блок регистрирует возможность записи в системные журналы Windows (оснастка Просмотр событий).
Теперь рассмотрим блок INFфайла для регистрации службы. Он может включать в себя следующие ключевые слова.
■ DisplayName — имя службы, отображаемое в оснастке services.msc.
■ Description — описание службы, отображаемое в оснастке services.msc.
■ ServiceType — тип службы. Значение этого параметра соответствует уже рассмотренному значению параметра реестра Type (см. часть 2).
■ StartType — режим запуска службы. Значение этого параметра соответствует уже рассмотренному значению параметра реестра Start.
■ ErrorControl — действие при возникновении ошибки при запуске службы. Значение этого параметра соответствует уже рассмотренному значению параметра реестра ErrorControl.
■ ServiceBinary — путь и имя файла службы. Значение данного ключевого слова заносится в уже рассмотренный параметр ImagePath реестра.
■ Dependencies — определяет службы, необходимые для работы данной службы. Эти значения заносятся в параметр реестра DependOnService.
■ LoadOrderGroup — определяет группу, к которой принадлежит данная служба. Эти значения заносятся в параметр реестра Group.
Удаление службы
Для удаления службы предназначено ключевое слово DelService, которое также указывается в блоке, названном в формате [«блок удаления».Services]. Удаление службы выполняется намного проще — просто указывается имя службы, которую нужно удалить (название раздела реестра, в котором служба описана).
[version]
Signature="$CHICAGO$"
[Uninstall.Services]
DelService=sr
В листинге 15.6 ключевое слово DelService указано в блоке [Uninstall.Services], так как именно блок [Uninstall] используется в примере при вызове INF-файла для удаления службы с помощью команды rundll32.exe.
Копирование файлов
Копирование в INF-файлах реализовано наиболее сложно. Для его выполнения необходимо не только использовать ключевое слово CopyFiles, но и, кроме того, создать три отдельных блока INF-файла: DestinationDirs, SourceDisksFiles и SourceDisksNames. Рассмотрим простой пример.
[version]
Signature = $CHICAGO$
[DefaultInstall]
CopyFiles = INFcopy
[INFcopy]
1.INF
[DestinationDirs]
INFcopy = 17
[SourceDisksFiles]
1.INF = 55
[SourceDisksNames]
55 = "имя диска", , 1
В этом примере для описания копируемых файлов используется блок INF-файла [INFcopy]. Ссылка на него содержится в ключевом слове CopyFiles. В этом блоке находятся только названия файлов, которые должны быть скопированы (если файлов несколько, каждый из них пишется в отдельной строке). Кроме блока [INFcopy], файл обязательно должен хранить и три других стандартных блока INF-файлов.
Блок [DestinationDirs] определяет каталоги, в которые должны копироваться файлы, описанные в отдельных блоках INF-файла, предназначенных для описания копируемых файлов. При этом все файлы, описанные в одном блоке INF-файла, должны копироваться только в один каталог (то есть если бы в нашем блоке [INFcopy] описывалось два файла, например 1.INF и 2.INF, то они оба должны были бы скопироваться в один каталог). Формат определения каталога, в который будут копироваться файлы, следующий:
«блок описания копируемых файлов»=«числовой номер каталога»,«дальнейший путь к каталогу»
Числовой номер каталога представляет собой число, идентифицирующее одну из системных папок. Рассмотрим некоторые из этих чисел, а также каталоги, которые они определяют.
■ 10 — %systemroot%.
■ 11 — %systemroot%\system32.
■ 17 — %systemroot%\Inf.
■ 53 — %userprofile%.
■ 54 — %systemdrive%.
■ 1 — говорит о том, что необходимо использовать абсолютный путь, который должен быть записан после числового номера (через запятую). Абсолютным называется путь, который не начинается с числового номера каталога. Например, числовым является путь d:\test\1.
С помощью блока [SourceDisksFiles] осуществляется присваивание каждому копируемому файлу уникального идентификатора, он будет определять в блоке [SourceDisksNames] название диска, с которого копируется файл. Формат строк этого блока следующий:
«название копируемого файла»=«уникальный идентификатор диска, на котором находится этот файл»
Блок [SourceDisksNames] определяет диски, на которых находятся копируемые файлы. Формат строк этого блока таков:
«уникальный идентификатор диска»=«имя диска»,«метка диска»,«серийный номер диска»
Метка диска отображается в диалоге копирования файлов. Эта метка также отображается в диалоге, выводимом, если система не может найти указанные для копирования файлы. В этом случае система попросит вас вставить диск, название которого как раз и указано в блоке [SourceDisksNames].
Удаление файлов
Удаление файлов напоминает их копирование, поэтому рассмотрим этот процесс лишь поверхностно — в подсказках к листингу 15.8. Для определения блоков, содержащих описания удаляемых файлов, используется ключевое слово DelFiles.
[version]
Signature = $CHICAGO$
;данный раздел будет вызываться с помощьюкоманды rundll32
[DefaultUninstall]
DelFiles = INFdel
;мы будем удалять файл vfolder.INF
[INFdel]
vfolder.INF
;теперь данный блок указывает не каталог, в который копируются файлы,
;а каталог, из которого удаляются файлы, описанные в блоке
[DestinationDirs]
INFdel = 17
[SourceDisksFiles]
vfolder.INF = 55
[SourceDisksNames]
55 = "имя диска", , 1
Создание ярлыка файл в меню Пуск
Это еще одна возможность, которой можно воспользоваться благодаря INF-файлу. С помощью ключевого слова ProfileItems можно определить блок INF файла, в котором описывается создаваемый в меню Пуск ярлык. Рассмотрим пример, с помощью которого создается ярлык программы Восстановление системы в меню Пуск (Стандартные►Служебные).
[version]
Signature="$CHICAGO$"
[DefaultInstall]
ProfileItems=SRProfile
[SRProfile]
Name="Восстановление системы"
CmdLine=11,restore,rstrui.exe
SubDir="Стандартные\Служебные"
InfoTip="Это подсказка, отображаемая при наведении указателя на ярлык"
DisplayResource="%systemroot%\system32\restore\rstrui.exe",2048
ProfileItems=SRProfile
Блок для описания ярлыка в меню Пуск может содержать следующие ключевые слова.
■ Name — определяет название создаваемого в меню Пуск ярлыка.
■ CmdLine — указывает путь к программе, для которой создается ярлык. Формат данного ключевого слова немного необычен: «числовой путь к стандартному каталогу, размещение файла, название файла».
■ SubDir — определяет расположение ярлыка в меню Пуск. Если точнее, то данное ключевое слово определяет дальнейший путь к каталогу, который будет содержать ярлык на программу. Дальнейший путь добавляется к пути %systemdrive%\Documents and Settings\All Users\Главное меню\Программы.
■ WorkingDir — указывает рабочие каталоги для программы, на которую создается ярлык (как правило, это ключевое слово не указывается).
■ InfoTip — определяет подсказку, отображаемую при наведении указателя на созданный в меню Пуск ярлык.
Расширенные INF-файлы
Расширенные INFфайлы отличаются от обычных одной строкой, которую нужно добавить в блок [version]. Ниже приведен пример блока версии для расширенного INF-файла.
[Version]
Signature="$CHICAGO$"
AdvancedINF=2.5,"Эта строка будет выводиться, если на компьютере не найдено библиотеки advpack.dll"
Для работы с расширенными INFфайлами необходима библиотека advpack.dll, по умолчанию расположенная в каталоге %systemroot%. Если перед началом выполнения расширенного INFфайла система не найдет данной библиотеки, то она выведет сообщение, указанное в ключевом слове AdvancedINF после запятой. К тому же, как известно, расширенные INFфайлы вызываются с помощью команды rundll32.exe ADVPACK.dll, LaunchINFSectionEx «имя файла», «имя раздела», «имя cab-файла», «флаг». Тогда как обычные INF-файлы вызываются с помощью следующей команды: rundll32.exe setupapi.dll, InstallHINFSection «раздел в файле для начала установки», «флаг», «путь и имя файла».
Запуск программ до и после установки
Расширенные INF-файлы поддерживают такую возможность, как запуск команд перед установкой INF-файла или после нее. При этом для указания блока, описывающего программы, запускаемые перед установкой INF-файла, используется ключевое слово RunPreSetupCommands. Для указания блока, описывающего программы, запускаемые после установки INF-файла, используется ключевое слово RunPostSetupCommands. Посмотрим на пример использования этих ключевых слов.
[version]
Signature = $CHICAGO$
AdvancedINF=2.5,"Эта строка будет выводиться, если на компьютере не найдено библиотеки advpack.dll"
[DefaultInstall]
RunPreSetupCommands=RunPre
RunPostSetupCommands=RunPost
[RunPre]
calc.exe
cmd.exe
[RunPost]
"rundll32.exe IEAKENG.dll, DoReboot"
Приведенный в листинге 15.10 INF-файл перед своей установкой вызывает Калькулятор, а потом — стандартный командный интерпретатор Windows. После своей установки он вызовет диалоговое окно с вопросом о перезагрузке компьютера. Конечно, это окно принадлежит Internet Explorer, но зато оно работает.
ПРИМЕЧАНИЕ
Вопрос о перезагрузке компьютера можно было вызвать и с помощью флагов вызова INF-файла, но в листинге специально были использованы команды rundll32.exe.
Не забывайте также, что данный INF-файл не выполнится после выбора команды Установить контекстного меню INF-файла. Для его установки придется воспользоваться командой RunDll32 advpack.dll, LaunchINFSection d:\1.INF, DefaultInstall. Здесь d:\1.INF соответствует пути к INF-файлу и его названию.
Вывод сообщения перед установкой
Перед установкой INF-файла или после нее можно вывести окно сообщения с произвольным текстом. Диалог сообщения, выводимый перед установкой, позволяет эту установку отменить. Он содержит две кнопки — OK и Отмена. Если нажать кнопку Отмена, то установка INF-файла будет отменена. Диалог сообщения, выводимый после установки, является информационным и имеет только одну кнопку — OK.
Чтобы вывести диалоговое окно перед установкой, необходимо воспользоваться ключевым словом BeginPrompt (окно сообщения будет выведено до вызова программ, описанных ключевым словом RunPreSetupCommands), а чтобы вывести окно сообщения после установки, нужно воспользоваться ключевым словом EndPrompt. В листинге 15.11 приведен простой пример использования как окна сообщения, выводимого перед установкой, так и окна сообщения, выводимого после установки.
[version]
Signature = $CHICAGO$
AdvancedINF=2.5,"Эта строка будет выводиться, если на компьютере не найдено библиотеки advpack.dll"
[DefaultInstall]
RunPreSetupCommands = RunPre
BeginPrompt=BeginText
EndPrompt=EndText
[RunPre]
cmd.exe
[BeginText]
Prompt="Это пример текста, который выведется перед установкой"
Title="Это заголовок для сообщения, которое выведется перед установкой"
[EndText]
Prompt="Это пример текста, который выведется после установки"
Блок для описания сообщения, выводимого перед установкой INF-файла (в данном случае BeginText) содержит следующие ключевые слова.
■ Prompt — определяет саму строку выводимого сообщения.
■ Title — указывает заголовок окна сообщения. Следует учитывать, что данный заголовок будет использоваться не только для окна сообщения, отображаемого перед установкой, но и для окна сообщения, отображаемого после установки.
Дополнительные возможности
Выше были рассмотрены лишь основы работы с INF-файлами. Кроме приведенных ключевых слов, INF-файлы поддерживают многие другие, но если начать их описывать, то понадобится отдельная книга. Закончим на этом рассказ о ключевых словах INF-файлов. Теперь рассмотрим несколько примеров не совсем стандартного использования INF-файлов. Без описания этих примеров рассказ о возможностях INF-файлов был бы не полон.
Работа с диалогом Установка и удаление программ
Одной из интересных возможностей INF-файлов является возможность их использования как для добавления команды в диалог Установка и удаление программ, так и для выполнения процесса деинсталляции при помощи диалога Установка и удаление программ. Рассмотрим простой пример использования INF-файлов для создания так называемого зацикленного элемента диалога Установка и удаление программ, который применяется для включения и отключения возможности автоматического запуска дисков. Принцип работы приведенного ниже сценария прост. При первом своем вызове он копирует себя в папку %systemroot%\INF, отключает автоматический запуск дисков, а также добавляет возможность включения автоматического запуска дисков в диалог Установка и удаление программ. После удаления данного INF-файла с помощью диалога Установка и удаление программ происходит включение автоматического запуска дисков, а также создание в диалоге Установка и удаление программ новой строки, с помощью которой можно опять отключить автоматический запуск диска. Другими словами, создается постоянный цикл. Конечно, пример с изменением значения одного параметра довольно спорен, ведь намного проще было бы добавить свой флажок в один из стандартных диалогов Windows, поддерживающих добавление в свои списки новых элементов. Но если необходимо при установке параметра также выполнять какие-либо команды или модифицировать сразу несколько параметров (например, создать несколько разновидностей настройки оболочки Windows, а потом переходить между ними), то данный способ использования INF-файлов может быть незаменим (рис. 15.1).
Рис. 15.1. Создание команды в диалоге Установка и удаление программ
[version]
Signature = $CHICAGO$
[DefaultInstall]
AddReg = AutoRunOff, InstallInf
CopyFiles = INFcopy
;Ниже мы используем переменную %PATH% для указания изменяемой ветви реестра.
;Переменная – это специальная последовательность символов, которая при
;установке INF-файла будет преобразовываться в строку, определенную для нее
;в стандартном блоке [Strings] (обычно этот блок располагается в самом низу
;INF-файла). Использование переменных позволяет улучшить читабельность
;INF-файлов большого размера, а также предоставляет разработчику возможность
;цетрализованного хранения всех информационных и других строчек программы.
;Иными словами, вместо того чтобы искать необходимую для изменения строку
;по всему содержимому INF-файла, он может описать ее в блоке [Strings]
[AutoRunOff]
HKLM, %PATH%, AutoRun, 0x00010001, 0
;Добавляем строку в диалог Установка\удаление программ. В первой главе
;мы кратко рассматривали формат этого диалога.
[InstallInf]
HKLM, %DISPLAY% autorunOnOff,,,
HKLM, %DISPLAY% autorunOnOff, DisplayName,,%NAME_ON%
HKLM, %DISPLAY% autorunOnOff, UninstallString,,\"rundll32 setupapi, InstallHINFSection DefaultUninstall 132 %17%\primer.INF"
[DefaultUninstall]
AddReg = AutoRunOn
[AutoRunOn]
HKLM, %PATH%, AutoRun, 0x00010001, 1
HKLM, %DISPLAY% autorunOnOff, DisplayName,,%NAME_OFF%
HKLM, %DISPLAY% autorunOnOff, UninstallString,,\"rundll32 setupapi, InstallHINFSection DefaultInstall 132 %17%\primer.INF"
[INFcopy]
primer.INF
[DestinationDirs]
INFcopy = 17
[SourceDisksFiles]
primer.INF = 55
[SourceDisksNames]
55 = %DISKNAME%, , 1
;Описывает переменные, используемые в INF-файле
[Strings]
PATH = "SYSTEM\CurrentControlSet\Services\Cdrom"
DISPLAY = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
NAME_ON = "Восстановить автоматический запуск дисков"
NAME_OFF="Отключить автоматический запуск дисков"
DISKNAME = "parad0x-des1Gn"
Диалог установки компонентов Windows
Отдельной частью окна Установка и удаление программ является диалог Установка компонентов Windows, который вызывается нажатием соответствующей кнопки. Как правило, данный диалог включает в себя сведения не обо всех компонентах Windows, доступных на компьютере. Например, с его помощью нельзя удалить с компьютера стандартные игры, такие как Сапер или Паук. Это происходит потому, что по умолчанию возможность удаления или установки игр скрыта из диалога установки компонентов Windows. Список содержимого диалога Установка компонентов Windows описывается в файле sysoc.INF, расположенном в каталоге %systemroot%\INF. Данный файл включает в себя блок INF-файла [Components]. Блок содержит наборы строк, определяющих, будет ли отображаться в диалоге отдельный компонент операционной системы Windows XP. Строки имеют следующий формат:
идентификатор»=«библиотека для работы компонентов», «функция библиотеки», «INF-файл, описывающий компоненты»,«отображение компонентов»,«номер»
Следующие элементы являются наиболее важными.
■ INF-файл, описывающий компоненты — описывает разделы, отображаемые в диалоге Установка и удаление программ. Именно такой INF-файл сейчас и будет создан.
■ Отображение компонентов — если в данном поле будет стоять слово HIDE, то данный компонент не будет отображаться в диалоге дополнительных компонентов Windows. Чтобы компонент отображался в диалоге, необходимо чтобы это поле было пустым.
■ Например, чтобы добавить в диалог компонентов возможность удаления игр, необходимо в строке, начинающейся с идентификатора games, удалить строку HIDE.
На рис. 15.2 показан пример содержимого этого файла.
Рис. 15.2 .Содержимое файла sysoc.INF
Другой возможностью является добавление в данный диалог своих компонентов. Для этого необходимо сначала создать INF-файл, описывающий новые компоненты, а потом создать в файле sysoc.inf ссылку на созданный INF-файл. Сначала посмотрим на простой пример INF-файла. В этом примере сразу создается корневой раздел, отображаемый непосредственно в диалоге установки компонентов Windows, два вложенных в этот раздел подраздела, а также еще два раздела, которые и будут устанавливать или удалять компоненты. В нашем случае эти разделы будут просто скрывать (или отображать, в зависимости от состояния флажка) версию Windows на Рабочем столе, а также скрывать (или отображать) название значка Мой компьютер.
[version]
signature="$Chicago$"
[Optional Components]
TopMain
Interface
Settings
HTMcomputer
Versus
[TopMain]
OptionDesc = Мои настройки
Tip = Варианты настройки интерфейса и конфигурации
IconIndex = 0
[Interface]
OptionDesc = Интерфейс Windows
Tip = Варианты настройки интерфейса
IconIndex = 4
Parent = TopMain
[Settings]
OptionDesc = Конфигурация Windows
Tip = Варианты настройки конфигурации компьютера
IconIndex = 16
Parent = TopMain
[HTMcomputer]
OptionDesc = Скрыть название моего компьютера
Tip = Скрывает название значка Мой компьютер
IconIndex = 0
Parent = Interface
AddReg = AddHTM
Uninstall = HTMUn
Modes = 0,1,2,3
[Versus]
OptionDesc = Отобразить версию на Рабочем столе
Tip = отображает версию операционной системы на Рабочем столе пользователя
IconIndex =4
Parent = Interface
AddReg =AddVersion
Uninstall =VersUn
Modes = 0,1,2,3
[AddHTM]
HKCR, "CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\ShellFolder", WantsFORDISPLAY, 0x00010001, 1
[AddVersion]
HKCU, "Control Panel\Desktop", PaintDesktopVersion, 0x00010001, 1
[HTMUn]
DelReg = HTMDel
[VersUn] AddReg = VersDel
[HTMDel]
HKCR, "CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\ShellFolder", WantsFORDISPLAY
[VersDel]
HKCU, "Control Panel\Desktop", PaintDesktopVersion, 0x00010001, 0
Формат INF-файла для создания компонентов в диалоге установки Windows немного отличается от обычного формата INF-файлов. Во-первых, основной блок INF-файла обязательно должен называться [Optional Components], иначе INF-файл работать не будет. Блок включает в себя список других блоков данного INF-файла. Каждый из описанных в [Optional Components] блоков определяет один раздел в диалоге установки компонентов Windows.
Блок описания раздела установки компонента содержит следующие ключевые слова.
■ OptionDesc — определяет название раздела, отображаемого в диалоге Установка компонентов Windows.
■ Tip — указывает подсказку для раздела, отображаемого в нижней части диалога Установка компонентов Windows.
■ Icon Index — определяет индекс значка, отображаемого напротив данного раздела в диалоге Установка компонентов Windows. Например, идентификатор 0 определяет значок компьютера, идентификатор 2 — монитора, 14 — принтера.
■ Parent — указывает название блока INF-файла, описывающего раздел, который будет родителем для нашего раздела в диалоге установки компонентов Windows. Если данное ключевое слово отсутствует, то наш раздел будет отображаться непосредственно в диалоге установки конфигурации Windows.
■ Uninstall — определяет блок INF-файла, вызываемый для данного компонента при установке созданного раздела (устанавливать можно только разделы, входящие непосредственно в список диалога установки компонентов (корневые), а не отдельно разделы, вложенные в корневой), если флажок напротив данного компонента будет снят.
В блоке установки компонента можно также пользоваться такими стандартными ключевыми словами, как AddReg, BitReg, DelReg, CopyFiles и т.д. Все блоки, описанные в этих ключевых словах, будут выполняться при установке флажка напротив соответствующего компонента.
Теперь добавим ссылку на наш компонент в файл sysoc.inf. Для того чтобы так сделать, необходимо в блок [Components] добавить строку следующего вида: hello=ocgen.dll, OcEntry, prim2.inf, , 7. Здесь test2 определяет идентификатор присоединяемого INF-файла, a prim.inf является названием самого присоединяемого файла. Стоит еще сказать, что созданный INF-файл должен находиться в каталоге %systemroot%\inf.
ПРИМЕЧАНИЕ
В строке также указывается название библиотеки и функция из этой библиотеки, которая будет устанавливать наши компоненты. Как правило, нет никакой разницы между различными функциями различных библиотек. Главное, чтобы они умели работать с диалогом установки компонентов. Поэтому была выбрана первая попавшаяся в файле sysoc.inf библиотека и функция для нее.
На рис. 15.3 показан результат добавления компонентов.
Рис. 15.3. Создание разделов диалога
INF-файл для логического диска
Еще одной возможностью, которую предоставляют INF-файлы, является добавление в контекстное меню логических дисков своих команд, а также изменение значка логического диска. Для этого необходимо создать специальный файл, который должен называться autorun.inf. Созданный INF-файл необходимо поместить в корень логического диска. Рассмотрим пример создания файла autorun.inf.
[autorun]
icon = E:\images\fotoo\Art_galery\p.BMP
shell = open
shell\RunPh\command = photoshop.exe
shell\RunPh = Запустить photoshop
Файл autorun.inf не имеет блока версии INF-файла, но должен иметь блок [autorun]. Содержимое этого блока довольно просто в понимании, если вы прочитали главу 8 о корневом разделе HKEY_CLASSES_ROOT. Как можно заметить, ключевые слова, начинающиеся со слова shell, являются просто разделами реестра, которые должны быть добавлены к ветви HKEY_CLASSES_ROOT\Drive при отображении контекстного меню данного логического диска, а ключевое слово icon определяет значок диска. Тем не менее вспомним содержимое корневого раздела HKEY_CLASSES_ROOT\Drive\shell и опишем, что же конкретно делают ключевые слова данного файла.
■ shell = open — добавляет в параметр (По ум олчанию) раздела shell строку open. Эта строка говорит о том, что по умолчанию при двойном щелчке на диске он должен открываться.
■ Shell\RunPh = Запустить photoshop — добавляет в параметр (По умолчанию) раздела RunPh строку Запустить photoshop. Эта строка определяет название команды в контекстном меню нашего диска.
■ Shell\RunPh\command = photoshop.exe — добавляет в параметр (По умолчанию) раздела command строку photoshop.exe. Эта строка определяет команду, которая будет выполняться при выборе из контекстного меню нашего диска соответствующей команды.
ПРИМЕЧАНИЕ
Для возможности работы файла autorun.inf необходимо, чтобы REG_BINARY-параметр NoDriveTypeAutoRun, расположенный в ветви реестра HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer, был равен 0.
Как можно заметить, с помощью INF-файлов можно выполнить довольно много интересного. При этом рассмотренные возможности являются только каплей в море. Например, с помощью INF-файлов можно выполнить такие действия, как запуск или остановка служб, назначение прав на доступ к файлам, архивирование реестра и многое другое. Кроме того, INF-файлы постоянно усовершенствуются и еще неизвестно, что с их помощью можно будет выполнить завтра.
Глава 16