Курсовая

Курсовая Программа поиска в свободных кластерах символьных последовательностей из заданного набора

Работа добавлена на сайт bukvasha.net: 2015-10-25

Поможем написать учебную работу

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

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 11.11.2024





Федеральное агентство по образованию

ГОУ ВПО «Уральский государственный технический университет – УПИ

имени первого Президента России Б.Н.Ельцина»
Кафедра «Автоматика и информационные технологии»
Оценка проекта:           ____________
Члены комиссии:    ____________

                                                         

                                                          ____________                                

Программа поиска в свободных кластерах символьных последовательностей из заданного набора
Курсовая работа по дисциплине

«Системное программное обеспечение»
Пояснительная записка
23.01 000000 042 ПЗ
Руководитель                                                                                С. С. Соколов

доц. тех. наук
Студент                                                                                         С. И. Суриков

Р-37031
2010

СОДЕРЖАНИЕ


СОДЕРЖАНИЕ. 2

ПОСТАНОВКА ЗАДАЧИ.. 3

ВВЕДЕНИЕ. 4

1.     ТЕОРЕТИЧЕСКАЯ ЧАСТЬ. 5

1.4.         Расширенный блок параметров BIOS. 8

1.5.         Логический номер сектора. 10

1.6.         Прерывания INT 25h и INT 26h. 10

1.8.         Содержимое таблицы FAT. 13

1.9.         Форматы таблицы FAT. 15

1.10.      Удаленные файлы в FAT. 16

1.11.      Идентификация кластеров. 17

2.     РАЗРАБОТКА ПРОГРАММЫ.. 18

2.1.     Схема и алгоритм программы.. 18

ЗАКЛЮЧЕНИЕ. 26

БИБЛИОГРАФИЧЕСКИЙ СПИСОК.. 27

ПРИЛОЖЕНИЕ 1. 28



ПОСТАНОВКА ЗАДАЧИ


В данной курсовой работе необходимо разработать программу для поиска в свободных кластерах символьных последовательностей из заданного набора.

ВВЕДЕНИЕ


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

Так называемая файловая система FAT использовалась во всех версиях MS-DOS и в первых двух выпусках OS/2 (версии 1.0 и 1.1). Каждый логический том имеет собственный FAT, который выполняет две функции: содержит информацию распределения для каждого файла в томе в форме списка связей модулей распределения (кластеров) и указывает, какие модули распределения свободны.

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

1.    ТЕОРЕТИЧЕСКАЯ ЧАСТЬ




1.1.        
Структура диска

Персональный компьютер обычно комплектуется одним или более накопителями на магнитных дисках (НМД). Однако операционная система позволяет вам разбивать НМД на части, причем каждая часть будет рассматриваться MS-DOS как отдельный, "логический" диск.

Первые персональные компьютеры IBM PC были укомплектованы только накопителями на гибких магнитных дисках (НГМД). Дискеты позволяют хранить относительно небольшие объемы информации, поэтому делить их на части не имеет смысла. Следующая модель компьютера IBM PC/XT имела НМД объемом 10 или 20 Мбайт. При использовании таких дисков и операционных систем MS-DOS версий до 3.20 у пользователей не возникало никаких проблем и желания разбить диск относительно малого объема на еще меньшие части.

Проблемы возникли, когда производители НМД освоили выпуск дисков объемом 40 Мбайт и больше. Оказалось, что используемый в MS-DOS механизм 16-разрядной адресации секторов не позволяет использовать диски объемом, большим, чем 32 Мбайт.

Операционная система MS-DOS версии 3.30 предложила выход из создавшегося положения. С помощью программы fdisk.exe можно было разбить физический диск на логические, каждый из которых не должен превышать по объему 32 Мбайт.

Впоследствии в версии 4.00 операционной системы MS-DOS и в версии 3.31 операционной системы COMPAQ DOS указанное выше ограничение на размер логического диска было снято, однако схема разделения физического диска на логические диски полностью сохранилась.
1.2.        
Загрузочная запись


Самый первый сектор логического диска (и самый первый сектор на системной дискете) занимает загрузочная запись (Boot Record). Эта запись считывается из активного раздела диска программой главной загрузочной записи (Master Boot Record) и запускается на выполнение. Задача загрузочной записи - выполнить загрузку операционной системы. Каждый тип операционной системы имеет свою загрузочную запись. Даже для разных версий одной и той же операционной системы программа загрузки может выполнять различные действия.

Кроме программы начальной загрузки операционной системы в загрузочной записи находятся параметры, описывающие характеристики данного логического диска. Все эти параметры располагаются в самом начале сектора, в его так называемой форматированной области. Формат этой области изменился в версии 4.0 операционной системы MS-DOS.

1.3.        
Формат загрузочной записи

Формат загрузочной записи для версий MS-DOS, более ранних, чем 4.0 имеет вид, представлены в табл. 1.

Таблица 1

Формат загрузочной записи MS-DOS версии ниже 4.0

Смещение


Размер


Содержимое


0

3

