Dump the first MFT cluster and some file attributes.

svn path=/trunk/; revision=3230
This commit is contained in:
Eric Kohl 2002-07-15 15:37:33 +00:00
parent d34f38d43f
commit 3886e2f66b
5 changed files with 470 additions and 15 deletions

View file

@ -0,0 +1,217 @@
/*
* ReactOS kernel
* Copyright (C) 2002 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* 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.1 2002/07/15 15:37:33 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ntfs/attrib.c
* PURPOSE: NTFS filesystem driver
* PROGRAMMER: Eric Kohl
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
//#define NDEBUG
#include <debug.h>
#include "ntfs.h"
/* FUNCTIONS ****************************************************************/
VOID
NtfsDumpAttribute(PATTRIBUTE Attribute)
{
PNONRESIDENT_ATTRIBUTE NresAttr;
PRESIDENT_ATTRIBUTE ResAttr;
UNICODE_STRING Name;
PUCHAR Ptr;
UCHAR RunHeader;
ULONG RunLength;
ULONG RunStart;
switch (Attribute->AttributeType)
{
case AttributeStandardInformation:
DbgPrint(" $STANDARD_INFORMATION ");
break;
case AttributeAttributeList:
DbgPrint(" $ATTRIBUTE_LIST ");
break;
case AttributeFileName:
DbgPrint(" $FILE_NAME ");
break;
case AttributeObjectId:
DbgPrint(" $OBJECT_ID ");
break;
case AttributeSecurityDescriptor:
DbgPrint(" $SECURITY_DESCRIPTOR ");
break;
case AttributeVolumeName:
DbgPrint(" $VOLUME_NAME ");
break;
case AttributeVolumeInformation:
DbgPrint(" $VOLUME_INFORMATION ");
break;
case AttributeData:
DbgPrint(" $DATA ");
break;
case AttributeIndexRoot:
DbgPrint(" $INDEX_ROOT ");
break;
case AttributeIndexAllocation:
DbgPrint(" $INDEX_ALLOCATION ");
break;
case AttributeBitmap:
DbgPrint(" $BITMAP ");
break;
case AttributeReparsePoint:
DbgPrint(" $REPARSE_POINT ");
break;
case AttributeEAInformation:
DbgPrint(" $EA_INFORMATION ");
break;
case AttributeEA:
DbgPrint(" $EA ");
break;
case AttributePropertySet:
DbgPrint(" $PROPERTY_SET ");
break;
case AttributeLoggedUtilityStream:
DbgPrint(" $LOGGED_UTILITY_STREAM ");
break;
default:
DbgPrint(" Attribute %lx ",
Attribute->AttributeType);
break;
}
if (Attribute->NameLength != 0)
{
Name.Length = Attribute->NameLength * sizeof(WCHAR);
Name.MaximumLength = Name.Length;
Name.Buffer = (PWCHAR)((ULONG)Attribute + Attribute->NameOffset);
DbgPrint("'%wZ' ", &Name);
}
DbgPrint("(%s)\n",
Attribute->Nonresident ? "nonresident" : "resident");
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);
}
}
}
}
/* EOF */

View file

