Реферат: Розробка програмного забезпечення файлового менеджера

ЗМІСТ

ВСТУП

1 СТРУКТУРАПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ ФАЙЛОВОГО МЕНЕДЖЕРУ

2 СТРУКТУРА ДАНИХ

2.1 Стуктуризавантажувального запису

2.2 Структураслужбової області FAT

2.3 Структура елементакаталогу

2.4 Програмніструктури

3 ОПИС АЛГОРИТМІВ ПЗФМ

3.1 Алгоритм пошукудисків й іменування дисків

3.2 Алгоритм доступу коб'єктам файлової системи

3.3Алгоритм визначеннязайнятого місця на розділі

3.4 Алгоритм зрівняннядиректорій

4 ОПИС ПРОГРАМНИХМОДУЛІВ.

5 МЕТОДИКА РОБОТИ

6 ДОСЛІДЖЕННЯРЕЗУЛЬТАТІВ

ВИСНОВОК

ДОДАТОК А — Кодпрограми файлового менеджеру


ВСТУП

Метою даного проекту є практичне дослідження та засвоєння прийомів роботиз дисковими накопичувачами у середовищі ОС Windowsта роботи на низькому рівні з файловими системами FAT16/FAT32. Також підтримується робота з NTFS. Програма розроблена як WINDOWS програма, написана мовою С++. Інтерфейс програми буврозроблений схожий до існуючих файлових менеджерів середовища Microsoft Windows.


1. СТРУКТУРА ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ ФАЙЛОВОГО МЕНЕДЖЕРУ

Файловий менеджер – програма, яка виконує візуалізацію вмісту каталогу,дозволяє виконувати різноманітні операції з об’єктами каталогу, наприклад,копіювання, видалення, правка та інші.

Файловий менеджер, який був розроблений згідно з завданням до проектувиконує наступні функції:

-       пошук і найменування всіхлогічних дисків у межах даної конфігурації технічних засобів;

-       визначення характеристиклогічних дисків;

-       порівняння директорій закількісним фактом.

Також була реалізована підтримка довгих імен такирилиці для об’єктів директорій.

Структура файлового менеджеру на рис. 1.1.

Згідно зі структурою файловий менеджер має інтерфейс, в якому можнаобрати наступну дію.

Список дій показаний в структурі ФМ.

Програма багатомодульну структуру. Кожний модуль виконує свої функції.Кожна дія, яку можна виконати, реалізована в окремій функції. Виключення іззагального правил являє собою модуль manager.cpp, який реалізує як інтерфейс (за правилами створення VCL) так і роботу з NTFS та порівняння директорії. Тому на структурнійсхемі проекту він зустрічається двічі.

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

Після цього обирається завантажувальний диск та зчитується кореневийкаталог цього диску. Вміст каталогу показується на екрані. Далі програма очікуєнаступних вказівок користувача щодо подальшої діяльності.

/>

Рисунок 1.1 – Структура ФМ


2СТРУКТУРА ДАНИХ

У програмі використовуються декілька структур даних. Структуризавантажувального запису, службової частини ФС та елементу каталогу – цесистемні структури. Також програма містить і власні структури – інформація прологічні диски та інші.

2.1        Структуризавантажувального запису

Інформація про розділи жорсткого диску зберігається у першому секторіпристрою. Це – головний завантажувальний запис MBR (Master Boot Record). Структура MBR наведена у табл. 2.1.

Таблиця 2.1 — Структура MBR

Зсув Розмір, байт Опис Ім’я 1BE h Код завантажника MBR reserved 1BE h 40 h Масив з 4х елементів Partition Table Partition Table 1FE h 2 Сигнатура MBR (0х55АА) sign

Один елемент Partition Table може визначати логічний диск або розширенийрозділ. У межах одного жорсткого диска може бути лише один розширений розділ.Заповнення полів Partition Table виконуєтьсяна етапі розбивання диска на розділи. В табл. 2.2 наведена структура елементу Partition Table.

Таблиця2.2 — Структура елементу Partition Table

Зсув Розмір, байт Опис Ім’я 1 Ознака активного розділу (80h — активний / 0 — неактивний) priznak 1 1 Початкова голівка розділу starthead 2 2 Початкова доріжка та сектор розділу. 6-бітний номер сектору визначається як 6 молодших бітів молодшого байту, а 10-бітний номер циліндру, як 2 старші біти молодшого байту та розташовані за ним 8 бітів старшого байту starttrack 4 1 Код системи syscode 5 1 Кінцева голівка розділу endhead 6 2 Кінцева доріжка та сектор розділу endtrack 8 4 Початковий сектор розділу startsector 12 4 Розмір розділу у секторах size

Поле код системи містить інформацію про тип ФС (основний розділ) або проознаку розширеного розділу (05h, 0Fh).

Основний розділ описує логічний диск, адресу початку якого можна взяти зіструктури елементу Partition Table – поле startsector. Це ж поле у елементі Partition Table при ознаці розширеного розділу вказує навторинну MBR. Ця MBR може містити максимум два елементи Partition Table з чотирьох. Перший елемент буде вказувати начерговий логічний диск, а другий – на наступну вторинну MBR. Дляотримання абсолютної адреси початку логічного диска необхідно до значення поля startsector додати адресу MBR, у якій описуєтьсяданий диск.

2.2        Структура службовоїобласті FAT

Після отримання абсолютної адреси початку логічного диска в програмівиконується зчитування першого сектора диска. В системі FAT це –завантажувальна область (BOOT – область). BOOT – область містить параметри тахарактеристики логічного диска. Її структура для ФС FAT12 та FAT16 наведена у табл.2.3, а для системи FAT32 – у табл. 2.4.

Таблиця 2.3 – Структура BOOT – сектору для FAT12 та FAT16

Зсув Розмір, байт Опис Ім’я 3 Команда JMP на код завантажника jmpcode 3 8 Назва операційної системи, у якій виконано форматування диску os 11 2 Кількість байт у секторі BytePerSector 13 1 Кількість секторів у кластері SectorPerCluster 14 2 Кількість резервних секторів SizeReserv 16 1 Кількість копій FAT NumberCopiesFAT 17 2 Кількість елементів кореневого каталогу MaxDirElem 19 2 Розмір диску в секторах для дисків <32MB, інакше 0 Smallsize 21 1 Описувач середовища MediaDescriptor 22 2 Кількість секторів таблиці FAT SizeFAT16inSectors 24 2 Секторів на доріжці SectorPerTrack 26 2 Кількість голівок Heads  28 4 Кількість схованих секторів NumberHiddenSectors 32 4 Розмір в секторах для дисків > 32MB BigSize 36 1 Тип пристрою(для першого диску в системі 80h, для інших 0) -- 37 1 Резерв -- 38 1 Сигнатура 29h. Code 39 4 Серійний номер SerialNumber 43 11 Метка диску Label 54 8 Ідентифікатор FAT (‘FAT12’ або ‘FAT16’) FATID 62 2 Код завантажника --

Таблиця 2.4 – Структура BOOT – сектору для FAT32    

Зсув Розмір, байт Опис Ім’я 3 Команда JMP на код завантажника jmpcode 3 8 Назва операційної системи, у якій виконано форматування диску os 11 2 Кількість байт у секторі BytePerSector 13 1 Кількість секторів у кластері SectorPerCluster 14 2 Кількість резервних секторів SizeReserv 16 1 Кількість копій FAT NumberCopiesFAT 17 4 Резерв --- 21 1 Описувач середовища MediaDescriptor 22 2 Резерв --- 24 2 Секторів на доріжці SectorPerTrack 26 2 Кількість голівок Heads 28 4 Кількість схованих секторів NumberHiddenSectors 32 4 Резерв --- 38 6 Резерв reserv1 44 4 Початковий кластер кореневого каталогу StartCluster 48 2 Початковий сектор структури FS INFO BegFS 50 2 Номер сектору з копією BOOT-розділу BootCopy 52 12 Резерв reserv2 64 1 Фізичний номер пристрою PhysNum 65 1 Резерв reserv3 66 1 Розширена сігнатура ExtSign 67 4 Серійний номер пристрою SerialNumber 71 11 Метка диску Label 82 8 Ідентифікатор (‘FAT32’) FATID 90 2 55AA ---

Дана структура дозволяє отримати доступ до інформаційних полівBOOT-сектора необхідного логічного диска.

BOOT-область в файловихсистемах FAT12,16 займає1 сектор, а в ФС FAT32 – 3 сектори. Другий сектор містить додатковіпараметри та сигнатури, а третій – продовження програми завантаження. Зазавантажувальною областю розташовані таблиці FAT –таблиці кластерів. Їх кількість визначається у BOOT-секторі.У файлових системах FAT12,16 за таблицями кластерів знаходиться кореневийкаталог. Його розмір обмежений кількістю елементів, вказаних в BOOT-секторі.Кореневий каталог FAT32 може не розміщатися відразу ж за таблицями кластерів тане має меж щодо свого розміру. За всіма цими службовими областями знаходиться областьданих.

Таблиця FAT містить інформацію про розподілення дисковогопростору під об’єкти ФС. Ця таблиця – масив елементів із розмірністю 12, 16 або32 біти в залежності від версії ФС. Номер елементу таблиці FAT відповідає номеру кластера в області даних. У таблиці 2.5 наведеніможливі значення одного елементу FAT.

Таблиця 2.5 – Значення елементу FAT

