Мегаобучалка Главная | О нас | Обратная связь


Разработка подпрограмм



2015-12-15 414 Обсуждений (0)
Разработка подпрограмм 0.00 из 5.00 0 оценок




В этой программе нам понадобятся две подпрограммы: процедура записи строки в файл и процедура получения серийного номера раздела жесткого диска. Разумеется, совсем необязательно выносить их в отдельные подпрограммы, можно выполнить все в одной программе в виде монолита. Однако чем сильнее раздроблена программа на процедуры и функции, тем легче ее читать и отлаживать. Поэтому настоятельно рекомендуется создать отдельные подпрограммы для выполнения этих функций. Код подпрограммы записи строки в файл приведен в листинге 4.1. Код подпрограммы определения серийного номера раздела жесткого диска приведен в листинге 4.2.

 

procedure WriteStringToFile(Filename, Str: String; Option : Integer);

var fp : TextFile;

Begin

AssignFile(fp, Filename); // Связываем файл с дескриптором

 

Case Option Of

FP_Append: Append(fp);

Else Rewrite(fp);

End;

 

Writeln(fp, Str); // Пишем строку в файл

CloseFile(fp); // Закрываем файл, освобождаем дескриптор

 

end;

Листинг 4.1 – Код подпрограммы записи строки в файл

 

Подпрограмма записи строки в файл получает три входных параметра: имя файла, в который производится запись, строка, которую нужно записать, и режим записи. Внутри самой подпрограммы используется константа FP_Append, объявленная в секции объявлений. В зависимости от значения переменной Option файл будет либо открыт на добавление, либо перезаписан. Все остальное в этой подпрограмме уже встречалось в предыдущих лабораторных работах.

 

function GetHardDiskSerial(const DriveLetter: Char): String;

Var

NotUsed: DWORD;

VolumeFlags: DWORD;

VolumeInfo: Array[0..MAX_PATH] Of Char;

VolumeSerialNumber: DWORD;

Begin

GetVolumeInformation(PChar(DriveLetter + ':\'),

nil, SizeOf(VolumeInfo), @VolumeSerialNumber, NotUsed,

VolumeFlags, nil, 0);

Result := Format('Метка = %s С/Н = %8.8X',

[VolumeInfo, VolumeSerialNumber])

end;

Листинг 4.2 – Код подпрограммы определения серийного номера раздела HDD

 

Подпрограмма определения серийного номера раздела жесткого диска в завуалированном виде использует системную API функцию GetVolumeInformation. Эта функция описана в системной библиотеке kernel32.dll и получает на входе множество параметров. Их описание занимает достаточно много места и выходит за рамки этого пособия, но вкратце можно сказать, что GetVolumeInformation получает несколько адресов переменных типа PChar, куда на выходе будут записаны данные о параметрах раздела жесткого диска. Вторая команда возвращает результат в удобном отформатированном для вывода на экран виде.

 

Разработка подпрограмм-обработчиков событий

Поскольку на форме нашего приложения установлены четыре кнопки, нам понадобятся четыре обработчика событий нажатия на каждую из кнопок. Два обработчика вполне тривиальны и не нуждаются в особых комментариях. Это подпрограммы завершения работы приложения и очистки журнала. Коды этих подпрограмм приведены в листингах 4.3 и 4.4 соответственно.

 

procedure TfrmCopyProtect.btnQuitClick(Sender: TObject);

Begin

Close;

end;

Листинг 4.3 – Код подпрограммы-обработчика события «Выход»

 

procedure TfrmCopyProtect.btnClearLogClick(Sender: TObject);

Begin

memoLog.Clear;

end;

Листинг 4.4 – Код подпрограммы-обработчика события «Очистка журнала»

 

Теперь нам предстоит разработать оставшиеся две подпрограммы обработки событий снятия «снимка» текущей конфигурации системы и сверки конфигурации. Код подпрограммы-обработчика события снятия «снимка» конфигурации приведен в листинге 4.5. Код подпрограммы-обработчика события сверки конфигурации приведен в листинге 4.6.

 

procedure TfrmCopyProtect.btnSetConfigClick(Sender: TObject);

Var

lpVI : TOSVersionInfo; // Структура версии ОС

CurrentDriveType : Integer; // Тип текущего накопителя

DriveCSN : String;

Begin

 

// Устанавливаем защиту путем опроса системы и сохранения конфигурации

 

memoLog.Lines.Clear; // Чистим журнал

 

////////////////////////////////////////////////////////////////////////

// ТИП ТЕКУЩЕГО ДИСКА

////////////////////////////////////////////////////////////////////////

 

CurrentDriveType := GetDriveType(Nil);

// Получаем тип текущего дискового накопителя

 

memoLog.Lines.Add('ТИП ТЕКУЩЕГО НАКОПИТЕЛЯ:');

 

Case CurrentDriveType Of

0 : memoLog.Lines.Add('Тип текущего накопителя не определен');

1 : memoLog.Lines.Add('Корневой директорий не существует');

DRIVE_REMOVABLE:

memoLog.Lines.Add('Сьемный накопитель');

DRIVE_FIXED:

memoLog.Lines.Add('Несъемный накопитель');

DRIVE_REMOTE:

memoLog.Lines.Add('Сетевой диск');

DRIVE_CDROM:

memoLog.Lines.Add('Привод CD/DVD');

DRIVE_RAMDISK:

memoLog.Lines.Add('Виртуальный RAM-диск');

End;

 

memoLog.Lines.Add('');

 

WriteStringToFile(ConfigFile, IntToStr(CurrentDriveType), FP_Rewrite);

// Получаем и сохраняем тип текущего драйвера в файле

 

////////////////////////////////////////////////////////////////////////

// ТЕКУЩАЯ ВЕРСИЯ ОС

////////////////////////////////////////////////////////////////////////

 

lpVI.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);