@ -16,7 +16,7 @@
* 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.1 2002/06/25 22:23:06 ekohl Exp $
/* $Id: fsctl.c,v 1.2 2002/07/15 15:37:33 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -119,7 +119,7 @@ NtfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
PDEVICE_EXTENSION Vcb)
{
DISK_GEOMETRY DiskGeometry;
PUCHAR Buffer;
// PUCHAR Buffer;
ULONG Size;
NTSTATUS Status;
PBOOT_SECTOR BootSector;
@ -160,8 +160,8 @@ NtfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
Vcb->NtfsInfo.BytesPerCluster = BootSector->BytesPerSector * BootSector->SectorsPerCluster;
Vcb->NtfsInfo.SectorCount = BootSector->SectorCount;
Vcb->NtfsInfo.MftStart = BootSector->MftLocation;
Vcb->NtfsInfo.MftMirrStart = BootSector->MftMirrLocation;
Vcb->NtfsInfo.MftStart.QuadPart = BootSector->MftLocation;
Vcb->NtfsInfo.MftMirrStart.QuadPart = BootSector->MftMirrLocation;
Vcb->NtfsInfo.SerialNumber = BootSector->SerialNumber;
//#indef NDEBUG
@ -179,9 +179,12 @@ NtfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
DbgPrint(" SerialNumber: %I64x\n", BootSector->SerialNumber);
//#endif
NtfsOpenMft(DeviceObject, Vcb);
}
ExFreePool(Buffer);
ExFreePool(BootSector);
return(Status);
}

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.1 2002/06/25 22:23:06 ekohl Exp $
# $Id: makefile,v 1.2 2002/07/15 15:37:33 ekohl Exp $
PATH_TO_TOP = ../../..
@ -6,8 +6,8 @@ TARGET_TYPE = driver
TARGET_NAME = ntfs
TARGET_OBJECTS = $(TARGET_NAME).o blockdev.o create.o dirctl.o fcb.o finfo.o \
fsctl.o volinfo.o
TARGET_OBJECTS = $(TARGET_NAME).o attrib.o blockdev.o create.o dirctl.o \
fcb.o finfo.o fsctl.o mft.o volinfo.o
include $(PATH_TO_TOP)/rules.mak

View file

@ -0,0 +1,100 @@
/*
* ReactOS kernel
* Copyright (C) 2002 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* 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 $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ntfs/mft.c
* PURPOSE: NTFS filesystem driver
* PROGRAMMER: Eric Kohl
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
//#define NDEBUG
#include <debug.h>
#include "ntfs.h"
/* FUNCTIONS ****************************************************************/
NTSTATUS
NtfsOpenMft(PDEVICE_OBJECT DeviceObject,
PDEVICE_EXTENSION Vcb)
{
PVOID Buffer;
PFILE_RECORD_HEADER RecordHeader;
PATTRIBUTE Attribute;
NTSTATUS Status;
DPRINT1("NtfsOpenMft() called\n");
Buffer = ExAllocatePool(NonPagedPool,
Vcb->NtfsInfo.BytesPerCluster);
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,
Vcb->NtfsInfo.BytesPerSector,
(PVOID)Buffer);
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);
/* Enumerate attributes */
Attribute = (PATTRIBUTE)((ULONG)RecordHeader +
RecordHeader->Ntfs.UsnOffset +
RecordHeader->Ntfs.UsnSize * sizeof(USHORT));
while (Attribute->AttributeType != 0xFFFFFFFF)
{
NtfsDumpAttribute(Attribute);
Attribute = (PATTRIBUTE)((ULONG)Attribute + Attribute->Length);
}
RecordHeader = (PFILE_RECORD_HEADER)((ULONG)RecordHeader + RecordHeader->BytesAllocated);
}
}
ExFreePool(Buffer);
return(Status);
}
/* EOF */

View file