FAT12 FAT16 FAT32 Пояснення Вільний кластер FF0-FF6 FFF0-FFF6 0FFFFFF0-0FFFFFF6 Зарезервований кластер FF7 FFF7 0FFFFFF7 BAD-кластер FF8-FFF FFF8-FFFF 0FFFFFF8-0FFFFFFF Останній кластер об’єкту

Усі інші значення вказують на наступний кластер.

Послідовність кластерів, яка може належати одному об’єкту в таблиці ФАТ,представляє собою односпрямований список, голова якого в явному виді відсутня,а кінець визначається ознакою кінця ланцюжка.

2.3        Структура елементакаталогу

Кожен каталог представляє собою послідовність дескрипторів. Структурадескриптора об’єкта з коротким ім’ям наведена у табл. 2.6 для FAT13/FAT16 та у табл. 2.8 для FAT32.Структура байту атрибуту у табл. 2.7.

Таблиця 2.6 – Структура дескриптора для FAT12 / FAT16

Зсув Розмір, байт Опис Ім’я 1 Ознака дескриптору: 0 – вільний; E5h — видалений; інше-перший символ імені об’єкту fn 1 7 7 символів імені об’єкту name 8 3 Розширення об’єкту ext 11 1 Байт атрибутів attr 12 10 Резерв reserv 22 2 Час створення або останньої модифікації TimeMade 24 2 Дата створення або останньої модифікації DateMade 26 2 Молодша частина початкового кластеру об’єкта FirstCluster 28 4 Розмір об’єкта в байтах SizeFileInBytes

Таблиця 2.7 – Байт атрибутів об’єкта

Номербіту Значення біту Опис 1 Об’єкт тільки для читання 1 1 Об’єкт схованого типу 2 1 Об’єкт системного типу 3 1 Мітка тому 4 1 Директорія 5 1 Архівний файл 6 Не використовується

Таблиця 2.8 – Структура дескриптора для FAT32

Зсув Розмір, байт Опис Ім’я 1 Ознака дескриптору: 0 – вільний; E5h — видалений; інше-перший символ імені об’єкту fn 1 7 7 символів імені об’єкту name 8 3 Розширення об’єкту ext 11 1 Байт атрибутів attr 12 1 Резерв reserv 13 2 Час створення (0.1 секунд) TimeMadeSec 14 2 Час створення TimeMade 16 2 Дата створення або останньої модифікації DateMade 18 2 Дата останнього звертання DateLast 20 2 Старший байт номеру першого кластеру, який був виділений об’єкту FirstClusterHigh 22 2 Час останньої модифікації об’єкту TimeLast 24 2 Дата останнього запису об’єкту DateLastWrite 26 2 Молодший байт номеру першого кластеру, який був виділений об’єкту FirstClusterLow 28 4 Розмір файлу в байтах SizeFileInBytes

Якщо об’єкт іменується довгим ім’ям, то під нього виділяється декількадескрипторів стандартного розміру (32б). Кількість дескрипторів визначаєтьсядовжиною імені об’єкта. Максимальна довжина імені об’єкта – 255 символів, якізберігаються в форматі UNICODE (по два байти на один символ). У кожномудескриптору може зберігатися 13 символів імені об’єкту. Структура дескрипторадля довгого імені наведена у табл. 2.9.

Таблиця2.9 – Структура дескриптора для довгого імені

Зсув Розмір, байт Опис Ім’я 1 Номер порції імені fn 1 10 5 символів імені об’єкту FiveSymb 11 1 Байт атрибутів, дорівнює 0Fh attr 12 1 Завжди дорівнює 0 reserv 13 1 Контрольна сума короткого ім’я CRC 14 12 6 символів імені об’єкту SixSymb 26 2 Резерв reserv2 28 4 2 символа імені об’єкту TwoSymb

Ім’я в останній порції довгого імені може бути меншим за 13 символів. Утакому випадку значима частина імені завершується нулем. усі інші поля іменізаповнюються FFFF.

/>2.4        Програмні структури

Всі необхідні програмні структури представлені в header-файлах. Ціль їхнього створення — організація даних, прочитаних з носіїв.Наприклад, кожний жорсткий диск буде представлений структурою

typedef struct _HARDINFO

{

         char nHard;                            //номержорсткого диску

         void* hDrive;                //хендл жорсткого диску

         UINT dwSectorSize;     //розмір сектора

         UINT bitsPerSector;     //кількість розрядів для адресації всередині сектора

         UINT dwExtendedAddr;        //адреса розширеногорозділу

         PLOGICAL_DISC disklist;

}HARDINFO, *PHARDINFO;

Інформаціяпро розділи організується в список структур, по одному списку на кожнийжорсткий диск:

typedef struct _LOGICAL_DISC

{

         void* next;

         char nHard;

         char nDisc;

         char active;

         UINT abs_addr;

         UINT secLength;

         UINT id;

         char* cpFS;

         UINT SN4;

         UINT gbLength;

         UINT mbLength;

        

         void* disc_info;

         UINTprcfree;

} LOGICAL_DISC, *PLOGICAL_DISC, **PPLOGICAL_DISC;

Післятого, як FAT32-розділ був відкритий для читання, інформація пронього записується в таку структуру

typedef struct _DISC_INFO {

         char Disc;                      //логічний диск

         UINT beginFAT;           //адресапочатку FAT-таблиці у секторах

         UINT nBytePerSector;  //розмір сектора убайтах

         void* hDrive;                //хендл відкритого розділу

         char SectPerCluster;      //розміркластера в секторах

         UINT BytesPerCluster; //розмір кластера в байтах

         UINT sizeFAT;             //розмір FAT-таблиців секторах

         UINT*pFAT;                        //адреса образу FAT-таблиці у ОЗУ

         UINTsizeFATbytes;     //розмір FAT-таблиці в байтах

         USHORTnFATCopy;           //кількість копій FAT

         USHORTsizeReserved;         //розмір зарезервованої області в секторах

         UINTbitsPerSector;     //кількість розрядів для адресації всередині сектора

         UINTRootCluster;       //номер першогокластера корневой директории

         UINTdwRootDirSize;  //кількістькластерів для кореневої директорії

         HDIRhRootDir;           //хендл кореневоїдиректориії

         UINT prcfree;

         BOOL bFAT16;

         UINT RootSector;

         UINT nRootElements;

}DISC_INFO, *PDISC_INFO;

Списокпрочитаних файлів організується в структуру:

typedef struct _FILES {

         char* ansiname;

         UINT attrib;

         UINT firstcluster;

         __int64 filesize;

         void* next;

} FILES, *PFILES;

Якщо необхідно вивести на екран уміст файлу, спочатку його вміст буде відображено в таку структуру:

typedef struct _FILEBUF {

         char* pBuf;

         char* ansiname;

         UINT dwLen;

} FILEBUF, *PFILEBUF;


3 ОПИС АЛГОРИТМІВ ПЗ ФМ

У цьому пункті розглядаються послідовно алгоритми пошуку та іменуваннядисків, доступу до об’єктів файлової системи, визначення зайнятого місця дляфайлової системи FAT32, FAT16.

3.1 Алгоритм пошуку дисків й іменування дисків

Алгоритм іменування логічних дисків засновано на звіренні серійногономера, отриманого логічного диска із серійним номером, збереженим системою.

/>

Рисунок3.1 – Пошук та найменування дисків


3.2 Алгоритм доступу к об’єктам файлової системи

Основна концепція файлової системи FAT полягає в тім, що кожному файлу йкаталогу виділяється структура даних, називана дескриптором. У цій структурізберігається ім'я файлу, його розмір, початкова адреса вмісту файлу й іншіметадані. Данні файлів і каталогів зберігається в блоках даних, називанихкластерами. Якщо файлу або каталогу виділяється більш одного кластера, іншікластери знаходять за допомогою структури даних, називаної FAT(File AllocationTable). Структура FAT використовується як для ідентифікації наступних кластеріву файлах, так і для визначення стану кластерів. Існує три версії FAT: FAT12,FAT16 і FAT32. Вони відрізняються друг від друга насамперед розміром запису уструктурі FAT. Зв'язки між структурами даних показано на рис.3.4.

/>

Рисунок 3.4 – Зв’язки між структурами даних

Файлова система FAT ділиться на три фізичні області для FAT32, та на чотири для FAT12/16.Перша область називаєтьсязарезервованою; в FAT12 і FAT16 зарезервована область займає всього 1 сектор,але формально її розмір визначається в завантажувальному секторі. Друга областьFAT — містить основні й резервні структури FAT. Вона починається в секторі,котрий розташовано за зарезервованою областю, а її розмір визначаєтьсякількістю й розміром структур FAT. Третя – кореневий каталог, для FAT12/16починається за областю FAT, а у FAT32 маєповільне положення у області даних. Область даних — містить кластери, виділенідля зберігання файлів і вмісту каталогів.

Доступ до файлових об’єктів виконується з припущення, що відома адресапершого кластеру об’єкту.

У даній реалізації алгоритм доступу до об’єктів містить дві частини –алгоритм пошуку шляху до поточної директорії та алгоритм пошуку об’єктів узавантаженій директорії.

Алгоритмпошуку об’єктів в каталогі наведено на рис. 3.2

Алгоритмпошуку поточного шляху — рис.3.3


/>

Рисунок 3.2 – Алгоритм пошуку об’єктівв каталогі


/>

Рисунок 3.3 – Алгоритм пошукупоточного шляху

