⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntfs.cpp

📁 命令行方式的硬盘工具 可以在dos和nt下运行。 需要djgpp和vs7.0以上
💻 CPP
字号:
/*
Command Line Tools for DOS(V32) Prgram v0.1.0 write by 孙宝建
6-20-2004
(暂停)
*/
#include "stdafx.h"

#ifndef __commcpp_h
#include "commcpp.hpp"
#endif

#ifndef _INCLUDE_SLIB_FUNC_HPP_INCLUDE
#include "slib_func.hpp"
#endif

#ifndef _INCLUDE_SLIB_ERROR_HPP_INCLUDE
#include "slib_error.hpp"
#endif

#ifndef _INT13_H
#include "int13.hpp"
#endif

#ifndef _NTFS_H
#include "ntfs.hpp"
#endif

using namespace SLib;

SLIB_DEFINE_FILE_NAME_VARIABLE

#ifdef _WIN32
ULONG CNtfs::RunLength(PUCHAR run)
{
	return (*run&0x0f)+((*run>>4)&0x0f)+1;
}

LONGLONG CNtfs::RunLCN(PUCHAR run)
{
	UCHAR n1=*run&0x0f;
	UCHAR n2=(*run>>4)&0x0f;
	LONGLONG lcn=n2==0?0:CHAR (run[n1+n2]);
	for(LONG i=n1+n2-1;i>n1;i--)
		lcn=(lcn<<8)+run[i];
	return lcn;
}

ULONGLONG CNtfs::RunCount(PUCHAR run)
{
	UCHAR n=*run&0x0f;
	ULONGLONG count=0;
	for(ULONG i=n;i>0;i--)
		count=(count<<8)+run[i];
	return count;
}

BOOL CNtfs::FindRun(PNONRESIDENT_ATTRIBUTE attr,ULONGLONG vcn,PULONGLONG lcn,PULONGLONG count)
{
	if(vcn<attr->LowVcn||vcn>attr->HighVcn)return FALSE;
	*lcn=0;
	ULONGLONG base=attr->LowVcn;
	for(PUCHAR run=PUCHAR (Padd(attr,attr->RunArrayOffset));*run!=0;run+=RunLength(run))
	{
		*lcn+=RunLCN(run);
		*count=RunCount(run);
		if(base<=vcn&&vcn<base+*count)
		{
			*lcn=RunLCN(run)==0?0:*lcn+vcn-base;
			*count-=ULONG(vcn-base);
			return TRUE;
		}
		else
			base+=*count;
	}

	return FALSE;
}

PATTRIBUTE CNtfs::FindAttribute(PFILE_RECORD_HEADER file,ATTRIBUTE_TYPE type,PWSTR name)
{
	for(PATTRIBUTE attr=PATTRIBUTE(Padd(file,file->AttributesOffset));
		attr->AttributeType!=-1;
		attr=Padd(attr,attr->Length))
	{
		if(attr->AttributeType==type)
		{
			if(name==0&&attr->NameLength==0)
				return attr;
			if( name!=0
				&&wcslen(name)==attr->NameLength
				&&wcsicmp(name,PWSTR(Padd(attr,attr->NameOffset)))==0
				)
				return attr;
		}
	}
	return 0;
}

VOID CNtfs::FixupUpdateSequenceArray(PFILE_RECORD_HEADER file)
{
	PUSHORT usa=PUSHORT(Padd(file,file->Ntfs.UsaOffset));
	PUSHORT sector=PUSHORT(file);
	for(ULONG i=1;i<file->Ntfs.UsaCount;i++)
	{
		sector[255]=usa[i];
		sector+=256;
	}
}

BOOL CNtfs::ReadSector(ULONGLONG sector,ULONG count,PVOID buffer)
{
	/*	ULARGE_INTEGER offset;
	OVERLAPPED overlap={0};
	ULONG n;
	offset.QuadPart=sector*m_BootB.BytesPerSector;
	overlap.Offset=offset.LowPart;
	overlap.OffsetHigh=offset.HighPart;
	ReadFile(hVolume,buffer,count*m_BootB.BytesPerSector,&n,&overlap);
	*/
	return m_pInt13->ReadSector(sector+m_BootBlockPos,count, buffer);
}


