Статьи

Доступ к реестру Windows с помощью PHP

Вы когда-нибудь просыпались утром и думали про себя: «Я хочу сделать что-то сумасшедшее сегодня?» Что ж, если сегодня был один из тех утра, то вам повезло. Я хотел бы дать вам небольшое представление о доступе к реестру Windows с помощью PHP. PHP … Реестр … CRAZY!

Реестр Windows — это просто иерархически структурированная база данных, в которой операционная система Windows и другие приложения хранят важную информацию о конфигурации. В реестре хранятся все виды данных: профили пользователей, ассоциации типов файлов, информация об оборудовании, серийные номера и многое другое. С помощью функций, доступных в расширении win32std, ваши PHP-приложения для Windows также могут получить доступ к реестру.

Расширение win32std можно загрузить в виде предварительно скомпилированной библиотеки с сайта downloads.php.net/pierre/ . Просто поместите его в папку extphp.ini Обратите внимание, что прямо сейчас библиотеки DLL, которые вы загружаете, являются 32-битными, поэтому, если вы используете 64-битную сборку WampServer или что-то подобное, у вас не будет большого успеха. Вам придется либо понизить WampServer до 32-битной сборки, либо попробовать скомпилировать библиотеку самостоятельно.

Структура реестра

Реестр имеет репутацию темного, опасного и страшного места в операционной системе Windows. Вероятно, это слишком преувеличенный страх, но я все же повторю мантру реестра Microsoft: «Прежде чем изменять реестр, сделайте его резервную копию и убедитесь, что вы понимаете, как его восстановить в случае возникновения проблемы. Неправильные изменения могут вызвать серьезные проблемы, которые могут потребовать переустановки операционной системы ».

Так как же выглядит это темное, страшное место? Реестр Windows разделен на 5 основных групп, известных как ключи:

HKEY_CURRENT_CONFIG
Этот ключ хранит информацию об оборудовании компьютера, такую ​​как разрешение монитора и настройки динамиков. Вы можете увидеть этот ключ сокращенно как HKCC.

HKEY_LOCAL_MACHINE
Этот ключ содержит информацию о конфигурации устройства, такую ​​как принтеры, программное обеспечение и информация о сети. Сначала загружается ключ, а затем записи из профиля пользователя переопределяют различные значения. Вы увидите этот ключ сокращенно как HKLM.

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

HKEY_CLASSES_ROOT
Этот ключ является псевдонимом, указывающим на программное обеспечение HKEY_LOCAL_MACHINES, которое хранит информацию об ассоциациях файлов и типах mime. Аббревиатура HKCR.

HKEY_CURRENT_USER
Этот ключ является псевдонимом, указывающим на профиль в HKEY_USERS для текущего пользователя, вошедшего в систему. Вы увидите этот ключ сокращенно как HKCU.

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

Работа под HKEY_CURRENT_USER достаточна для того, чтобы поиграться с несколькими сценариями CLI и песочницей. Используйте HKEY_LOCAL_MACHINE только для общесистемных данных приложений и ситуаций, когда вам удобно работать с разрешениями безопасности Microsoft. Поймите, что подходит для вашей ситуации, знайте, под какой учетной записью работает PHP, и создайте свои ключи соответствующим образом.

Создание Песочницы

Я рекомендую установить специальный ключ для использования в ваших сценариях в целях безопасности, особенно при разработке. Ошибаться — это человек, и мы не хотим случайно перезаписать что-то важное. Организация является еще одной причиной для установки назначенного ключа. В реестре хранится много информации, и мы хотим легко находить собственные значения.

Редактор реестра — это программа Microsoft, используемая для просмотра и редактирования реестра. Чтобы создать нашу песочницу, перейдите в «Пуск», введите «regedit» в строке поиска и выберите regedit.exe

Левая панель показывает древовидную структуру существующих ключей, в то время как правая панель показывает значения, хранящиеся в них. Разверните узел HKEY_CURRENT_USER, щелкните правой кнопкой мыши ключ Software и выберите New> Key из контекстного меню. В качестве альтернативы, мы могли бы также пройти через дерево с помощью клавиш со стрелками, чтобы выделить программную клавишу и выбрать «Создать»> «Ключ» в меню «Правка». Введите имя для ключа и нажмите ввод.

Теперь, когда у нас есть место для игры, позвольте мне познакомить вас с функциями, которые win32std предлагает для манипулирования записями реестра.

Чтение из реестра

Функция reg_open_key() Этот ресурс затем используется с другими функциями реестра для работы с этим соединением. Функция reg_close_key()

reg_open_key()

 <?php
$keyConst = HKEY_CURRENT_USER;

// backslash is used as an escape so it must be escaped itself
$key = "Software\Intel";

// open the registry key HKCUSoftwareIntel
if (!($reg = @reg_open_key($keyConst, $key))) {
    throw new Exception("Cannot access registry.");
}
...

reg_close_key($reg);

Теперь, когда у вас есть открытое соединение, вы можете получить информацию из реестра, используя функции reg_enum_key()reg_enum_value()reg_get_value()

Если в reg_enum_key() Целочисленное значение также может быть передано для извлечения подключа по определенному индексу.

 <?php
// retrieve an array of subkeys under the current key
$subkeys = reg_enum_key($reg);
foreach ($subkeys as $index => $subkey) {
    echo "The subkey at " . $index . " is " . $subkey . "n";
}

// retrieve a specific subkey
$index = 2;
$subkey = reg_enum_key($reg, $index);
echo "The subkey at " . $index . " is " . $subkey . "n";

Поскольку reg_enum_key()reg_enum_value() Функция принимает ресурс и необязательный индекс. Имя значения может быть передано в reg_get_value()

 <?php