3.3 Алгоритм визначення зайнятого місця на розділі

Визначення зайнятого місця на розділі реалізується шляхом аналізу таблиціFAT. Виконується перевірка усіх елементів таблиці FAT. Рахується кількість елементів, що містять 0. Ці елементи в файловійсистемі ідентифікують незайняте місце.

Отже, після повного перегляду FAT таблиці відомакількість елементів FAT таблиці та кількість елементів незайнятогомісця. Знаходиться відсоткове співвідношення. Через нього обчислюється зайнятемісце в байтах.

Алгоритм визначення на рис. 3.4.

/>

Рисунок 3.4 – Алгоритм визначення зайнятого місця


3.4 Алгоритм зрівняння директорій

/>

Рисунок 3.5 – Алгоритм зрівняння директорій


4 ОПИСПРОГРАМНИХ МОДУЛІВ

Точка входу знаходиться у модулі з назвою manager.cpp. Після автоматичної ініціалізації графічного інтерфейсу (все цевідбувається за рахунок VCL), виконується пошук і іменування всіхлогічних дисків. Код, відповідальний за це, знаходиться в модулі mbrmodule.cpp. Далі, якщо знайдено завантажувальний розділі, якщо файлова система на ньому є однією з підтримуваних, виконується пошукусіх файлів у кореневому каталозі. Якщо файлова система розділу — FAT або FAT32 торобиться це за допомогою модуля fat32.cpp. Якщо файлова система – NTFS, то пошук виконується невеликими функціями,описаними, безпосередньо, у головному модулі (manager.cpp, на таку структуру вже наголошувалося раніше). Інші файлові системи непідтримуються.

Короткий опис ключових функцій:

PHARDINFO Init(char n);

Функція виконує всі попередні дії, необхідні для подальшої роботи зжорстким диском(виклик CreateFіle(), визначення розміру сектора й т.д.). Увипадку невдачі повертає NULL.

BOOL WalkOnMBR(PHARDINFO inf, PPLOGICAL_DISC first);

Функція проходить по ланцюжку MBR жорсткого диска, попередньо відкритогофункцією Іnіt

void DeInit(PHARDINFO inf);

Звільняє зайняту структурами пам'ять і закриває дескриптор жорсткогодиска

PDISC_INFO Fat32Init(char disc);

Виконує всі необхідні попередні дії для роботи з логічним диском, файловасистема котрого FAT або FAT32 (зчитування таблиці FAT, визначення кластеракореневого каталогу та ін.)

UINT GotoDir(PDISC_INFO info, char* cpPath);

Повертає номер кластера виходячи зі шляху до директорії

UINT ListDirectory(PDISC_INFO info, HDIR hDir,UINT dwDirSize,char*cpObjectName, PFILES* ppfiles);

Виконує побудова списку файлів у директорії або пошук елемента каталогу вній.

PFILES PrintRootDirectory(PDISC_INFO info);

Пошук всіх файлів у кореневому каталозі

HDIR LoadDirectory(PDISC_INFO info, UINT cluster, UINT* dirsize);

Завантажує вміст зазначеного ланцюжка кластерів на згадку

char* Fat32ReadFile(PDISC_INFO info, UINT FirstCluster, UINT*dwFileSize);

Читає вміст файлу, перший кластер котрого відомий

void Fat32DeInit(PDISC_INFO info);

Звільняє зайняту пам'ять і закриває дескриптори.

void AnalyzeError(char* comment, int iErr);

Виконує аналіз помилки, що відбулася, результати виводить в MessageBox головного вікна

void createFolder(PDISC_INFO info,AnsiStringnewDirName)

Виконує додаткове завдання КП. Створення директорії в FAT16/32. Приймає у якості параметрів структуруінформації про поточний розділ та назву нової директорії. Функція отримує іншінеобхідні дані та інтерфейс до роботи з раніше створених функцій та глобальнихзмінних (ознака кореневої директорії, поточний шлях, тип ФС та ін.).


5 МЕТОДИКИ РОБОТИ

Для навігації серед елементів каталогу та серед списку логічних дисківвикористовуються дії миші. Для порівняння директорії – окрема кнопка «Сравнение папок». Для вибору поточного диску – випадаючий список з усіма літераминаявних дисків.

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

При зміні поточного диску відбувається оновлення інформації про диск управій частині вікна, та якщо зміна диска була у правому вікні, то й там євідновлення. та оновлюється гістограма зайнятого/вільного простору.


6ДОСЛІДЖЕННЯ РЕЗУЛЬТАТІВ

Відразу після запуску формується інтерфейс користувача й виводиться вмісткореневого каталогу активного розділу. Виводиться наступна інформація профайли: ім'я файлу, розмір, атрибути.

Також у праві1 частині вікна виводиться деяка інформація про логічний диск.

На гістограмі відображено співвідношення зайнятого й вільного просторулогічного диску (рис. 6.1).

/>

Рисунок6.1 – Список файлів активного каталогу.

Перехід в іншу директорію здійснюється за допомогою мишки (подвійненатискання) або ж натисканням клавіші ENTER (перед цим потрібна директоріяповинна бути виділена, цього можна домогтися нажатим клавіш «Нагору»або «Униз» або ж одинарним натисканням лівої клавіші миші, рис.6.2).


/>

Рисунок6.2 – Список файлів в некореневому каталогі.

Зрівняння ми побачимо, нажавши кнопку «Сравнение папок». Праворуч відпанелей буде кількісна інформація щодо кожної панелі. (рис. 6.4).

/>

Рисунок 6.4 – відображення вмісту кількісного зрівняння папок.


ВИСНОВОК

Уході виконання курсового проектубула створена програма для ОС Windows. Також були покращені навички роботи знакопичувачем на жорсткому магнітному диску. Був розібраний низький рівеньіснування інформації на жорсткому диску.

Так як основна увага приділялася роботі з ФС FAT,були здобуті вичерпні знання про структуру цієї ФС та навички роботи з нею нанизькому рівні.


ДОДАТОК А.

ВИХІДНІ ТЕКCТИ ПРОГРАМИ

MANAGER.CPP

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include «manager.h»

#include <string.h>

#include <vector>

#include <math.h>

#include «mbrmodule.h»

#include «fat32.h»

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma link «CGAUGES»

#pragma resource "*.dfm"

PHARDINFO hdd[256];

PFILES files, files2;

PLOGICAL_DISC currpld, currpld2;

char DisplayName[]="#Commander from Hell#";

char path[65536],path2[65536], pat[256], pat2[256], nulpat[256];//pat,pat2 переменные для копирования имени которое будетудалятся из пути

HANDLE hlistbox,hwnd,hComboBox;

UINT iSelected, iSelected2;

PFILES mfile;

char buf[64];

char pathcpy[1024];

PLOGICAL_DISC pld;

PFILEBUF pfb;

int fil1, fil2, dir1, dir2; // счетчики файлов и папок

int fl=0;

void AnalyzeError(char* comment, int iErr)

{

         char locBuf[1024];

         char s[1024];

         int len;

         len = FormatMessage(

          FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,

          0, iErr, 0, locBuf, sizeof(locBuf), 0

         );

         if(len>=2)

                   if(locBuf[len-2]==0x0D)locBuf[len-2]=0;

         wsprintf(s,"%s (%u)%s",comment?comment:"", iErr, locBuf);

         MessageBox(hwnd,s,DisplayName,MB_OK);

}

/*******************************************************************************

 *Очистка списка файлов, необходима перед началом работы со списком. *

 *Если забыть про очистку, то файлы на экране не очистятся, а новые добавятся *

 * в конец *

******************************************************************************

 */

void FreeFilesList()

{

         PFILES pfiles, ppred;

 fil1=0;

 dir1=0;

         pfiles = files;

         while(pfiles)

         {

                   free(pfiles->ansiname);

                   ppred = pfiles;

                   pfiles =(_FILES*) pfiles->next;

                   free(ppred);

         }

         files = NULL;

}

void FreeFilesList2()

{

         PFILES pfiles, ppred;

 fil2=0;

 dir2=0;

         pfiles = files2;

         while(pfiles)

         {

                   free(pfiles->ansiname);

                   ppred = pfiles;

                   pfiles =(_FILES*) pfiles->next;

                   free(ppred);

         }

         files2= NULL;

}

/*******************************************************************************

 *Конкретная функция для чтения директории в NTFS-томе *

*******************************************************************************

 */

int NTFSReadDir(PLOGICAL_DISC pld, char* pPath)

{

         char pFullPath[1024];

         HANDLE hFind;

         WIN32_FIND_DATA fd;

         PFILES pfirst = NULL, pfiles, ppred = NULL;

         if(!pld)return 0;

         pFullPath[0] = pld->nDisc;

         pFullPath[1] = ':';

         pFullPath[2] = '\\';

         pFullPath[3] = 0;

         if(pPath &&pPath[0]!=0)wsprintf(pFullPath+3,pPath);

         strcat(pFullPath,"*");

         if((hFind =

FindFirstFile(pFullPath,&fd))==INVALID_HANDLE_VALUE)return0;

         if(files)FreeFilesList();

         while(1)

         {

                   pfiles =(_FILES*)malloc(sizeof(FILES));

                   if(!pfirst)pfirst = pfiles;

                   pfiles->attrib =fd.dwFileAttributes;

                   pfiles->filesize =fd.nFileSizeLow;

                   pfiles->ansiname =(char*)malloc(strlen((const char*)&fd.cFileName)+1);

                   if(ppred)ppred->next = pfiles;

                   wsprintf(pfiles->ansiname,(constchar*)&fd.cFileName);

                   ppred = pfiles;

                   if(!FindNextFile(hFind, &fd))

                            if(GetLastError() ==ERROR_NO_MORE_FILES)

                                      break;

         }

         pfiles->next = NULL;

         FindClose(hFind);

         files = pfirst;

Form1->APrintFileListExecute(0);

         return 1;

}

