Текст программы
Unit1.h
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ImgList.hpp>
#include <malloc.h>
typedef struct{
unsigned char Name[8];
unsigned char Ext[3];
unsigned char Attr;
unsigned char _Reserved[10];
unsigned short Time;
unsigned short Date;
unsigned short FirstCluster;
unsigned int Size;
}DirItem;
typedef struct{
HANDLE hDrv;
unsigned int ClusterSize;
unsigned int StartOfData;
unsigned char* FAT;
}DiskParam;
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TTreeView *TreeView1;
TImageList *ImageList1;
void __fastcall FormCreate(TObject *Sender);
private: // User declarations
int ReadDrive(TTreeNode* drive);
int ReadDir(TTreeNode* Parent, DirItem* File, DiskParam Param);
void BuildName(char* Name, DirItem* File);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
const int SectorSize=0x200; const int DirItemSize=0x20;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
char DrivesBuffer[1024]; //буфер дисков
int NumDrives=GetLogicalDriveStrings(1024,DrivesBuffer); //получение списка дисков
for(int i=0;i<NumDrives/4;i++)
{
DrivesBuffer[i*4+2]=0;
if(GetDriveType(&DrivesBuffer[i*4])==DRIVE_REMOVABLE) //сменные диски
{
TTreeNode *trn=TreeView1->Items->Add(0,&DrivesBuffer[i*4]); //заполнение дерева
trn->ImageIndex=1; trn->SelectedIndex=1;
if(ReadDrive(trn)) trn->HasChildren=1;
}
}
}
//---------------------------------------------------------------------------
int TForm1::ReadDrive(TTreeNode* drive)
{
int retval=0;
DiskParam Param;
AnsiString DrPath="\\\\.\\";
HANDLE hDrv=CreateFile((DrPath+drive->Text).c_str(),GENERIC_READ,FILE_SHARE_READ,NULL,
OPEN_EXISTING,0,NULL); //открытие диска
Param.hDrv=hDrv;
if(hDrv==INVALID_HANDLE_VALUE) return 0;
unsigned char* Boot=(unsigned char*)malloc(SectorSize);
unsigned long readed;
if(!ReadFile(hDrv,Boot,SectorSize,&readed,NULL)||readed<SectorSize)
{ //чтение boot
free(Boot); CloseHandle(hDrv); return 0;
}
Param.ClusterSize=SectorSize*Boot[0xD]; //получение значений
unsigned char FATsCount=Boot[0x10];
short RootSize=*(short*)&Boot[0x11];
short SizeOfFAT=*(short*)&Boot[0x16]; //Размер FAT
free(Boot);
unsigned char* FAT=(unsigned char*)malloc(SectorSize*SizeOfFAT); Param.FAT=FAT;
if(!ReadFile(hDrv,FAT,SectorSize*SizeOfFAT,&readed,NULL)
||readed<(unsigned)SectorSize*SizeOfFAT)
{
free(Boot); free(FAT); CloseHandle(hDrv); return 0; //Чтение FAT
}
for(int i=1;i<FATsCount;i++) //Пропуск резервных FAT
SetFilePointer(hDrv,(unsigned)SectorSize*SizeOfFAT,NULL,FILE_CURRENT);
unsigned char* Root=(unsigned char*)malloc(RootSize*DirItemSize);
if(!ReadFile(hDrv,Root,RootSize*DirItemSize,&readed,NULL)
||readed<(unsigned)RootSize*DirItemSize)
{ //чтение корневого каталога
free(Boot); free(FAT); free(Root); CloseHandle(hDrv); return 0;
}
Param.StartOfData=SetFilePointer(hDrv,0,NULL,FILE_CURRENT); //кластер 2(!)
for(int i=0;i<RootSize;i++)
{
DirItem* File=(DirItem*)&Root[i*DirItemSize];
if(File->Name[0]==0) break;
if((File->Name[0]!=0xE5&&File->Name[0]!=0x2E)&&(File->Attr&FILE_ATTRIBUTE_DIRECTORY)
&&File->Attr!=0xF) //выбор подкаталогов
{
char Name[14]={0};
BuildName(Name,File);
TTreeNode *trn=TreeView1->Items->AddChild(drive,Name);
if(ReadDir(trn,File,Param))trn->HasChildren=1; //чтение подкаталога
retval=1;
}
}
free(Root);
free(FAT);
CloseHandle(hDrv);
return retval;
}
//---------------------------------------------------------------------------
void TForm1::BuildName(char* Name, DirItem* File)
{
strncat(Name,File->Name,8); //постройка имени
if(char* p=strstr(Name," "))*p=0;
if(File->Ext[0]!=' ')strcat(Name,".");
strncat(Name,File->Ext,3);
if(char* p=strstr(Name," "))*p=0;
}
//---------------------------------------------------------------------------
int TForm1::ReadDir(TTreeNode* Parent, DirItem* File, DiskParam Param)
{
int retval=0;
unsigned long readed;
unsigned char* Dir=(unsigned char*)malloc(Param.ClusterSize);
unsigned short Cluster=File->FirstCluster;
File->Name;
int i=0;
do{
SetFilePointer(Param.hDrv,Param.StartOfData+Param.ClusterSize*(Cluster-2),
NULL,FILE_BEGIN);
if(!ReadFile(Param.hDrv,Dir+Param.ClusterSize*i,Param.ClusterSize,&readed,NULL)
||readed<Param.ClusterSize) //сборка каталога
{
free(Dir); return 0;
}
if(!(Cluster%2))
{Cluster=*(unsigned short*)&Param.FAT[(Cluster*3)/2]&0x0FFF;}else
{Cluster=*(unsigned short*)&Param.FAT[(Cluster*3)/2]>>4;};
i++;
Dir=(unsigned char*)realloc(Dir,Param.ClusterSize+Param.ClusterSize*i);
}while(Cluster<0x0FF0);
DirItem* File1;
i=0;
do{
File1=(DirItem*)&Dir[i*DirItemSize];
if((File1->Name[0]!=0xE5&&File1->Name[0]!=0x2E)
&&(File1->Attr&FILE_ATTRIBUTE_DIRECTORY)&&File1->Attr!=0xF) //выбор подкаталогов
{
char Name[14]={0};
BuildName(Name,File1);
TTreeNode *trn=TreeView1->Items->AddChild(Parent,Name);
//buildnext
if(ReadDir(trn,File1,Param))trn->HasChildren=1; //чтение подкаталога
retval=1;
}
i++;
}while(File1->Name[0]!=0);
free(Dir);
return retval;
}
//---------------------------------------------------------------------------