BOOL  CNtfs::WriteSector(ULONGLONG sector,ULONG count,PVOID buffer)
{
	/*	ULARGE_INTEGER offset;
	OVERLAPPED overlap={0};
	ULONG n;
	offset.QuadPart=sector*m_BootB.BytesPerSector;
	overlap.Offset=offset.LowPart;
	overlap.OffsetHigh=offset.HighPart;
	ReadFile(hVolume,buffer,count*m_BootB.BytesPerSector,&n,&overlap);
	*/
	return m_pInt13->WriteSector(sector+m_BootBlockPos,count,buffer);
}

VOID CNtfs::ReadLCN (ULONGLONG lcn,ULONG count,PVOID buffer)
{
	ReadSector(lcn*m_BootB.SectorsPerCluster,
		count*m_BootB.SectorsPerCluster,buffer);
}

VOID CNtfs::ReadExternalAttribute(PNONRESIDENT_ATTRIBUTE attr,ULONGLONG vcn,ULONG count,PVOID buffer)
{
	ULONGLONG lcn,runcount;
	ULONG readcount,left;
	PUCHAR bytes=PUCHAR(buffer);
	for(left=count;left>0;left-=readcount)
	{
		FindRun(attr,vcn,&lcn,&runcount);
		readcount=ULONG(min(runcount,left));
		ULONG n=readcount*m_BootB.BytesPerSector*m_BootB.SectorsPerCluster;
		if(lcn==0)
			memset(bytes,0,n);
		else
			ReadLCN(lcn,readcount,bytes);
		vcn+=n;
	}
}

ULONG CNtfs::AttributeLength(PATTRIBUTE attr)
{
	return attr->Nonresident==FALSE?PRESIDENT_ATTRIBUTE (attr)->ValueLength
		:ULONG(PNONRESIDENT_ATTRIBUTE(attr)->DataSize);
}

ULONG CNtfs::AttributeLengthAllocated(PATTRIBUTE attr)
{
	return attr->Nonresident==FALSE?PRESIDENT_ATTRIBUTE(attr)->ValueLength
		:ULONG(PNONRESIDENT_ATTRIBUTE(attr)->AllocatedSize);
}

VOID CNtfs::ReadAttribute(PATTRIBUTE attr,PVOID buffer)
{
	if(attr->Nonresident==FALSE)
	{
		PRESIDENT_ATTRIBUTE rattr=PRESIDENT_ATTRIBUTE (attr);
		memcpy(buffer,Padd(rattr,rattr->ValueOffset),rattr->ValueLength);
	}
	else
	{
		PNONRESIDENT_ATTRIBUTE nattr=PNONRESIDENT_ATTRIBUTE(attr);
		ReadExternalAttribute(nattr,0,ULONG(nattr->HighVcn)+1,buffer);
	}
}
VOID CNtfs::ReadVCN(PFILE_RECORD_HEADER file,ATTRIBUTE_TYPE type
					,ULONGLONG vcn ,ULONG count,PVOID buffer)
{
	PNONRESIDENT_ATTRIBUTE attr
		=PNONRESIDENT_ATTRIBUTE(FindAttribute(file,type,0));
	if(attr==0||(vcn<attr->LowVcn
		||vcn>attr->HighVcn))
	{
		PATTRIBUTE attrlist=FindAttribute(file,AttributeAttributeList,0);
		DebugBreak();
	}
	ReadExternalAttribute(attr,vcn,count,buffer);
}

VOID CNtfs::ReadFileRecord(ULONG index,PFILE_RECORD_HEADER file)
{
	ULONG clusters=m_BootB.ClustersPerFileRecord;
	if(clusters>0x80)
		clusters=1;
	PUCHAR p=new UCHAR [m_BootB.BytesPerSector*m_BootB.SectorsPerCluster*clusters];
	ULONGLONG vcn=ULONGLONG(index)*BytesPerFileRecord
		/m_BootB.BytesPerSector
		/m_BootB.SectorsPerCluster;
	ReadVCN(MFT,AttributeData,vcn,clusters,p);
	LONG m=(m_BootB.SectorsPerCluster*m_BootB.BytesPerSector/BytesPerFileRecord);
	delete []p;
	FixupUpdateSequenceArray(file);
}