Команда JMP xxxx - ближний переход на программу начальной загрузки

3

8

Название фирмы-изготовителя операционной системы и версия, например: "IBM 4.0"

11

13

Блок параметров BIOS (BPB)

24

2

Количество секторов на дорожке

26

2

Количество головок (поверхностей диска)

28

2

Количество скрытых секторов, эти секторы могут использоваться для схемы разделения физического диска на разделы и логические диски

В самом начале загрузочного сектора располагается команда внутрисегментного перехода JMP. Она нужна для обхода форматированной зоны сектора и передачи управления загрузочной программе, располагающейся со смещением 30.

Название фирмы-изготовителя не используется операционной системой.

Со смещением 11 располагается BPB - блок параметров BIOS , основная работа с которым и будет проводиться в ходе создания программы. Именно этот блок содержит всю необходимую информацию для создания программы. Этот блок активно используется дисковыми драйверами.

Для современных версий MS-DOS загрузочный сектор имеет формат отличный от используемого в версиях более ранних, чем 4.0. Формат загрузочного сектора современных версий MS-DOS имеет структуру, представленную в табл. 2.

Таблица 2

Формат загрузочной записи современных версий MS-DOS

Смещение


Размер


Содержимое


0

3

Команда JMP xxxx - ближний переход на программу начальной загрузки

3

8

Название фирмы-изготовителя операционной системы и версия

11

25

Extended BPB - расширенный блок параметров BIOS

36

1

Физический номер устройства (0 -НГМД, 80h -НМД)

37

1

Зарезервировано

38

1

Символ ')' - признак расширенной загрузочной записи

39

4

Серийный номер диска (Volume Serial Number), создается во время форматирования диска

43

11

Метка диска (Volume Label)

54

8

Зарезервировано, обычно содержит запись типа 'FAT12 ', которая идентифицирует формат таблицы размещения файлов FAT

Первые два поля в загрузочном секторе аналогичны описанным раньше.

Поле со смещением 38 всегда содержит символ ')'. Этот символ означает, что используется формат расширенной загрузочной записи.

Серийный номер диска формируется во время форматирования диска на основе даты и времени форматирования. Это поле может быть использовано для определения факта замены дискеты.

Метка диска формируется при форматировании и может быть изменена командой LABEL операционной системы MS-DOS. Одновременно метка диска помещается в корневой каталог.

1.4.         Расширенный блок параметров BIOS


Рассмотрим более детально формат расширенного блока параметров BIOS.

Поле загрузочного сектора со смещением 11 содержит расширенный блок параметров BIOS . Он состоит из обычного блока BPB и дополнительного расширения, структура расширенного блока представлена в виде табл. 3.

Таблица 3

Расширенный блок параметров BIOS

Смещение, байт


Размер, байт


Имя поля


Описание


1

2

3

4

0

2

sect_siz

Количество байт в одном секторе диска

2

1

clustsiz

Количество секторов в одном кластере

3

2

res_sect

Количество зарезервированных секторов

5

1

fat_cnt

Количество таблиц FAT

6

2

root_siz

Максимальное количество дескрипторов файлов в корневом каталоге диска

8

2

tot_sect

Общее количество секторов на носителе данных (в разделе MS-DOS)

10

1

media

Байт-описатель среды носителя данных

11

2

fat_size

Количество секторов, занимаемых одной копией FAT

13

2

sectors

Количество секторов на дорожке

15

2

heads

Количество магнитных головок

17

2

hidden_l

Количество скрытых секторов для раздела, который по размеру меньше 32 Мбайт

1

2

3

4

19

2

hidden_h

Количество скрытых секторов для раздела, превышающего по размеру 32 Мбайт

21

4

tot_secs

Общее количество секторов на логическом диске для раздела, превышающего по размеру 32 Мбайт

Как обычный, так и расширенный блок параметров BIOS содержат байт-описатель среды media. Этот байт может служить для идентификации носителя данных и может содержать величины, характеризующие носитель данных по количеству сторон диска и количеству секторов на дорожке. Байт-описатель среды media может содержать значения, представленные в табл. 4.

Таблица 4

Возможные значения байта-описателя среды носителя данных

Значение


Количество сторон


Количество секторов


Диаметр, дюймы


Емкость, Кбайт


1

2

3

4

5

F0h

2

18

3,5

1440

- " -

2

36

3,5

2880

- " -

2

15

5,25

1200

F8h

-

-



Жесткий диск любой емкости

F9h

2

9

3,5

720

- " -

2

15

5,25

1200

FAh

1

8

5,25

320

FBh

2

8

3,5

640

1

2

3

4

5

FCh

1

9

5,25

180

FDh

2

9

5,25

360

FEh

1

8

5,25; 8

160

FFh

2

8

5,25; 8

320

1.5.         Логический номер сектора


Следует отметить, что MS-DOS предоставляет программе возможность работы с так называемыми логическими номерами секторов. Это номера секторов внутри логического диска.

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

