Всё сдал! - помощь студентам онлайн Всё сдал! - помощь студентам онлайн

Реальная база готовых
студенческих работ

Узнайте стоимость индивидуальной работы!

Вы нашли то, что искали?

Вы нашли то, что искали?

Да, спасибо!

0%

Нет, пока не нашел

0%

Узнайте стоимость индивидуальной работы

это быстро и бесплатно

Получите скидку

Оформите заказ сейчас и получите скидку 100 руб.!


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

Тип Реферат
Предмет Информатика
Просмотров
520
Размер файла
811 б
Поделиться

Ознакомительный фрагмент работы:

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

ЗМІСТ

ВСТУП

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 (MasterBootRecord). Структура MBR наведена у табл. 2.1.

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

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

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

Таблиця 2.2 - Структура елементу PartitionTable

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

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

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

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

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

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

ЗсувРозмір, байтОписІм’я
03Команда JMP на код завантажникаjmpcode
38Назва операційної системи, у якій виконано форматування дискуos
112Кількість байт у секторіBytePerSector
131Кількість секторів у кластеріSectorPerCluster
142Кількість резервних секторівSizeReserv
161Кількість копій FATNumberCopiesFAT
172Кількість елементів кореневого каталогуMaxDirElem
192Розмір диску в секторахдля дисків <32MB, інакше 0Smallsize
211Описувач середовищаMediaDescriptor
222Кількість секторів таблиці FATSizeFAT16inSectors
242Секторів на доріжціSectorPerTrack
262Кількість голівокHeads
284Кількість схованих секторівNumberHiddenSectors
324Розмір в секторах для дисків > 32MBBigSize
361Тип пристрою(для першого диску в системі 80h, для інших 0)--
371Резерв--
381Сигнатура 29h.Code
394Серійний номерSerialNumber
4311Метка дискуLabel
548Ідентифікатор FAT (‘FAT12’ або ‘FAT16’)FATID
622Код завантажника--

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

ЗсувРозмір, байтОписІм’я
03Команда JMP на код завантажникаjmpcode
38Назва операційної системи, у якій виконано форматування дискуos
112Кількість байт у секторіBytePerSector
131Кількість секторів у кластеріSectorPerCluster
142Кількість резервних секторівSizeReserv
161Кількість копій FATNumberCopiesFAT
174Резерв---
211Описувач середовищаMediaDescriptor
222Резерв---
242Секторів на доріжціSectorPerTrack
262Кількість голівокHeads
284Кількість схованих секторівNumberHiddenSectors
324Резерв---
386Резервreserv1
444Початковий кластер кореневого каталогуStartCluster
482Початковий сектор структури FS INFOBegFS
502Номер сектору з копією BOOT-розділуBootCopy
5212Резервreserv2
641Фізичний номер пристроюPhysNum
651Резервreserv3
661Розширена сігнатураExtSign
674Серійний номер пристроюSerialNumber
7111Метка дискуLabel
828Ідентифікатор (‘FAT32’)FATID
90255AA---

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

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

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

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

FAT12FAT16FAT32Пояснення
000Вільний кластер
FF0-FF6FFF0-FFF60FFFFFF0-0FFFFFF6Зарезервований кластер
FF7FFF70FFFFFF7BAD-кластер
FF8-FFFFFF8-FFFF0FFFFFF8-0FFFFFFFОстанній кластероб’єкту

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

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

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

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

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

ЗсувРозмір, байтОписІм’я
01Ознака дескриптору: 0 – вільний; E5h - видалений; інше-перший символ імені об’єктуfn
177 символів імені об’єктуname
83Розширення об’єктуext
111Байт атрибутів attr
1210Резервreserv
222Час створення або останньої модифікаціїTimeMade
242Дата створення або останньої модифікаціїDateMade
262Молодша частина початкового кластеру об’єктаFirstCluster
284Розмір об’єкта в байтахSizeFileInBytes

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

НомербітуЗначення бітуОпис
01Об’єкт тільки для читання
11Об’єктсхованого типу
21Об’єкт системного типу
31Мітка тому
41Директорія
51Архівний файл
6Не використовується

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

ЗсувРозмір, байтОписІм’я
01Ознака дескриптору: 0 – вільний; E5h - видалений; інше-перший символ імені об’єктуfn
177 символів імені об’єктуname
83Розширення об’єктуext
111Байт атрибутів attr
121Резервreserv
132Час створення (0.1 секунд)TimeMadeSec
142Час створенняTimeMade
162Дата створення або останньої модифікаціїDateMade
182Дата останнього звертанняDateLast
202Старший байт номеру першого кластеру, який був виділений об’єкту FirstClusterHigh
22 2Час останньої модифікації об’єкту TimeLast
24 2Дата останнього запису об’єктуDateLastWrite
262Молодший байт номеру першого кластеру, який був виділений об’єктуFirstClusterLow
284Розмір файлу в байтахSizeFileInBytes

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

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