// retrieve an array of values under a given key
$values = reg_enum_value($reg);
foreach ($values as $index => $value) {
    echo "The value at " . $index . " is " . $value . " and stores ";
    echo reg_get_value($reg, $value) . "n";
}

// retrieve a specific value given the index
$index = 1;
$value = reg_enum_value($reg, $index);
echo "The value at " . $index . " is " . $value . " and stores ";
echo reg_get_value($reg, $value) . "n";

Запись в реестр

Существует несколько типов данных, которые вы можете выбрать при чтении и записи в реестр. Они, как правило, не имеют большого значения из-за динамической природы PHP, но вы должны указать тип, когда пишете значение. Большую часть времени вы обнаружите, что используете REG_SZ или REG_DWORD, но вот список типов данных, представленных расширением:

  • REG_DWORD — значение хранится в виде 32-разрядного целого числа
  • REG_SZ — значение сохраняется в виде строки фиксированной длины
  • REG_EXPAND_SZ — значение сохраняется в виде строки переменной длины
  • REG_MULTI_SZ — значение представляет собой список элементов, разделенных таким разделителем, как пробел или запятая
  • REG_BINARY — значение является двоичной строкой
  • REG_NONE — значение не имеет определенного типа данных, связанного с ним

Функция reg_set_value() Если значение уже существует, то новое значение перезапишет его, но если оно не существует, оно создаст его. Функция принимает четыре аргумента: сначала открытый ресурс, затем имя значения, затем предопределенная константа, представляющая тип данных значения и, наконец, сами данные.

 <?php
$keyConst = HKEY_CURRENT_USER;
$key = "Software\SitePoint";
if (!($reg = @reg_open_key($keyConst, $key))) {
    throw new Exception("Cannot access registry.");
}

$values = array(
    array("dbDriver", REG_SZ,    "mssql"),
    array("dbHost",   REG_SZ,    "localhost"),
    array("dbPort",   REG_DWORD, 1433),
    array("dbSchema", REG_SZ,    "MyAppDB"),
    array("dbUser",   REG_SZ,    "DBUser"),
    array("dbPass",   REG_SZ,    "s3cr3t"));

foreach ($values as $value) {
    reg_set_value($reg, $value[0], $value[1], $value[2]);
}

reg_close_key($reg);

Пример — USB-накопитель

Вам может быть интересно, есть ли практическое применение для работы с реестром. В веб-приложении вы можете сохранить информацию о конфигурации в реестре. Если вы написали приложение для настольного компьютера, то реестр может быть хорошим местом для хранения всех видов информации от данных приложения до пользовательских настроек. Сама Windows записывает в реестр всевозможные интересные сведения об оборудовании и состоянии, и некоторые из них могут быть полезны, если вы достаточно креативны.

Предположим, что наше PHP-приложение лицензировано таким образом, что для его запуска необходимо подключить USB-ключ. Как PHP может обнаружить наличие ключа? Ответ на Windows лежит в реестре! Каждое устройство имеет уникальный идентификатор, поэтому сценарий может искать соответствующие ключи для идентификатора при запуске, чтобы определить, подключен ли ключ или нет.

Первым шагом является определение идентификатора устройства. Для этого примера я буду использовать товарный привод. Просто подключите диск к USB-порту компьютера, а затем перейдите в «Пуск», введите «устройство» в строке поиска и выберите «Диспетчер устройств» в появившемся списке результатов.

Найдите устройство в диспетчере устройств, щелкните правой кнопкой мыши запись и выберите «Свойства» в контекстном меню. Затем перейдите на вкладку «Сведения» в окне «Свойства» и выберите «Путь к экземпляру устройства» в раскрывающемся списке. Последовательность шестнадцатеричных чисел в конце значения — это идентификатор устройства (отмечен красным).

Windows записывает наличие USB-устройств в различных подразделах HKEY_LOCAL_MACHINESystemCurrentControlSetServices. Носители, такие как мой флэш-накопитель, появятся в разделе USBSTOR; другие устройства могут появляться под usbaudio, usbccgp и usbehci. Также обратите внимание, что HKEY_LOCAL_MACHINE будут доступны только для привилегированных учетных записей.

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

 <?php
// device instance ID
$id = "0060E049DF74EC311000711F";

// WARNING: must run with administrative privs to access these keys
$keyConst = HKEY_LOCAL_MACHINE;
$key = "SYSTEM\CurrentControlSet\services\USBSTOR\Enum";

if (!($reg = reg_open_key($keyConst, $key))) {
    throw new Exception("Cannot access registry.");
}

$found = false;
$numDevices = reg_get_value($reg, "Count");
for ($i = 0; $i < $numDevices; $i++) {
    $value = reg_get_value($reg, $i);
    if (strpos($val, $id) !== false) {
        $found = true;
        break;
    }
}    
reg_close_key($reg);

echo "USB drive dongle ", ($found) ? "found" : "not found";

Эта простая проверка также открывает некоторые другие интересные возможности; Вы можете легко закодировать чувствительный интерфейс только для администратора, который проверяет ключ и запрос отправляется с самого сервера, проверяя $_SERVER["REMOTE_ADDR"] Такая настройка потребует от пользователя физического присутствия на назначенном сервере и предоставления формы физической аутентификации.

В заключение

На протяжении всей этой статьи мы видели, что такое реестр Windows, и небольшой пример того, какую информацию можно найти в нем. Вы можете написать свои собственные данные конфигурации или вы можете прочитать информацию обратно, используя функции, предоставляемые расширением win32std.

Кстати, расширение win32std предлагает больше, чем просто доступ к реестру. Если вам интересно, посмотрите wildphp.free.fr/wiki/doku.php?id=win32std:index, чтобы узнать, что еще он предлагает.

Изображение через Fotolia