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#";

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

{

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

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]='\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);

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]='\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, 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]='\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))

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[]="\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))

{

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

*/

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

{

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/gb\n");

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

}

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

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

BOOL CheckMBR(UCHAR* pMBR)

{

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

 // if(!bRetValue)printf("# not valid MBR\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,(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;}


Информация о работе «Розробка програмного забезпечення файлового менеджера»
Раздел: Информатика, программирование
Количество знаков с пробелами: 59552
Количество таблиц: 9
Количество изображений: 10

Похожие работы

Скачать
56956
0
11

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

Скачать
34004
0
0

... // Тези до конференції аспірантів і студентів ”Інженерія програмного забезпечення 2006”. – К.: НАУ, 2006. – С. 41. АНОТАЦІЯ   Авраменко О.А. Метод та засоби редокументування успадкованого програмного забезпечення. – Рукопис. Дисертація на здобуття вченого ступеня кандидата технічних наук зі спеціальності 01.05.03 – Математичне та програмне забезпечення обчислювальних машин і систем. – Наці ...

Скачать
85276
0
11

... RTOS складається з ядра, планувальника процесів (process manager) і розширених сервісів на рівні користувача. Як справжня мікроядерного операційна система, QNX Neutrino RTOS реалізує в ядрі ОС тільки найбільш фундаментальні сервіси, такі як передача повідомлень, сигнали, таймери, планування потоків, об'єкти синхронізації. Всі інші сервіси ОС, драйвери та програми виконуються як окремі процеси, які ...

Скачать
214694
25
9

... останньому випадку розрізняються експедиційний засіб, коли особа, що проводить опитуванння, сама роздає і збирає анкети, і кореспондентський, коли анкети розсилаються і повертаються поштою. [7]   3. УДОСКОНАЛЕННЯ ІНФОРМАЦІЙНОГО ЗАБЕЗПЕЧЕННЯ МАРКЕТИНГУ НА ПІДПРИЄМСТВІ Сьогодні виграє той, кого більше знають зовні з кращої сторони, той, хто знає більше про дійсний стан своєї організац ...

0 комментариев


Наверх