BOOL CNtfs::LoadMFT(DWORD64 bootBlockSector)
{
//	if(!ReadSector(bootBlockSector,1,&m_BootB))
//		return FALSE;
	BytesPerFileRecord=m_BootB.ClustersPerFileRecord<0x80
		?m_BootB.ClustersPerFileRecord*m_BootB.BytesPerSector*m_BootB.SectorsPerCluster
		//    :i<<(0x100-BytesPerFileRecord);
		:1 << (0x100-BytesPerFileRecord);
	MFT=PFILE_RECORD_HEADER (new UCHAR[BytesPerFileRecord]);
	if( !ReadSector(m_BootB.MftStartLcn*m_BootB.SectorsPerCluster
		,BytesPerFileRecord/m_BootB.BytesPerSector,MFT) )
		return FALSE;
	//FixupUpdateSequenceArray(MFT);
	return TRUE;
}

BOOL CNtfs::BitSet(PUCHAR bitmap,ULONG i)
{
	return (bitmap[i>>3]&&(i<<(i&7)))!=0;
}

VOID CNtfs::FindDeleted()
{
	PATTRIBUTE attr=FindAttribute(MFT,AttributeBitmap,0);
	PUCHAR bitmap=new UCHAR[AttributeLengthAllocated(attr)];
	ReadAttribute(attr,bitmap);
	ULONG n=AttributeLength(FindAttribute(MFT,AttributeBitmap,0));
	PFILE_RECORD_HEADER file=PFILE_RECORD_HEADER(new UCHAR[BytesPerFileRecord]);
	for(ULONG i=0;i<n;i++)
	{
		if(BitSet(bitmap,i))
			continue;
		ReadFileRecord(i,file);
		if(file->Ntfs.Type=='ELIF'
			&&(file->Flags&1)==0)
		{
			attr=FindAttribute(file,AttributeFileName,0);
			if(attr==0)
				continue;
			PFILENAME_ATTRIBUTE name=PFILENAME_ATTRIBUTE (
				Padd(attr,PRESIDENT_ATTRIBUTE( attr)->ValueOffset));
			wostringstream ostr;
			ostr.fill(L'0');
			ostr.setf(ios_base::right,ios_base::adjustfield);
			ostr.setf(ios_base::uppercase| ios_base::showbase);
			ostr.setf(ios_base::hex,ios_base::basefield);
			ostr<<setw(10) << i << dec <<unsigned int (name->NameLength)<<name->Name;
			wcout<<ostr.str();
		}
	}
}

#endif //_WIN32

#ifdef _WIN32

VOID CNtfs::DumpData(ULONG index,PCSTR filename)
{
	PFILE_RECORD_HEADER file=PFILE_RECORD_HEADER(new UCHAR[BytesPerFileRecord]);
	ULONG n;
	ReadFileRecord(index,file);
	if(file->Ntfs.Type!='ELIF')
		return ;
	PATTRIBUTE attr=FindAttribute(file,AttributeData,0);
	if(attr==0)
		return;
	PUCHAR buf=new UCHAR[AttributeLengthAllocated(attr)];
	ReadAttribute(attr,buf);
	HANDLE hFile=CreateFile(filename,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0);
	WriteFile(hFile,buf,AttributeLength(attr),&n,0);
	//
	//
	delete []buf;
}

#ifndef _WINNT_
#include <winnt.h>
#endif

typedef ULONG NTSTATUS;

