Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Николаев СПО ЛР2.doc
Скачиваний:
4
Добавлен:
04.05.2019
Размер:
201.73 Кб
Скачать

Текст программы

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;

}

//---------------------------------------------------------------------------