-







































:

:

̲

1

2

2.1

2.2 FAT

2.3

2.4

3 ̲

3.1

3.2 '

3.3

3.4

4 ˲.

5

6 ˲ Ҳ

-


Windows FAT16/FAT32. NTFS. WINDOWS , ++. Microsoft Windows.


1.

, , ᒺ , , , , .

, :

-        ;

-        ;

-        .

ᒺ .

. 1.1.

, .

.

. . , , . manager.cpp, ( VCL) NTFS . .

, , .

ϳ . . .

1.1


2

. , . .

2.1       

. MBR (Master Boot Record). MBR . 2.1.

2.1 - MBR

,
0 1BE h MBR reserved
1BE h 40 h 4 Partition Table Partition Table
1FE h 2 MBR (055) sign

Partition Table . . Partition Table . . 2.2 Partition Table.

2.2 - Partition Table

,
0 1 (80h - / 0 - ) priznak
1 1 starthead
2 2 . 6- 6 , 10- , 2 8 starttrack
4 1 syscode
5 1 ʳ endhead
6 2 ʳ endtrack
8 4 startsector
12 4 size

( ) (05h, 0Fh).

, Partition Table startsector. Partition Table MBR. MBR Partition Table . , MBR. startsector MBR, .

2.2        FAT

ϳ . FAT (BOOT ). BOOT . FAT12 FAT16 . 2.3, FAT32 . 2.4.

2.3 BOOT FAT12 FAT16

,
0 3 JMP jmpcode
3 8 , os
11 2 ʳ BytePerSector
13 1 ʳ SectorPerCluster
14 2 ʳ SizeReserv
16 1 ʳ FAT NumberCopiesFAT
17 2 ʳ MaxDirElem
19 2 <32MB, 0 Smallsize
21 1 MediaDescriptor
22 2 ʳ FAT SizeFAT16inSectors
24 2 SectorPerTrack
26 2 ʳ Heads
28 4 ʳ NumberHiddenSectors
32 4 > 32MB BigSize
36 1 ( 80h, 0) --
37 1 --
38 1 29h. Code
39 4 SerialNumber
43 11 Label
54 8 FAT (FAT12 FAT16) FATID
62 2 --

2.4 BOOT FAT32

,
0 3 JMP jmpcode
3 8 , os
11 2 ʳ BytePerSector
13 1 ʳ SectorPerCluster
14 2 ʳ SizeReserv
16 1 ʳ FAT NumberCopiesFAT
17 4 ---
21 1 MediaDescriptor
22 2 ---
24 2 SectorPerTrack
26 2 ʳ Heads
28 4 ʳ NumberHiddenSectors
32 4 ---
38 6 reserv1
44 4 StartCluster
48 2 FS INFO BegFS
50 2 ﳺ BOOT- BootCopy
52 12 reserv2
64 1 Գ PhysNum
65 1 reserv3
66 1 ExtSign
67 4 SerialNumber
71 11 Label
82 8 (FAT32) FATID
90 2 55AA ---

BOOT- .

BOOT- FAT12,16 1 , FAT32 3 . , . FAT . BOOT-. FAT12,16 . , BOOT-. FAT32 . .

FAT ᒺ . 12, 16 32 . FAT . 2.5 FAT.

2.5 FAT

FAT12 FAT16 FAT32
0 0 0 ³
FF0-FF6 FFF0-FFF6 0FFFFFF0-0FFFFFF6
FF7 FFF7 0FFFFFF7 BAD-
FF8-FFF FFF8-FFFF 0FFFFFF8-0FFFFFFF

.

, ᒺ , , , .

2.3       

. ᒺ . 2.6 FAT13/FAT16 . 2.8 FAT32. . 2.7.

2.6 FAT12 / FAT16

,
0 1 : 0 ; E5h - ; - ᒺ fn
1 7 7 ᒺ name
8 3 ext
11 1 attr
12 10 reserv
22 2 TimeMade
24 2 DateMade
26 2 FirstCluster
28 4 SizeFileInBytes

2.7 ᒺ

0 1
1 1
2 1
3 1 ̳
4 1
5 1
6

2.8 FAT32

,
0 1 : 0 ; E5h - ; - ᒺ fn
1 7 7 ᒺ name
8 3 ext
11 1 attr
12 1 reserv
13 2 (0.1 ) TimeMadeSec
14 2 TimeMade
16 2 DateMade
18 2 DateLast
20 2 , ᒺ FirstClusterHigh
22 2 TimeLast
24 2 DateLastWrite
26 2 , ᒺ FirstClusterLow
28 4 SizeFileInBytes

ᒺ , (32). ʳ ᒺ. ᒺ 255 , UNICODE ( ). 13 ᒺ. . 2.9.

2.9

,
0 1 fn
1 10 5 ᒺ FiveSymb
11 1 , 0Fh attr
12 1 0 reserv
13 1 CRC
14 12 6 ᒺ SixSymb
26 2 reserv2
28 4 2 ᒺ TwoSymb

13 . . FFFF.

2.4       

header- . ֳ - , . ,

typedef struct _HARDINFO

{

char nHard; //

void* hDrive; //

UINT dwSectorSize; //

UINT bitsPerSector; //

UINT dwExtendedAddr; //

PLOGICAL_DISC disklist;

} HARDINFO, *PHARDINFO;

, :

typedef struct _LOGICAL_DISC

{

void* next;

char nHard;

char nDisc;

char active;

UINT abs_addr;

UINT secLength;

UINT id;

char* cpFS;

UINT SN4;

UINT gbLength;

UINT mbLength;

void* disc_info;

UINT prcfree;

} LOGICAL_DISC, *PLOGICAL_DISC, **PPLOGICAL_DISC;

ϳ , FAT32- ,

typedef struct _DISC_INFO {

char Disc; //

UINT beginFAT; // FAT-

UINT nBytePerSector; //

void* hDrive; //

char SectPerCluster; //

UINT BytesPerCluster; //

UINT sizeFAT; // FAT-

UINT* pFAT; // FAT-

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

䳿, ( CreateFle(), ..). NULL.

BOOL WalkOnMBR(PHARDINFO inf, PPLOGICAL_DISC first);

MBR , nt

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)

%s",comment?comment:"", iErr, locBuf);

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

* , . *

* , , *

* *

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

*/

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







2009