#include"_MFT_READER.h"
void _MFT_READER::LoadMFT()
{
unsigned __int64 point,i,j,k,temp;
unsigned __int64 HeaderSize;
unsigned __int64 offset;
PFILE_RECORD_HEADER $MFT;
BytesPerFileRecord = boot_block.ClustersPerFileRecord < 0x80? boot_block.ClustersPerFileRecord* boot_block.SectorsPerCluster* boot_block.BytesPerSector : 1 << (0x100 - boot_block.ClustersPerFileRecord);
$MFT = PFILE_RECORD_HEADER(new U8[BytesPerFileRecord]);
if(!$MFT)
{
ErrorCode=OUT_OF_MEMORY_ERROR;
return;
}
ReadSector((boot_block.MftStartLcn) * boot_block.SectorsPerCluster, BytesPerFileRecord / boot_block.BytesPerSector, $MFT);
for(j=1;j<=*((unsigned short*)((unsigned char*)$MFT+6));j++)
{
if( *((char*)$MFT+j*boot_block.BytesPerSector-2)==
*((char*)$MFT+*((unsigned short*)((unsigned char*)$MFT+4)))
&&
*((char*)$MFT+j*boot_block.BytesPerSector-1)==
*((char*)$MFT+*((unsigned short*)((unsigned char*)$MFT+4))+1)
)
{
*((char*)$MFT+j*boot_block.BytesPerSector-2)=
*((char*)$MFT+*((unsigned short*)((unsigned char*)$MFT+4))+2*j);
*((char*)$MFT+j*boot_block.BytesPerSector-1)=
*((char*)$MFT+*((unsigned short*)((unsigned char*)$MFT+4))+2*j+1);
}
}
point=*((unsigned short*)((unsigned char*)$MFT+20));//Offset으로 포인터 이동
while(*((unsigned long*)((unsigned char*)$MFT+point))!=0xFFFFFFFF)
{
/*
*((unsigned char*)MFT+point+9) = Attribute Name Size
Attribute Header size : Resident=24 / Non-resident=64
*/
if(*((unsigned char*)$MFT+point+8))
HeaderSize=64+*((unsigned char*)$MFT+point+9);
else
HeaderSize=24+*((unsigned char*)$MFT+point+9);
switch(*((unsigned long*)((unsigned char*)$MFT+point)))
{
case 0x80://$DATA
MFT=PFILE_RECORD_HEADER(new U8[*((unsigned __int64*)((unsigned char*)$MFT+point+40))]);
if(!MFT)
{
delete $MFT;
ErrorCode=OUT_OF_MEMORY_ERROR;
return;
}
i=*(short*)((unsigned char*)$MFT+point+32);
MFTLength=ReadCluster((unsigned char*)$MFT+point+i,(unsigned char*)MFT);
break;
}
point+=*((unsigned long*)((unsigned char*)$MFT+point+4));
}
delete $MFT;
}
void _MFT_READER::ReadSector(U64 sector, U32 count, void* buffer)
{
ULARGE_INTEGER offset;
OVERLAPPED overlap = {0};
U32 n;
offset.QuadPart = sector * boot_block.BytesPerSector;
overlap.Offset = offset.LowPart;
overlap.OffsetHigh = offset.HighPart;
ReadFile(hVolume, buffer, count * boot_block.BytesPerSector, &n, &overlap);
}
long _MFT_READER::ReadAttribute(FILE* fp, unsigned char* point, long flag)
{
unsigned char* offset=0;
SYSTEMTIME time;
int i,sub_mask;
sub_mask=1;
for(i=1;i<25;i++)
{
if(sub_mask&flag && *(long*)point==0x10*i)
{
if(*((unsigned char*)point+8))
{
if(*((unsigned __int64*)((unsigned char*)point+40)))
offset=(new U8[*((unsigned __int64*)((unsigned char*)point+40))]);
else
offset=0;
if(offset)
ReadCluster(point+(*(short*)((unsigned char*)point+32)),offset);
}
else
{
offset=point+24+*((unsigned char*)point+9);
}
}
sub_mask<<=1;
}
if(!offset)
return *(long*)((unsigned char*)point+4);
if(!((*(long*)point)&0xFFFFFF00))
{
switch(*(long*)point)
{
case 0x10://Standard Information
fprintf(fp,"Attribute type : Standard Information\n");
FileTimeToSystemTime((FILETIME*)offset,&time);
fprintf(fp,"File 생성 %d년 %d월 %d일\n",time.wYear,time.wMonth,time.wDay);
FileTimeToSystemTime((FILETIME*)(offset+8),&time);
fprintf(fp,"File 수정 %d년 %d월 %d일\n",time.wYear,time.wMonth,time.wDay);
FileTimeToSystemTime((FILETIME*)(offset+24),&time);
fprintf(fp,"File 접근 %d년 %d월 %d일\n",time.wYear,time.wMonth,time.wDay);
break;
case 0x20://Attribute List
fprintf(fp,"Attribute type : Attribute list\n");
break;
case 0x30://File Name
fprintf(fp,"Attribute type : File Name\n");
FileTimeToSystemTime((FILETIME*)(offset+8),&time);
fprintf(fp,"File 생성 %d년 %d월 %d일\n",time.wYear,time.wMonth,time.wDay);
FileTimeToSystemTime((FILETIME*)(offset+16),&time);
fprintf(fp,"File 이름 수정 %d년 %d월 %d일\n",time.wYear,time.wMonth,time.wDay);
FileTimeToSystemTime((FILETIME*)(offset+32),&time);
fprintf(fp,"File 접근 %d년 %d월 %d일\n",time.wYear,time.wMonth,time.wDay);
fprintf(fp,"File Name Size : %d\n",*((unsigned char*)offset+64));
fprintf(fp,"File NameSpace : ");
switch(*((unsigned char*)offset+65))
{
case 0:
fprintf(fp,"POSIX\n");
break;
case 1:
fprintf(fp,"Win32\n");
break;
case 2:
fprintf(fp,"DOS\n");
break;
case 3:
fprintf(fp,"Win32 & DOS\n");
break;
default:
fprintf(fp,"Unkown\n");
break;
}
fprintf(fp,"File Name : ");
fwprintf(fp,L"%s",((unsigned char*)offset+66));
fprintf(fp,"\n");
break;
case 0x40://Volume Version
break;
case 0x50://Object ID
break;
case 0x60://Security
break;
}
}
if(*((unsigned char*)point+8))
{
delete offset;
}
if(*(long*)((unsigned char*)point+4))
return *(long*)((unsigned char*)point+4);
else
return 0;
}
//*
__int64 _MFT_READER::ReadCluster(unsigned char* point,unsigned char* info)
{
int i=0,j=0,k;
__int64 offset=0,temp;
__int64 length=0;
while(*(point+i))
{
length=0;
for(k=0;k<(*(point+i)&0x0F);k++)
{
length<<=8;
length+=*((point+i)+(*(point+i)&0x0F)-k);
}
temp=offset; //*오프셋값은 이전 값들과 합계로 계산됨.
offset=0;
for(;k<(*(point+i)&0x0F)+((*(point+i)&0xF0)>>4);k++)
{
offset<<=8;
offset+=*((point+i)+(*(point+i)&0x0F)+((*(point+i)&0xF0)>>4)-k+(*(point+i)&0x0F));
}
//*
if(offset&(0x80<<(8*(((*(point+i)&0xF0)>>4)-1))) && ((*(point+i)&0xF0)>>4)<8)
{
offset=offset^(0x80<<(8*(((*(point+i)&0xF0)>>4)-1)));
offset=-offset;
}
//*/
offset+=temp;
ReadSector(offset * boot_block.SectorsPerCluster,
length * boot_block.SectorsPerCluster,
info+j*boot_block.BytesPerSector*boot_block.SectorsPerCluster);
i+=(*(point+i)&0x0F)+((*(point+i)&0xF0)>>4)+1;
j+=length;
}
return j;
}
//*/