,,,
̲
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)
{
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;}
̲ 1 2 2.1 2.2 FAT 2.3 2.4
Copyright (c) 2024 Stud-Baza.ru , , , .