Например, у нас есть дискета с девятью секторами на дорожке. Сектор с логическим номером, равным 1, расположен на нулевой дорожке. Это самый первый сектор на дорожке, он имеет номер 1. Следующий сектор на нулевой дорожке имеет логический номер 2, последний сектор на нулевой дорожке имеет логический номер 9. Сектор с логическим номером 10 расположен уже на дорожке номер 1. Это тоже самый первый сектор на дорожке. И так далее, по мере увеличения логического номера сектора изменяются номера дорожек.

1.6.         Прерывания INT 25h и INT 26h


Для работы с логическим диском (или дискетой) на уровне логических номеров секторов MS-DOS предоставляет программам два прерывания - INT 25h (чтение сектора по его логическому номеру) и INT 26h (запись сектора по его логическому номеру). Вызов этих прерываний имеет различный формат для разных версий MS-DOS. Для тех версий, которые не поддерживают размер логических дисков более 32 Мбайт (MS-DOS 3.10, 3.20, 3.30) используется следующий формат команд:

INT 25h - чтение сектора по его логическому номеру:

На входе:

·        AL - адрес НГМД или НМД (0 - A:, 1 - B:, ...);

·        CX - количество секторов, которые нужно прочитать;

·        DX - логический номер начального сектора;

·        DS:BX - адрес буфера для чтения.

На выходе:

·        AH - код ошибки при неуспешном завершении операции;

·        CF - 1, если произошла ошибка, 0, если ошибки нет.

INT 26h - запись сектора по его логическому номеру:

На входе:

·        AL - адрес НГМД или НМД (0 - A:, 1 - B:, ...);

·        CX - количество секторов, которые нужно записать;

·        DX - логический номер начального сектора;

·        DS:BX - адрес буфера, содержащего данные.

На выходе:

·        AH - код ошибки при неуспешном завершении операции;

·        CF - 1, если произошла ошибка, 0, если ошибки нет.

Для более поздних версий MS-DOS и для COMPAQ DOS версии 3.31 используется другой способ указания номера логического сектора.

Так как шестнадцати разрядов недостаточно для адресации диска размером более 32 Мбайт, то при работе с расширенным разделом диска, занимающим более 32 Мбайт, регистры используются по-другому.

Регистр CX содержит FFFFh - признак того, что программа работает с логическим диском, имеющим размер более 32 Мбайт.

Регистры DS:BX содержат адрес следующей структуры:

·       0:4 - начальный номер логического сектора;

·       4:2 - количество секторов для чтения или записи;

·       6:4 - дальний адрес буфера для передачи данных.

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

Сделаем очень важное замечание, касающееся только что рассмотренных прерываний MS-DOS. Эти прерывания оставляют в стеке одно слово - старое значение регистра флагов. Поэтому после вызова прерывания должна следовать, например, такая команда:

pop ax

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

1.7.        
Кластеры


Операционная система ОС ЕС для ЭВМ ряда ЕС позволяла задать начальное количество цилиндров диска для размещения набора данных и размер области диска, которая может быть использована для этого набора дополнительно. Если при записи в файл все распределенное для файла место на диске окажется исчерпанным, программа завершится аварийно, даже если на диске еще есть свободные цилиндры.

Операционная система MS-DOS использует дисковое пространство другим способом.

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

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

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

1.8.         Содержимое таблицы FAT


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

Таблица FAT (как основная копия, так и резервная) состоит из массива индексных указателей, количество которых равно количеству кластеров области данных. Между кластерами и индексными указателями имеется взаимно однозначное соответствие — нулевой указатель соответствует нулевому кластеру и т. д.

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

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


Рис. 5. Пример распределения кластеров для файлов autoexec.bat и config.sys

На рис. 5. показаны фрагменты корневого каталога диска С: и элементы FAT для файлов autoexec.bat и config.sys .

Из рисунка видно, что для файла autoexec.bat отведено три кластера, а для файла config.sys - два кластера. Реально эти файлы не используют столько кластеров, так как их размер обычно невелик.

В каталоге кроме всего прочего указаны номера первых кластеров, распределенных этим файлам (соответственно 11 и 12). В своей одиннадцатой ячейке таблица FAT содержит число 17 - номер второго кластера, распределенного файлу autoexec.bat. Ячейка с номером 17 содержит число 18. Это номер третьего кластера, принадлежащего файлу autoexec.bat. Последняя ячейка, которая соответствует последнему кластеру, распределенному этому файлу, содержит специальное значение - FFFF.

Таким образом, файл autoexec.bat занимает три несмежных кластера с номерами 11, 17 и 18. Что же касается файла config.sys , то в нашем примере для него отведено два смежных кластера с номерами 12 и 13.

Размер таблицы FAT и разрядность используемых в ней индексных указателей определяется количеством кластеров в области данных. Для уменьшения потерь из-за фрагментации желательно кластеры делать небольшими, а для сокращения объема адресной информации и повышения скорости обмена наоборот — чем больше, тем лучше. При форматировании диска под файловую систему FAT обычно выбирается компромиссное решение, и размеры кластеров выбираются из диапазона от 1 до 128 секторов, или от 512 байт до 64 Кбайт.