int NTFSReadDir2(PLOGICAL_DISC pld, char* pPath)

{

         char pFullPath[1024];

         HANDLE hFind;

         WIN32_FIND_DATA fd;

         PFILES pfirst = NULL, pfiles, ppred = NULL;

         if(!pld)return 0;

         pFullPath[0] = pld->nDisc;

         pFullPath[1] = ':';

         pFullPath[2] = '\\';

         pFullPath[3] = 0;

         if(pPath &&pPath[0]!=0)wsprintf(pFullPath+3,pPath);

         strcat(pFullPath,"*");

         if((hFind =

FindFirstFile(pFullPath,&fd))==INVALID_HANDLE_VALUE)return0;

         if(files2)FreeFilesList2();

         while(1)

         {

                   pfiles =(_FILES*)malloc(sizeof(FILES));

                   if(!pfirst)pfirst = pfiles;

                   pfiles->attrib =fd.dwFileAttributes;

                   pfiles->filesize =fd.nFileSizeLow;

                   pfiles->ansiname =(char*)malloc(strlen((const char*)&fd.cFileName)+1);

                   if(ppred)ppred->next = pfiles;

                   wsprintf(pfiles->ansiname,(constchar*)&fd.cFileName);

                   ppred = pfiles;

                   if(!FindNextFile(hFind, &fd))

                            if(GetLastError() ==ERROR_NO_MORE_FILES)

                                      break;

         }

         pfiles->next = NULL;

         FindClose(hFind);

         files2 = pfirst;

 Form1->APrintFileListExecute2(0);

         return 1;

}

/****************************************************************************

*Получение свободного места в МБ свободного тома, если он в NTFS

**************************************************************************

 */

UINT GetNtfsFreeSpace(PLOGICAL_DISC pld)

{

         __int64 i64FreeBytesToCaller, i64TotalBytes,i64FreeBytes;

         char szdisk[3];

         szdisk[0] = pld->nDisc;

         szdisk[1] = ':';

         szdisk[2] = 0;

 if(Sysutils::GetDiskFreeSpaceEx (szdisk,

 i64FreeBytesToCaller,

 i64TotalBytes,

 &i64FreeBytes))

 {

 //Application->MessageBoxA(IntToStr(i64FreeBytes/(1024*1024)).c_str(),IntToStr(i64FreeBytes/(1024*1024)).c_str(),MB_OK);

 return (i64FreeBytes/(1024*1024));

 }

 return0;

}

/*******************************************************************************

 *Чтение заданной директории, определение того, какие ф-ции для этого надо *

 * использовать *

*******************************************************************************

 */

int ReadDir(PLOGICAL_DISC pld, char* pPath)

{

         ULONG dwDirSize;               //размер директории в кластерах

         HDIR hDir;                            //ccылкана директорию

         UINT DirCluster; //номер кластера директории

         PDISC_INFO info;

         PFILES pfirst, pfiles, ppred;

         char disc;

         char filename[1024];

 char *ptr;

 char pathh[65356];

 //strcpy(pathh,path);

         if(!pld)return 0;

         info =(_DISC_INFO*) pld->disc_info;

         disc = pld->nDisc;

         if(!info)

         {

                   if((pld->id ==0x07)||(pld->id == 0x17))

                   {

                            if(!pld->prcfree)pld->prcfree= GetNtfsFreeSpace(pld);

                            returnNTFSReadDir(pld,pPath);

                   }

                   if(!(info =(_DISC_INFO*)pld->disc_info = Fat32Init(disc)))

                            return 0;

                   pld->prcfree =((PDISC_INFO)(pld->disc_info))->prcfree;

         }

         if(pPath && pPath[0]!=0)

         {

                   DirCluster=GotoDir(info, pPath+1);

                   if(DirCluster)

                   {

                            hDir=LoadDirectory(info,DirCluster, &dwDirSize);

                            ListDirectory(info, hDir,dwDirSize, NULL, &pfirst);

                            free(hDir);

                   }

         }

         else pfirst=PrintRootDirectory(info);

 if(strlen(path)>1)

 {

 wsprintf(pathh,path);

 pathh[strlen(pathh)-1]='\0';

 ptr= strrchr(pathh,'\\')+1;

 if (strcmp(ptr,"..")==0)

 {

 pathh[(strrchr(pathh,'\\')-pathh)]='\0';

 if (strrchr(pathh,'\\')==pathh)

 {

 pfirst=PrintRootDirectory(info);

 while(strlen(path)>1)

 strncpy(path+strlen(path)-1,nulpat,1);

 }

 else

          if(pfirst)

          {

                   if(files)FreeFilesList();

                   files = pfirst;

 Form1->APrintFileListExecute(0);

                   return 1;

          }

 }

 else

          if(pfirst)

          {

                   if(files)FreeFilesList();

                   files = pfirst;

 Form1->APrintFileListExecute(0);

                   return 1;

          }

 }

 else

         if(pfirst)

         {

                   if(files)FreeFilesList();

                   files = pfirst;

 Form1->APrintFileListExecute(0);

                   return 1;

         }

         return 0;

}

int ReadDir2(PLOGICAL_DISC pld, char* pPath)

{

         ULONG dwDirSize;               //размер директории в кластерах

         HDIR hDir;                            //ccылкана директорию

         UINT DirCluster; //номер кластера директории

         PDISC_INFO info;

         PFILES pfirst, pfiles, ppred;

         char disc;

         char filename[1024];

 char pathh[65356];

 char *ptr;

 //strcpy(pathh,path);

         if(!pld)return 0;

         info =(_DISC_INFO*) pld->disc_info;

         disc = pld->nDisc;

         if(!info)

         {

                   if((pld->id ==0x07)||(pld->id == 0x17))

                   {

                            if(!pld->prcfree)pld->prcfree= GetNtfsFreeSpace(pld);

                            returnNTFSReadDir2(pld,pPath);

                   }

                   if(!(info =(_DISC_INFO*)pld->disc_info = Fat32Init(disc)))

                            return 0;

                   pld->prcfree =((PDISC_INFO)(pld->disc_info))->prcfree;

         }

         if(pPath && pPath[0]!=0)

         {

                   DirCluster=GotoDir(info, pPath+1);

                   if(DirCluster)

                   {

                            hDir=LoadDirectory(info,DirCluster, &dwDirSize);

                            ListDirectory(info, hDir,dwDirSize, NULL, &pfirst);

                            free(hDir);

                   }

         }

         else pfirst=PrintRootDirectory(info);

 if(strlen(path2)>1)

 {

 wsprintf(pathh,path2);

 pathh[strlen(pathh)-1]='\0';

 ptr= strrchr(pathh,'\\')+1;

 if (strcmp(ptr,"..")==0)

 {

 pathh[(strrchr(pathh,'\\')-pathh)]='\0';

 if (strrchr(pathh,'\\')==pathh)

 {

 pfirst=PrintRootDirectory(info);

 while(strlen(path2)>1)

 strncpy(path2+strlen(path2)-1,nulpat,1);

 }

 else

          if(pfirst)

          {

                   if(files2)FreeFilesList();

                   files2 = pfirst;

 Form1->APrintFileListExecute2(0);

                   return 1;

          }

 }

 else

          if(pfirst)

          {

                   if(files2)FreeFilesList();

                   files2 = pfirst;

 Form1->APrintFileListExecute2(0);

                   return 1;

          }

 }

 else

         if(pfirst)

         {

                   if(files2)FreeFilesList();

                   files2 = pfirst;

 Form1->APrintFileListExecute2(0);

                   return 1;

         }

         return 0;

}

/*-----------------------------------------------------------------------------*/

/*******************************************************************************

 * Инициализация списка разделов *

*******************************************************************************

 */

void InitPartitionList()

{

         int i, iRetVal, nActive = 0;

         char combobuf[64];

         PHARDINFO inf;

         PLOGICAL_DISC pld;

         UCHAR nHDD=0;

         while(inf = hdd[nHDD] = Init(nHDD))

         {

                   pld = inf->disklist;

                   while(pld)

                   {

                            combobuf[0] =pld->nDisc;

                            combobuf[1] = ':';

                            combobuf[2] = 0;

 iRetVal = Form1->CBDiskName->ItemIndex;

 iRetVal = Form1->CBDiskName2->ItemIndex;

                            if(pld->active=='+')

                            {

                                      nActive =iRetVal;

                                      currpld = pld;

                            }

                            pld =(_LOGICAL_DISC*)pld->next;

                   }

                   nHDD++;

         }

         ReadDir(currpld,NULL);

 ReadDir2(currpld2,NULL);

}

/*-----------------------------------------------------------------------------*/

/*******************************************************************************

 *Поиск диска по его имени *

*******************************************************************************

 */

PLOGICAL_DISC FindDiskByChar(char disk)

{

         int i = 0;

         PHARDINFO inf;

         PLOGICAL_DISC pld;

         while(inf=hdd[i++])

         {

                   pld = inf->disklist;

                   while(pld)

                   {

                            if(pld->nDisc ==disk)return pld;

                            pld =(_LOGICAL_DISC*)pld->next;

                   }

         }

         return NULL;

}