ЗсувРозмір, байтОписІм’я
01Номер порції іменіfn
1105 символів імені об’єктуFiveSymb
111Байт атрибутів, дорівнює 0Fhattr
121Завжди дорівнює 0reserv
131Контрольна сума короткого ім’яCRC
14126 символів імені об’єктуSixSymb
262Резервreserv2
2842 символа імені об’єкту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;

UINT prcfree;

} LOGICAL_DISC, *PLOGICAL_DISC, **PPLOGICAL_DISC;

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

typedef struct _DISC_INFO {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 Allocation Table). Структура 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,AnsiString newDirName)

Виконує додаткове завдання КП. Створення директорії в 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#";

charpath[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)return 0;

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,(const char*)&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)return 0;

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,(const char*)&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));

}

return 0;

}

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

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

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

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

*/

int ReadDir(PLOGICAL_DISC pld, char* pPath)

{

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

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

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

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);

return NTFSReadDir(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]=' ';

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

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

{

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

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)

{

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

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

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

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);

return NTFSReadDir2(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]=' ';

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

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

{

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

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;

}

}

returnNULL;

}

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

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

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

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

*/

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++;

}

}

returnNULL;

}

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

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

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

*/

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++;

}

returnNULL;

}

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

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

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

*/

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 __fastcallTForm1::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, UINT bufsize)

{

int nRead;

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

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

return bRetValue;

}

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

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

UINT Fat32DataMovePointer(PDISC_INFO info, UINT secpointer)

{

UINT iErr;

UINT HiPointer=secpointer>>(32-info->bitsPerSector);

UINT LoPointer=secpointer<<(info->bitsPerSector);

UINT bRetValue=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, UINT nCurrCluster)

{

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, UINT FirstCluster, ULONG* dwFileSize)

{

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

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

return retval;

}

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

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

UINT WalkOnFATTable(PDISC_INFO info, UINT FirstCluster, 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)

{

UINT dwSize=(info->sizeFAT)*(info->nBytePerSector);

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

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,UINT dwDirSize,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]=' ';

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))

return firstcluster;

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_INFO info=(_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 at CreateFile: ",GetLastError());

free(info);

return NULL;

}

GetDiskFreeSpace(RootDir,NULL,(unsigned long*)&(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 sig n'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("# unknown FS");

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);

return DirCluster;

}

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[]="x01x04x06x0Dx0E";

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

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

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))