1.9.         Форматы таблицы FAT


Очевидно, что разрядность индексного указателя должна быть такой, чтобы в нем можно было задать максимальный номер кластера для диска определенного объема. Существует несколько разновидностей FAT, отличающихся разрядностью индексных указателей, которая и используется в качестве условного обозначения: FAT12, FAT16 и FAT32. В файловой системе FAT12 используются 12-разрядные указатели, что позволяет поддерживать до 4096 кластеров в области данных диска[1], в FAT16 — 16-разрядные указатели для 65 536 кластеров и в FAT32 — 32-разрядные для более чем 4 миллиардов кластеров.

Форматирование FAT 12 обычно характерно только для небольших дисков объемом не более 16 Мбайт, чтобы не использовать кластеры более 4 Кбайт. По этой же причине считается, что FAT 16 целесообразнее для дисков с объемом не более 512 Мбайт, а для больших дисков лучше подходит FAT32, которая способна использовать кластеры 4 Кбайт при работе с дисками объемом до 8 Гбайт и только для дисков большего объема начинает использовать 8, 16 и 32 Кбайт. Максимальный размер раздела FAT16 ограничен 4 Гбайт, такой объем дает 65 536 кластеров по 64 Кбайт каждый, а максимальный размер раздела FAT32 практически не ограничен — 232 кластеров по 32 Кбайт.

Файловые системы FAT12 и FAT16 получили большое распространение благодаря их применению в операционных системах MS-DOS и Windows 3.х — самых массовых операционных системах первого десятилетия эры персональных компьютеров. По этой причине эти файловые системы поддерживаются сегодня и другими ОС, такими как UNIX, OS/2, Windows NT/2000 и Windows 95/98. Однако из-за постоянно растущих объемов жестких дисков, а также возрастающих требований к надежности, эти файловые системы быстро вытесняются как системой FAT32, впервые появившейся в Windows 95 OSR2, так и файловыми системами других типов.

Файловые системы FAT 12 и FAT 16 оперировали с именами файлов, состоящими из 12 символов по схеме «8.3». В версии FAT 16 операционной системы Windows NT был введен новый тип записи каталога — «длинное имя», что позволяет использовать имена длиной до 255 символов, причем каждый символ длинного имени хранится в двухбайтном формате Unicode. Имя по схеме «8.3», названное теперь коротким (не нужно путать его с простым именем файла, также называемого иногда коротким), по-прежнему хранится в 12-байтовом поле имени файла в записи каталога, а длинное имя помещается порциями по 13 символов в одну или несколько записей, следующих непосредственно за основной записью каталога. Каждый символ в формате Unicode кодируется двумя байтами, поэтому 13 символов занимают 26 байт, а оставшиеся 6 отведены под служебную информацию. Таким образом у файла появляются два имени — короткое, для совместимости со старыми приложениями, не понимающими длинных имен в Unicode, и длинное, удобное в использовании имя. Файловая система FAT32 также поддерживает короткие и длинные имена.

1.10.    Удаленные файлы в FAT


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

1.11.    Идентификация кластеров


Первый байт таблицы FAT называется "Описатель среды" (Media Descriptor). Он имеет такое же значение, как и байт-описатель среды, находящийся в загрузочном секторе логического диска.

Следующие 1,5 байта для 12-битового формата или 2 байта для 16-битового формат всегда содержат значение 0FFh.

Остальная часть таблицы FAT состоит из 12- или 16-битовых ячеек. Каждая ячейка соответствует одному кластеру диска. Эти ячейки могут содержать значения, приведенные в таблице 4.

Таблица 4.

FAT12

FAT16

Что означает

000h

0000h

Свободный кластер

FF0h - FF6h

FFF0h - FFF6h

Зарезервированный кластер

FF7h

FFF7h

Плохой кластер

FF8h - FFFh

FFF8h - FFFFh

Последний кластер в списке

002h - FEFh

0002h - FFEFh

Номер следующего кластера в списке

2.    РАЗРАБОТКА ПРОГРАММЫ

2.1.         Схема и алгоритм программы




2.2.        
Тест


1. Форматируем USB-накопитель в файловой системе FAT16
Рис. 6. Форматирование

2. Создаем на USB-накопителе три текстовых документа:

1. 1.txt – Текст в кодировке Unicode

2. 2.txt – Текст в кодировке ANSI

3. 3.txt – Любой непустой документ

3. Удалим первые два файлы, тем самым освободив кластеры. При удалении документов кластеры помечаются как свободные, однако, их содержимое не очищается, и в них будут присутствовать символьные последовательности.

4. Проверим содержимое USB-накопителя и убедимся, что второй и третий кластер свободен, но в них присутствует информация, а четвертый кластер занят, так как документ 3.txt не был удален



Рис. 7. Содержимое USB-накопителя
Содержимое кластера 2 (1.txt)
Рис. 8. Содержимое файла 1.txt