GetVersionEx(lpVI);

// Получаем текущую версию ОС

 

memoLog.Lines.Add('ВЕРСИЯ ОС');

 

Case lpVI.dwMajorVersion Of

3 : memoLog.Lines.Add('Windows NT 3.5');

4 : memoLog.Lines.Add('Windows NT 4.0/9x');

5 : memoLog.Lines.Add('Windows 2000/XP');

End; // Старшая часть версии ОС

 

memoLog.Lines.Add('Сборка - ' + IntToStr(lpVI.dwBuildNumber));

memoLog.Lines.Add(String(lpVI.szCSDVersion));

memoLog.Lines.Add('');

 

WriteStringToFile(ConfigFile,

IntToStr(lpVI.dwMajorVersion), FP_Append);

WriteStringToFile(ConfigFile,

IntToStr(lpVI.dwMinorVersion), FP_Append);

WriteStringToFile(ConfigFile,

IntToStr(lpVI.dwBuildNumber), FP_Append);

WriteStringToFile(ConfigFile, IntToStr(lpVI.dwPlatformId), FP_Append);

WriteStringToFile(ConfigFile, String(lpVI.szCSDVersion), FP_Append);

// Записываем информацию в файл

 

////////////////////////////////////////////////////////////////////////

// НОМЕР РАЗДЕЛА ЖЕСТКОГО ДИСКА

////////////////////////////////////////////////////////////////////////

 

memoLog.Lines.Add('СЕРИЙНЫЙ НОМЕР ТОМА');

 

DriveCSN := GetHardDiskSerial('C');

// Получаем информацию о диске С

 

memoLog.Lines.Add(DriveCSN);

 

WriteStringToFile(ConfigFile, DriveCSN, FP_Append);

// Записываем информацию в файл

end;

Листинг 4.5 – Код подпрограммы-обработчика события снятия «снимка» конфигурации

 

Несмотря на значительный объем код, приведенный в листинге 4.5, очень прост и выполняется линейно без глубоких ветвлений и циклов. Логически он состоит из трех блоков: блока определения типа текущего диска (съемный, несъемный, CD-ROM, RAM-диск, сетевой и т.д.), блока определения типа и версии операционной системы и блока определения серийного номера раздела жесткого диска. Эти блоки, в общем-то, не зависят друг от друга, и некоторые из них могут вообще отсутствовать в программе. Однако, поскольку речь идет о конфигурации системы, чем большее количество параметров мы учтем, тем выше, в конечном счете, окажется вероятность определения законности производимого запуска программы. Все логические блоки имеют одинаковую структуру. Сначала производится обращение к системной API функции для получения информации о конфигурации. Затем полученные данные анализируются с помощью оператора case (только в том случае, если полученные данные закодированы, или имеют сложную структуру), выводятся на пользовательскую форму и сохраняются в файл.

 

procedure TfrmCopyProtect.btnCheckConfigClick(Sender: TObject);

Var

lpVI : TOSVersionInfo; // Структура версии ОС

CurrentDriveType : Integer; // Тип текущего накопителя

fp : TextFile;

tempStr : String;

isAnyError : Boolean;

DriveCSN : String;

Begin

// Проверка конфигурации путем опроса текущей и сверки с сохраненной

 

AssignFile(fp, ConfigFile);

Reset(fp);

// Готовим файл конфигурации к загрузке

 

isAnyError := False; // Инициализируем флаг ошибки

memoLog.Lines.Clear; // Чистим журнал

 

////////////////////////////////////////////////////////////////////////

// ТИП ТЕКУЩЕГО ДИСКА

////////////////////////////////////////////////////////////////////////

 

CurrentDriveType := GetDriveType(Nil);

// Получаем тип текущего дискового накопителя

 

memoLog.Lines.Add('ТИП ТЕКУЩЕГО НАКОПИТЕЛЯ:');

 

Readln(fp, tempStr);

// Загружаем сохраненное в файле значение

 

If tempStr = IntToStr(CurrentDriveType) Then memoLog.Lines.Add('OK')

Else

Begin

memoLog.Lines.Add('ОШИБКА!');

isAnyError := True;

End;

 

memoLog.Lines.Add('');

 

////////////////////////////////////////////////////////////////////////

// ТЕКУЩАЯ ВЕРСИЯ ОС

////////////////////////////////////////////////////////////////////////

 

lpVI.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);

GetVersionEx(lpVI);

// Получаем текущую версию ОС

 

memoLog.Lines.Add('ВЕРСИЯ ОС');

 

Readln(fp, tempStr);

If tempStr = IntToStr(lpVI.dwMajorVersion)

Then memoLog.Lines.Add('Семейство ОС - ОК')

Else

Begin

memoLog.Lines.Add('Семейство ОС - ОШИБКА!');

isAnyError := True;

End; // Проверка семейства ОС

 

Readln(fp, tempStr);

If tempStr = IntToStr(lpVI.dwMinorVersion)

Then memoLog.Lines.Add('Версия ОС - ОК')

Else

Begin

memoLog.Lines.Add('Версия ОС - ОШИБКА!');

isAnyError := True;

End; // Проверка версии ОС

 

Readln(fp, tempStr);

If tempStr = IntToStr(lpVI.dwBuildNumber)

Then memoLog.Lines.Add('Сборка - OK')

Else

Begin

memoLog.Lines.Add('Сборка - ОШИБКА!');

isAnyError := True;

End; // Проверка сборки ОС

 

Readln(fp, tempStr);

If tempStr = IntToStr(lpVI.dwPlatformId)

Then memoLog.Lines.Add('Платформа - ОК')

Else

Begin

memoLog.Lines.Add('Платформа - ОШИБКА!');

isAnyError := True;

End; // Проверка платформы

 

Readln(fp, tempStr);

If tempStr = String(lpVI.szCSDVersion)

Then memoLog.Lines.Add('Service Pack - OK')

Else

Begin

memoLog.Lines.Add('Service Pack - ОШИБКА!');

isAnyError := True;

End; // Проверка номера сервис пака

 

memoLog.Lines.Add('');

 

////////////////////////////////////////////////////////////////////////

// НОМЕР РАЗДЕЛА ЖЕСТКОГО ДИСКА

////////////////////////////////////////////////////////////////////////

 

DriveCSN := GetHardDiskSerial('C');

// Получаем информацию о текущем томе

 

Readln(fp, tempStr);

 

memoLog.Lines.Add('СЕРИЙНЫЙ НОМЕР ТОМА');

 

If tempStr = DriveCSN Then memoLog.Lines.Add('ОК')

Else

Begin

memoLog.Lines.Add('ОШИБКА!');

isAnyError := True;

End; // Проверка серийного номера тома

 

CloseFile(fp); // Закрываем файл, освобождаем дескриптор

 

If isAnyError Then

Application.MessageBox('Параметры системы не соответствуют' +

+ ' сохраненным данным','Неудача')

Else

Application.MessageBox('Проверка прошла успешно','Успех');

 

end;

Листинг 4.6 – Код подпрограммы-обработчика события сверки конфигурации со «снимком»

 

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

 

Общее задание

 

В данном примере все операции (и снятие конфигурации и проверка) реализованы в одной программе, тогда в действительности «снимок конфигурации» должна снимать программа-инсталлятор, а проверку производить сама защищаемая программа. Поэтому, прежде всего, нужно разнести эти функции по разным программам и обеспечить их сопряжение. Программа-инсталлятор должна записывать «снимок» системы в файл, а защищаемая программа должна иметь возможность загрузить его оттуда и проверить соответствие реальной и сохраненной конфигурации.

 



2015-12-15 414 Обсуждений (0)
Разработка подпрограмм 0.00 из 5.00 0 оценок









Обсуждение в статье: Разработка подпрограмм

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

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



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (414)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.008 сек.)