/*-----------------------------------------------------------------------------*/

/*******************************************************************************

 *Поискдиска по его индексу, вызывается, когда происходит смена текущего диска*

*******************************************************************************

 */

PLOGICAL_DISC FindDiskByIndex(char index)

{

         int i = 0, j = 0;

         PHARDINFO inf;

         PLOGICAL_DISC pld;

         while(inf=hdd[i++])

         {

                   pld = inf->disklist;

                   while(pld)

                   {

                            if(j == index)return pld;

                            pld =(_LOGICAL_DISC*)pld->next;

                            j++;

                   }

         }

         return NULL;

}

/*******************************************************************************

 *Поиск файла в заранее сформированном списке по его индексу *

 *******************************************************************************

 */

PFILES FindFileByIndex(int index)

{

         int i = 0;

         PFILES pfiles;

         pfiles = files;

         while(pfiles)

         {

                   if(i == index)return pfiles;

                   pfiles =(_FILES*) pfiles->next;

                   i++;

         }

         return NULL;

}

PFILES FindFileByIndex2(int index)

{

         int i = 0;

         PFILES pfiles;

         pfiles = files2;

         while(pfiles)

         {

                   if(i == index)return pfiles;

                   pfiles =(_FILES*) pfiles->next;

                   i++;

         }

         return NULL;

}

/*******************************************************************************

 *Ложимся спать и освобождаем все, что загадили. *

*******************************************************************************

 */

void DeInitialize()

{

         int i = 0;

         PHARDINFO inf;

         PLOGICAL_DISC pld, pred;

         while(inf=hdd[i++])

         {

                   pld = inf->disklist;

                   while(pld)

                   {

                            if(pld->disc_info)Fat32DeInit((_DISC_INFO*)pld->disc_info);

                            pred = pld;

                            pld =(_LOGICAL_DISC*)pld->next;

                            free(pred);

                   }

                   DeInit(inf);

         }

}

/*****************************************************************************/

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

 : TForm(Owner)

{

}

/*******************************************************************************

 *Функция списка действий, обновление списка дисков. Выполняет полное *

 *полное обновление, аналогично, как и при запуске программы. *

*******************************************************************************

 */

void __fastcall TForm1::ARefreshListExecute(TObject*Sender)

{

int i, iRetVal, nActive = 0;

         char combobuf[64];

         PHARDINFO inf;

         PLOGICAL_DISC pld;

         UCHAR nHDD=0;

 CBDiskName->Items->Clear();

 CBDiskName2->Items->Clear();

         while(inf = hdd[nHDD] = Init(nHDD))

         {

                   pld = inf->disklist;

                   while(pld)

                   {

 if(pld->nDisc=='?')

 goto figoviyDisk;

                            combobuf[0] =pld->nDisc;

                            combobuf[1] = ':';

                            combobuf[2] = 0;

                            iRetVal =CBDiskName->ItemIndex;

 iRetVal = CBDiskName2->ItemIndex;

                            CBDiskName->Items->Add(combobuf);

 CBDiskName2->Items->Add(combobuf);

                            if(pld->active=='+')

                            {

                                      nActive =iRetVal;

                                      currpld = pld;

 currpld2 = pld;

                            }

 figoviyDisk:

                            pld =(_LOGICAL_DISC*)pld->next;

                   }

                   nHDD++;

         }

         //ReadDir(currpld,NULL);

 //ReadDir2(currpld,NULL);

}

/*******************************************************************************

 *При первом показе формы устанавливает текущий диск как индекс значения в *

 *списке дисков, это значение всегда используется для получения номера диска. *

*******************************************************************************

 */

void __fastcall TForm1::FormShow(TObject *Sender)

{

 CBDiskName2->ItemIndex=0;

 Form1->CBDiskName2->OnChange(0);

 CBDiskName->ItemIndex=0;

 Form1->CBDiskName->OnChange(0);

 wsprintf(path,"\\");

 wsprintf(path2,"\\");

}

/*******************************************************************************

 *Вывод файлов на панель, функция списка действий *

 *******************************************************************************

 */

void __fastcall TForm1::APrintFileListExecute(TObject*Sender)

{

PFILES pfiles;

         char sz[128];

         char s[2048];

 int maxx=0;

 pfiles = files;

         Form1->Label11->Caption=currpld->cpFS;

 Form1->Label12->Caption=currpld->mbLength;

 Form1->Label13->Caption=currpld->abs_addr;

 Form1->Label14->Caption=currpld->prcfree;

 Form1->LBFileList->Items->Clear();

 //Form1->LBFileList->Items->SetText("");

         while(pfiles)

         {

 if(pfiles->attrib==8)

 {

 pfiles =(_FILES*) pfiles->next;

 fl=1;

 continue;

 }

 if(pfiles->attrib &FILE_ATTRIBUTE_DIRECTORY){wsprintf(sz,"<DIR>"); dir1++;}

                   else{wsprintf(sz,"%u",pfiles->filesize); fil1++;}

 //if (!strstr("..",pfiles->ansiname ))dir1-=2;

 if(pfiles->attrib & FILE_ATTRIBUTE_DIRECTORY)

 wsprintf(s,"[%-18s] %#10s %02X",pfiles->ansiname,sz,pfiles->attrib);

 else

 wsprintf(s,"%-20s %#10s %02X",pfiles->ansiname,sz,pfiles->attrib);

 Form1->LBFileList->Items->Add(AnsiString(s));

                  pfiles =(_FILES*) pfiles->next;

 if (strlen(s)>maxx) maxx=strlen(s);

         }

 Form1->LBFileList->ScrollWidth=maxx*8+10;

 Form1->Edit1->Text =Form1->CBDiskName->Text+'\\';

 //if (strlen(path) > 1) dir1 -= 2;

 Form1->Label22->Caption=dir1;

 Form1->Label25->Caption=fil1;

}

void __fastcall TForm1::APrintFileListExecute2(TObject*Sender)

{

PFILES pfiles;

         char sz[128];

         char s[2048];

 int maxx=0;

         pfiles = files2;

 Form1->LBFileList2->Items->Clear();

         while(pfiles)

         {

 if(pfiles->attrib==8)

 {

 pfiles =(_FILES*) pfiles->next;

 continue;

 }

 if(pfiles->attrib &FILE_ATTRIBUTE_DIRECTORY){wsprintf(sz,"<DIR>"); dir2++;}

                   else{wsprintf(sz,"%u",pfiles->filesize);/*ltoa((ULONG)pfiles->filesize,sz,10);*/fil2++;}

 if(pfiles->attrib & FILE_ATTRIBUTE_DIRECTORY)

 wsprintf(s,"[%-18s] %#10s %02X",pfiles->ansiname,sz,pfiles->attrib);

 else

 wsprintf(s,"%-20s %#10s %02X",pfiles->ansiname,sz,pfiles->attrib);

 Form1->LBFileList2->Items->Add(AnsiString(s));

                  pfiles =(_FILES*) pfiles->next;

 if (strlen(s)>maxx) maxx=strlen(s);

         }

 Form1->LBFileList2->ScrollWidth=maxx*8+10;

 Form1->Edit2->Text =Form1->CBDiskName2->Text+'\\';

 //if (strlen(path2) > 1) dir2 -= 2;

 Form1->Label27->Caption=dir2;

 Form1->Label29->Caption=fil2;

}

*******************************************************************************

 *Обработчик изменения имени диска в выпадающем списке вверху. Обновляются все*

 *необходимые данные. *

*******************************************************************************

 */

void __fastcall TForm1::CBDiskNameChange(TObject *Sender)

{

 LBFileList->Items->Clear();

 currpld=FindDiskByChar(*(CBDiskName->Text.SubString(0,1).c_str()));

 if(currpld == NULL) return;

 ReadDir(currpld,NULL);

 wsprintf(path,"\\");

 CGauge1->Progress=100-currpld->prcfree/(currpld->mbLength/100);

}

void __fastcall TForm1::CBDiskName2Change(TObject*Sender)

{

 LBFileList2->Items->Clear();

 currpld2=FindDiskByChar(*(CBDiskName2->Text.SubString(0,1).c_str()));

 if(currpld2 == NULL) return;

 ReadDir2(currpld2,NULL);

 wsprintf(path2,"\\");

}

/*******************************************************************************

 *Обработчик двойного щелчка на области панели с файлами, обрабатываем только *

 * бегание по директориям. *

 *******************************************************************************

 */

void __fastcall TForm1::LBFileListDblClick(TObject*Sender)

{

 int i;

 iSelected = LBFileList->ItemIndex;

 char *ptr;

 char bufferstr[65356];

 char buffpath[2048];

         PFILES pfirst, pfiles;

 if(iSelected == -1)return;

 mfile = FindFileByIndex(iSelected);

 /*Реагируемтолько на вход в директорию и на выход из нее */

 if((mfile->attrib & 0x10))

 if((strlen(path)==1) ||((strlen(path)>1)&&(iSelected>0)))

 {

 if((strlen(mfile->ansiname)+strlen(path)+3)>sizeof(path))return;

 strcat(path, mfile->ansiname);

 wsprintf(bufferstr,mfile->ansiname);

 strcat(path, "\\");

 //ReadDir(currpld,path);

 if(!ReadDir(currpld,path))

 if (strcmp(bufferstr,"..")!=0)

 {

 ptr = strrchr(path,'\\');

 while((ptr — path) < strlen(path))

 strncpy(ptr,nulpat,strlen(path));

 ptr = strrchr(path,'\\')+1;

 while((ptr — path) < strlen(path))

 strncpy(ptr,nulpat,strlen(path));

 }

if(strlen(path) == 0) strcat(path, "\\");

 else if(strlen(path) != 1)

 {

 if (strcmp(bufferstr,"..")==0)

 {

 ptr = strrchr(path,'\\');

 while((ptr — path) < strlen(path))

 strncpy(ptr,nulpat,strlen(path));

 ptr = strrchr(path,'\\');

 while((ptr — path) < strlen(path))

 strncpy(ptr,nulpat,strlen(path));

 ptr = strrchr(path,'\\')+1;

 while((ptr — path) < strlen(path))

 strncpy(ptr,nulpat,strlen(path));

 LBFileList->Items->Clear();

 ReadDir(currpld,path);

 }

 }

 else

 {

 LBFileList->Items->Clear();

 ReadDir(currpld,NULL);

 wsprintf(path,"\\");

 }

 if (strcmp(bufferstr,".")==0)

 {

 ptr = strrchr(path,'\\')-1;

 strncpy(ptr,nulpat,strlen(path));

 }

 Form1->Edit1->Text =Form1->CBDiskName->Text+path;

 if (strlen(path) > 1) dir1 -= 2;

// (buffpath,IntToStr(dir1));

 Form1->Label22->Caption=dir1;

 }

}

//---------------------------------------------------------------------------

void __fastcall TForm1::LBFileList2DblClick(TObject*Sender)

{

 int i;

 iSelected2 = LBFileList2->ItemIndex;

 char *ptr;

 char bufferstr[65356];

 char buffpath2[2048];

         PFILES pfirst, pfiles;

 if(iSelected2 == -1)return;

 mfile = FindFileByIndex2(iSelected2);

 /*Реагируемтолько на вход в директорию и на выход из нее */

 if((mfile->attrib & 0x10))

 if((strlen(path2)==1) ||((strlen(path2)>1)&&(iSelected2>0)))

 {

 if((strlen(mfile->ansiname)+strlen(path2)+3)>sizeof(path2))return;

 strcat(path2, mfile->ansiname);

 wsprintf(bufferstr,mfile->ansiname);

 strcat(path2, "\\");

 //ReadDir2(currpld2,path2);

 if(!ReadDir2(currpld2,path2))

 if (strcmp(bufferstr,"..")!=0)

 {

 ptr = strrchr(path2,'\\');

 while((ptr — path2) < strlen(path2))

 strncpy(ptr,nulpat,strlen(path2));

 ptr = strrchr(path2,'\\')+1;

 while((ptr — path2) < strlen(path2))

 strncpy(ptr,nulpat,strlen(path2));

 }

 if(strlen(path2) == 0) strcat(path2, "\\");

 else if(strlen(path2) != 1)

 {

 if (strcmp(bufferstr,"..")==0)

 {

 ptr = strrchr(path2,'\\');

 while((ptr — path2) < strlen(path2))

 strncpy(ptr,nulpat,strlen(path2));

 ptr = strrchr(path2,'\\');

 while((ptr — path2) < strlen(path2))

 strncpy(ptr,nulpat,strlen(path2));

 ptr = strrchr(path2,'\\')+1;

 while((ptr — path2) < strlen(path2))

 strncpy(ptr,nulpat,strlen(path2));

 LBFileList2->Items->Clear();

 ReadDir2(currpld2,path2);

 }

 }

 else

 {

 LBFileList2->Items->Clear();

 ReadDir2(currpld2,NULL);

 wsprintf(path2,"\\");

 }

 if (strcmp(bufferstr,".")==0)

 {

 ptr = strrchr(path2,'\\')-1;

 strncpy(ptr,nulpat,strlen(path2));

 }

 Form1->Edit2->Text =Form1->CBDiskName2->Text+path2;

 if (strlen(path2) > 1) dir2 -= 2;

// (buffpath,IntToStr(dir1));

 Form1->Label27->Caption=dir2;

 }

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Compare->Visible = false;

Button2->Visible = true;

Button2->SetFocus();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)

{

Compare->Visible = true;

Button2->Visible = false;

Button1->SetFocus();

}

//---------------------------------------------------------------------------

FAT32.CPP

#include <windows.h>

//#include «fat32.h»

#include «err.h»

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//Чтение данных раздела

BOOL Fat32DataRead(PDISC_INFO info, char* buf, UINTbufsize)