На рисунке 8  видно, что в кластере находится текст в формате Unicode (Символ занимает 2 байта)
Содержимое кластера 3 (2.txt)
Рис. 9. Содержимое файла 2.txt

На рисунке видно, что в кластере находится текст в формате ANSI (Символ занимает 1 байт)
Запускаем программу
Рис. 10. Окно программы после запуска

Для выбора диска необходимо воспользоваться командой Выбрать диск
Рис. 11. Окно выбора диска

После выбора диска, для поиска свободных кластеров, необходимо воспользоваться командой Поиск свободных кластеров

Рис. 12. Процесс поиска

После поиска свободных кластеров
Рис. 13. Содержимое файла 1.txt

Список свободных кластеров у которых контрольная сумма не равна 0. То есть список свободных но непустых кластеров. Содержимое кластера 2 при кодировке Unicode
Рис. 14. Содержимое файла 2.txt

Список свободных кластеров у которых контрольная сумма не равна 0. То есть список свободных но непустых кластеров. Содержимое кластера 3 при кодировке 1252 Западноевропейская (Windows)



ЗАКЛЮЧЕНИЕ


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

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

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

Неоспоримым достоинством будет являться реализация в программе графического интерфейса пользователя (GUI). Это позволит более наглядно и привычно рядовому пользователю использовать все возможности программы.


БИБЛИОГРАФИЧЕСКИЙ СПИСОК


1.     Александр Фролов, Григорий Фролов Операционная система MS-DOS. – Том 1, книги 1-2, М.: Диалог-МИФИ, 1991, 239 стр.

2.     Александр Фролов, Григорий Фролов. MS-DOS для программиста
Том 19, М.: Диалог-МИФИ, 1995, 253 стр.

3.     Дейтел Х. М., Дейтел П. Дж. Как программировать на С: Четвертое издание. Пер. с англ. – М.: ООО «Бином – Пресс», 2006 г. – 912 с.: ил.

4.     Литвиненко Н.А. Технология программирования на С++. Начальный курс.-СПб.: БХВ-Петербург, 2005.-288 с.: ил.

5.     Подбельский В. В. Практикум по программированию на языке Си (+CD).: Учеб. пособие. – М.: Финансы и статистика, 2004. – 576.: ил.

6.     Подбельский В. В., Фомин С. С. Программирование на языке Си: учеб. пособие. – 2-е доп. изд. – М.: Финансы и статистика, 2007. – 600с.: ил.

7.     Страуструп Б.. Язык программирования С++. Специальной издание. Пер. с англ.-М.: ООО «Бином-Пресс», 2008 г. – 1104с.:ил.

8.     Шилдт Г. Полный справочник по С++, 4-е издание.: Пер. с англ. – М.: Издательский дом «Вильямс», 2008. – 800 с.: ил.


ПРИЛОЖЕНИЕ 1


Листинг модуля FAT_data.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

using System.Runtime.InteropServices;

using Microsoft.Win32.SafeHandles;
namespace HiddenLost

{

    //Класс моделирующий файл в FAT16

    public class FileFAT16

    {

        FileInfo _File;// Описатель файла

        uint _SizeFile=0;//Размер файла

        uint _SizeFileClusters=0;//Размер файла в кластерах

        LogicalDrive _Disk;//Диск на котором находится файл

        uint _Error=0;//Код ошибки

        uint _PositionSector = 0;//Сектор в котором находится поле длины файла

        uint _PositionByte = 0;//Смещение в катором находтся поле длины файла

        public FileFAT16(FileInfo File, LogicalDrive Disk, uint BeginingDyrectory)

