#include "stdafx.h"
#include "Winuser.h"
#include "NTFS.h"
//*************************************************类成员函数的实现****************************************************
//*************************************************类成员函数的实现****************************************************
//TODO:实现文件恢复的类
//定义小端数字转换成大端数字
WORD CNTFS_Recovery::DiskNumToRealNum( IN WORD wNeedChange )
{
WORD wReturn=0 ;
//截取wNeedChange低8位,实际数高8位
wReturn = wReturn|( 255&wNeedChange );
wReturn=wReturn<<8;
wReturn=wNeedChange>>8;
wReturn = wReturn|( 255&wNeedChange );
return wReturn ;
}
DWORD CNTFS_Recovery::DiskNumToRealNum(IN DWORD dwNeedChange )
{
DWORD dwReturn=0 ;
//截取wNeedChange低8位,实际数高8位
for ( int i = 0 ; i<3 ; i++ )
{
dwReturn = dwReturn|( 255&dwNeedChange );
dwReturn=dwReturn<<8;
dwReturn=dwNeedChange>>8;
}
dwReturn = dwReturn|( 255&dwNeedChange );
return dwReturn ;
}
QWORD CNTFS_Recovery::DiskNumToRealNum(IN QWORD qwNeedChange )
{
QWORD qwReturn=0 ;
//截取wNeedChange低8位,实际数高8位
for ( int i = 0 ; i<7 ; i++ )
{
qwReturn = qwReturn|( 255&qwNeedChange );
qwReturn=qwReturn<<8;
qwReturn=qwNeedChange>>8;
}
qwReturn = qwReturn|( 255&qwNeedChange );
return qwReturn ;
}
//实现读取磁盘数据的函数,一次性最大可读65535字节
BOOL CNTFS_Recovery::ReadDiskData(IN HANDLE hFile , IN QWORD qwStartByte , IN DWORD qwLength ,OUT LPVOID lpData )
{
DWORD dwCB ;
//将qwStartByte,qwLength用512整倍字节长度替代
DWORD dOffsetBytes = qwStartByte%512; //dOffset为qwStartByte距离qwStartByte所在扇区的偏移地址
QWORD qwOffsetSectors = qwStartByte/512 ; //dOffsetStartSectors为读取数据的起始扇区
DWORD dLengthAwayEnd = ( 512 -(qwLength + dOffsetBytes )%512 )%512; //应读取的数据尾距离本扇区的末尾距离
LARGE_INTEGER llOffset ;
llOffset.QuadPart = (QWORD)( qwOffsetSectors*512 ); //llOffset.QuadPart为实际读取的起始字节位置
//设置文件句柄位置
if ( INVALID_SET_FILE_POINTER == SetFilePointer( hFile , llOffset.LowPart , &llOffset.HighPart , FILE_BEGIN ))
{
return FALSE ;
}
//读取文件数据
DWORD dLength = ( qwLength + dOffsetBytes + dLengthAwayEnd )>65024 ? 65024 : ( qwLength + dOffsetBytes + dLengthAwayEnd ) ;
CHAR *lpBuffer = (CHAR *)malloc(dLength+1);
ZeroMemory( lpBuffer , sizeof(lpBuffer) );
if ( !ReadFile( hFile , lpBuffer ,dLength , & dwCB , NULL ) )
{
return FALSE ;
}
memcpy( lpData , lpBuffer+dOffsetBytes , qwLength );
free(lpBuffer);
return TRUE ;
}
//实现读取指定驱动器盘的函数
BOOL CNTFS_Recovery::ReadDriverData( IN CHAR *pcDriver ,IN QWORD qwStartByte ,IN DWORD dwLength ,OUT LPVOID lpData )
{
TCHAR szFilePath[255]={0};
wsprintf( szFilePath , L"\\\\.\\%s:" , pcDriver );
//根据路径获取物理磁盘指针
HANDLE hDevice = CreateFile( szFilePath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if( hDevice == INVALID_HANDLE_VALUE)
{
CloseHandle(hDevice);
return FALSE;
}
if ( !ReadDiskData( hDevice , qwStartByte , dwLength , lpData ) )
{
CloseHandle(hDevice);
return FALSE;
}
CloseHandle(hDevice);
return TRUE ;
}
//实现NTFS文件系统判断函数
DWORD CNTFS_Recovery::IsNTFSFileSystem(IN CHAR *pcDriver )
{
//磁盘驱动第一个扇区缓冲区
TCHAR szFilePath[255]={0};
CHAR szFirstSertorOfDriver[512]={0};
wsprintf( szFilePath , L"\\\\.\\%s:" , pcDriver );
//根据路径获取物理磁盘指针
HANDLE hDevice = CreateFile( szFilePath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if( hDevice == INVALID_HANDLE_VALUE)
{
CloseHandle(hDevice);
return -1;
}
if ( !ReadDiskData( hDevice , 0 , 512 , szFirstSertorOfDriver ) )
{
CloseHandle(hDevice);
return -1;
}
if ( strncmp( szFirstSertorOfDriver+3 , "NTFS" , 4 ) == 0 )
{
CloseHandle(hDevice);
return 1 ;
}
else
{
return 0;
}
}
//实现读取指定驱动器盘引导扇区重要的数据
BOOL CNTFS_Recovery::ReadDriverBootSectorData( IN CHAR *pcDriver ,OUT NTFS_BOOTSECTERDATA *pNtfsBootSerterData )
{
NTFS_BPB NtfsBPB;
ZeroMemory( pNtfsBootSerterData , sizeof(pNtfsBootSerterData) );
if ( !ReadDriverData( pcDriver , 0 , sizeof(NTFS_BPB) , &NtfsBPB )) return FALSE;
pNtfsBootSerterData->cMediaID = NtfsBPB.cMediaID ;
pNtfsBootSerterData->cSectorPerCluster = NtfsBPB.cSectorPerCluster ;
pNtfsBootSerterData->dwClustersPerMFTRecord = NtfsBPB.dwClustersPerMFTRecord;
pNtfsBootSerterData->qwMFTStartCluster = NtfsBPB.qwMFTStartCluster ;
pNtfsBootSerterData->qwTotalSectors = NtfsBPB.qwTotalSectors;
pNtfsBootSerterData->wBytesPerSector = NtfsBPB.wBytesPerSector ;
pNtfsBootSerterData->qwMFTStartSector = pNtfsBootSerterData->qwMFTStartCluster*pNtfsBootSerterData->cSectorPerCluster;
pNtfsBootSerterData->qwMFTStartByte = pNtfsBootSerterData->qwMFTStartSector*pNtfsBootSerterData->wBytesPerSector ;
return TRUE;
}
//实现读取NTFS中MFT项纪录头数据函数
BOOL CNTFS_Recovery::ReadMFTDataFromNTFS( IN CHAR *pcDriver ,OUT NTFS_XPMFTRECORDERHEADER *pMftRecordHeader )
{
NTFS_BPB NtfsBPB;
if ( !ReadDriverData( pcDriver , 0 , sizeof(NTFS_BPB) , &NtfsBPB )) return FALSE;
QWORD qwStartByteOfMft,qwStartSectorOfMft ;
qwStartSectorOfMft = NtfsBPB.cSectorPerCluster*NtfsBPB.qwMFTStartCluster ;
qwStartByteOfMft = qwStartSectorOfMft*NtfsBPB.wBytesPerSector ;
if ( !ReadDriverData( pcDriver , qwStartByteOfMft , sizeof(NTFS_XPMFTRECORDERHEADER) , pMftRecordHeader )) return FALSE;
return TRUE ;
}
//实现获取MFT原元文件信息
BOOL CNTFS_Recovery::ReadMFTUnitFiles( IN QWORD qwMFTStartSector , IN QWORD qwBytesPerSector , OUT NTFS_MFTUNITFILES *pNtfsMFTUnitFiles )
{
pNtfsMFTUnitFiles->$MFT_UnitFileInfo.qwStartSector = qwMFTStartSector ;
pNtfsMFTUnitFiles->$MFT_UnitFileInfo.qwStartByte = qwMFTStartSector*qwBytesPerSector ;
pNtfsMFTUnitFiles->$MFT_UnitFileInfo.dwUnitFileLength = 1024 ;
pNtfsMFTUnitFiles->$MFTMirr_UnitFileInfo.qwStartSector = qwMFTStartSector+2 ;
pNtfsMFTUnitFiles->$MFTMirr_UnitFileInfo.qwStartByte = (qwMFTStartSector+2)*qwBytesPerSector ;
pNtfsMFTUnitFiles->$MFTMirr_UnitFileInfo.dwUnitFileLength = 1024 ;
pNtfsMFTUnitFiles->$LogFile_UnitFileInfo.qwStartSector = qwMFTStartSector+4 ;
pNtfsMFTUnitFiles->$LogFile_UnitFileInfo.qwStartByte = (qwMFTStartSector+4)*qwBytesPerSector;
pNtfsMFTUnitFiles->$LogFile_UnitFileInfo.dwUnitFileLength = 1024 ;
pNtfsMFTUnitFiles->$Volumn_UnitFileInfo.qwStartSector = qwMFTStartSector+6 ;
pNtfsMFTUnitFiles->$Volumn_UnitFileInfo.qwStartByte = (qwMFTStartSector+6)*qwBytesPerSector ;
pNtfsMFTUnitFiles->$Volumn_UnitFileInfo.dwUnitFileLength = 1024 ;
pNtfsMFTUnitFiles->$AttrDef_UnitFileInfo.qwStartSector = qwMFTStartSector+8;
pNtfsMFTUnitFiles->$AttrDef_UnitFileInfo.qwStartByte = (qwMFTStartSector+8)*qwBytesPerSector ;
pNtfsMFTUnitFiles->$AttrDef_UnitFileInfo.dwUnitFileLength = 1024 ;
pNtfsMFTUnitFiles->$Root_UnitFileInfo.qwStartSector = qwMFTStartSector+10;
pNtfsMFTUnitFiles->$Root_UnitFileInfo.qwStartByte = (qwMFTStartSector+10)*qwBytesPerSector ;
pNtfsMFTUnitFiles->$Root_UnitFileInfo.dwUnitFileLength = 1024 ;
pNtfsMFTUnitFiles->$Bitmap_UnitFileInfo.qwStartSector = qwMFTStartSector +12 ;
pNtfsMFTUnitFiles->$Bitmap_UnitFileInfo.qwStartByte = (qwMFTStartSector+12)*qwBytesPerSector ;
pNtfsMFTUnitFiles->$Bitmap_UnitFileInfo.dwUnitFileLength = 1024 ;
pNtfsMFTUnitF