@ -47,8 +47,8 @@ typedef struct _NTFS_INFO
ULONG SectorsPerCluster;
ULONG BytesPerCluster;
ULONGLONG SectorCount;
ULONGLONG MftStart;
ULONGLONG MftMirrStart;
ULARGE_INTEGER MftStart;
ULARGE_INTEGER MftMirrStart;
ULONGLONG SerialNumber;
} NTFS_INFO, *PNTFS_INFO;
@ -122,8 +122,6 @@ typedef struct _CCB
#define TAG_CCB TAG('I', 'C', 'C', 'B')
typedef struct
{
PDRIVER_OBJECT DriverObject;
@ -131,15 +129,145 @@ typedef struct
ULONG Flags;
} NTFS_GLOBAL_DATA, *PNTFS_GLOBAL_DATA;
typedef enum
{
AttributeStandardInformation = 0x10,
AttributeAttributeList = 0x20,
AttributeFileName = 0x30,
AttributeObjectId = 0x40,
AttributeSecurityDescriptor = 0x50,
AttributeVolumeName = 0x60,
AttributeVolumeInformation = 0x70,
AttributeData = 0x80,
AttributeIndexRoot = 0x90,
AttributeIndexAllocation = 0xA0,
AttributeBitmap = 0xB0,
AttributeReparsePoint = 0xC0,
AttributeEAInformation = 0xD0,
AttributeEA = 0xE0,
AttributePropertySet = 0xF0,
AttributeLoggedUtilityStream = 0x100
} ATTRIBUTE_TYPE, *PATTRIBUTE_TYPE;
typedef struct
{
ULONG Type;
USHORT UsnOffset;
USHORT UsnSize;
ULONGLONG Usn;
} NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;
typedef struct
{
NTFS_RECORD_HEADER Ntfs;
USHORT SequenceNumber;
USHORT LinkCount;
USHORT AttributeOffset;
USHORT Flags;
ULONG BytesInUse;
ULONG BytesAllocated;
ULONGLONG BaseFileRecord;
USHORT NextAttributeNumber;
} FILE_RECORD_HEADER, *PFILE_RECORD_HEADER;
typedef struct
{
ATTRIBUTE_TYPE AttributeType;
ULONG Length;
BOOLEAN Nonresident;
UCHAR NameLength;
USHORT NameOffset;
USHORT Flags;
USHORT AttributeNumber;
} ATTRIBUTE, *PATTRIBUTE;
typedef struct
{
ATTRIBUTE Attribute;
ULONG ValueLength;
USHORT ValueOffset;
UCHAR Flags;
// UCHAR Padding0;
} RESIDENT_ATTRIBUTE, *PRESIDENT_ATTRIBUTE;
typedef struct
{
ATTRIBUTE Attribute;
ULONGLONG StartVcn; // LowVcn
ULONGLONG LastVcn; // HighVcn
USHORT RunArrayOffset;
USHORT CompressionUnit;
ULONG Padding0;
UCHAR IndexedFlag;
ULONGLONG AllocatedSize;
ULONGLONG DataSize;
ULONGLONG InitializedSize;
ULONGLONG CompressedSize;
} NONRESIDENT_ATTRIBUTE, *PNONRESIDENT_ATTRIBUTE;
typedef struct
{
ULONGLONG CreationTime;
ULONGLONG ChangeTime;
ULONGLONG LastWriteTime;
ULONGLONG LastAccessTime;
ULONG FileAttribute;
ULONG AlignmentOrReserved[3];
#if 0
ULONG QuotaId;
ULONG SecurityId;
ULONGLONG QuotaCharge;
USN Usn;
#endif
} STANDARD_INFORMATION, *PSTANDARD_INFORMATION;
typedef struct
{
ATTRIBUTE_TYPE AttributeType;
USHORT Length;
UCHAR NameLength;
UCHAR NameOffset;
ULONGLONG StartVcn; // LowVcn
ULONGLONG FileReferenceNumber;
USHORT AttributeNumber;
USHORT AlignmentOrReserved[3];
} ATTRIBUTE_LIST, *PATTRIBUTE_LIST;
typedef struct
{
ULONGLONG DirectoryFileReferenceNumber;
ULONGLONG CreationTime;
ULONGLONG ChangeTime;
ULONGLONG LastWriteTime;
ULONGLONG LastAccessTime;
ULONGLONG AllocatedSize;
ULONGLONG DataSize;
ULONG FileAttributes;
ULONG AlignmentOrReserved;
UCHAR NameLength;
UCHAR NameType;
WCHAR Name[1];
} FILENAME_ATTRIBUTE, *PFILENAME_ATTRIBUTE;
extern PNTFS_GLOBAL_DATA NtfsGlobalData;
//int CdfsStrcmpi( wchar_t *str1, wchar_t *str2 );
//void CdfsWstrcpy( wchar_t *str1, wchar_t *str2, int max );
/* attrib.c */
VOID
NtfsDumpAttribute(PATTRIBUTE Attribute);
/* blockdev.c */
NTSTATUS
@ -251,6 +379,13 @@ NTSTATUS STDCALL
NtfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
/* mft.c */
NTSTATUS
NtfsOpenMft(PDEVICE_OBJECT DeviceObject,
PDEVICE_EXTENSION Vcb);
#if 0
/* misc.c */