        {

            _File = File;//Сохранение описателя файла во внутренней переменной

            _Disk = Disk;//Сохранение диска во внутренней переменной
            _SizeFile = (uint)_File.Length;//Получение длины файла

            //Вычисление длины файла в кластерах

            _SizeFileClusters = _SizeFile / _Disk.ClusterSize + (uint)((_SizeFile % _Disk.ClusterSize == 0) ? 0 : 1);
            #region Получение короткого имени файла

            StringBuilder lpszShortPath = new StringBuilder(512);

            UInt32 ShortNameRes = Win32API.GetShortPathName(new StringBuilder(_File.FullName), lpszShortPath, 512);

            if (ShortNameRes==0)

                _Error = _Error | 1;

            #endregion

           

            //Вспомогательные переменные

            Int32 L32Bytes;//младшие 32 бита long

            Int32 H32Bytes;//Старшие 32 бита long

            UInt32 PositionRes;// Результат позиционирования

            byte[] lpBuffer = new byte[512];// Буффер для записи и чтения

            UInt32 pNumberOfBytesRead;//Число прочитанных байт

            UInt32 pNumberOfBytesWrite;//Число записанных байт

            bool ReadRes;//Результат чтения

            bool WriteRes;//Результат записи

            ulong Position;//Позиция на диске

            Encoding ASCIIConverter=Encoding.GetEncoding(866);//Перекодировщик 866 в Unicod

            if (_Error==0)

            {

                #region

                string ShortNameFile = lpszShortPath.ToString().Substring(lpszShortPath.ToString().LastIndexOf('\\')+1);

                if (ShortNameFile.IndexOf(".") != -1)

                {

                    ShortNameFile = ShortNameFile.Insert(ShortNameFile.IndexOf("."), new string(' ', 8 - ShortNameFile.IndexOf(".")));

                    ShortNameFile = ShortNameFile.Replace(".", "");

                }

                ShortNameFile = ShortNameFile + new string(' ', 11 - ShortNameFile.Length);

                #endregion
                #region Получение позиции файла

                //Поиск записи файла в заданном каталоге.

                //Позиция каталога задана переменной BeginingDyrectory

                if(Disk.cHDevice.IsInvalid==false && _Disk.cHDevice.IsClosed==false)

                {

                    Position = BeginingDyrectory;//Позиция на диске для начала поиска

                    L32Bytes = (Int32)((Position << 32) >> 32);//Получение младших 32 бит позици

                    H32Bytes = (Int32)(Position >> 32);//Получение старших 32 бит позици

                    //Позиционируемся на начало каталога

                    PositionRes = Win32API.SetFilePointer(Disk.cHDevice, L32Bytes, out H32Bytes, 0);

                    if(!(PositionRes==Win32API.INVALID_SET_FILE_POINTER && Win32API.GetLastError()!=0))

                    {

                        while (true)

                        {

                            //Чтение сектора в каталоге

                            ReadRes = Win32API.ReadFile(_Disk.cHDevice, lpBuffer, 512, out pNumberOfBytesRead, IntPtr.Zero);

                            if (lpBuffer[0] == 0)

                            {

                                _Error = _Error|2;

                                break;

                            }

                            //Разбиение прочитанного сектора на записи длиной 32 байта

                            for (int p = 0; p < 16; p++)

                            {

                                //Поиск имени файла в начальных 11 байтах каждой записи

                                if (ShortNameFile.ToUpper() == ASCIIConverter.GetString(lpBuffer, p * 32, 11).ToUpper())

                                {

                                    _PositionSector = (uint)Position;//Сектор в котором найден файл

                                    _PositionByte = (uint)p*32+28;// Смещение где находится длина файла

                                    break;

                                }

                            }

                            if (_PositionByte != 0)

                                break;

                            Position += 512;// если сектор просмотрен и файл не найден, чтение следующего сектора

                        }

                    }

                    else

                        _Error = _Error|4;//Возведение 4 бита ошибки

                }

                else

                    _Error = _Error|8;//Возведение 5 бита ошибки

                #endregion

            }

                        if(_Error==0 && _SizeSlack>0 )

            {

                #region

                Position = _PositionSector;//Позиция сектора где найден файл

                L32Bytes = BitConverter.ToInt32(BitConverter.GetBytes(Position), 0);//Младшие 32 бита позиции

                H32Bytes = BitConverter.ToInt32(BitConverter.GetBytes(Position), 4);//Старшие 32 бита позиции

               

                //Выполняем функцию позиционирования на нужный сектор

                PositionRes = Win32API.SetFilePointer(Disk.cHDevice, L32Bytes, out H32Bytes, 0);               

                if(!(PositionRes==Win32API.INVALID_SET_FILE_POINTER && Win32API.GetLastError()!=0))

                {

                    //Изменяем содержимое нужного сектора, сектор был прочитан ранее при поиске записи

                    //Изменяем только те байты которые отвечают за длину файла. Делаем длину кратную размеру сектора

                    lpBuffer[_PositionByte] = BitConverter.GetBytes(_SizeFile+_SizeSlack)[0];

                    lpBuffer[_PositionByte+1] = BitConverter.GetBytes(_SizeFile+_SizeSlack)[1];

                    lpBuffer[_PositionByte+2] = BitConverter.GetBytes(_SizeFile+_SizeSlack)[2];

                    lpBuffer[_PositionByte+3] = BitConverter.GetBytes(_SizeFile+_SizeSlack)[3];

                   

                    //Записываем измененный сектор в нужное место, где хранился оригинал   

                    WriteRes = Win32API.WriteFile(_Disk.cHDevice, lpBuffer, 512, out pNumberOfBytesWrite, IntPtr.Zero);

                    if (WriteRes)

                    

                        //Позиционирумся обратно на сектор, где находится длина файла

                        PositionRes = Win32API.SetFilePointer(Disk.cHDevice, L32Bytes, out H32Bytes, 0);

                        if(!(PositionRes==Win32API.INVALID_SET_FILE_POINTER && Win32API.GetLastError()!=0))

                        {

                            //Изменяем обратно длину файла на положенную

                            lpBuffer[_PositionByte] = BitConverter.GetBytes(_SizeFile)[0];

                            lpBuffer[_PositionByte+1] = BitConverter.GetBytes(_SizeFile)[1];

                            lpBuffer[_PositionByte+2] = BitConverter.GetBytes(_SizeFile)[2];

                            lpBuffer[_PositionByte+3] = BitConverter.GetBytes(_SizeFile)[3];

                            //Переписываем ранее измененный сектор на оригинал

                            WriteRes = Win32API.WriteFile(_Disk.cHDevice, lpBuffer, 512, out pNumberOfBytesWrite, IntPtr.Zero);

                            _Disk.CloseDrive();//Закрываем диск, чтобы изменения немедленно вступили в силу

                            _Disk.OpenDrive();

                            if (!WriteRes)

                                _Error = _Error |128;

                        }

                        else

                            _Error = _Error | 64;

                    }

                    else

                        _Error = _Error | 32;

                }

                else

                    _Error = _Error | 16;

                #endregion

            }

        }