extern "C"
{
	NTSTATUS NTAPI RtlDecompressBuffer(USHORT CompressionFormat,
		PVOID OUtputBuffer,ULONG OutputBufferLength,
		PVOID InputBuffer,ULONG InputBufferLength,
		PULONG ReturnLength);
}
void CNtfs::DecompressFile(IN tstring compressFile,OUT tstring decompressFile)
{
	HANDLE hFile1=CreateFile(compressFile.c_str(),GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
	HANDLE hFile2=CreateFile(decompressFile.c_str(),GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,0,0);
	ULONG n=GetFileSize(hFile1,0);
	HANDLE hMapping1=CreateFileMapping(hFile1,0,PAGE_READONLY,0,0,0);
	HANDLE hMapping2=CreateFileMapping(hFile2,0,PAGE_READWRITE,0,n,0);
	PCHAR p=PCHAR(MapViewOfFileEx(hMapping1,FILE_MAP_READ,0,0,0,0));
	PCHAR q=PCHAR(MapViewOfFileEx(hMapping2,FILE_MAP_WRITE,0,0,0,0));
	//for(ULONG m,i=0;i<n;i+=m)
	// 	RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1,q++,n-i,p+i,n+i,&m);		//ntddk.h
}

#endif //_WIN32

CNtfs::CNtfs(CInt13 *pInt13,CSError *perror) :	m_pInt13(pInt13),m_pError(perror)
{
	SVERIFY_ARGUMENTS(pInt13!=NULL);
}

CNtfs::~CNtfs(void)
{
}

tstring CNtfs::BootBToString(void)
{
    ostringstream ostr;
    ostr.fill('0');
    ostr.setf(ios_base::right,ios_base::adjustfield);
    ostr.setf(ios_base::uppercase| ios_base::showbase);
    ostr.setf(ios_base::hex,ios_base::basefield);
	ostr<< "Format[8]: \t"				<<	(char*)	m_BootB.Format				<< endl 
		<< "BytesPerSector: \t"			<< setw(6)	<<	m_BootB.BytesPerSector				<< endl
		<< "SectorsPerCluster: \t"		<< setw(4)	<<(unsigned short)m_BootB.SectorsPerCluster			<< endl
		<< "BootSectors: \t"			<< setw(6)	<<	m_BootB.BootSectors					<< endl 
		<< "Mbz1: \t"					<< setw(4)	<<	m_BootB.Mbz1						<< endl
		<< "Mbz2: \t"					<< setw(6)	<<	m_BootB.Mbz2						<< endl
		<< "Reserved1: \t"				<< setw(6)	<<	m_BootB.Reserved1					<< endl
		<< "MediaType: \t"				<< setw(4)	<<(unsigned short)m_BootB.MediaType 					<< endl
		<< "Mbz3: \t"					<< setw(6)	<<	m_BootB.Mbz3						<< endl
		<< "SectorsPerTrack: \t"		<< setw(6)	<<  m_BootB.SectorsPerTrack				<< endl 
		<< "NmberOfheads: \t"			<< setw(6)	<<  m_BootB.NmberOfheads				<< endl
		<< "PartitionOffset: \t"		<< setw(10)	<<  m_BootB.PartitionOffset				<< endl 
		<< "dwMbzTotalSectors: \t"		<< setw(18)	<<  m_BootB.dwMbzTotalSectors				<< endl 
		<< "Mbz4: \t"					<< setw(10)	<<  m_BootB.Mbz4					<< endl
		<< "TotalSectors: \t"			<< setw(18)	<<  m_BootB.TotalSectors				<< endl 
		<< "MftStartLcn: \t"			<< setw(18)	<<  m_BootB.MftStartLcn					<< endl
		<< "Mft2StartLcn: \t"			<< setw(18)	<<  m_BootB.Mft2StartLcn 				<< endl
		<< "ClustersPerFileRecord: \t"	<< setw(10)	<<  m_BootB.ClustersPerFileRecord		<< endl
		<< "ClustersPerIndexBlock: \t"	<< setw(10)	<<  m_BootB.ClustersPerIndexBlock		<< endl
		<< "VolumeSerialNumber: \t"		<< setw(18)	<<  m_BootB.VolumeSerialNumber			<< endl
		<< "BootSignature: \t"			<< setw(6)	<<	m_BootB.BootSignature				<< endl
		<< endl;
	return ostr.str();
}

BOOL CNtfs::LoadBootBlock(DWORD64 bootBlockSector)
{
	m_BootBlockPos=bootBlockSector;
//	return m_pInt13->ReadSector(bootBlockSector,1,&m_BootB);
	if(m_pInt13->ReadSector(bootBlockSector,1,&m_BootB) )
	{
		//return LoadMFT(bootBlockSector);
		return TRUE;
	}
	return FALSE;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -