mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Dump the first MFT cluster and some file attributes.
svn path=/trunk/; revision=3230
This commit is contained in:
parent
d34f38d43f
commit
3886e2f66b
5 changed files with 470 additions and 15 deletions
217
reactos/drivers/fs/ntfs/attrib.c
Normal file
217
reactos/drivers/fs/ntfs/attrib.c
Normal 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 */
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
100
reactos/drivers/fs/ntfs/mft.c
Normal file
100
reactos/drivers/fs/ntfs/mft.c
Normal 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 */
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue