Разработка вспомогательной системной программы в системе программирования Delphi с использованием средств WinApi
Разработка вспомогательной системной программы в системе программирования Delphi с использованием средств WinApi
Разработка вспомогательной системной программы в системе программирования Delphi с использованием средств WinApi
Министерство образования и науки Российской Федерации
Государственное образовательное учреждение высшего профессионального образования
РЯЗАНСКИЙ ГОСУДАРСТВЕННЫЙ РАДИОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Кафедра ЭВМ
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА К КУРСОВОЙ РАБОТЕ
по дисциплине “Операционные системы”
по теме “Разработка вспомогательной системной программы в системе программирования Delphi с использованием средств WinApi”
Выполнил студент группы 742
Шипилов Д.А.
Руководитель Доц. Каф. ЭВМ
Засорин С.В.
Рязань 2010
Содержание
Введение
1. Техническое задание
1.1 Основания для разработки программы
1.2 Назначение разработки
1.3 Требования к программам
1.4 Требования к надежности
1.5 Требования к программной документации
1.6 Текст задания по варианту
2. Описания разработанных программ
2.1 Общие сведения
2.2 Функциональное назначение
2.3 Описание логической структуры
2.3.1 Логическая структура программы
2.3.2 Логическая структура справочной системы
2.3.3 Создание программы-инсталлятора
2.4 Используемые технические средства
2.5 Вызов и загрузка
2.6 Входные данные
2.7 Выходные данные
3. Программа и методика испытаний
3.1 Объект испытаний
3.2 Цель испытаний
3.3 Требования к программе
3.4 Требования к программной документации
3.5 Средства и порядок испытаний
3.6 Методы испытаний
3.6.1 Тестирование программы методом белого ящика
3.6.2 Тестирование программы методом чёрного ящика
4. Эксплуатационные документы
4.1 Руководство программиста
4.1.1 Общие сведения о программе
4.1.2 Структура программ
4.1.3 Проверка программ
4.1.4 Дополнительные возможности
4.1.5 Сообщения системному программисту
4.2. Руководство оператора (пользователя)
4.2.1 Назначение и условия применения программ
4.2.2 Обращение к программам для запуска
4.2.3 Входные и выходные данные
4.2.4 Сообщения оператору
Приложение
Список литературы
Введение
В данной курсовой работе было разработано приложение осуществляющее передачу данных между копиями этого приложения с помощью потоков, а также анализ системной области рабочего. Анализ производится путём ассоциирования жёсткого диска с файлом программы и дальнейшей работы с дескриптором этого файла.
1. Техническое задание
1.1 Основания для разработки программы
Основанием для разработки программы являлось задание для курсового проекта (вариант 21).
Содержание задания
Разработать многопоточное приложение, выполняющее различные операции
1)Обмен данными между двумя процессами с помощью файла проецируемого в память.
2)Анализ содержимого служебной области системного диска.
1.2 Назначение разработки
Программа служит для обмена текстовыми сообщениями между копиями этой программы, а также для анализа активных носителей, присутствующих в системе. Конкретно, происходит анализ блока параметров BIOS выбранного логического диска на носителе, и считывание и анализ таблицы разделов этого носителя.
1.3 Требования к программам
Приложение должно удовлетворять следующим требованиям
1) Обеспечивать указание данных для обмена в одном из процессов
2) Выполнять чтение и анализ содержимого служебной области, расшифровку её содержимого и представление результатов в виде таблицы на устройство стандартного вывода или в файле.
В данном приложении реализован способ представления результатов работы в устройстве стандартного вывода информации — мониторе.
Для удобства модификации приложения оно выполнено в виде нескольких функциональных модулей. Первая группа модулей служит для обмена данными между различными копиями приложения. Вторая группа модулей служит для считывания рабочей области системного, или какого-либо другого носителя информации. Приложение позволяет получить информацию о таблице разделов физического носителя и блоке параметров BIOS этого носителя.
1.4 Требования к надежности
Программа должна выдавать сообщения об ошибках в следующих случаях
1)Если не удалось создать проекцию файла
2)Не удалось синхронизировать приложение с другими копиями приложения
3)Не удалось осуществить обмен данными
4) Если не введено имя при регистрации пользователя в системе
1.5 Требования к программной документации
Приложение должно содержать справочную систему , включающую в себя всю необходимую информацию по работе программы.
1.6 Текст задания по варианту
Разработать многопоточное приложение, выполняющее операции.
1)Обмен данными между двумя процессами с помощью файлов проецируемых в память.
2)Анализ содержимого служебной области системного диска.
Исходные данные
Для выполнения первой операции использовать прикладные программы типа простых текстовых редакторов или графических редакторов.
Имя системного диска.
Полное имя файла для вывода результатов.
Технические требования и условия
Приложение должно выполнять следующие операции
Обеспечивать возможность указывать данные для обмена в одном из процессов.
Выполнять чтение и анализ служебной области , расшифровку её содержимого и представление результатов в виде таблицы на устройстве стандартного вывода или в файле.
2. Описания разработанных программ
2.1 Общие сведения
Для выполнения программы необходима ОS Windows 9x/2000/XP, а также более поздние модели такие как Windovs Vista или Windows7/
Программы написаны на языке программирования Object Pascal в среде разработки Delphi 7.
2.2 Функциональное назначение
Программа предназначена для обмена данными между пользователями, работающими на одной вычислительной системе под ос Windows на разных терминалах. Также программа осуществляет анализ служебной области системного диска (Partition Table носителя и блока параметров Bios логического диска того же носителя )
2.3 Описание логической структуры
2.3.1 Логическая структура программы
Этап1
Работа программы начинается с запуска приложения OffClient.exe. Перед переходом на главную форму программы появляется окно регистрации (рисунок 1.).
Рисунок 1. Окно регистрации в программе.
На этом этапе возможно наступление следующих событий
1) «Событие1» – Кнопка «Войти»;
2) «Событие2» – Кнопка «Закрыть»;
Алгоритмы обработчиков событий этой формы.
Глобальные переменные
Form2 TForm2 – переменная класса формы, отвечающая за её состояние
formClose boolean – булевская переменная отвечающая за проверку разрешения закрытия формы.
Также есть возможность обращаться к объекту TForm1 через подключение к модулю этой формы модуля главной формы (в рабочем каталоге приложения главный модуль имеет имя «Unit1»).
1) Описание события «Событие1»
Выполнение обработчика начинается при нажатии кнопки «Войти».
Для успешного выполнения обработчика события «Событие1» необходимо ввести псевдоним в соответствующее поле. После нажатия на кнопку «войти» происходит проверка поля ввода псевдонима, если поле пустое , то выводится сообщение о том, что необходимо ввести псевдоним, если поле псевдонима не пустое, то специальной переменной булевского типа, которая сигнализирует о том, что форма регистрации может быть закрыта присваивается значение TRUE. После этого, происходить передача псевдонима в основную форму программы. Очистка поля Memo1 на главной форме программы. Далее происходит вызов процедуры из главного модуля программы WriteDatainMMF для оповещения других пользователей о том что подключился новый пользователь. Далее происходит закрытие данной формы и переход к основной форме программы.
Алгоритм обработки данного события представлен на схеме – (блок схема1)
Блок схема 1 Алгоритм обработки события «Событие 1»
Данный алгоритм реализует процедуру регистрации пользователя в системе под определённым именем «NICKNAME», которое он вводит в поле псевдонима. При этом программа оповещает других пользователей, которые уже зарегистрированы, о подключении ещё одного пользователя с именем «NICKNAME». После регистрации каждое отправленное сообщение будет маркировано как сообщение от определённого пользователя с именем «NICKNAME».
2) Описание события «Событие2»
Выполнение обработчика события начинается при нажатии кнопки «Закрыть».
Алгоритм выполнения обработчика представлен на схеме «блок схема 2».
Этап 2
На этом этапе происходит переход к главной форме приложения(рисунок2). и происходит обмен сообщениями помощью файла , проецируемого в память. Также на этой форме имеются кнопки для перехода к окну информации о системных носителях. Это сделано исходя из задания на курсовой проект
Рисунок2. Форма основного приложения.(программно Form2).
На этом этапе возможны следующие события
1) «Событие1» при на жатии на кнопку «ОТПРАВИТЬ»
2) «Событие2»при нажатии кнопку «Отсоединиться»
3) «Событие3» при нажатии на кнопку «Соединиться»
4) «Событие4» при нажатии на кнопку с изображение каталога.
5) «Событие5» при нажатии на кнопку с изображением дискеты
6) «Событие6» при нажатии на кнопку с изображением восклицательного занка.
7) «Событие7» при нажатии на кнопку «Закрыть»
8) «Событие8» при нажатии на кнопку с изображением жёсткого диска.
Алгоритмы обработчиков событий для основной формы программы
Глобальные переменные
TxtFile TextFile; Файл для сохранения и загрузки истории переписки
St PansiChar; .// строка для хранения текста сообщений об ошибках и программных сообщениях.
lincInt Boolean; переменная для проврки правильности соединения
TxtContaningStr String;// строка , содержащая текст. Используется для хранения текста загружаемой и сохраняемой ситории сообщений.
userName string; Переменная хранящая имя пользователя, работающего с программой.
Также в программе используются публичные переменные , доступные во всей сборке(всех модулях данного приложения)
HMutex THandle; — дескриптор объекта типа
ThreadRec TThreadReceiver;-дескриптор объекта типа поток, для принятия сообщений посланных из первичного потока приложения.
HEvent THandle;- дескриптор объекта типа событие. Необходим для сообщения вторичным потокам об отправке данных из первичного потока
HFileSender Thandle;-Дескриптор файла , проецируемого в память, необходим для обращения к файлу ,проецируемому в память, и обмена через него информацией с другими приложениями.
1) Описание события «Событие1»
Наступление события происходит при нажатии на кнопку «ОТПРАВИТЬ». После нажатия на кнопку «ОТПРАВИТЬ» происходит проверка присутствия данных в поле ввода сообщения , если данные отсутствуют, то происходит выход из процедуры, если данные присутствуют, то происходит вызов процедуры WriteDataInMMF. В данной процедуре происходит ожидания объекта типа Mutex в течении бесконечного интервала времени. Это необходимо для реализации обмена сообщениями между несколькими копиями приложения. В данный момент происходит попытка захвата разделяемого ресурса — файа, проецируемого в память. После захвата объекта типа MUTEX происходит проецирование файла на адресное пространство основного процесса. Если файл спроецирован успешно, то происходит запись данных в этот файл, которые становятся доступны для чтения другим процессам, а затем проекция удаляется. Если проекцию создать не удалось, то выводится сообщение «Не удалось создать проекцию файла». Алгоритм представлен на схемеах(блок схема 2.1, блок схема 2.2).
Блок схема 2.1 Алгоритм обработки события «Событие1».
Блок схема 2.2 Алгоритм процедуры передачи данных.
Данный алгоритм реализуется при нажатии на кнопку «ОТПРАВИТЬ» . В теле обработчика события «Событие1» вызывается данная процедура.(передачи данных. Программно «WriteDataInMMF»)
2) Описание события «Событие2»
Данное событие происходит при нажатии на кнопку «Отсоединиться». После нажатия на кнопку «Отсоединится» происходит вызов метода Terminate для потока, который осуществляет приём данный, то есть считывание их из проецируемого файла. Далее , пока поток не остановлен, В проецируемый файл, с помощью рассмотренной выше функции WriteDataInMMF Записываются данные о том, что пользователь отключился. Далее происходит ожидание завершения потока и освобождение ресурсов памяти выделенных этому потоку. После этого происходит уничтожение дескрипторов всех объектов необходимых для обмена информацией таких как файл проецируемый в память , обьект типа mutex и объект типа, событие, который необходим, для оповещения вторичных потоков приложений о том, что данные записаны в проецируемый файл. Алгоритм работы представлен на схеме (блок схема 2.3).
Блок схема 2.3 Алгоритм обработчика события «Событие2».
3) Описание события «Событие3». Событие происходит при нажатии на кнопку «Соединится». При нажатии на данную кнопку происходит создание дескрипторов объектов , необходимых для обмена, эти дескрипторы были рассмотрены выше. Далее происходит запуск на выполнение вторичного потока приложения, который осуществляет считывание данных из проецируемого файла после их записи. Далее происходит запись данных в проецируемый файл с помощью функции. Алгоритм работы представлен на схеме(блок схема 2.4).
Блок схема алгоритма события «Событие3».
4) Описание события «Событие4».
Загрузка истории сообщений пользователей Событие наступает при нажатии на кнопку . После нажатия на данную кнопку происходит запуск объекта Open Dialog, в котором выбирается файл для загрузки, далее происходит создание файловой переменной и ассоциирование её с выбранным в Open Dialog файлом, далее в цикле происходит считывание строк из файла и последовательная запись их в поле истории переписки. После считывания файла целиком цикла завершается и происходит закрытие файла. Алгоритм обработки данного события представлен на схеме (блок схема 2.5).
Блок схема 2.5 Обработчик события «Событие4».
5) Описание события «Событие 5». Сохранение истории переписки участников чата.
Событие наступает при нажатии на кнопку . При нажатии на эту кнопку появляется диалоговое окно , где предлагается задать имя файлу и каталог, в котором этот файл будет сохранён, далее происходит ассоциирование созданного файла с файловой переменной и открытие этого файла для записи. Построчно текст из поля истории переписки заносится в строковую переменную , а затем в файл. Алгоритм обработчика события данной процедуры представлен на схеме(блок схема 2.6).
Блок схема 2.6. Алгоритм обработчика события «Событие 5».
6) Описание события «Событие 6». Это событие происходит по нажатию кнопки. При этом происходит вызов предметного указателя файла справки, который находится в рабочем каталоге приложения.
7) Описание события «Событие7». Происходит по нажатию на кнопку «Закрыть».Алгоритм обработчика представлен на схеме (блок схема 2.7).
Блок схема 2.7 обработчик события «Событие7».
8) Описание события «Событие8». Это событие происходит по нажатию на кнопку . При этом происходит создание третьей формы приложения, переход на которую является третьим этапом построения приложения. Алгоритм обработчика события представлен на схеме (блок схема 2.8).
Блок схема 2.7.
Этап3
На этом этапе происходит переход к третьему окну приложения. На данном этапе реализуется вторая часть задания на курсовой проект – анализ служебной области системного диска Форма3 приложения OffClient имеет заголовок «Служебная информация о системных носителях» её вид представлен на рисунке 3.
Рисунок 3. Окно отображения служебной информации о носителе.
При работе с данной формой возникает 4 события
С1-начать работу с диском
С2-Считать BPB (Блок параметров BioS)
C3-Счтать Partition Table.(Таблицу разделов диска).
С4-Закрытие формы. Данное событие имеет стандартный обработчик. Его описание опущено.
Алгоритм обработки событий для третьей формы приложения.
Глобальные переменные
hDrive,hMBRDrive THandle; — Дескрипторы дисков для работы с главной загрузочной записью носитель и блоком параметров Bios.
DiscGeometry TDiscGeometry; — Структрура DiscGeometry Имеет в своём составе такие поля как количество секторов на дорожке , количество дорожек на носителе , количество байт в секторе,
1) Описание события С1. Данное событие происходит при нажатии на кнопку
«Начать работу с диском». Если дескрипторы дисков уже существуют, то происходит их уничтожение. Далее происходит создание новых дескрипторов дисков. Если дескрипторы создаются успешно, то происходит заполнение структуры Disk Geometry, в полях которой содержатся данные о диске и вывод их в соответствующее поле. Если дескрипторы создать не удалось, то выводится сообщение об ошибке.
Алгоритм обработки данного события представлен на схеме1.
Схема 1 — Алгоритм работы обработчика события С1.
2) Описание события С2 Данное событие происходит по нажатию на кнопку
«Считать BPB», после этого происходит обработка этого события. Данные из дескриптора диска читаются в буфер, эти данные располагаются в первом секторе логического диска. Если данные считаны, то происходит заполнение специальных таблиц данными из этого буфера, если нет, то выводится специальное сообщение о том, что данные прочитать не удалось.
Алгоритм обработчика этого события представлен на схеме2.
Схема2 –Обработчик события С2. «Считывание блока параметров BIoS»
3) Описание события С3. Данное событие аналогично предыдущему, за исключением сектора который необходимо прочитать. Данное событие реализуется при нажатии на кнопку «считать Partition Table». Конструктивно данный алгоритм идентичен предыдущему – данные из первого сектора носителя данных читаются в буфер, если они успешно прочитаны происходит заполнение соответствующих страниц данными, если нет, то выводится сообщение о том, что данные не удалось считать в буфер. Алгоритм обработчика события представлен на схеме3.
Дополнительные структуры и алгоритмы
В данном разделе будут рассмотрены дополнительные логические структуры приложения
1) Алгоритм работы потока «приёмника» (программно ThreadReceiver)
2) Алгоритм работы модуля, определяющего все активные носители, присутствующие в системе.(программно расположена в модуле HDDInfo).
1) Алгоритм работы потока «приёмника» представлен на схеме 4. Описание алгоритма В потоке организуется бесконечный цикл(пока поток не остановлен) в этом цикле проверяется некоторое событие, сигнализирующее потоку о том, что данные записаны в файл. После того как событие перешло в сигнальное состояние происходит его обратный сброс в несигнальное состояние. Затем происходит проецирование файла, переменная которого уже создана при запуске основной программы, на адресное пространство процесса. Если проекция создана, то данные читаются из файла и передаются в основную форму программы, а точнее в поле истории переписки. Если создать проекцию не удалось то появляется соответствующее сообщение.
Схема 4 – Алгоритм работы потока «приёмника».
2) Описание алгоритма работы модуля, определяющего все активные носители в системе. Алгоритм работы представлен на схемах 5,6,7 и 8.
1. Описание алгоритма (схема5) При выполнении функции, реализующей данный алгоритм, в её теле происходит создание массива имён диско – массив латинских букв A-Z. После этого в цикле происходит считывание имён дисков присутствующих в системе и сравнивание этих имён с именами из массива. Если носитель с данным именем присутствует, то это имя возвращается в качестве результата работы функции.
Схема 5 –Алгоритм получения имени носителя, присутствующего в системе.
2. Описание алгоритма (схема6 ) Данный алгоритм необходим для верного определения номера системного носителя. Входными параметрами для этой функции является номер логического диска полученный с помощью API функции GetVolumeInformation. Данный номер считывается в строку и длина этой строки присваивается специальной переменной. Если значение этой переменной не равно восьми, происходит выход из процедуры, если и значение номера не меняется, если длина равна 8, то в цикле происходит изменение номера, считанного с помощью функции GetVolumeInformation, на правильный. В семействе ОС Windows в поздних версиях таких как «XP», «Vista» и «7» номер, полученный с помощью функции GetVolumeInformation является общим для всех носителей присутствующих в системе, хотя на практике это не является таковым.
Схема 6 –алгоритм работы функции, определяющей верный номер логического диска.
Данная функция необходима для правильного определения номера логического диска, если программа запущена под операционной системой Windows Xp , или более поздних.
Схема 7-Алгоритм процедуры для получения системной информации о логическом носителе.
Входным параметром для данной функции является имя логического диска, которое извлекается при вызове функции GetDisk, алгоритм которой представлен на схеме 5.
3. Описание алгоритма (схема 8). Этот алгоритм реализуется при вызове функции, определяющей все присутствующие в системе диски, при запуске третьей формы программы(этап3). В данном алгоритме реализуется, сперва, вызов функции GetDisks, для получения имён всех дисков присутствующих в системе и записи этих имён в строку, далее в цикле происходит считывание символа из строки и получение с помощью функции GetVolumeInformation всех данных о диске с именем совпадающем со считанным символом. Если данные считаны , то происходи вывод их в специальную компоненту, если нет , то происходит заполнение полей отображающих данные о носителе нулевыми значениями.
Схема 8 – Алгоритм работы функции вызова процедуры получающей данные о всех активных носителях системы.
2.3.2 Логическая структура справочной системы.
Сначала в файле «текст справки.rtf» в редакторе MS Word составляется содержание разделов справки. Затем с помощью программы Microsoft Help Workshop создается оглавление справочной системы и проект. В оглавлении вводятся названия всех разделов и номера. В проекте указывается файл rtf, файл содержания, идентификаторам разделов сопоставляются номера и названия, устанавливаются настройки и производится компиляция. После компиляции создается файл справочной системы CПРАВКА.HLP.
Рисунок 3.1 — Пример раздела в файле «текст справки.rtf».
Рисунок 3.2 — Пример файла содержания справочной системы
.
Рисунок 3.3 — Пример файла проекта справочной системы
Рисунок 4.4 Пример окна справки.
2.3.3 Создание программы инсталлятора
Для создания инсталлятора использовалась программа InstallShield Express.
Рисунок 3.3.1 – Общая информация.
Рисунок 3.3.2 — Тип установки.
Рисунок 3.3.4 — Содержание устанавливаемых файлов проекта
Рисунок 3.3.5 — Создание ярлыков
Рисунок 3.3.6 — Выбор диалоговых окон.
Рисунок 3.3.7 — Программа установки.
Рисунок 3.3.8 — Ход установки.
Рисунок 3.3.9 — Окончание установки.
2.4 Используемые технические средства
При выполнении данной курсовой работы используется персональный компьютер операционной системой Windows7 с процессором IntelCore2Duo6300. Данный компьютер оснащен всеми устройствами необходимыми для работы в среде разработки Delphi 7 и последующем запуске полученных программ.
2.5 Вызов и загрузка
Вызов программы осуществляется выполнением приложения OffClient, ярлыки которого находятся на рабочем столе и панели программ Windows.
2.6 Входные данные
Входными данными в данной программе являются сообщения ,которые вы вводите в поле ввода сообщений. Также входными данными являются имена логических дисков, которые выбираются из выпадающего списка.
2.7 Выходные данные
Выходными данными в данном приложении являются
Для первого задания это сообщения пришедшие от пользователей других копий программы, а также сообщения, которые были посланы из текущей версии приложения
Для второго задания выходными данными являются данные о системном носителе, который выбирается из списка доступных носителей. Эта информация отображается в полях и таблицах второй части программы.
3. Программа и методика испытаний
3.1 Объект испытаний
Объектом испытаний является приложение Redactor.exe.
3.2 Цель испытаний
Целью испытании приложения является выяснение возможных ошибок во время выполнения программы, которые не были обнаружены на стадии разработки.
3.3 Требования к программе
Требуется проверить работу логической и интерфейсной частей программ. А так же обеспечить контроль входных и выходных данных.
3.4 Требования к программной документации
В приложении необходимо запустить справочную систему.
3.5 Средства и порядок испытаний
Испытание приложения будет производиться 2-мя методами “белым и черным ящиками”.
3.6 Методы испытаний
3.6.1 Тестирование методом белого ящика
Прежде чем нумеровать текст программы, необходимо все циклы изменить на структурированные, сложные условия разбить на простые, а линейные части программы(по возможности) записать в одну строку. Затем строки текста функции нумеруются номер получают только те строки, которые содержат операторы, условия или закрывающие операторные скобки.
1) Тестирование процедуры выполняющей запись данных в проецируемый файл(2 этап выполнения программы). В данном случае это является первым заданием курсового проекта — обмен данными между приложениями с помощью файла проецируемого в память.
1инициализация
2if Edit1.Text <> » then
Begin
WriteDataInMMF(Nicname+’ Написал ‘+#13#10+string(Edit1.Text));
(тело функции WriteDataInMMF(вхдными данными является строка S)
имеет следующий вид)
begin
3 WaitForSingleObject(HMutex, INFINITE);
PBaseAdress =MapViewOfFile(HFileSender,FILE_MAP_WRITE,0,0,Length(s)+4);
4 if(PBaseAdress = nil) then
begin
5 CloseHandle(HFileSender);
st =’не удалось передать данные’;
Application.MessageBox(st,’Сообщение…’,MB_OK);
exit;
end;
begin
6 integer(PBaseAdress^) =length(s);
CopyMemory(Pointer(Integer(PBaseAdress)+4),PChar(s),length(s));
UnmapViewOfFile(PBaseAdress);
SetEvent(HEvent);
ReleaseMutex(HMutex);
7 end;
8 end;
9 Edit1.Text =»;
10 end
else
11 exit;
12 end;
Рисунок 4.1 – Потоковый граф обработчика события «Событие1» которое происходит при нажатии на кнопку «ОТПРАВИТЬ» на основной форме программы.
Цикломатическая сложность потокового графа
1) V(G) = 3 региона;
2) V(G) = 13 дуг — 12 узлов + 2 = 3;
3) V(G) = 2 предикатных узла +1 = 3.
Базовое множество независимых линейных путей
Путь 1 1-2-11-12 .
Путь 2 1-2-3-4-5-12.
Путь 3 1-2-3-4-5-6-7-8-9-10-12.
Таблица тестовых вариантов 4.1
№ пути
Исходные данные
Ожидаемые результаты
Реальные результаты
1
Строка содержащая, которая должна содержать текст сообщения пуста
Не происходит отправки пустого сообщения
Состояние программы после перехода на главную форму не
2
Не удалось отобразить файл на адресное пространство процесса при обращении к дескриптору файла , проецируемого в память.
Сообщение «Не удалось отобразить файл на адресное пространство процесса»..
Сообщение «Не удалось отобразить файл на адресное пространство процесса».
3
Текст сообщения «Привет!»
Появление текста «Привет!» в поле истории переписки.
Удачный исход – появление текста «Привет!» в поле истории переписки
2) Тестирование процедуры выполняющей создание дескрипторов логического диска с
которым ведётся работа и дескриптора жёсткого диска которому принадлежит этот логический диск(3 этап выполнения программы ).
1 инициализация
2 if hDrive <> 0 then
3CloseHandle(hDrive);
4 if hMBRDrive <> 0 then
5CloseHandle(hMBRDrive);
6 discNameBPB =’.’+DriveComboBox1.Drive+’ ‘;
discNameMBR =’.PHYSICALDRIVE’+intToStr(0);
hMBRDrive = CreateFile(PChar(discNameMBR),GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
hDrive = CreateFile(PChar(discNameBPB),GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
7 if (hDrive <> INVALID_HANDLE_VALUE) and (hMBRDrive <> INVALID_HANDLE_VALUE) then
begin
8 Result = DeviceIoControl(hDrive,IOCTL_DISK_GET_DRIVE_GEOMETRY,nil,0,
@DiscGeometry,SizeOf(TDiscGeometry),junk,nil) and (junk = SizeOf(TDiscGeometry));
DiscGeometryShow();
9 end
else
begin
10 ShowMessage(‘не удалось создать дескрипторы дисков’);
11 exit;
end;
12 end;
Рисунок 4.2 Потоковый граф обработчика события «С1» которое происходит при нажатии на кнопку «Начать работу с диском»
Цикломатическая сложность потокового графа
1) V(G) = 4 регионов;
2) V(G) = 14 дуга — 12 узлов + 2 = 4;
3) V(G) = 3 предикатных узлов +1 = 4.
Путь 1 1-2-4-6-7-10-11-12;
Путь 2 1-2-3-4-6-7-10-11-12.
Путь 3 1-2-4-5-6-7-10-11-12.
Путь 4 1-2-3-4-5-7-8-9-12.
№ пути
Исходные данные
Ожидаемые результаты
Реальные результаты
1
Дескрипторы файлов не созданы .
Невозможно получить данные о носителе вывод сообщения «Не удалось создать дескрипторы файлов»
Вывод сообщения «Не удалось создать дескрипторы файлов»
2
Создан дескриптор файла BPB
Невозможно получить данные о носителе вывод сообщения «Не удалось создать дескрипторы файлов»
Вывод сообщения «Не удалось создать дескрипторы файлов»
3
Создан дескриптор файла MBR
Невозможно получить данные о носителе вывод сообщения «Не удалось создать дескрипторы файлов»
Вывод сообщения «Не удалось создать дескрипторы файлов»
4
Дескрипторы файлов существуют как MBR так и BPB
Загрузка данных о носителе.
Загрузка данных о носителе.
3) Тестирование процедуры считывающей блок параметров Bios — событие «С2» (происходит при нажатии на кнопку «Считать BPB»)логического диска
дескриптор которого был создан в процедуре обрабатывающей событие «С1» при нажатии на кнопку «Начать работу с диском»
1инициализация
2IfReadSectors(hDrive,0,1,@buffer,DiscGeometry.BytesPerSector) = DiscGeometry.BytesPerSector then
begin
3for i = 1 to 16 do
4Grid1.Cells[i,0] =intToHex((i-1),1);
5i =1; j =1; k =1;
6while k<=DiscGeometry.BytesPerSector do
begin
7 if i=1 then
8 Grid1.Cells[0,j] =IntToHex(((j-1)*16+(i-1)),3);
9 Grid1.Cells[i,j] =IntToHex(Buffer[k],2);
inc(k);
inc(i);
10 if i>16 then
begin
11 i =1;
j =j+1;
Grid1.RowCount = Grid1.RowCount+1;
12end;
13end;
14{линейный блок расшифровки данных BPB}
end
else
15ShowMessage(‘не удалось считать BPB’);
16end
17end;
программа многопоточный приложение служебный
Рисунок 4.3 – Потоковый граф обработчика события С2 (Считывание блока параметров Bios).
Цикломатическая сложность потокового графа
1) V(G) = 6 регионов;
2) V(G) = 21дуг — 17 узлов + 2 = 6;
3) V(G) = 5 предикатных узлов +1 = 6.
Путь 1 1-2-15-16-17;
Путь 2 1-2-3-4-5-6-7-9-10-12-13-14-17.
Путь 3 1-2-3-4-5-6-7-8-9-10-12-13-14-16-17.
Путь 4 1-2-3-4-5-6-7-9-10-11-12-13-14-16-17.
Путь 5 1-2-3-4-5-6-7-8-9-10-11-12-13-14-16-17.
Путь 6 1-2-3-4-3-4-5-6-7-9-10-12-13-6-7-8-9-10-11-12-13-14-16-17.
№ пути
Исходные данные
Ожидаемые результаты
Реальные результаты
1
Не удалось считать сектор BPB .
Вывод сообщения о том, что считать BPB не удалось
Вывод сообщения « не удалось считать BPB»
2
Часть данных считана , при этом номер строки остаётся прежним и номер элемента строки не достиг 16.
Вывод данных в таблицу, содержащую данные о BPB,например команду перехода на программу загрузки «EB0090h»
Вывод данных в таблицу, содержащую данные о BPB команда перехода на программу загрузки «EB0090h»
3
Чтение данных началось и строка получила значение
Вывод данных в таблицу, содержащую данные о BPB,например команду перехода на программу загрузки «EB0090h»
Вывод данных в таблицу, содержащую данные о BPB команда перехода на программу загрузки «EB0090h»
4
Строка считана и номер элемента в строке достиг 16
Вывод данных в таблицу, содержащую данные о BPB,например команду перехода на программу загрузки «EB0090h»
Вывод данных в таблицу, содержащую данные о BPB команда перехода на программу загрузки «EB0090h»
5
Строка получила номер и элемент в строке достиг 16
Вывод данных в таблицу, содержащую данные о BPB,например команду перехода на программу загрузки «EB0090h»
Вывод данных в таблицу, содержащую данные о BPB команда перехода на программу загрузки «EB0090h»
6
Чтение данных из буфера в течении нескольких проходов циклов с изменением номера строк и столбцов таблицы , содержащей значения BPB
Пошаговый вывод данных в таблицу содержащую 16рмчные значения и вывод данных в таблицу содержащую расшифрованные значения
Обе таблицы «Шестнадцатиричное представление BPB логического диска» и «Расшифровка блока параметров BIOS» заполняются необходимыми значениями
4) Тестирование процедуры, считывающей таблицу разделов носителя(событие «С3» — происходит при нажатии на кнопку «Считать Partition Table»), к которому принадлежит ,выбранный из выпадающего списка логический диск
1инициализация.
2Memo2.Clear;
3If.ReadSectors(hMBRDrive,0,1,@buffer,DiscGeometry.BytesPerSector)= DiscGeometry.BytesPerSector then
begin
4for i = 1 to 16 do
5Grid2.Cells[i,0] =intToHex((i-1),1);
6i =1; j =1; k =1;
7while k<=DiscGeometry.BytesPerSector do
begin
8if i=1 then
9Grid2.Cells[0,j] =IntToHex(((j-1)*16+(i-1)),3);
10Grid2.Cells[i,j] =IntToHex(Buffer[k],2);
inc(k);
inc(i);
11if i>16 then
begin
12 i =1;
j =j+1;
Grid2.RowCount = Grid2.RowCount+1;
13 end;
14end;
begin
15{Линейный блок расшифровки значений полученных в буфере после чтения сектора}
16end
else
17ShowMessage(‘Не удалось считать блок PartitionTable’);
18end;
Рисунок 4.4 – Потоковый граф обработчика события «С3» (кнопка «Считать PartitionTable »)
Цикломатическая сложность потокового графа
1) V(G) = 6 регионов;
2) V(G) = 22 дуга — 18 узлов + 2 = 6;
3) V(G) = 5 предикатных узлов +1 = 6.
Путь 1 1-2-17-18;
Путь 2 1-2-3-4-5-6-7-8-10-11-13-14-15-16-18;
Путь 3 1-2-3-4-5-6-7-8-9-10-11-13-14-15-16-18;
Путь 4 1-2-3-4-5-6-7-8-10-11-12-13-14-15-16-18;
Путь 5 1-2-3-4-5-4-5-6-7-8-9-10-11-13-14-15-16-18;
Путь 6 1-2-3-4-5-4-5-6-7-8-10-11-12-13-14-7-8-9-10-11-13-14-15-16-18;
№ пути
Исходные данные
Ожидаемые результаты
Реальные результаты
1
Если не удалось считать Partition Table
Должно появиться сообщение о том , что не возможно считать Partition Table
Вывод сообщения «Не удалось считать Partition Table»
2
Происходить считывание элемента массива , который имеет номер отличающийся от 1 и от 16.
Вывод данных, например «Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }»
Вывод данных, например «Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }»
3
Считывание элемента массива , который имеет номер 1 в строке таблицы
Вывод данных, например «Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }»
Вывод данных, например «Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }»
4
Считывание элемента, который имеет последний номер в строке (16)
Вывод данных, например «Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }»
Вывод данных, например «Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }»
5
Считывание данных из массива. При прохождении этого пути проверяется заполнение верхней строчки таблицы номерами от 0 до F.
Вывод данных, например «Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }»
Вывод данных, например «Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }»
6
Считывание данных из массива. Когда элемент имеет номер 16 в строке, а последующий элемент имеет номер 1 в след. строке.
Вывод данных, например «Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }»
Вывод данных, например «Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }»
Дополнительный тест
Тестирование алгоритма работы потока, который также относится к основному заданию курсового проекта.
1инициализация.
2while (not terminated) do
begin
3 WaitForSingleObject(Form1.HEvent, INFINITE);
4 ResetEvent(Form1.HEvent);
5 try
// резерв. память в потоке для этотой проекции
6PBaseAdress =MapViewOfFile(Form1.HFileSender, FILE_MAP_READ,0,0,65536);
7 if (PBaseAdress = nil) then
begin
8 CloseHandle(Form1.HFileSender);
st =’не удалось отобразить файл на адресное пространство’;
Application.MessageBox(st,’Сообщение…’,MB_OK);
form1.BitBtn2.Visible =false;
form1.Button1.Visible =false;
9 exit;
10end;
11 nlineSize =integer(PBaseAdress^);
SetLength(TextString,nlineSize);
CopyMemory(PChar(TextString),Pointer(Integer(PBaseAdress)+4),nlineSize);
Form1.Memo1.Text =Form1.Memo1.Text+’———‘+#13#10;
Form1.Memo1.Text =Form1.Memo1.Text+TextString+#13#10;
sendmessage(Form1.memo1.handle, em_linescroll, 0, Form1.memo1.lines.count-1);
UnmapViewOfFile(PBaseAdress);
finally
12end;
13end;
Рисунок 4.5 – Потоковый граф обработчика потока(данный обработчик выполняется постоянно после запуска программы и если не была нажата кнопка «отсоединится при работе программы»)
Цикломатическая сложность потокового графа
1) V(G) = 3 регионов;
2) V(G) = 14 дуг — 13 узлов + 2 = 3;
3) V(G) = 2 предикатных узлов +1 = 3.
Путь 1 1-2-3-4-5-6-7-8-9-13;
Путь 2 1-2-3-4-5-6-7-10-11-12-13;
Путь 3 1-2-3-4-5-6-7-8-9-10-11-12-2-3-4-5-6-7-10-11-12-13;
№ пути
Исходные данные
Ожидаемые результаты
Реальные результаты
1
Не удалось отобразить файл на адресное пространство в потоке.
Должно появиться сообщение не удалось отобразить данные на адресное пространство потока
Вывод сообщения «Не отобразить файл на адресное пространство»
2
Ввод данных в поле сообщения и однократное нажатие на кнопку «отправить»
Вывод сообщения «отправить» в поле истории переписки.
Сообщение введённое в поле сообщений «отправить» появилось в поле истории переписки.
3
Ввод сообщения в поле сообщений и нажатие на кнопку «отправить» с последующим повторение этих действий
Вывод сообщения «отправить» в поле истории переписки.
Сообщение введённое в поле сообщений «отправить» появилось в поле истории переписки.
3.6.2 Тестирование методом черного ящика
1) Тестирование процедуры, выполняющей запись данных в проецируемый файл
(Рисунок 4.6. ).
(Этап выполнения программы 2 «Событие 1»).
Предусловие Текст сообщения должен быть обязательно введён.
Постусловие Если проекция файла создана, и объект типа поток сработал нормально, то вывод текста сообщения в поле истории переписки.
Рисунок 4.6 – Дерево разбиений для события «Событие1» (первое задание)
№ листа
Исходные данные
Ожидаемые результаты
Реальные результаты
1
Сообщение не введено
Никаких действий не должно происходить, программа не должна отвечать на действия такого рода
Программа никак не реагирует
2
Проекция файла не создана
Вывод сообщения «Не удалось передать данные»
Вывод сообщения «Не удалось передать данные»
3
Поток не сработал
Вывод сообщения «Не удалось создать проекцию файла»
Вывод сообщения «Не удалось создать проекцию файла»
4
В поле ввода сообщения введено «СЛОВО»
Вывод сообщения с содержимым «СЛОВО» в поле истории переписки
В поле истории появится сообщение с текстом «<имя введённое при авторизации> написал СЛОВО»
2) Тестирование процедуры выполняющей создание дескрипторов носителя с которым ведётся работа (Рисунок 4.7).
(Этап выполнения программы 3 , событие С1).
Предусловие Программа должна быть запущена от имени администратора.
Постусловие 1 Должен быть выбран присутствующий носитель.
2 Если дескрипторы файлов успешно созданы и данные прочитаны в буфер, то- вывод информации в таблицы.
Рисунок 4.7 Дерево разбиений для процедуры, выполняющей создание дескрипторов носителя(Этап выполнения программы 3 события C1).
№ листа
Исходные данные
Ожидаемые результаты
Реальные результаты
1
Программа запущена не от имени администратора
Заполнение таблиц ,содержащих данные о BPB и данные о Partition Table нулевыми значениями.
Заполнение таблиц нулевыми значениями
2
Выбран носитель отсутствующий в списке активных носителей
Заполнение таблиц ,содержащих данные о BPB и данные о Partition Table нулевыми значениями.
Заполнение таблиц нулевыми значениями
3
Если не удалось создать дескрипторы файлов, отождествляющих жёсткий и логический диски.
Вывод сообщения «Не удалось создать дескрипторы носителя»
Вывод сообщения «Не удалось создать дескрипторы носителя»
4
Выбран активный носитель и дескрипторы носителя успешно созданы.
Вывод данных о блоке параметров Bios , Partition Table и расшифрованных значений в специальные таблицы.
Заполнение таблиц всеми необходимыми данными о носителе.
3)Тестирование процедуры, выполняющей считывание блока параметров Bios (Рисунок 4.8).
(Этап выполнения программы 3 , событие «С2»).
Предусловие Дескрипторы должны быть созданы.
Постусловие Файловая система должна быть FAT32.
Рисунок 4.8 –Дерево разбиений для процедуры, выполняющей считывание блока BPB для выбранного носителя.
№ листа
Исходные данные
Ожидаемые результаты
Реальные результаты
1
Дескрипторы не созданы.
Вывод сообщения «Не удалось считать блок параметров Bios»
Вывод сообщения «Не удалось считать блок параметров Bios»
2
Файловая система отличается от FAT32.
Заполнение таблицы расшифровки BPB неверными значениям , например «Количество FAT 0»
Заполнение таблицы содержащей расшифрованные данные о BPB неверными значениям «Количество FAT 0»
3
Файловая система FAT32
Заполнение таблицы расшифровки верными значениями, например «количество FAT 2»
Заполнение таблицы расшифровки верными значениями «количество FAT 2»
4)Тестирование процедуры, считывающей таблицу разделов жёсткого диска(Рисунок 4.9).
(Этап выполнения программы 3 , событие «С3»).
Предусловие Программа должна быть запущена от имени администратора.
Постусловие Дескрипторы должны быть созданы.
Рисунок 4.9 – Дерево разбиений для процедуры считывающей таблицу разделов носителя.
№ листа
Исходные данные
Ожидаемые результаты
Реальные результаты
1
Программа запущена не от имени администратора.
Заполнение полей таблицы расшифровки нулевыми значениями.
Заполнение полей таблицы расшифровки нулевыми значениями.
2
Дескрипторы не созданы
Вывод сообщения «Не удалось считать PartitionTable»
Вывод сообщения «Не удалось считать PartitionTable»
3
Дескрипторы созданы
Заполнение таблицы расшифровки верными значениями, например «Размер раздела { 61432497 }»
Заполнение таблицы расшифровки верными значениями «Размер раздела { 61432497 }»
5)Тестирование процедуры работы потока.(Рисунок 4.10).
Предусловие 1.Поток должен быть запущен.
2.Средства синхронизации созданы.
Постусловие Файл проецируемый в память должен быть успешно создан.
Рисунок 4.10 – Дерево разбиений для процедуры работы потока.
№ листа
Исходные данные
Ожидаемые результаты
Реальные результаты
1
Средства синхронизации не созданы.
Вывод сообщения «не удалось осуществить обмен сообщениями»
Вывод сообщения «не удалось осуществить обмен сообщениями»
2
Проекция файла не создана.
Вывод сообщения «не удалось отобразить файл на адресное пространство»
Вывод сообщения «не удалось отобразить файл на адресное пространство»
3
Проекция файла создана. Было введено сообщение «Отправлено»
Вывод сообщения «Отправлено»
Вывод сообщения «Отправлено»
4. Эксплуатационные документы
4.1 Руководство программиста
4.1.1 Общие сведения о программе
Программа предназначена для обмена сообщениями между копиями этой программы с помощью файла, проецируемого в память. А также для анализа рабочей области системного диска, т.е анализ и расшифровку блока параметров Bios и анализ и расшифровку таблицы разделов носителя.
4.1.2 Структура программы
После запуска приложения появляется форма «Авторизация» для присвоения пользователя специального псевдонима для обмена информацией. Форма содержит две кнопки «Войти» и «Закрыть». По нажатию кнопки «закрыть» происходит выход из приложения. По нажатию кнопки «войти» происходит переход на основную форму программы, данная форма содержит поле вывода сообщений – «поле истории переписки», также поле ввода сообщений, кнопку «ОТПРАВИТЬ» для отправки сообщений, а также кнопки отсоединиться, закрыть и соединится, которая будет появится на форме только после нажатия на кнопку «отсоединиться». Также на форме присутствует панель инструментов с кнопками
1. Сохранить историю переписки,
2. Загрузить историю переписки.
3. Получить данные о носителях.
4. Справка.
При нажатии на первую кнопку появляется диалоговое окно, в котором необходимо выбрать файл, содержащий историю переписки, если такой имеется, и вывод содержимого этого файла в поле истории переписки.
При нажатии на вторую кнопку происходит открытие диалогового окна, в котором предлагается назначить сохраняемому файлу имя и каталог, в котором данный файл будет сохранён. Содержимым данного файла будет являться история последней переписки.
При нажатию на четвёртую кнопку происходит запуск файла справочной системы, содержащей всю необходимую информацию о программе.
При нажатии на третью кнопку происходит открытие дополнительного окна программы.
Дополнительное окно программы имеет заголовок «Служебная информация о носителях». Это окно содержит поле вывод информации о всех носителях присутствующих в системе . Поле вывода краткой информации о носителе, поле вывода расшифрованной информации о блоке параметров Bios, поле вывода расшифрованной информации о таблице разделов носителя, а также две таблицы, содержащие 16ричные значения первого сектора логического диска- блок параметров Bios и 16ричные значения первого сектора носителя, к которому относится выбранный логический диск (в этом секторе находится таблица разделов логического диска – Partition Table). Также на форме находятся 4 кнопки
1. Начать работу с диском
2. Считать BPB(блок параметров Bios)
3. Считать Partition Table.
4. Закрыть.
При нажатии на первую кнопку происходит вывод краткой информации о носителе. При нажатии на кнопку «Считать BPB» происходит считывание блока BPB и заполнение значениями таблицы содержащей расшифрованные данные из BPB и таблицы, содержащей 16ричные значения считанные из BPB, выбранного логического диска.
При нажатии на кнопку – «Считать Partition Table» происходит считывание первого сектора носителя информации и заполнение данными таблицы, содержащей расшифрованные данные о таблице разделов диска и таблицы содержащей 16ричные значения считанные из первого сектора носителя.
4.1.3 Проверка программы
Входные данные строка сообщения «сообщение №1»; логический диск «H».
Выходные данные «сообщение№1»;
Краткая информация о носителе
«Вы просматриваете логический диск h
Количество цилиндров 247
Тип носителя съёмный носитель
Дорожек на цилиндре 255
Секторов на дорожке 63
Байт в секторе 512»
Информация о таблице разделов диска
Первый элемент таблицы разделов системного диска
Признак загрузки 80
Начало раздела диска{Головка 1 Сектор 1 Цилиндр 0 }
Тип раздела {Ос 7 }
Конец раздела диска{Головка 254 Сектор 255 Цилиндр 255 }
Номер Сектора { 63 }
Размер раздела { 61432497 }
Второй элемент таблицы разделов системного диска
Признак загрузки 00
Начало раздела диска{Головка 255 Сектор 255 Цилиндр 15 }
Тип раздела {Ос 254 }
Конец раздела диска{Головка 255 Сектор 255 Цилиндр 240 }
Номер Сектора { 61432560 }
Размер раздела { 318782480 }
4.1.4 Дополнительные возможности
Программа имеет справочную систему, для её запуска необходимо нажать кнопку , или F1 на клавиатуре. Также программа определяет носители доступные в системе, это происходит автоматически при переходе на третью форму программы.
4.1.5 Сообщения системному программисту
1) При подключении, если не удалось создать проекцию файла при запуске программы, появляется сообщение
Рисунок 5.1 –Содержание сообщения
2)Если не удалось создать объект типа Mutex для обмена сообщениями с другими программами, появляется сообщение
Рисунок 5.2 – Содержание сообщения.
3) Если не удалось наладить приём сообщений от других копий программ, появляется сообщение
Рисунок 5.3 – Текст сообщения.
4) Если не удалось создать объект типа события для оповещения потока о том, что данные записаны в проецируемый файл, появляется сообщение
Рисунок 5.4 –Текст сообщения.
5) Если не удалось передать данные (записать данные в проецируемый файл) , появляется сообщение
Рисунок 5.6 – Текст сообщения.
4.2 Руководство пользователя
4.2.1 Назначение и условия выполнения программы
Данная программа предназначена для обмена сообщениями между копиями данной программы, а также для получения системной информации о носителях. Для выполнения программы необходим IBM-совместимый персональный компьютер, оснащенный процессором Intel или аналогичным и операционной системой семейства Windows.
4.2.2 Обращение к программе для запуска
Для запуска программы необходимо запустить приложение с Redactor.exe . Это делается с помощью ярлыка , который появляется на рабочем столе после установки, с именем OffClient.
4.2.3 Входные и выходные данные
Входными и выходными данными при обмене сообщениями являются сами сообщения. При получении служебных данных о носителях входными данными являются имена этих носителей, а выходными – данные о них, такие как
Количество цилиндров, тип носителя, дорожек на цилиндре, секторов на дорожке, байт в секторе и т.д.
4.2.4 Сообщения оператору
1) Если не введён псевдоним при регистрации то появится сообщение
Рисунок 5.7 — Текст сообщения.
2) Если не удалось передать сообщение
Рисунок 5.8 – Текст сообщения.
Приложение
1) Текст основного модуля программы
program Redactor;
uses
Forms,
Unit1 in ‘Unit1.pas’ {Form1},
ThrdRcvr in ‘ThrdRcvr.pas’,
Unit2 in ‘Unit2.pas’ {Form2},
Unit3 in ‘Unit3.pas’ {Form3},
HDDInfo in ‘HDDInfo.pas’;
{$R *.res}
begin
Application.Initialize;
Application.HelpFile =’СПРАВКА.HLP’;
Application.CreateForm(TForm1, Form1);
Application.ShowMainForm =false;
Application.CreateForm(TForm2, Form2);
Application.Run;
end.
2) Текст модуля Unit1
unit Unit1; //Основной модуль
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ThrdRcvr,
StdCtrls, Buttons, Menus,ToolWin, ComCtrls, ActnMan, ActnColorMaps,
ImgList, ExtCtrls,Unit3;
const
MMFName PChar = ‘MMFProectFile’;
MutxName PChar = ‘UniqMutexName’;
EvntName Pchar = ‘ChatEventName’;
SHARED_MEMORY_SIZE = 65536;
type
TForm1 = class(TForm)
Memo1 TMemo;
OpenDialog1 TOpenDialog;
SaveDialog1 TSaveDialog;
MainMenu1 TMainMenu;
N1 TMenuItem;
N3 TMenuItem;
N4 TMenuItem;
N5 TMenuItem;
N6 TMenuItem;
N7 TMenuItem;
BitBtn2 TBitBtn;
BitBtn3 TBitBtn;
Edit1 TEdit;
Button1 TButton;
Button2 TButton;
ToolBar1 TToolBar;
OpenToolButton TToolButton;
SaveAsToolButton TToolButton;
ToolButton3 TToolButton;
ImageList1 TImageList;
StatusBar1 TStatusBar;
Timer1 TTimer;
ToolButton1 TToolButton;
N2 TMenuItem;
N8 TMenuItem;
procedure Button1Click(Sender TObject);
procedure N4Click(Sender TObject);
procedure BitBtn2Click(Sender TObject);
procedure BitBtn3Click(Sender TObject);
procedure FormCreate(Sender TObject);
procedure CloseHandles;
procedure CreateHandles;
procedure Button2Click(Sender TObject);
procedure WriteDataInMMF(s string);
procedure FormCloseQuery(Sender TObject; var CanClose Boolean);
procedure N5Click(Sender TObject);
procedure Timer1Timer(Sender TObject);
procedure ToolButton3Click(Sender TObject);
procedure ToolButton1Click(Sender TObject);
procedure N8Click(Sender TObject);
procedure N2Click(Sender TObject);
private
procedure AppHint(Sender TObject);
public
HMutex THandle;
ThreadRec TThreadReceiver;
HEvent THandle;
HFileSender Thandle;
NicName string;
end;
var
Form1 TForm1;
TxtFile TextFile;// пременная файла
St PansiChar;
lincInt Boolean;
TxtContaningStr String;
userName string;
implementation
{$R *.dfm}
//процедура для показа кртких справок
procedure TForm1.AppHint(Sender TObject);
begin
StatusBar1.SimpleText =Application.Hint; //для отображения ииформации в панели соостояния
end;
//закрытие всех хендлов в этой копии программы
procedure TForm1.CloseHandles();
begin
CloseHandle(HFileSender);
CloseHandle(HMutex);
CloseHandle(HEvent);
end;
// создание всех необходимых объектов
procedure TForm1.CreateHandles;
begin
// проекция файла
HFileSender =CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SHARED_MEMORY_SIZE,MMFName);
lincInt =(GetLastError() <> ERROR_ALREADY_EXISTS);
if HFileSender = 0 then
begin
st =’не удалось создать проекцию файла’;
Application.MessageBox(st,’Сообщение…’,MB_OK);
exit;
end;
// мьютекс
HMutex =CreateMutex(nil,false,MutxName);
if HMutex = 0 then
begin
CloseHandle(HFileSender);
st =’не удалось синхронизировать приложение’;
Application.MessageBox(st,’Сообщение…’,MB_OK);
exit;
end;
// событие
HEvent =CreateEvent(nil,true,false,EvntName);
if HEvent = 0 then
begin
CloseHandle(HFileSender);
CloseHandle(HMutex);
st =’не удалось осуществить обмен сообщениями’;
Application.MessageBox(st,’Сообщение…’,MB_OK);
exit;
end;
end;
// отсоединиться
procedure TForm1.Button1Click(Sender TObject);
begin
ThreadRec.Terminate;
WriteDataInMMF(‘Пользователь ‘+NicName+’ отключился’);
ThreadRec.WaitFor;
ThreadRec.Free;// правильно уничтожаем поток
CloseHandles();
button2.Visible =true;
button1.Visible =false;
bitbtn2.Visible =false;
end;
// загрузить историю переписки
procedure TForm1.N4Click(Sender TObject);
begin
if OpenDialog1.Execute then
begin
AssignFile(TxtFile,OpenDialog1.FileName);
Reset(TxtFile);
Memo1.Text =Memo1.Text +'{————Загруженная переписка ниже————-}’ + #13#10;
while not eof(TxtFile) do
begin
readln(TxtFile,TxtContaningStr);
Memo1.Text =Memo1.Text + TxtContaningStr + #13#10;
end;
Memo1.Text =Memo1.Text +'{————Загруженная переписка выше ————-}’ + #13#10;
CloseFile(TxtFile);
end;
end;
//процедура записи данных в MMF
procedure TForm1.WriteDataInMMF(s string);
var
PBaseAdress Pointer;
begin
WaitForSingleObject(HMutex, INFINITE);
PBaseAdress =MapViewOfFile(HFileSender,FILE_MAP_WRITE,0,0,Length(s)+4);
if(PBaseAdress = nil) then
begin
CloseHandle(HFileSender);
st =’не удалось передать данные’;
Application.MessageBox(st,’Сообщение…’,MB_OK);
exit;
end;
begin
integer(PBaseAdress^) =length(s);
CopyMemory(Pointer(Integer(PBaseAdress)+4),PChar(s),length(s));
UnmapViewOfFile(PBaseAdress);
SetEvent(HEvent);
ReleaseMutex(HMutex);
end;
end;
// процедура записи данных в PBaseAdress
procedure TForm1.BitBtn2Click(Sender TObject);
begin
if Edit1.Text <> » then
begin
WriteDataInMMF(Nicname+’ написал ‘+#13#10+string(Edit1.Text));
Edit1.Text =»;
end
else
exit;
end;
// Закрытия формы
procedure TForm1.BitBtn3Click(Sender TObject);
begin
close;
end;
//создаём хендлы и потоки
procedure TForm1.FormCreate(Sender TObject);
begin
Memo1.Clear;
// создание потока принимающего данные из файла
ThreadRec =TThreadReceiver.Create(false);
ThreadRec.Priority =tpLowest;
CreateHandles();// создаем хендлы
end;
// соединение
procedure TForm1.Button2Click(Sender TObject);
begin
CreateHandles();
ThreadRec =TThreadReceiver.Create(false);
button2.Visible =false;
button1.Visible =true;
bitbtn2.Visible =true;
WriteDataInMMF(NicName+’ Cоединился!’);
end;
// Запрос подтверждения при закрытии формы
procedure TForm1.FormCloseQuery(Sender TObject; var CanClose Boolean);
begin
case messageBox(Handle,’Действительно выйти?’,’Внимание!’, MB_YESNO) of
IDYES
begin
if Button1.Visible = true then
begin
ThreadRec.Terminate;
WriteDataInMMF(‘Пользователь ‘+NicName+’ отключился’);
ThreadRec.WaitFor;
ThreadRec.Free;
CanClose =true;
end
else
CanClose =true;
end;
IDNO CanClose =false;
end;
end;
//Сохранить историю переписки
procedure TForm1.N5Click(Sender TObject);
begin
If SaveDialog1.Execute then
begin
AssignFile(TxtFile,SaveDialog1.FileName);
rewrite(TxtFile);
TxtContaningStr = Memo1.Text;
Write(TxtFile,TxtContaningStr);
CloseFile(TxtFile);
St =’Файл сохранён’;
Application.MessageBox(St,’Сообщение…’,MB_OK);
exit;
end
else
begin
St =’файл не сохранён’;
Application.MessageBox(St,’Сообщение…’,MB_OK);
end;
end;
procedure TForm1.Timer1Timer(Sender TObject);
begin
if Form1.Visible = true then
begin
Application.OnHint =AppHint;
Timer1.Enabled =false;
Timer1.Destroy;
end;
end;
procedure TForm1.ToolButton3Click(Sender TObject);
begin
Application.CreateForm(TForm3, Form3);
Application.ShowMainForm =false;
Form3.Visible =true;
end;
procedure TForm1.ToolButton1Click(Sender TObject);
begin
//вызов справки (основная форма программы)
Application.HelpContext(2);
end;
procedure TForm1.N8Click(Sender TObject);
begin
Application.HelpCommand(HELP_FINDER,0);
end;
procedure TForm1.N2Click(Sender TObject);
begin
ShowMessage(‘Программу подготовил студент группы 742 ‘+#13#10+’Шипилов Д.А.’);
end;
end.
3) Текст модуля Unit2 (Модуль формы «Авторизация»)
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Unit1, ComCtrls, Buttons;
type
TForm2 = class(TForm)
Button2 TButton;
Edit1 TEdit;
Label1 TLabel;
BitBtn1 TBitBtn;
procedure Button2Click(Sender TObject);
procedure FormCloseQuery(Sender TObject; var CanClose Boolean);
procedure BitBtn1Click(Sender TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2 TForm2;
formClose boolean=false;
implementation
{$R *.dfm}
// закрытие формы
procedure TForm2.Button2Click(Sender TObject);
begin
close;
end;
// запрос подтверждения при завершении программы из дочерней формы
procedure TForm2.FormCloseQuery(Sender TObject; var CanClose Boolean);
begin
if formClose = true then
begin
CanClose =true;
end
else
begin
case messageBox(Handle,’Действительно выйти?’,’Внимание!’, MB_YESNO) of
IDYES
begin
Application.Terminate;
end;
IDNO CanClose =false;
end;
end;
end;
procedure TForm2.BitBtn1Click(Sender TObject);
var
St PansiChar;
begin
if Edit1.Text <> » then
begin
formClose =true;
Form1.Memo1.Clear;
Form1.NicName =Edit1.Text;
Form1.WriteDataInMMF(‘Пользователь ‘+Form1.NicName+’ подключился’);
Application.ShowMainForm =true;
Form1.Visible =true;
Form2.Close;
end
else
begin
st =’Пожалуйста введите псевдоним для авторизации’;
Application.MessageBox(st,’Сообщение…’,MB_OK);
exit;
end;
end;
end.
4) Модуль Unit 3 (Модуль формы, осуществляющей работу с носителями информации в системе)
unit Unit3;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, FileCtrl, ExtCtrls, Grids, ValEdit,HDDInfo, Buttons,
ComCtrls;
const
IOCTL_DISK_GET_DRIVE_GEOMETRY = $70000;
type
// версия ОС
TWinVersion = (wvUnknown,wv95,wv98,wvME,wvNT3,wvNT4,wvW2K,wvXP,wv2003,wvVista,wv7);
//геометрия
TDiscGeometry = packed record
Cylinders Int64; // колличество цилиндров
MediaType DWORD; // тип носителя
TracksPerCylinder DWORD; // дорожек на цилиндре
SectorsPerTrack DWORD; // секторов на дорожке
BytesPerSector DWORD; // байт в секторе
end;
//TForm
TForm3 = class(TForm)
Button1 TButton;
DriveComboBox1 TDriveComboBox;
Panel1 TPanel;
Button2 TButton;
Grid1 TStringGrid;
Button3 TButton;
GroupBox1 TGroupBox;
bpbList TValueListEditor;
Label1 TLabel;
GroupBox2 TGroupBox;
Disks TLabel;
BitBtn1 TBitBtn;
GroupBox3 TGroupBox;
Memo1 TMemo;
Grid2 TStringGrid;
Label2 TLabel;
Memo2 TMemo;
Label3 TLabel;
procedure Button1Click(Sender TObject);
procedure DiscGeometryShow;
procedure Button2Click(Sender TObject);
procedure Button3Click(Sender TObject);
procedure FormActivate(Sender TObject); // Result = LoDWORD
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3 TForm3;
hDrive,hMBRDrive THandle;
DiscGeometry TDiscGeometry;
typeOfDisc string;
implementation
{$R *.dfm}
// определение версии ОС
function DetectWinVersion TWinVersion;
var
OSVersionInfo TOSVersionInfo;
begin
Result = wvUnknown; // Неизвестная версия ОС
OSVersionInfo.dwOSVersionInfoSize = sizeof(TOSVersionInfo);
if GetVersionEx(OSVersionInfo)
then
begin
case OSVersionInfo.DwMajorVersion of
3 Result = wvNT3; // Windows NT 3
4 case OSVersionInfo.DwMinorVersion of
0 if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT
then Result = wvNT4 // Windows NT 4
else Result = wv95; // Windows 95
10 Result = wv98; // Windows 98
90 Result = wvME; // Windows ME
end;
5 case OSVersionInfo.DwMinorVersion of
0 Result = wvW2K; // Windows 2000
1 Result = wvXP; // Windows XP
2 Result = wv2003; // Windows 2003
end;
6 case OSVersionInfo.DwMinorVersion of
0 Result = wvVista; // Windows Vista
1 Result = wv7; // Windows 7
end;
end;
end;
end;
// для вывода версии
function DetectWinVersionStr string;
const
VersStr array[TWinVersion] of string = (
‘Unknown’,
‘Windows 95’,
‘Windows 98’,
‘Windows ME’,
‘Windows NT 3’,
‘Windows NT 4’,
‘Windows 2000’,
‘Windows XP’,
‘Windows 2003’,
‘Windows Vista’,
‘Windows Seven’);
begin
Result = VersStr[DetectWinVersion];
end;
// для перемещения по диску
function __Mul(a,b DWORD; var HiDWORD DWORD) DWORD;
asm
mul edx
mov [ecx],edx
end;
// Чтение сектора жесткго диска(Вызыв когда работа с диском начата)
function ReadSectors(hDrive Thandle; StartingSector, SectorCount DWORD;
Buffer Pointer; BytesPerSector DWORD) DWORD;
var
br,TmpLo,TmpHi DWORD;
begin
Result = 0;
TmpLo = __Mul(StartingSector,BytesPerSector,TmpHi);
if SetFilePointer(hDrive,TmpLo,@TmpHi,FILE_BEGIN) = TmpLo then
begin
SectorCount = SectorCount*BytesPerSector;
if ReadFile(hDrive,Buffer^,SectorCount,br,nil) then Result = br;
end;
end;
// вывод геометрии
procedure TForm3.DiscGeometryShow;
begin
Memo1.Clear;
Memo1.Text =’Вы просматриваете логический диск ‘+DriveComboBox1.Drive+#13#10;
Memo1.Text = memo1.Text + ‘Количество цилиндров ‘+inttoStr(DiscGeometry.Cylinders)+#13#10;
case DiscGeometry.MediaType of
12 typeOfDisc =’ жёсткий диск’;
11 typeOfDisc =’ съёмный носитель’;
end;
Memo1.Text = memo1.Text + ‘Тип носителя ‘+typeOfDisc+#13#10;
Memo1.Text = memo1.Text + ‘Дорожек на цилиндре ‘+intToStr(DiscGeometry.TracksPerCylinder)+#13#10;
Memo1.Text = memo1.Text + ‘Секторов на дорожке ‘+intToStr(DiscGeometry.SectorsPerTrack)+#13#10;
Memo1.Text = memo1.Text + ‘Байт в секторе ‘+intToStr(DiscGeometry.BytesPerSector)+#13#10;
end;
//создаем файл диска/выводим геомертию
//начинаем работу с жёстким диском
procedure TForm3.Button1Click(Sender TObject);
var
discNameBPB,discNameMBR string;
junk Cardinal;
result boolean;
begin
if hDrive <> 0 then CloseHandle(hDrive);
if hMBRDrive <> 0 then CloseHandle(hMBRDrive);
discNameBPB =’.’+DriveComboBox1.Drive+’ ‘;
discNameMBR =’.PHYSICALDRIVE’+intToStr(0);
hMBRDrive = CreateFile(PChar(discNameMBR),GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
hDrive = CreateFile(PChar(discNameBPB),GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if (hDrive <> INVALID_HANDLE_VALUE) and (hMBRDrive <> INVALID_HANDLE_VALUE) then
begin
Result = DeviceIoControl(hDrive,IOCTL_DISK_GET_DRIVE_GEOMETRY,nil,0,
@DiscGeometry,SizeOf(TDiscGeometry),junk,nil) and (junk = SizeOf(TDiscGeometry));
DiscGeometryShow();
end
else
begin
ShowMessage(‘Не возможно создать дескрипторы носителя’);
exit;
end;
end;
// Чтение и рашифровка BPB
procedure TForm3.Button2Click(Sender TObject);
var
i,j,k integer;
read Cardinal;
s string;
buffer array[1..131072] of byte;
begin
if ReadSectors(hDrive,0,1,@buffer,DiscGeometry.BytesPerSector) = DiscGeometry.BytesPerSector then
begin
for i = 1 to 16 do
Grid1.Cells[i,0] =intToHex((i-1),1);
i =1; j =1; k =1;
while k<=DiscGeometry.BytesPerSector do
begin
if i=1 then Grid1.Cells[0,j] =IntToHex(((j-1)*16+(i-1)),3);
Grid1.Cells[i,j] =IntToHex(Buffer[k],2);
inc(k);
inc(i);
if i>16 then
begin
i =1;
j =j+1;
Grid1.RowCount = Grid1.RowCount+1;
end;
end;
// расшифровка данных BPB
for i = 1 to 3 do
s =s+ intToHex(buffer[i],2);
bpbList.Cells[1,1] = s + ‘h’;
s =»;
// чтение имени ОС
for i = 4 to 4 + 7 do
s =s+ chr(buffer[i]);
bpbList.Cells[1,2] = s;
s =»;
//—————————
bpbList.Cells[1,3] =IntToStr(buffer[$C+1] shl 8 + buffer[$C]);
bpbList.Cells[1,4] =IntToStr(buffer[$C + 2]);
bpbList.Cells[1,5] =intToStr(buffer[$C + 4] shl 8 + buffer[$C+3]);
bpbList.Cells[1,6] =intToStr(buffer[$C+5]);
bpbList.Cells[1,7] =IntToStr(buffer[$F + 4] shl 8 + buffer[$F + 3]);
bpbList.Cells[1,8] =intToStr(buffer[$F+6] shl 8 + buffer[$F + 5]);
bpbList.Cells[1,9] =intToHex(buffer [22],2);
if bpbList.Cells[1,9] = ‘F8′ then bpbList.Cells[1,9] =’Системный носитель инФормации’
else if bpbList.Cells[1,9] = ‘FDh’ then bpbList.Cells[1,9] =’ накопитель — 2 стороны, 9 секторов’
else if bpbList.Cells[1,9] = ‘F9h’ then bpbList.Cells[1,9] =’ накопитель — 2 стороны, 9 секторов’
else if bpbList.Cells[1,9] = ‘F0h’ then bpbList.Cells[1,9] =’ накопитель — 2 стороны, 15 секторов’;
bpbList.Cells[1,10] =intToStr(buffer[$F+9] shl 8 + buffer[$F+8]);
bpbList.Cells[1,11] =intToStr(buffer[$F+11] shl 8 + buffer[$F+10]);
bpbList.Cells[1,12] =intToStr(buffer[$F+13] shl 8 + buffer[$F+12]);
bpbList.Cells[1,13] =intToStr(buffer[$F+17] shl 32 + buffer[$f+16]+ buffer[$f+15]+buffer[$f+14]);
bpbList.Cells[1,14] =intToStr(buffer[$F + 21] shl 24 + buffer[$F + 20] shl 16 + buffer[$F + 19] shl 8 + buffer[$F + 18]);
bpbList.Cells[1,15] =intToStr(buffer[$C + 25]);
bpbList.Cells[1,16] =intToStr(buffer[$F + 23]);
bpbList.Cells[1,17] =intToStr(buffer[$F + 24]);
bpbList.Cells[1,18] =intToHex((buffer[$F + 28] shl 24 + buffer[$F + 27] shl 16 + buffer[$F + 26] shl 8 + buffer[$F + 25]),8);
//————вывод метки ————
s =»;
for i =29 to 40 do
s =s+chr(buffer[$F+i]);
bpbList.Cells[1,19] = s;
s =»;
//———————————-
//— чтение ID ОС————-
for i = 55 to 62 do
s =s+ chr(buffer[i]);
bpbList.Cells[1,20] = s;
s =»;
//—————————-
end
else
ShowMessage(‘Не удалось считать блок параметров Bios’);
end;
// чтение данных из структуры DriveInfo
procedure TForm3.Button3Click(Sender TObject);
var
i,j,k integer;
read Cardinal;
s string;
buffer array[1..131072] of byte;
begin
Memo2.Clear;
if ReadSectors(hMBRDrive,0,1,@buffer,DiscGeometry.BytesPerSector) = DiscGeometry.BytesPerSector then
begin
for i = 1 to 16 do
Grid2.Cells[i,0] =intToHex((i-1),1);
i =1; j =1; k =1;
while k<=DiscGeometry.BytesPerSector do
begin
if i=1 then Grid2.Cells[0,j] =IntToHex(((j-1)*16+(i-1)),3);
Grid2.Cells[i,j] =IntToHex(Buffer[k],2);
inc(k);
inc(i);
if i>16 then
begin
i =1;
j =j+1;
Grid2.RowCount = Grid2.RowCount+1;
end;
end;
// Расшифровка PartitionTable
// первая часть
Memo2.Text =Memo2.Text+’Первый элемент таблицы разделов системного диска ‘+#13#10;
Memo2.Text =Memo2.Text+’Признак загрузки ‘+intToHex(buffer[$1bf],2)+#13#10;
Memo2.Text =Memo2.Text+’Начало раздела диска{‘;
Memo2.Text =Memo2.Text+’Головка ‘+intToStr(buffer[448]);
Memo2.Text =Memo2.Text+’ Сектор ‘+intToStr(buffer[449]);
Memo2.Text =Memo2.Text+’ Цилиндр ‘+intToStr(buffer[450]);
Memo2.Text =Memo2.Text+’ }’+#13#10;
Memo2.Text =Memo2.Text+’Тип раздела {‘;
Memo2.Text =Memo2.Text+’Ос ‘+intToStr(buffer[451]);
Memo2.Text =Memo2.Text+’ }’+#13#10;
Memo2.Text =Memo2.Text+’Конец раздела диска{‘;
Memo2.Text =Memo2.Text+’Головка ‘+intToStr(buffer[$1c4]);
Memo2.Text =Memo2.Text+’ Сектор ‘+intToStr(buffer[$1c5]);
Memo2.Text =Memo2.Text+’ Цилиндр ‘+intToStr(buffer[$1c6]);
Memo2.Text =Memo2.Text+’ }’+#13#10;
Memo2.Text =Memo2.Text+’Номер Сектора {‘;
Memo2.Text =Memo2.Text+’ ‘+intToStr(buffer[458]shl 32+buffer[457]+buffer[456]+buffer[455]);
Memo2.Text =Memo2.Text+’ }’+#13#10;
Memo2.Text =Memo2.Text+’Размер раздела {‘;
Memo2.Text =Memo2.Text+’ ‘+intToStr(buffer[462]shl 24 +buffer[461] shl 16 +buffer[460]shl 8+buffer[459]);
Memo2.Text =Memo2.Text+’ }’+#13#10+#13#10+#13#10;
//вторая часть
Memo2.Text =Memo2.Text+’Второй элемент таблицы разделов системного диска ‘+#13#10;
Memo2.Text =Memo2.Text+’Признак загрузки ‘+intToHex(buffer[$1CF],2)+#13#10;
Memo2.Text =Memo2.Text+’Начало раздела диска{‘;
Memo2.Text =Memo2.Text+’Головка ‘+intToStr(buffer[465]);
Memo2.Text =Memo2.Text+’ Сектор ‘+intToStr(buffer[466]);
Memo2.Text =Memo2.Text+’ Цилиндр ‘+intToStr(buffer[467]);
Memo2.Text =Memo2.Text+’ }’+#13#10;
Memo2.Text =Memo2.Text+’Тип раздела {‘;
Memo2.Text =Memo2.Text+’Ос ‘+intToStr(buffer[468]);
Memo2.Text =Memo2.Text+’ }’+#13#10;
Memo2.Text =Memo2.Text+’Конец раздела диска{‘;
Memo2.Text =Memo2.Text+’Головка ‘+intToStr(buffer[469]);
Memo2.Text =Memo2.Text+’ Сектор ‘+intToStr(buffer[470]);
Memo2.Text =Memo2.Text+’ Цилиндр ‘+intToStr(buffer[471]);
Memo2.Text =Memo2.Text+’ }’+#13#10;
Memo2.Text =Memo2.Text+’Номер Сектора {‘;
Memo2.Text =Memo2.Text+’ ‘+intToStr(buffer[$1D7+3]shl 24+buffer[$1D7+2] shl 16+buffer[$1D7+1]shl 8 +buffer[$1D7]);
Memo2.Text =Memo2.Text+’ }’+#13#10;
Memo2.Text =Memo2.Text+’Размер раздела {‘;
Memo2.Text =Memo2.Text+’ ‘+intToStr(buffer[$1db+3]shl 24 +buffer[$11db+2] shl 16 +buffer[$1db+1]shl 8+buffer[$1db]);
Memo2.Text =Memo2.Text+’ }’+#13#10+#13#10+#13#10;
end
else
ShowMessage(‘Не удалось считать PartitionTable’);
end;
// получение инфо о нужных дисках
procedure TForm3.FormActivate(Sender TObject);
var
S,SOut String;
i Integer;
VolumeName,FileSystemName,NewDiscNumber String;
MaxComponentLength,FileSystemFlags LongWord;
// от переменной VolumeSerialNo DWord;
begin
S =GetDisks(DiskHDD); {Получаем список Жёстких дисков (Параметр DiskHDD)}
s =s+GetDisks(DiskFDD);
s =s+GetDisks(DiskNet);
s =s+GetDisks(DiskCDROM);
s =s+GetDisks(DiskRAM);
SOut =»;
For i =1 to Length(S) do {Получаем информацию о всех дисках и пишем в TLabel на форме}
begin
{Если диск существует/вставлен …}
if GetHDDInfo(S[I], VolumeName, FileSystemName,NewDiscNumber,
MaxComponentLength, FileSystemFlags) then {… тогда собираем информацию}
SOut =SOut+
‘Диск ‘+S[I]+#13#10+
‘Метка ‘+VolumeName+#13#10+
‘Файловая система ‘+FileSystemName+#13+#10+
‘Серийный номер ‘+NewDiscNumber+#13+#10+
‘Макс. длина имени файла ‘+IntToStr(MaxComponentLength)+#13+#10+
‘Flags ‘+IntToHex(FileSystemFlags,4)+#13#10+#13#10;
end;
Disks.Caption =SOut; {Выводим в компонент TLabel полученные данные о дисках}
end;
end.
5) Модуль ThrdRcvr (модуль описывающий работу потока – приёмника сообщений)
unit ThrdRcvr; // принимающий поток
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,StdCtrls, Buttons, Menus, ComCtrls, ActnMan, ActnColorMaps;
type
TThreadReceiver = class(TThread)
private
PBaseAdress PChar;
TextString String;
nlineSize integer;
protected
procedure Execute; override;
public
end;
implementation
uses
Unit1;
// Считываем соержимое из проекции файла в Memo1
procedure TThreadReceiver.Execute;
begin
while (not terminated) do
begin
WaitForSingleObject(Form1.HEvent, INFINITE);
ResetEvent(Form1.HEvent);
try
// резерв. память в потоке для этотой проекции
PBaseAdress =MapViewOfFile(Form1.HFileSender, FILE_MAP_READ,0,0,65536);
if (PBaseAdress = nil) then
begin
CloseHandle(Form1.HFileSender);
st =’не удалось отобразить файл на адресное пространство’;
Application.MessageBox(st,’Сообщение…’,MB_OK);
form1.BitBtn2.Visible =false;
form1.Button1.Visible =false;
exit;
end;
nlineSize =integer(PBaseAdress^);
SetLength(TextString,nlineSize);
CopyMemory(PChar(TextString),Pointer(Integer(PBaseAdress)+4),nlineSize);
Form1.Memo1.Text =Form1.Memo1.Text+’———‘+#13#10;
Form1.Memo1.Text =Form1.Memo1.Text+TextString+#13#10;
sendmessage(Form1.memo1.handle, em_linescroll, 0, Form1.memo1.lines.count-1);
UnmapViewOfFile(PBaseAdress);
finally
end;
end;
end;
end.
6) Модуль HDDInfo (модуль получающий информацию о жёстких дисках)
unit HDDInfo;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, FileCtrl, ExtCtrls, Grids, ValEdit;
const {Константы для TypeOfDisk функции GetDisks}DiskUnknown=0; {Неизвестные диски}
DiskNone=1; {Отсутствующие диски}
DiskFDD=DRIVE_REMOVABLE; {Съёмные диски, дискеты}
DiskHDD=DRIVE_FIXED; {Не съёиные диски, жёсткие диски}
DiskNet=DRIVE_REMOTE; {Сетевые диски}
DiskCDROM=DRIVE_CDROM; {CD ROM}
DiskRAM=DRIVE_RAMDISK; {Диски в ОЗУ}
function GetDisks(TypeOfDisk Word) String;
function GetHDDInfo(Disk Char;Var VolumeName, FileSystemName,NewDiscNumber String;
MaxComponentLength, FileSystemFlags LongWord) Boolean;
implementation
//получить имена доступных дисков
function GetDisks(TypeOfDisk Word) String;{Получить имена нужных дисков}
var
DriveArray array[1..26] of Char;
i integer;
beginDriveArray =’ABCDEFGHIJKLMNOPQRSTUVWXYZ’;
for i = 1 to 26 do
if GetDriveType(PChar(DriveArray[I]+’ ‘)) = TypeOfDisk then
Result = Result+DriveArray[I];
end;
// определение правильного серийного номера диска
function GetReplaceCDNumber(num String) String;
var
i, len Integer;
begin
Result = »;
len = Length(num);
if len <> 8 then exit;
for i = 1 to (len div 2) do begin
Dec(len);
Result = Result + num[len];
Result = Result + num[len+1];
Dec(len);
end;
end;
// получить инфо о дисках с нужными именами
function GetHDDInfo(Disk Char;Var VolumeName, FileSystemName,NewDiscNumber String;
MaxComponentLength, FileSystemFlags LongWord) Boolean;
var
_VolumeName,_FileSystemName array [0..MAX_PATH-1] of Char;
_VolumeSerialNo,_MaxComponentLength,_FileSystemFlags LongWord;
_NewDiscNumber string;
begin
if GetVolumeInformation(PChar(Disk+’ ‘),_VolumeName,MAX_PATH,@_VolumeSerialNo,
_MaxComponentLength,_FileSystemFlags,_FileSystemName,MAX_PATH) then
begin
NewDiscNumber =IntToHex(integer(_VolumeSerialNo),8);
NewDiscNumber =GetReplaceCDNumber(NewDiscNumber);
VolumeName =_VolumeName;
MaxComponentLength =_MaxComponentLength;
FileSystemFlags =_FileSystemFlags;
FileSystemName =_FileSystemName;
Result =True;
end
else
Result =False;
end;
end.
Список литературы
1) М. Фленов «Библия Delphi»
2) А. Танцер «Синхронизация процессов при работе с Windows»
3) Сайт CitForum > http //citforum.ru/programming/delphi/disk_editor/ </
4)Cайт Delphi-Faq > http //delphi-faq.zoxt.net/a79.htm <.
5) Cайт DelphiSource.