Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #71, НОЯБРЬ 2004 г.

Live Update в X-стиле

[RU].Ban0K! (www.int3.net)

Хакер, номер #071, стр. 071-106-3


Вызов ее довольно прост:

Status := InternetReadFile(hUrl,@Buffer,SizeOf(Buffer),nr);

После этого мы получаем в Status логическое значение - False при неудаче и True, соответственно, при удачном вызове процедуры. Buffer будет содержать NumberOfBytesRead прочитанных данных.

5). InternetCloseHandle. Рассмотрение API мы закончим этой функцией, которая закрывает все открытые дескрипторы.

function InternetCloseHandle(hInet: HINTERNET): BOOL; stdcall;

Здесь hInet – это наши дескрипторы. Данную функцию мы должны будем вызвать два раза: один раз с параметром hURL и второй раз - с hSession.

Итак, кирпичики функций мы подготовили, осталось только сложить из них наше прекрасное здание исходного кода :).

Создание типовых функций

Весь исходный код для удобства я разбил на функции. Они не зависят друг от друга (ну, быть может, только чуть-чуть :)), и их можно безболезненно переносить в свои программки. Сначала давай разберемся с функциями, при помощи которых будут скачиваться обновления. Разжевывать все подряд я не буду, поскольку со многими вещами ты в состоянии разобраться сам. Возьмем, к примеру, функции Connect и Disconnect - первая проверяет соединение с интернетом и выдает идентификатор соединения, вторая - закрывает этот идентификатор. В первой я использовал функцию InternetGetConnectedState (кстати, попробуй провести исследование на тип подключения самостоятельно, используя InternetGetConnectedStateEx).

Функция GetVersion будет выглядеть так, как указано в листинге 2 (я пропустил объявление некоторых переменных, думаю, их типы и так понятны, если же нет, смотри прилагаемый исходник). В этой функции в качестве буфера используется массив типа Char, но я бы рекомендовал переправить его под использование динамической памяти, которая локализуется функцией AllocMem и позволяет не терять времени на инициализацию, так как автоматически обнуляет память (в отличие от ее соотечественниц), либо использовать небольшой массив.

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

Процедура обработки GetFileSize запроса, в общем, идентична предыдущей (листинг 3), да и принципиальных отличий также мало. Тут следует использовать динамическое выделение памяти, так как нам заранее неизвестно, буфер какой длины понадобится для получения файла. В функции InternetReadFile теперь придется указать длину файла как FileSize. Также обрати внимание, каким образом передается параметр буфера в функции FileWrite.

Для того чтобы не обновлять ПО по несколько раз, у нас должна быть записана текущая версия, а при успешном апдейте мы должны ее менять. Для этого можно использовать либо реестр, либо ini-файл. Я пошел вторым путем, результат чего показан на листинге 4. Заметь, что там использован чистый API-код, для того чтобы не подгружать зазря огромные модули и не увеличивать размер exe-файла. Тем не менее, там все довольно просто: первый параметр - это секция в файле, второй - подсекция. Далее при чтении мы видим: один параметр нам не нужен (0), затем идет буфер, его размер и место для записи. На деле же все еще проще – без всяких извращений указываем, что и куда писать. Чтобы лишить себя и такого минимального напряжения, можно использовать, например, функции uses inifiles.

Назад на стр. 071-106-2  Содержание  Вперед на стр. 071-106-4