        public uint Error

        {

            get { return _Error; }

        }

        public string Status

        {

            get{if(_Error==0) return "OK"; else return "Error";}

        }

        public FileInfo File

        {

            get { return _File; }

        }

        public uint SizeSlack

        {

            get { return _SizeSlack; }

        }

        public uint SizeFile

        {

            get { return _SizeFile; }

        }

        public uint SizeFileClusters

        {

            get { return _SizeFileClusters; }

        }

        public byte[] Slack

        {

            get { return _Slack; }

        }

    }

}
LogicalDrive.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.Win32.SafeHandles;
namespace HiddenLost

{

     public class LogicalDrive

    {

        uint _BytesPerSector = 0;// Байт в секторе

        uint _SectorsPerCluster = 0;// Секторов в кластера

        uint _SectorsPerFAT = 0;// Секторов в FAT

        uint _CopiesFAT = 0;// Число FAT

        uint _RootEntries = 0;// Записей в коренвом каталоге

        uint _TotalSize = 0;// Размер тома

        uint _ReservedSectors = 0;// Зарезервированно секторов

        SafeFileHandle _cHDevice = null; //Handle логического диска для доступа функций

        string _Name;// Буква логического диска

        byte[] _CopyBR;// Копия загрузочного сектора BR

        ulong _TypeSystem;// Тип файловой системы

        public LogicalDrive(string Name)

        {

            _Name = Name;

            _cHDevice = Win32API.CreateFile(new StringBuilder("\\\\.\\"+Name), Win32API.GENERIC_READ | Win32API.GENERIC_WRITE, Win32API.FILE_SHARE_WRITE|Win32API.FILE_SHARE_READ, IntPtr.Zero, Win32API.OPEN_EXISTING, Win32API.FILE_FLAG_BACKUP_SEMANTICS|Win32API.FILE_FLAG_NO_BUFFERING|Win32API.FILE_FLAG_WRITE_THROUGH, IntPtr.Zero);

           

            if(_cHDevice.IsInvalid==false)

            {

                _CopyBR = new byte[512];

                UInt32 pNumberOfBytesRead;

                //Чтение BR

                bool ReadRes = Win32API.ReadFile(_cHDevice, _CopyBR, 512, out pNumberOfBytesRead, IntPtr.Zero);

                if(ReadRes == true)

                {

                    //Инициализация внутренних переменных значениями из BR

                    _BytesPerSector = BitConverter.ToUInt16(_CopyBR, 11);

                    _SectorsPerCluster = (uint)_CopyBR[13];

                    _TotalSize = BitConverter.ToUInt16(_CopyBR, 19) + BitConverter.ToUInt32(_CopyBR, 32);

                    _SectorsPerFAT = BitConverter.ToUInt16(_CopyBR, 22);

                    _CopiesFAT = _CopyBR[16];

                    _RootEntries = BitConverter.ToUInt16(_CopyBR, 17);

                    _ReservedSectors = BitConverter.ToUInt16(_CopyBR, 14);

                    _TypeSystem = BitConverter.ToUInt64(_CopyBR, 54);

                    _TypeSystem = _TypeSystem & 0xFFFFFFFFFF;

                }

                else

                    _Error = _Error | 2;

            }

            else

                _Error = _Error | 1;

        }

        //Метод  для закрытия устрйства

        public void CloseDrive()

        {

            //Закрытие устройства

            Win32API.CloseHandle(_cHDevice);// Вызов статической функции из класса Win32API

        }

        //Метод для открытия устройства

        public void OpenDrive()

