mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Patch by Valentin Verkhovsky: Ntfs driver is updated now and ready for testing.
I've been working on MFT processing for while. Thus driver performs only files & attribute enumerating by VCN-LCN pair mapping like M$ Nfi utility. For me it compiles and the image loads correctly. svn path=/trunk/; revision=6087
This commit is contained in:
parent
ed00963623
commit
1f1078fba3
4 changed files with 463 additions and 117 deletions
|
@ -16,13 +16,14 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: attrib.c,v 1.5 2003/08/07 11:47:32 silverblade Exp $
|
||||
/* $Id: attrib.c,v 1.6 2003/09/15 16:01:16 ea Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/fs/ntfs/attrib.c
|
||||
* PURPOSE: NTFS filesystem driver
|
||||
* PROGRAMMER: Eric Kohl
|
||||
* Updated by Valentin Verkhovsky 2003/09/12
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
@ -39,13 +40,47 @@
|
|||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
||||
|
||||
ULONG RunLength(PUCHAR run)
|
||||
{
|
||||
return(*run & 0x0f) + ((*run >> 4) & 0x0f) + 1;
|
||||
}
|
||||
|
||||
|
||||
LONGLONG RunLCN(PUCHAR run)
|
||||
{
|
||||
UCHAR n1 = *run & 0x0f;
|
||||
UCHAR n2 = (*run >> 4) & 0x0f;
|
||||
LONGLONG lcn = n2 == 0 ? 0 : (CHAR)(run[n1 + n2]);
|
||||
LONG i = 0;
|
||||
|
||||
for (i = n1 +n2 - 1; i > n1; i--)
|
||||
lcn = (lcn << 8) + run[i];
|
||||
return lcn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ULONGLONG RunCount(PUCHAR run)
|
||||
{
|
||||
UCHAR n = *run & 0xf;
|
||||
ULONGLONG count = 0;
|
||||
ULONG i = 0;
|
||||
|
||||
for (i = n; i > 0; i--)
|
||||
count = (count << 8) + run[i];
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
NtfsDumpFileNameAttribute(PATTRIBUTE Attribute)
|
||||
{
|
||||
PRESIDENT_ATTRIBUTE ResAttr;
|
||||
PFILENAME_ATTRIBUTE FileNameAttr;
|
||||
|
||||
DbgPrint(" $FILE_NAME ");
|
||||
DbgPrint(" FILE_NAME ");
|
||||
|
||||
ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
|
||||
// DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
|
||||
|
@ -90,7 +125,7 @@ NtfsDumpVolumeInformationAttribute(PATTRIBUTE Attribute)
|
|||
}
|
||||
|
||||
|
||||
VOID
|
||||
BOOL
|
||||
NtfsDumpAttribute(PATTRIBUTE Attribute)
|
||||
{
|
||||
PNONRESIDENT_ATTRIBUTE NresAttr;
|
||||
|
@ -100,9 +135,16 @@ NtfsDumpAttribute(PATTRIBUTE Attribute)
|
|||
UCHAR RunHeader;
|
||||
ULONG RunLength;
|
||||
ULONG RunStart;
|
||||
|
||||
|
||||
switch (Attribute->AttributeType)
|
||||
{
|
||||
|
||||
case AttributeFileName:
|
||||
NtfsDumpFileNameAttribute(Attribute);
|
||||
break;
|
||||
|
||||
|
||||
case AttributeStandardInformation:
|
||||
DbgPrint(" $STANDARD_INFORMATION ");
|
||||
break;
|
||||
|
@ -111,9 +153,7 @@ NtfsDumpAttribute(PATTRIBUTE Attribute)
|
|||
DbgPrint(" $ATTRIBUTE_LIST ");
|
||||
break;
|
||||
|
||||
case AttributeFileName:
|
||||
NtfsDumpFileNameAttribute(Attribute);
|
||||
break;
|
||||
|
||||
|
||||
case AttributeObjectId:
|
||||
DbgPrint(" $OBJECT_ID ");
|
||||
|
@ -133,6 +173,7 @@ NtfsDumpAttribute(PATTRIBUTE Attribute)
|
|||
|
||||
case AttributeData:
|
||||
DbgPrint(" $DATA ");
|
||||
//DataBuf = ExAllocatePool(NonPagedPool,AttributeLengthAllocated(Attribute));
|
||||
break;
|
||||
|
||||
case AttributeIndexRoot:
|
||||
|
@ -184,85 +225,23 @@ NtfsDumpAttribute(PATTRIBUTE Attribute)
|
|||
|
||||
DbgPrint("(%s)\n",
|
||||
Attribute->Nonresident ? "non-resident" : "resident");
|
||||
|
||||
|
||||
|
||||
if (Attribute->Nonresident != 0)
|
||||
|
||||
if (Attribute->Nonresident != 0)
|
||||
{
|
||||
NresAttr = (PNONRESIDENT_ATTRIBUTE)Attribute;
|
||||
Ptr = (PUCHAR)((ULONG)NresAttr + NresAttr->RunArrayOffset);
|
||||
while (*Ptr != 0)
|
||||
{
|
||||
RunHeader = *Ptr++;
|
||||
|
||||
switch (RunHeader & 0x0F)
|
||||
{
|
||||
case 1:
|
||||
RunLength = (ULONG)*Ptr++;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
RunLength = *((PUSHORT)Ptr);
|
||||
Ptr += 2;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
RunLength = *Ptr++;
|
||||
RunLength += *Ptr++ << 8;
|
||||
RunLength += *Ptr++ << 16;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
RunLength = *((PULONG)Ptr);
|
||||
Ptr += 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
DbgPrint("RunLength size of %hu not implemented!\n", RunHeader & 0x0F);
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
switch (RunHeader >> 4)
|
||||
{
|
||||
case 1:
|
||||
RunStart = (ULONG)*Ptr;
|
||||
Ptr++;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
RunStart = *((PUSHORT)Ptr);
|
||||
Ptr += 2;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
RunStart = *Ptr++;
|
||||
RunStart += *Ptr++ << 8;
|
||||
RunStart += *Ptr++ << 16;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
RunStart = *((PULONG)Ptr);
|
||||
Ptr += 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
DbgPrint("RunStart size of %hu not implemented!\n", RunHeader >> 4);
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
DbgPrint(" AllocatedSize %I64d DataSize %I64d\n", NresAttr->AllocatedSize, NresAttr->DataSize);
|
||||
// DbgPrint(" Run: Header %hx Start %lu Length %lu\n", RunHeader, RunStart, RunLength);
|
||||
if (RunLength == 1)
|
||||
{
|
||||
DbgPrint(" logical sector %lu (0x%lx)\n", RunStart, RunStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint(" logical sectors %lu-%lu (0x%lx-0x%lx)\n",
|
||||
RunStart, RunStart + RunLength - 1,
|
||||
RunStart, RunStart + RunLength - 1);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -16,20 +16,21 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: fsctl.c,v 1.7 2003/07/17 13:31:39 chorns Exp $
|
||||
/* $Id: fsctl.c,v 1.8 2003/09/15 16:01:16 ea Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/ntfs/fsctl.c
|
||||
* PURPOSE: NTFS filesystem driver
|
||||
* PROGRAMMER: Eric Kohl
|
||||
* Updated by Valentin Verkhovsky 2003/09/12
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "ntfs.h"
|
||||
|
@ -163,6 +164,7 @@ NtfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
|
|||
Vcb->NtfsInfo.MftStart.QuadPart = BootSector->MftLocation;
|
||||
Vcb->NtfsInfo.MftMirrStart.QuadPart = BootSector->MftMirrLocation;
|
||||
Vcb->NtfsInfo.SerialNumber = BootSector->SerialNumber;
|
||||
Vcb->NtfsInfo.ClustersPerFileRecord = BootSector->ClustersPerMftRecord;
|
||||
|
||||
//#indef NDEBUG
|
||||
DbgPrint("Boot sector information:\n");
|
||||
|
|
|
@ -16,13 +16,14 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: mft.c,v 1.1 2002/07/15 15:37:33 ekohl Exp $
|
||||
/* $Id: mft.c,v 1.2 2003/09/15 16:01:16 ea Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/ntfs/mft.c
|
||||
* PURPOSE: NTFS filesystem driver
|
||||
* PROGRAMMER: Eric Kohl
|
||||
* PROGRAMMER: Eric Kohl
|
||||
* Updated by Valentin Verkhovsky 2003/09/12
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
@ -35,6 +36,9 @@
|
|||
#include "ntfs.h"
|
||||
|
||||
|
||||
#define __min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
||||
|
@ -43,58 +47,379 @@ NtfsOpenMft(PDEVICE_OBJECT DeviceObject,
|
|||
PDEVICE_EXTENSION Vcb)
|
||||
{
|
||||
PVOID Buffer;
|
||||
PFILE_RECORD_HEADER RecordHeader;
|
||||
PVOID Bitmap;
|
||||
PFILE_RECORD_HEADER MftRecord;
|
||||
PFILE_RECORD_HEADER file;
|
||||
PATTRIBUTE Attribute;
|
||||
PATTRIBUTE AttrData;
|
||||
PRESIDENT_ATTRIBUTE ResAttr;
|
||||
|
||||
NTSTATUS Status;
|
||||
|
||||
ULONG BytesPerFileRecord;
|
||||
DPRINT1("NtfsOpenMft() called\n");
|
||||
ULONG n = 0;
|
||||
|
||||
BytesPerFileRecord = Vcb->NtfsInfo.ClustersPerFileRecord *
|
||||
Vcb->NtfsInfo.BytesPerCluster;
|
||||
|
||||
Buffer = ExAllocatePool(NonPagedPool,
|
||||
Vcb->NtfsInfo.BytesPerCluster);
|
||||
BytesPerFileRecord);
|
||||
if (Buffer == NULL)
|
||||
{
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
|
||||
/* read first MFT cluster */
|
||||
|
||||
|
||||
Status = NtfsReadRawSectors(DeviceObject,
|
||||
Vcb->NtfsInfo.MftStart.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster,
|
||||
Vcb->NtfsInfo.SectorsPerCluster,
|
||||
BytesPerFileRecord / Vcb->NtfsInfo.BytesPerSector,
|
||||
Vcb->NtfsInfo.BytesPerSector,
|
||||
(PVOID)Buffer);
|
||||
if (NT_SUCCESS(Status))
|
||||
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Enumerate MFT records */
|
||||
RecordHeader = Buffer;
|
||||
while (((ULONG)RecordHeader - (ULONG)Buffer) < Vcb->NtfsInfo.BytesPerCluster)
|
||||
{
|
||||
DbgPrint("\n");
|
||||
// DbgPrint("Magic: %.04s\n", (PCHAR)&RecordHeader->Ntfs.Type);
|
||||
// DbgPrint("Real size: %lx\n", RecordHeader->RealSize);
|
||||
// DbgPrint("AllocSize: %lx\n", RecordHeader->AllocSize);
|
||||
|
||||
DbgPrint("Enumerate MFT \n");
|
||||
MftRecord = Buffer;
|
||||
|
||||
/* Enumerate attributes */
|
||||
Attribute = (PATTRIBUTE)((ULONG)RecordHeader +
|
||||
RecordHeader->Ntfs.UsnOffset +
|
||||
RecordHeader->Ntfs.UsnSize * sizeof(USHORT));
|
||||
while (Attribute->AttributeType != 0xFFFFFFFF)
|
||||
{
|
||||
NtfsDumpAttribute(Attribute);
|
||||
FixupUpdateSequenceArray(MftRecord);
|
||||
|
||||
ULONG i;
|
||||
Attribute = FindAttribute(MftRecord, AttributeBitmap, 0);
|
||||
|
||||
|
||||
/* Get number of file records*/
|
||||
n = AttributeLength(FindAttribute(MftRecord, AttributeData,0))
|
||||
/ BytesPerFileRecord;
|
||||
|
||||
file = ExAllocatePool(NonPagedPool, BytesPerFileRecord);
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
/* Enumerate MFT Records */
|
||||
|
||||
for ( i=0; i < n; i++)
|
||||
{
|
||||
|
||||
|
||||
ReadFileRecord(i, file, Vcb, MftRecord, DeviceObject);
|
||||
|
||||
if (file->Ntfs.Type == 'ELIF' && (file->Flags & 1) != 0)
|
||||
{
|
||||
|
||||
DbgPrint("\n");
|
||||
DbgPrint("File %lu\n", i);
|
||||
DbgPrint("\n");
|
||||
/* Enumerate attributtes */
|
||||
|
||||
Attribute = (PATTRIBUTE)((ULONG)Attribute + Attribute->Length);
|
||||
}
|
||||
EnumerAttribute(file, Vcb, DeviceObject);
|
||||
DbgPrint("\n");
|
||||
DbgPrint("\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
RecordHeader = (PFILE_RECORD_HEADER)((ULONG)RecordHeader + RecordHeader->BytesAllocated);
|
||||
|
||||
}
|
||||
|
||||
ExFreePool(Buffer);
|
||||
|
||||
ExFreePool(file);
|
||||
|
||||
}
|
||||
|
||||
ExFreePool(Buffer);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
PATTRIBUTE FindAttribute(PFILE_RECORD_HEADER file,
|
||||
|
||||
/* EOF */
|
||||
ATTRIBUTE_TYPE type, PWSTR name)
|
||||
{
|
||||
PATTRIBUTE attr = (PATTRIBUTE)((PVOID)file + file->AttributeOffset);
|
||||
|
||||
while (attr->AttributeType !=-1)
|
||||
{
|
||||
|
||||
if(attr->AttributeType == type) {
|
||||
return attr;
|
||||
}
|
||||
attr = (PATTRIBUTE)((ULONG)attr + attr->Length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ULONG AttributeLengthAllocated(PATTRIBUTE attr)
|
||||
{
|
||||
|
||||
PRESIDENT_ATTRIBUTE ResAttr;
|
||||
PNONRESIDENT_ATTRIBUTE NresAttr;
|
||||
if(attr->Nonresident == FALSE)
|
||||
{
|
||||
ResAttr = (PRESIDENT_ATTRIBUTE)attr;
|
||||
return ResAttr->ValueLength;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
NresAttr = (PNONRESIDENT_ATTRIBUTE)attr;
|
||||
|
||||
return NresAttr->AllocatedSize;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
VOID ReadAttribute(PATTRIBUTE attr, PVOID buffer, PDEVICE_EXTENSION Vcb,
|
||||
PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
if(attr->Nonresident == FALSE)
|
||||
{
|
||||
PRESIDENT_ATTRIBUTE ResAttr = (PRESIDENT_ATTRIBUTE)attr;
|
||||
memcpy(buffer, (PRESIDENT_ATTRIBUTE)((PVOID)ResAttr + ResAttr->ValueOffset),
|
||||
ResAttr->ValueLength);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
PNONRESIDENT_ATTRIBUTE NresAttr = (PNONRESIDENT_ATTRIBUTE)attr;
|
||||
ReadExternalAttribute(NresAttr, 0, (ULONG)(NresAttr->LastVcn) + 1,
|
||||
buffer, Vcb, DeviceObject);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
ULONG AttributeLength(PATTRIBUTE attr)
|
||||
{
|
||||
PRESIDENT_ATTRIBUTE ResAttr;
|
||||
PNONRESIDENT_ATTRIBUTE NresAttr;
|
||||
|
||||
if(attr->Nonresident == FALSE)
|
||||
{
|
||||
ResAttr = (PRESIDENT_ATTRIBUTE)attr;
|
||||
return ResAttr->ValueLength;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
NresAttr = (PNONRESIDENT_ATTRIBUTE)attr;
|
||||
return NresAttr->DataSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID ReadFileRecord(ULONG index, PFILE_RECORD_HEADER file,
|
||||
PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER Mft,
|
||||
PDEVICE_OBJECT DeviceObject)
|
||||
|
||||
{
|
||||
|
||||
PVOID p;
|
||||
ULONG clusters = Vcb->NtfsInfo.ClustersPerFileRecord;
|
||||
ULONG BytesPerFileRecord = clusters * Vcb->NtfsInfo.BytesPerCluster;
|
||||
|
||||
|
||||
p = ExAllocatePool(NonPagedPool, BytesPerFileRecord);
|
||||
|
||||
ULONGLONG vcn = index * BytesPerFileRecord / Vcb->NtfsInfo.BytesPerCluster;
|
||||
|
||||
ReadVCN(Mft, AttributeData, vcn, clusters, p, Vcb,DeviceObject);
|
||||
|
||||
LONG m = (Vcb->NtfsInfo.BytesPerCluster / BytesPerFileRecord) - 1;
|
||||
|
||||
ULONG n = m > 0 ? (index & m) : 0;
|
||||
|
||||
memcpy(file, p + n * BytesPerFileRecord, BytesPerFileRecord);
|
||||
|
||||
ExFreePool(p);
|
||||
FixupUpdateSequenceArray(file);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID ReadExternalAttribute(PNONRESIDENT_ATTRIBUTE NresAttr,
|
||||
ULONGLONG vcn, ULONG count, PVOID buffer,
|
||||
PDEVICE_EXTENSION Vcb,
|
||||
PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
|
||||
|
||||
ULONGLONG lcn, runcount;
|
||||
ULONG readcount, left;
|
||||
|
||||
PUCHAR bytes = (PUCHAR)buffer;
|
||||
|
||||
for (left = count; left>0; left -=readcount)
|
||||
{
|
||||
FindRun(NresAttr, vcn, &lcn, &runcount);
|
||||
|
||||
readcount = (ULONG)(__min(runcount, left));
|
||||
|
||||
|
||||
ULONG n = readcount * Vcb->NtfsInfo.BytesPerCluster;
|
||||
|
||||
if (lcn == 0)
|
||||
memset(bytes, 0, n);
|
||||
else
|
||||
ReadLCN(lcn, readcount, bytes, Vcb, DeviceObject);
|
||||
|
||||
vcn += readcount;
|
||||
bytes += n;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOL FindRun(PNONRESIDENT_ATTRIBUTE NresAttr, ULONGLONG vcn,
|
||||
PULONGLONG lcn, PULONGLONG count)
|
||||
{
|
||||
PUCHAR run;
|
||||
|
||||
ULONGLONG base = NresAttr->StartVcn;
|
||||
|
||||
|
||||
if (vcn < NresAttr->StartVcn || vcn > NresAttr->LastVcn)
|
||||
return FALSE;
|
||||
|
||||
*lcn = 0;
|
||||
|
||||
|
||||
for (run = (PUCHAR)((ULONG)NresAttr + NresAttr->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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID ReadVCN(PFILE_RECORD_HEADER file, ATTRIBUTE_TYPE type,
|
||||
ULONGLONG vcn, ULONG count, PVOID buffer,
|
||||
PDEVICE_EXTENSION Vcb, PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
|
||||
PNONRESIDENT_ATTRIBUTE NresAttr;
|
||||
PATTRIBUTE attr;
|
||||
attr = FindAttribute(file, type,0);
|
||||
|
||||
NresAttr = (PNONRESIDENT_ATTRIBUTE) attr;
|
||||
|
||||
if (NresAttr == 0 || (vcn < NresAttr->StartVcn ||vcn > NresAttr->LastVcn))
|
||||
{
|
||||
|
||||
PATTRIBUTE attrList = FindAttribute(file,AttributeAttributeList,0);
|
||||
DbgPrint("Exeption \n");
|
||||
//KeDebugCheck(0);
|
||||
}
|
||||
|
||||
ReadExternalAttribute(NresAttr, vcn, count, buffer, Vcb, DeviceObject);
|
||||
|
||||
|
||||
}
|
||||
|
||||
BOOL bitset(PUCHAR bitmap, ULONG i)
|
||||
{
|
||||
return (bitmap[i>>3] & (1 << (i & 7))) !=0;
|
||||
}
|
||||
|
||||
|
||||
VOID FixupUpdateSequenceArray(PFILE_RECORD_HEADER file)
|
||||
{
|
||||
PUSHORT usa = (PUSHORT)((PVOID)file + file->Ntfs.UsaOffset);
|
||||
PUSHORT sector = (PUSHORT)file;
|
||||
ULONG i;
|
||||
|
||||
for( i =1; i < file->Ntfs.UsaCount; i++)
|
||||
{
|
||||
sector[255] = usa[i];
|
||||
sector += 256;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
VOID ReadLCN(ULONGLONG lcn, ULONG count, PVOID buffer, PDEVICE_EXTENSION Vcb,
|
||||
PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
|
||||
LARGE_INTEGER DiskSector;
|
||||
DiskSector.QuadPart = lcn;
|
||||
|
||||
|
||||
NtfsReadRawSectors(DeviceObject, DiskSector.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster,
|
||||
count * Vcb->NtfsInfo.SectorsPerCluster, Vcb->NtfsInfo.BytesPerSector, buffer);
|
||||
}
|
||||
|
||||
|
||||
VOID EnumerAttribute(PFILE_RECORD_HEADER file, PDEVICE_EXTENSION Vcb,
|
||||
PDEVICE_OBJECT DeviceObject)
|
||||
|
||||
{
|
||||
|
||||
ULONGLONG lcn;
|
||||
ULONGLONG runcount;
|
||||
ULONG size;
|
||||
PATTRIBUTE attr = (PATTRIBUTE)((PVOID)file + file->AttributeOffset);
|
||||
|
||||
while (attr->AttributeType !=-1)
|
||||
{
|
||||
|
||||
if(NtfsDumpAttribute(attr))
|
||||
{
|
||||
|
||||
PNONRESIDENT_ATTRIBUTE NresAttr = (PNONRESIDENT_ATTRIBUTE)attr;
|
||||
|
||||
|
||||
FindRun(NresAttr,0,&lcn, &runcount);
|
||||
|
||||
DbgPrint(" AllocatedSize %I64d DataSize %I64d\n", NresAttr->AllocatedSize, NresAttr->DataSize);
|
||||
DbgPrint(" logical sectors: %lu", lcn);
|
||||
DbgPrint("-%lu\n", lcn + runcount -1);
|
||||
|
||||
}
|
||||
attr = (PATTRIBUTE)((ULONG)attr + attr->Length);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -50,6 +50,7 @@ typedef struct _NTFS_INFO
|
|||
ULARGE_INTEGER MftStart;
|
||||
ULARGE_INTEGER MftMirrStart;
|
||||
ULONGLONG SerialNumber;
|
||||
ULONG ClustersPerFileRecord;
|
||||
|
||||
} NTFS_INFO, *PNTFS_INFO;
|
||||
|
||||
|
@ -153,8 +154,8 @@ typedef enum
|
|||
typedef struct
|
||||
{
|
||||
ULONG Type; /* Magic number 'FILE' */
|
||||
USHORT UsnOffset; /* Offset to the update sequence */
|
||||
USHORT UsnSize; /* Size in words of Update Sequence Number & Array (S) */
|
||||
USHORT UsaOffset; /* Offset to the update sequence */
|
||||
USHORT UsaCount; /* Size in words of Update Sequence Number & Array (S) */
|
||||
ULONGLONG Lsn; /* $LogFile Sequence Number (LSN) */
|
||||
} NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;
|
||||
|
||||
|
@ -280,9 +281,12 @@ extern PNTFS_GLOBAL_DATA NtfsGlobalData;
|
|||
|
||||
/* attrib.c */
|
||||
|
||||
VOID
|
||||
BOOL
|
||||
NtfsDumpAttribute(PATTRIBUTE Attribute);
|
||||
|
||||
LONGLONG RunLCN(PUCHAR run);
|
||||
|
||||
ULONG RunLength(PUCHAR run);
|
||||
|
||||
/* blockdev.c */
|
||||
|
||||
|
@ -399,6 +403,42 @@ NtfsOpenMft(PDEVICE_OBJECT DeviceObject,
|
|||
PDEVICE_EXTENSION Vcb);
|
||||
|
||||
|
||||
VOID ReadAttribute(PATTRIBUTE attr, PVOID buffer, PDEVICE_EXTENSION Vcb,
|
||||
PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
ULONG AttributeLength(PATTRIBUTE attr);
|
||||
|
||||
VOID ReadFileRecord(ULONG index, PFILE_RECORD_HEADER file,
|
||||
PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER Mft,
|
||||
PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
|
||||
PATTRIBUTE FindAttribute(PFILE_RECORD_HEADER file,
|
||||
|
||||
ATTRIBUTE_TYPE type, PWSTR name);
|
||||
|
||||
|
||||
ULONG AttributeLengthAllocated(PATTRIBUTE attr);
|
||||
|
||||
VOID ReadVCN(PFILE_RECORD_HEADER file, ATTRIBUTE_TYPE type,
|
||||
ULONGLONG vcn, ULONG count, PVOID buffer,
|
||||
PDEVICE_EXTENSION Vcb, PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
|
||||
VOID FixupUpdateSequenceArray(PFILE_RECORD_HEADER file);
|
||||
|
||||
VOID ReadExternalAttribute(PNONRESIDENT_ATTRIBUTE NresAttr,
|
||||
ULONGLONG vcn, ULONG count, PVOID buffer,
|
||||
PDEVICE_EXTENSION Vcb,
|
||||
PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
VOID ReadLCN(ULONGLONG lcn, ULONG count, PVOID buffer, PDEVICE_EXTENSION Vcb,
|
||||
PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
|
||||
VOID EnumerAttribute(PFILE_RECORD_HEADER file,PDEVICE_EXTENSION Vcb,
|
||||
PDEVICE_OBJECT DeviceObject );
|
||||
|
||||
#if 0
|
||||
/* misc.c */
|
||||
|
||||
|
|
Loading…
Reference in a new issue