{

case DRIVE_CDROM:

break;

default:

GetVolumeInformation(Drive,

NULL,0,

(unsigned long*)&VolumeSerialNumber,

NULL,0,NULL,0

);

if(VolumeSerialNumber==SN)

return Drive[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;

UINT HiPointer=secpointer>>(32-inf->bitsPerSector);

UINT LoPointer=secpointer<<(inf->bitsPerSector);

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

if(bRetValue==-1)

{

iErr=GetLastError();

if(iErr!=NO_ERROR)

{

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

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 - идентификатор файловой системы

*/

BOOLGetDiscSerial(PHARDINFOinf, UINTabs_addr, UCHAR* Serial, UCHARid)

{

char* buf;

int i;

if(MovePointer(inf,abs_addr)==-1)return FALSE;

if((buf=(char*)RawRead(inf))==NULL)return FALSE;

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, UINT dwMBRAddr, UINT* pExtended, PPLOGICAL_DISC last)

{

UCHAR* pPart;

UCHAR id,active;

UINT ext=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/gbn");

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

}

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

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

BOOL CheckMBR(UCHAR* pMBR)

{

BOOL bRetValue=*(USHORT*)(pMBR+0x01FE)==0xAA55;

// if(!bRetValue)printf("# not valid MBRn");

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,(unsigned char*)pMBR,0,&ext,&last))&&ext)

{

inf->dwExtendedAddr=ext;

ext=0;

while(1)

{

free(pMBR);

dwNextMBRAddr=ext+inf->dwExtendedAddr;

if(MovePointer(inf,dwNextMBRAddr)==-1)return FALSE;

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

if(!CheckMBR((unsigned char*)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)return NULL;

AnalyzeError("# Error at CreateFile: ",iErr);

return NULL;

}

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

inf->hDrive=hDrive;

inf->nHard=n;

inf->dwSectorSize=0;

WalkOnMBR(inf, &inf->disklist);

return inf;}


Нет нужной работы в каталоге?

Сделайте индивидуальный заказ на нашем сервисе. Там эксперты помогают с учебой без посредников Разместите задание – сайт бесплатно отправит его исполнителя, и они предложат цены.

Цены ниже, чем в агентствах и у конкурентов

Вы работаете с экспертами напрямую. Поэтому стоимость работ приятно вас удивит

Бесплатные доработки и консультации

Исполнитель внесет нужные правки в работу по вашему требованию без доплат. Корректировки в максимально короткие сроки

Гарантируем возврат

Если работа вас не устроит – мы вернем 100% суммы заказа

Техподдержка 7 дней в неделю

Наши менеджеры всегда на связи и оперативно решат любую проблему

Строгий отбор экспертов

К работе допускаются только проверенные специалисты с высшим образованием. Проверяем диплом на оценки «хорошо» и «отлично»

1 000 +
Новых работ ежедневно
computer

Требуются доработки?
Они включены в стоимость работы

Работы выполняют эксперты в своём деле. Они ценят свою репутацию, поэтому результат выполненной работы гарантирован

avatar
Математика
История
Экономика
icon
159599
рейтинг
icon
3275
работ сдано
icon
1404
отзывов
avatar
Математика
Физика
История
icon
156450
рейтинг
icon
6068
работ сдано
icon
2737
отзывов
avatar
Химия
Экономика
Биология
icon
105734
рейтинг
icon
2110
работ сдано
icon
1318
отзывов
avatar
Высшая математика
Информатика
Геодезия
icon
62710
рейтинг
icon
1046
работ сдано
icon
598
отзывов
Отзывы студентов о нашей работе
63 457 оценок star star star star star
среднее 4.9 из 5
Тгу им. Г. Р. Державина
Реферат сделан досрочно, преподавателю понравилось, я тоже в восторге. Спасибо Татьяне за ...
star star star star star
РЭУ им.Плеханово
Альберт хороший исполнитель, сделал реферат очень быстро, вечером заказала, утром уже все ...
star star star star star
ФЭК
Маринаааа, спасибо вам огромное! Вы профессионал своего дела! Рекомендую всем ✌🏽😎
star star star star star

Последние размещённые задания

Ежедневно эксперты готовы работать над 1000 заданиями. Контролируйте процесс написания работы в режиме онлайн

Подогнать готовую курсовую под СТО

Курсовая, не знаю

Срок сдачи к 7 дек.

только что
только что

Выполнить задания

Другое, Товароведение

Срок сдачи к 6 дек.

1 минуту назад

Архитектура и организация конфигурации памяти вычислительной системы

Лабораторная, Архитектура средств вычислительной техники

Срок сдачи к 12 дек.

1 минуту назад

Организации профилактики травматизма в спортивных секциях в общеобразовательной школе

Курсовая, профилактики травматизма, медицина

Срок сдачи к 5 дек.

2 минуты назад

краткая характеристика сбербанка анализ тарифов РКО

Отчет по практике, дистанционное банковское обслуживание

Срок сдачи к 5 дек.

2 минуты назад

Исследование методов получения случайных чисел с заданным законом распределения

Лабораторная, Моделирование, математика

Срок сдачи к 10 дек.

4 минуты назад

Проектирование заготовок, получаемых литьем в песчано-глинистые формы

Лабораторная, основы технологии машиностроения

Срок сдачи к 14 дек.

4 минуты назад

2504

Презентация, ММУ одна

Срок сдачи к 7 дек.

6 минут назад

выполнить 3 задачи

Контрольная, Сопротивление материалов

Срок сдачи к 11 дек.

6 минут назад

Вам необходимо выбрать модель медиастратегии

Другое, Медиапланирование, реклама, маркетинг

Срок сдачи к 7 дек.

7 минут назад

Ответить на задания

Решение задач, Цифровизация процессов управления, информатика, программирование

Срок сдачи к 20 дек.

7 минут назад
8 минут назад

Все на фото

Курсовая, Землеустройство

Срок сдачи к 12 дек.

9 минут назад

Разработка веб-информационной системы для автоматизации складских операций компании Hoff

Диплом, Логистические системы, логистика, информатика, программирование, теория автоматического управления

Срок сдачи к 1 мар.

10 минут назад
11 минут назад

перевод текста, выполнение упражнений

Перевод с ин. языка, Немецкий язык

Срок сдачи к 7 дек.

11 минут назад
planes planes
Закажи индивидуальную работу за 1 минуту!

Размещенные на сайт контрольные, курсовые и иные категории работ (далее — Работы) и их содержимое предназначены исключительно для ознакомления, без целей коммерческого использования. Все права в отношении Работ и их содержимого принадлежат их законным правообладателям. Любое их использование возможно лишь с согласия законных правообладателей. Администрация сайта не несет ответственности за возможный вред и/или убытки, возникшие в связи с использованием Работ и их содержимого.

«Всё сдал!» — безопасный онлайн-сервис с проверенными экспертами

Используя «Свежую базу РГСР», вы принимаете пользовательское соглашение
и политику обработки персональных данных
Сайт работает по московскому времени:

Вход
Регистрация или
Не нашли, что искали?

Заполните форму и узнайте цену на индивидуальную работу!

Файлы (при наличии)

    это быстро и бесплатно