        {

            //Открытие диска для записи и чтения

            _cHDevice = Win32API.CreateFile(new StringBuilder("\\\\.\\" + _Name), Win32API.GENERIC_READ | Win32API.GENERIC_WRITE, Win32API.FILE_SHARE_WRITE | Win32API.FILE_SHARE_READ, IntPtr.Zero, Win32API.OPEN_EXISTING, Win32API.FILE_FLAG_BACKUP_SEMANTICS | Win32API.FILE_FLAG_NO_BUFFERING | Win32API.FILE_FLAG_WRITE_THROUGH, IntPtr.Zero

      }

        //Свойства для доступа к основным переменным диска

        #region Свойства

        public uint BytesPerSector

        {

            get{return _BytesPerSector;}

            set{_BytesPerSector = value;}

        }

        public uint SectorsPerCluster

        {

            get{return _SectorsPerCluster;}

            set{_SectorsPerCluster = value;}

        }

        public uint ClusterSize

        {

            get{ return _BytesPerSector*_SectorsPerCluster;}

        }

        public uint TotalSize

        {

            get{return _TotalSize;}

            set{_TotalSize = value;}

        }

        public uint SectorsPerFAT

        {

            get{ return _SectorsPerFAT;}

            set{_SectorsPerFAT = value;}

        }

        public uint FATSize

        {

            get {return _SectorsPerFAT*_BytesPerSector;}

        }

        public uint CopiesFAT

        {

            get{ return _CopiesFAT;}

            set{_CopiesFAT = value;}

        }

        public uint RootEntries

        {

            get{ return _RootEntries;}

            set{_RootEntries = value;}

        }

        public uint RootSize

        {

            get{return _RootEntries * (uint)32;}

        }

        public uint ReservedSectors

        {

            get{ return _ReservedSectors;}

            set{_ReservedSectors = value;}

        }

        public uint ReservedSize

        {

            get { return _ReservedSectors * _BytesPerSector; }

        }

        public uint BeginningData

        {

            get{return ReservedSize + _CopiesFAT*FATSize+RootSize;}

        }

        public uint BeginningRoot

        {

            get { return ReservedSize + _CopiesFAT * FATSize; }

        }

        public byte[] CopyBR

        {

            get{return _CopyBR;}

        }

        public SafeFileHandle cHDevice

        {

            get { return _cHDevice; }

        }

        public uint Error

        {

            get { return _Error; }

        }

        public ulong TypeSystem

        {

            get { return _TypeSystem; }

        }

        #endregion

    }

}
Win32API.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.Win32.SafeHandles;

using System.Runtime.InteropServices;

namespace HiddenLost

{

    public class Win32API

    {

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern bool GetDiskFreeSpace(StringBuilder lpRootPathName, out UInt32 lpSectorsPerCluster, out UInt32 lpBytesPerSector, out UInt32 lpNumberOfFreeClusters, out UInt32 lpTotalNumberOfClusters);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern SafeFileHandle CreateFile(StringBuilder lpFileName, UInt32 dwDesiredAccess, System.UInt32 dwShareMode, IntPtr pSecurityAttributes, System.UInt32 dwCreationDisposition, System.UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);

        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern UInt32 SetFilePointer(SafeFileHandle hFile, Int32 lDistanceToMove, out Int32 lpDistanceToMoveHigh, UInt32 dwMoveMethod);

        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern UInt32 GetLastError();

        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern bool ReadFile(SafeFileHandle hFile, byte[] lpBuffer, UInt32 NumberOfBytesToRead, out UInt32 pNumberOfBytesRead, IntPtr Overlapped);

        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern bool WriteFile(SafeFileHandle hFile, byte[] lpBuffer, UInt32 NumberOfBytesToWrite, out UInt32 pNumberOfBytesWrite, IntPtr Overlapped);

        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern bool CloseHandle(SafeFileHandle hFile);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern UInt32 GetShortPathName(StringBuilder lpszLongPath, StringBuilder lpszShortPath, UInt32 cchBuffer);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern bool BackupRead(SafeFileHandle hFile, byte[] lpBuffer, UInt32 nNumberOfBytesToRead, out UInt32 lpNumberOfBytesRead, bool bAbort, bool bProcessSecurity, out IntPtr lpContext);

        public const UInt32 FILE_SHARE_READ = 0x00000001;

        public const UInt32 FILE_SHARE_WRITE = 0x00000002;

        public const UInt32 OPEN_EXISTING = 0x00000003;

        public const UInt32 GENERIC_READ = 0x80000000;

        public const UInt32 GENERIC_WRITE = 0x40000000;

        public const UInt32 INVALID_SET_FILE_POINTER = 0xFFFFFFFF;

        public const UInt32 FILE_FLAG_BACKUP_SEMANTICS = 0x2000000;

        public const UInt32 FILE_FLAG_NO_BUFFERING = 0x20000000;

        public const UInt32 FILE_FLAG_WRITE_THROUGH = 0x80000000;

    }

}



[1] Реально это число немного меньше, так как несколько значений индексною указателя расходуется для идентификации специальных ситуаций, таких как «Последний кластер», «Неиспользуемый кластер», «Дефектный кластер» и «Резервный кластер»

1. Реферат на тему Гнойные заболевания кисти
2. Реферат Исковая давность в гражданском праве и ее гражданско-правовое значение
3. Диплом Реорганизация юридических лиц 2 Понятие формы
4. Реферат Рынок акций
5. Биография на тему Старшинов Вячеслав Иванович
6. Контрольная работа на тему Роль отца в семье
7. Реферат Организационная и производственная структура предприятия
8. Курсовая Оценка качества среды города Орска по функциональной асимметрии листовой пластинки березы повисл
9. Контрольная работа на тему Деградация земель и лесов
10. Контрольная_работа на тему Анализ объема спроса