{

         int nRead;

         BOOL bRetValue=ReadFile(info->hDrive, buf,bufsize,(unsigned long*) &nRead, NULL);

         if(!bRetValue)AnalyzeError("# Error atReadFile: ",GetLastError());

         return bRetValue;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//сдвинуть указатель внутри раздела

UINT Fat32DataMovePointer(PDISC_INFO info, UINTsecpointer)

{

         UINT iErr;

         UINTHiPointer=secpointer>>(32-info->bitsPerSector);

         UINTLoPointer=secpointer<<(info->bitsPerSector);

         UINTbRetValue=SetFilePointer(info->hDrive,LoPointer,(long*)&HiPointer,FILE_BEGIN);

         if(bRetValue==-1)

         {

                   iErr=GetLastError();

                   if(iErr!=NO_ERROR)AnalyzeError("#Error at SetFilePointer: ",iErr);

         }

         return bRetValue;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//найти следующий элемент цепочки кластеров

UINT GetNextFileCluster(PDISC_INFO info, UINTnCurrCluster)

{

         UINT nextcluster;

        

         if(info->bFAT16)nextcluster =((USHORT*)(info->pFAT))[nCurrCluster];

         else nextcluster =info->pFAT[nCurrCluster];

         return nextcluster;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

UINT Cluster2Sector(PDISC_INFO info, UINT cluster)

{

         UINT retval;

         if(info->bFAT16)

         retval = info->sizeReserved+

                    (info->nFATCopy)*(info->sizeFAT)+

                    cluster*(info->SectPerCluster);

         else

         retval = info->sizeReserved+

                    (info->nFATCopy)*(info->sizeFAT)+

                    (cluster-2)*(info->SectPerCluster);

         return retval;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

char* Fat32ReadFile(PDISC_INFO info, UINTFirstCluster, ULONG* dwFileSize)

{

         char* retval = LoadDirectory(info,FirstCluster, dwFileSize);

         if(dwFileSize)*dwFileSize =(*dwFileSize)*(info->BytesPerCluster);

         return retval;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//пройтись по цепочке кластеров

UINT WalkOnFATTable(PDISC_INFO info, UINTFirstCluster, UINT* LastCluster, UINT* nClusters)

{

         UINT fragments=1;

         UINT predCluster, n=0;

         UINT currCluster=FirstCluster;

         while(1)

         {

                   predCluster=currCluster; n++;

                   currCluster=GetNextFileCluster(info,currCluster);

                   if(currCluster==0)return 0;

                   if(currCluster>=0x0FFFFFF8)break;

                   if(info->bFAT16 &&(currCluster>=0xfff8))break;

                   if(currCluster!=(predCluster+1))fragments++;

         }

         if(LastCluster)*LastCluster=predCluster;

         if(nClusters)*nClusters=n;

         return fragments;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//Загружает директорию в память

HDIR LoadDirectory(PDISC_INFO info, UINT cluster,ULONG* dirsize)

{

         UINT sector,currCluster;

         UINT i;

         UINT nClusters,dwSize;

         HDIR hDir;

         char b[1024];

        

         currCluster=cluster;

         if(info->bFAT16 && (0 == cluster))

         {

                  

                   nClusters = 1 +(info->nRootElements * 32) / info->BytesPerCluster;

                   dwSize = nClusters *info->BytesPerCluster;

                   //MessageBox(0,«zzz»,"",MB_OK);

         }else{

                   WalkOnFATTable(info,cluster,NULL,&nClusters);

                   dwSize=(info->BytesPerCluster)*nClusters;

         }

         hDir=(HDIR)malloc(dwSize);

         for(i=0;i<nClusters;i++)

         {

                   if(info->bFAT16 && (0 ==cluster))

                   {

                            sector =info->RootSector;

                   }else

                   sector = Cluster2Sector(info,currCluster);

                   if(Fat32DataMovePointer(info,sector)==-1)

                   {

                            free(hDir);

                            return NULL;

                   }

                   if(!Fat32DataRead(info,hDir+i*(info->BytesPerCluster),info->BytesPerCluster))

                   {

                            free(hDir);

                            return NULL;

                   }

                   if(info->bFAT16 && (0 ==cluster))

                            {currCluster++;}

                   else

                   {

                            currCluster =GetNextFileCluster(info,currCluster);

                            if(currCluster==0)

                            {

                                      free(hDir);

                                      return NULL;

                            }

                   }

                   if(currCluster>=0x0FFFFFF8)break;

         }

         //MessageBox(0,«zzz2»,"",MB_OK);

         if(dirsize)*dirsize=nClusters;

         return hDir;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//Загружает таблицу FAT в память

BOOL LoadFAT(PDISC_INFO info)

{

         UINTdwSize=(info->sizeFAT)*(info->nBytePerSector);

         if(Fat32DataMovePointer(info,info->beginFAT)==-1)return0;

         info->pFAT=(unsigned int*)malloc(dwSize);

         if(info->pFAT==NULL)return FALSE;

         if(!Fat32DataRead(info,(char*)(info->pFAT),dwSize))

         {

                   free(info->pFAT);

                   return FALSE;

         }

         info->sizeFATbytes=dwSize;

         return TRUE;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//если pObjectName==NULL то печатает содержимоедиректории, находящейся в памяти

//еслиpObjectName!=NULL ищет в директории директорию с именем pObjectName

UINT ListDirectory(PDISC_INFO info, HDIR hDir,UINTdwDirSize,char* cpObjectName, PFILES* ppfiles)

{       

         UCHAR attrib;

         UCHAR* p;

         UCHAR* t;

         USHORT firstclusterLo,firstclusterHi;

         UINT i,j,h,firstcluster,filesize;

         char ansiname[1024];

         unsigned char uname[1024];

         BOOL IsTheLong=FALSE;

         PFILES pfiles, pfirst=NULL, ppred=NULL;

         if(hDir==NULL)return 0;

         p=hDir; ansiname[11]=0;

         for(i=0;i<(dwDirSize*(info->BytesPerCluster))/32;i++)

         {

                   if((p[0]==0xE5) || (p[0] == 0x8F)|| (p[11]) == '\b')

                   {

                            p=p+32;

                            continue;

                   }

                   if(p[0]==0)break;

                   attrib=p[11];

                   if(attrib!=0x0F)

                   {

                            firstclusterLo=(*(USHORT*)&p[26]);

                            firstclusterHi=(*(USHORT*)&p[20]);

                            firstcluster=firstclusterHi;

                            firstcluster=(firstcluster<<16)+firstclusterLo;

                            if(!cpObjectName)

                            {

                                      filesize=*(UINT*)&p[28];

                                      pfiles=(_FILES*) malloc(sizeof(FILES));

                                      pfiles->attrib= attrib;

                                      pfiles->firstcluster= firstcluster;

                                      pfiles->filesize= filesize;

                                      if(!pfirst)pfirst= pfiles;

                                      if(ppred)ppred->next= pfiles;

                            }

 for(int g=10;g>1;g--)

 if(p[g]==' ') p[g]='\0';

                            memcpy(ansiname,p,11);

                            for(j=10;j>1;j--)

                                      if(ansiname[j]!=0x20)

                                      {

                                               ansiname[j+1]=0;

                                               break;

                                      }

                            if(IsTheLong)

                            {

                                      WideCharToMultiByte(CP_ACP,0,(LPCWSTR)uname,-1,ansiname,sizeof(ansiname),NULL,NULL);

                                      IsTheLong=FALSE;

                            }

                            if(cpObjectName)

                                      if((!strcmpi(cpObjectName,ansiname))&&

((attrib&0x10)!=0))

                                               returnfirstcluster;

                            if(!cpObjectName)

                            {

                                      pfiles->ansiname=(char*)

malloc(strlen(ansiname)+1);

                                      strcpy(pfiles->ansiname,ansiname);

                                      pfiles->next= NULL;

                                      ppred = pfiles;

                            }

                   }

                   else if((p[0]==1)||(p[0]&0x40))

                   {

                            if(p!=(hDir+dwDirSize))

                                      if((p[0]&0x40)&&((p+32)[11]==0x0F))

                                      {

                                               p+=32;

                                               continue;

                                      }

                            t=p; h=0;memset(uname,0,sizeof(uname));

                            while(1)

                            {

                                      j=t[0];

                                     

                                      memcpy(uname+h+00,t+1,10);

                                      memcpy(uname+h+10,t+14,12);

                                      memcpy(uname+h+22,t+28,4);

                                      if(j&0x40)

                                      {

                                               IsTheLong=TRUE;

                                               break;

                                      }

                                      t-=32; h+=26;

                                      if(t<hDir)break;

                                      if(t[11]!=0x0F)break;

                            }

                   }

                   p+=32;

         }

        

         if(ppfiles)

                   *ppfiles = pfirst;

         return 0;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

double GetFreeSpaceEx(PDISC_INFO info)//

{

         unsigned long i;

 double RET;

         double freeclusters = 0;

         double clusters = info->sizeFATbytes / 4;

         if (clusters == 0) return 0;

         for(i=0;i<clusters;i++)

                   if(!info->pFAT[i])freeclusters++;

 RET=(freeclusters * info->BytesPerCluster);

 RET /= (1024*1024);

         return RET;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//инициализирует структуру DISC_INFO

PDISC_INFO Fat32Init(char disc)

{

         char LogicalDiskName[]="\\\\.\\X:";

         char RootDir[]=«X:»;

         UCHAR buf[2048];

         UCHAR signature1;      //66

         USHORT signature2;    //510

         UCHAR signature3;      //38

         UINT i,n;

         PDISC_INFOinfo=(_DISC_INFO*)malloc(sizeof(DISC_INFO));

                   info->Disc=disc;

         LogicalDiskName[4]=disc;

         RootDir[0]=disc;

         info->hDrive=CreateFile(

                            LogicalDiskName,

                            GENERIC_READ,

                            FILE_SHARE_READ |FILE_SHARE_WRITE,

                            NULL, OPEN_EXISTING, 0,NULL);

        

         if(info->hDrive==INVALID_HANDLE_VALUE)

         {

                   AnalyzeError("# Error atCreateFile: ",GetLastError());

                   free(info);

                   return NULL;

         }

        

         GetDiskFreeSpace(RootDir,NULL,(unsignedlong*)&(info->nBytePerSector),NULL,NULL);

         if(!Fat32DataRead(info, buf,info->nBytePerSector))

         {

                   CloseHandle(info->hDrive);

                   free(info);

                   return NULL;

         }

         //bFAT16

                   signature3=*(UCHAR*)&buf[38];

         signature1=*(UCHAR*)&buf[66];

         signature2=*(USHORT*)&buf[510];

        

         if(signature2!=0xAA55)

         {

                   //printf("# 55AA sign'found");

                   CloseHandle(info->hDrive);

                   free(info);

                   return NULL;

         }

         if((signature3==0x29) &&(signature1!=0x29))

         {

                   //printf(«YAAHO!!!FAT16!!!!!!!!!»);

                   info->bFAT16 = TRUE;

                  

                   info->sizeFAT =*(short*)&buf[22];

                   info->nRootElements =*(short*)&buf[17];

                  

         }else{

                   if(signature1 != 0x29)

                   {

                            //printf("# unknownFS");

                            free(info);

                            return NULL;

                   }

                   info->bFAT16 = FALSE;

                   info->sizeFAT=*(short*)&buf[36];

                  

         }

                   info->nFATCopy=*(short*)&buf[16];

                   info->sizeReserved=*(short*)&buf[14];

         info->SectPerCluster=*(char*)&buf[13];

         info->BytesPerCluster=(info->SectPerCluster)*(info->nBytePerSector);

         info->beginFAT=info->sizeReserved;

         i=info->nBytePerSector; n=0;

         while(i=i/2)n++;

         info->bitsPerSector=n;

        

         if(!LoadFAT(info))

         {

                   CloseHandle(info->hDrive);

                   free(info);

                   return NULL;

         }

        

         if(info->bFAT16)

         {

                   info->RootSector =info->beginFAT + info->nFATCopy * info->sizeFAT;

                   info->RootCluster = 0;

         }

         else

         {

                   info->RootCluster=*(int*)&buf[44];

                   info->RootSector = 0;

         }

         info->hRootDir=LoadDirectory(info,info->RootCluster,&(info->dwRootDirSize));

         info->prcfree = GetFreeSpaceEx(info);

         return info;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//возвращает кластер директории расположенной по путиcpPath

UINT GotoDir(PDISC_INFO info, char* cpPath)

{

         UINT i,dwLen=strlen(cpPath);

         char* pStr=(char*)malloc(dwLen+2);

         char* cpDirName=pStr;

         UINT DirCluster; ULONG dwDirSize;

         HDIR hDir;

        

         hDir=info->hRootDir;

         dwDirSize=info->dwRootDirSize;

        

         strcpy(pStr,cpPath);

         if(pStr[dwLen-1]!='\\')

         {

                   strcat(pStr,"\\");

                   dwLen++;

         }

         for(i=0;i<dwLen;i++)

         {

                   if(pStr[i]=='\\')

                   {

                            pStr[i]=0;

                            DirCluster=ListDirectory(info,hDir,dwDirSize,cpDirName, NULL);

                            if(hDir!=info->hRootDir)free(hDir);

                            if(!DirCluster)

                            {

                                      //printf("#error directory %s not found",cpDirName);

                                      free(pStr);

                                      return 0;

                            }

                            if(i==(dwLen-1))

                            {

                                      free(pStr);

                                      returnDirCluster;

                            }

                            hDir=LoadDirectory(info,DirCluster, &dwDirSize);

                            cpDirName=pStr+i+1;

                   }

                  

         }

         free(pStr);

         return 0;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

void Fat32DeInit(PDISC_INFO info)

{

         free(info->pFAT);

         free(info->hRootDir);

         CloseHandle(info->hDrive);

         free(info);

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

PFILES PrintRootDirectory(PDISC_INFO info)

{

         PFILES pfirst = NULL;

         ListDirectory(info, info->hRootDir,info->dwRootDirSize, NULL, &pfirst);

         return pfirst;

}

MBRMODULE.CPP

#include <windows.h>

//#include «mbrmodule.h»

#include «err.h»

char FAT[]="\x01\x04\x06\x0D\x0E";

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//Узнать диск по серийному номеру

char GetDiscBySN(UINT SN)

{

         UINT VolumeSerialNumber;

         char Drive[4]=«X:\\»;

         int i;

         for(i=2;i<25;i++)

                   if((GetLogicalDrives()&(1<<i))!=0)

                   {

                            Drive[0] = 'A'+i;

                            switch(GetDriveType(Drive))

                            {

                                      caseDRIVE_CDROM:

                                      break;

                                      default:

                                      GetVolumeInformation(Drive,

                                       NULL,0,

          (unsigned long*)&VolumeSerialNumber,

          NULL,0,NULL,0

          );

          if(VolumeSerialNumber==SN)

                                               returnDrive[0];

                            }

                   }

         return 0;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//Узнать файловую систему диска по коду файловойсистемы

char* GetFileSystem(unsigned char code)

{

         int i;

        

         if((code==0x07)||(code==0x17))

                   return «NTFS »;

         if(code==0x82)

                   return «ext2 »;

         if(code==0x83)

                   return «ext3 »;

         if((code==0x0B)||(code==0x0C))

                   return «FAT32 »;

         for(i=0;i<sizeof(FAT);i++)

                   if(code==FAT[i])

                            return «FAT »;

         return "? ";

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//сдвинуть указатель

int MovePointer(PHARDINFO inf, UINT secpointer)

{

         UINT iErr;

         UINTHiPointer=secpointer>>(32-inf->bitsPerSector);

         UINTLoPointer=secpointer<<(inf->bitsPerSector);

         UINTbRetValue=SetFilePointer(inf->hDrive,LoPointer,(long*)&HiPointer,FILE_BEGIN);

         if(bRetValue==-1)

         {

                   iErr=GetLastError();

                   if(iErr!=NO_ERROR)

                   {

                            //printf("# error atSetFilePointer: ");

                            AnalyzeError(NULL,iErr);

                   }

         }

         return bRetValue;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//Читать один сектор с жесткого диска

void* RawRead(PHARDINFO inf)

{

         UINT iErr, SectorSize, nRead, i, n;

         void* buf;

         SectorSize=inf->dwSectorSize;

         if(!SectorSize)SectorSize=0x200;

        

         buf=malloc(SectorSize);

         while(!ReadFile(inf->hDrive, buf,SectorSize, (unsigned long*)&nRead, NULL))

         {

                   iErr=GetLastError();

                   free(buf);

         if((iErr==ERROR_INVALID_PARAMETER)&&(SectorSize<0x8000))

                   {

                            SectorSize=SectorSize*2;

                            buf=malloc(SectorSize);

                            continue;

                   }

                   //printf("# error at ReadFile:");

                   AnalyzeError(NULL,iErr);

                   return NULL;

         };

         if(inf->dwSectorSize!=SectorSize)

         {

                   i=SectorSize; n=0;

                   while(i=i/2)n++;

                   inf->bitsPerSector=n;

                   inf->dwSectorSize=SectorSize;

         }

        

         return buf;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*Изъять серийный номер для FAT или NTFS

         abs_addr    — адрес начала логического диска в секторах

         Serial          — адрес 8-байтного буфера для серийного номера

         id                — идентификатор файловой системы

*/

BOOL GetDiscSerial(PHARDINFO inf, UINT abs_addr,UCHAR* Serial, UCHAR id)

{

         char* buf;

         int i;

         if(MovePointer(inf,abs_addr)==-1)returnFALSE;

         if((buf=(char*)RawRead(inf))==NULL)returnFALSE;

        

         switch(id)

         {

                   case 0x07:                     //NTFS

                   memcpy(Serial,buf+72,8);

                   break;

                  

                   case 0x0E:

                   case 0x0C:

                   case 0x0B:                    //FAT32

                   memcpy(Serial,buf+67,4);

                   break;

                   default:

                   for(i=0;i<sizeof(FAT);i++)

                            if(id==FAT[i])

                            {

                                      memcpy(Serial,buf+39,4);

                                      free(buf);

                                      return TRUE;

                            }

                   return FALSE;

         }

         free(buf);

         return TRUE;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

void DeInit(PHARDINFO inf)

{

         CloseHandle(inf->hDrive);

         free(inf);

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//Вывести список разделов из Partition Table в MBR

PLOGICAL_DISC ListMBR(PHARDINFO inf, UCHAR* pMBR, UINTdwMBRAddr, UINT* pExtended, PPLOGICAL_DISC last)

{

         UCHAR* pPart;

         UCHAR id,active;

         UINText=0,secBegin,secLength,mbLength=0,gbLength=0;

         PLOGICAL_DISC first=NULL, pld=NULL,pred=NULL;

         UINT SectorSize,abs_addr,SN4;

         UCHAR SN[8];

        

         char* cpFS;

         int i;

        

         SectorSize=inf->dwSectorSize;

         pPart=pMBR+0x01BE;

        

         for(i=0;i<4;i++)

         {

                   id=pPart[4];

                   if(!id)

                   {

                            pPart+=0x10;

                            continue;

                   }

                   secBegin=*(UINT*)&pPart[8];

                   secLength=*(UINT*)&pPart[12];

                   active=pPart[0];

                   if(active)active='+';

                   else active='-';

                   pPart+=0x10;

                   mbLength=secLength/(2*1024)*SectorSize/512;

                   gbLength=mbLength/1024;

                   abs_addr=dwMBRAddr+secBegin;

                  

                   cpFS=GetFileSystem(id);

                  

                  

                   if((id==0x0F)||(id==0x05))

                   {

                            ext=secBegin;

                            continue;

                   }

                   memset(SN,0,sizeof(SN));

                   GetDiscSerial(inf,abs_addr,SN,id);

                   memcpy(&SN4,SN,4);

                            pred = pld;

                   pld =(_LOGICAL_DISC*)malloc(sizeof(LOGICAL_DISC));

                   memset(pld, 0,sizeof(LOGICAL_DISC));

                  

                   if(pred!=NULL)

                            pred->next = pld;

                   else first = pld;

                   pld->nHard = inf->nHard;

                   pld->nDisc =SN4?GetDiscBySN(SN4):'?';

                   pld->active = active;

                   pld->abs_addr = abs_addr;

                   pld->secLength = secLength;

                   pld->id = id;

                   pld->cpFS = cpFS;

                   pld->SN4 = SN4;

                   pld->gbLength = gbLength;

                   pld->mbLength = mbLength;

                   pld->next = NULL;

         }

         *pExtended = ext;

         *last = pld;

         return first;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//Печатать заголовок

void PrintHead()

{

         //printf(«HDD Disc Boot Addr Size FS SN mb/gb\n»);

         //printf("------------------------------------------------------------------------\n");

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//Проверить сигнатуру

BOOL CheckMBR(UCHAR* pMBR)

{

         BOOLbRetValue=*(USHORT*)(pMBR+0x01FE)==0xAA55;

 //      if(!bRetValue)printf("# not validMBR\n");

         return bRetValue;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//Пройтись по цепочке MBR

BOOL WalkOnMBR(PHARDINFO inf, PPLOGICAL_DISC first)

{

         PLOGICAL_DISC pred=NULL, last=NULL;

         UINT ext,dwNextMBRAddr;

         void* pMBR;

        

         *first = NULL;

         if((pMBR=RawRead(inf))==NULL)return FALSE;

         if(!CheckMBR((unsigned char*)pMBR))

         {

                   free(pMBR);

                   return FALSE;

         }

         if((*first=ListMBR(inf,(unsignedchar*)pMBR,0,&ext,&last))&&ext)

         {

                   inf->dwExtendedAddr=ext;

                   ext=0;

                   while(1)

                   {

                            free(pMBR);

                            dwNextMBRAddr=ext+inf->dwExtendedAddr;

                            if(MovePointer(inf,dwNextMBRAddr)==-1)returnFALSE;

                            if((pMBR=RawRead(inf))==NULL)returnFALSE;

                            if(!CheckMBR((unsignedchar*)pMBR))

                            {

                                      free(pMBR);

                                      return FALSE;

                            }

                            pred = last;

                            pred->next =ListMBR(inf,(unsigned char*)pMBR,dwNextMBRAddr,&ext,&last);

                            if(!ext)break;

                   }

         }

         free(pMBR);

         return TRUE;

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

PHARDINFO Init(char n)

{

         char HardDiskName[]="\\\\.\\PHYSICALDRIVE0";

         void* hDrive;

         UINT iErr, dwSectorSize;

         PHARDINFO inf;

        

         HardDiskName[sizeof(HardDiskName)-2]=n+'0';

         hDrive=CreateFile(

                    HardDiskName,

                    GENERIC_READ,

                    FILE_SHARE_READ |FILE_SHARE_WRITE,

                    NULL, OPEN_EXISTING, 0, NULL

          );

         if(hDrive==INVALID_HANDLE_VALUE)

         {

                   iErr=GetLastError();

                   if(iErr==ERROR_FILE_NOT_FOUND)returnNULL;

                   AnalyzeError("# Error atCreateFile: ",iErr);

                   return NULL;

         }

        

         inf=(_HARDINFO*)malloc(sizeof(HARDINFO));

         inf->hDrive=hDrive;

         inf->nHard=n;

         inf->dwSectorSize=0;

         WalkOnMBR(inf, &inf->disklist);

         return inf;}

еще рефераты
Еще работы по информатике, программированию