From c9a794eb0ed7571cbfd24ad9d439607506e915e7 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 12 Nov 2003 15:30:21 +0000 Subject: [PATCH] - Cleaned up some of the mess that was caused by a previous patch - Support verify override - Read volume name svn path=/trunk/; revision=6629 --- reactos/drivers/fs/ntfs/attrib.c | 119 +++++--- reactos/drivers/fs/ntfs/blockdev.c | 151 ++-------- reactos/drivers/fs/ntfs/fsctl.c | 328 +++++++++++---------- reactos/drivers/fs/ntfs/mft.c | 458 +++++++++++------------------ reactos/drivers/fs/ntfs/ntfs.h | 107 ++++--- reactos/drivers/fs/ntfs/volinfo.c | 31 +- 6 files changed, 548 insertions(+), 646 deletions(-) diff --git a/reactos/drivers/fs/ntfs/attrib.c b/reactos/drivers/fs/ntfs/attrib.c index efff474cc36..15f63cb555d 100644 --- a/reactos/drivers/fs/ntfs/attrib.c +++ b/reactos/drivers/fs/ntfs/attrib.c @@ -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: attrib.c,v 1.6 2003/09/15 16:01:16 ea Exp $ +/* $Id: attrib.c,v 1.7 2003/11/12 15:30:21 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -32,7 +32,7 @@ #include -//#define NDEBUG +#define NDEBUG #include #include "ntfs.h" @@ -42,17 +42,19 @@ -ULONG RunLength(PUCHAR run) +ULONG +RunLength(PUCHAR run) { return(*run & 0x0f) + ((*run >> 4) & 0x0f) + 1; } -LONGLONG RunLCN(PUCHAR run) +LONGLONG +RunLCN(PUCHAR run) { UCHAR n1 = *run & 0x0f; UCHAR n2 = (*run >> 4) & 0x0f; - LONGLONG lcn = n2 == 0 ? 0 : (CHAR)(run[n1 + n2]); + LONGLONG lcn = (n2 == 0) ? 0 : (CHAR)(run[n1 + n2]); LONG i = 0; for (i = n1 +n2 - 1; i > n1; i--) @@ -62,7 +64,8 @@ LONGLONG RunLCN(PUCHAR run) -ULONGLONG RunCount(PUCHAR run) +ULONGLONG +RunCount(PUCHAR run) { UCHAR n = *run & 0xf; ULONGLONG count = 0; @@ -74,13 +77,51 @@ ULONGLONG RunCount(PUCHAR run) } -VOID +BOOLEAN +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; +} + + +static 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 +131,7 @@ NtfsDumpFileNameAttribute(PATTRIBUTE Attribute) } -VOID +static VOID NtfsDumpVolumeNameAttribute(PATTRIBUTE Attribute) { PRESIDENT_ATTRIBUTE ResAttr; @@ -102,11 +143,11 @@ NtfsDumpVolumeNameAttribute(PATTRIBUTE Attribute) // DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset); VolumeName = (PWCHAR)((PVOID)ResAttr + ResAttr->ValueOffset); - DbgPrint(" '%.*S' ", ResAttr->ValueLength/2, VolumeName); + DbgPrint(" '%.*S' ", ResAttr->ValueLength / sizeof(WCHAR), VolumeName); } -VOID +static VOID NtfsDumpVolumeInformationAttribute(PATTRIBUTE Attribute) { PRESIDENT_ATTRIBUTE ResAttr; @@ -125,26 +166,22 @@ NtfsDumpVolumeInformationAttribute(PATTRIBUTE Attribute) } -BOOL -NtfsDumpAttribute(PATTRIBUTE Attribute) +static VOID +NtfsDumpAttribute (PATTRIBUTE Attribute) { PNONRESIDENT_ATTRIBUTE NresAttr; PRESIDENT_ATTRIBUTE ResAttr; UNICODE_STRING Name; - PUCHAR Ptr; - UCHAR RunHeader; - ULONG RunLength; - ULONG RunStart; - + + ULONGLONG lcn; + ULONGLONG runcount; switch (Attribute->AttributeType) { - - case AttributeFileName: + case AttributeFileName: NtfsDumpFileNameAttribute(Attribute); break; - - + case AttributeStandardInformation: DbgPrint(" $STANDARD_INFORMATION "); break; @@ -153,8 +190,6 @@ NtfsDumpAttribute(PATTRIBUTE Attribute) DbgPrint(" $ATTRIBUTE_LIST "); break; - - case AttributeObjectId: DbgPrint(" $OBJECT_ID "); break; @@ -225,25 +260,33 @@ NtfsDumpAttribute(PATTRIBUTE Attribute) DbgPrint("(%s)\n", Attribute->Nonresident ? "non-resident" : "resident"); - - - - if (Attribute->Nonresident != 0) + if (Attribute->Nonresident) { + NresAttr = (PNONRESIDENT_ATTRIBUTE)Attribute; - return TRUE; - } - - return FALSE; - - - - - - + FindRun (NresAttr,0,&lcn, &runcount); + DbgPrint (" AllocatedSize %I64u DataSize %I64u\n", + NresAttr->AllocatedSize, NresAttr->DataSize); + DbgPrint (" logical clusters: %I64u - %I64u\n", + lcn, lcn + runcount - 1); + } } +VOID +NtfsDumpFileAttributes (PFILE_RECORD_HEADER FileRecord) +{ + PATTRIBUTE Attribute; + + Attribute = (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset); + while (Attribute->AttributeType !=-1) + { + NtfsDumpAttribute (Attribute); + + Attribute = (PATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Length); + } +} + /* EOF */ diff --git a/reactos/drivers/fs/ntfs/blockdev.c b/reactos/drivers/fs/ntfs/blockdev.c index 72986ebbc28..1097adaca50 100644 --- a/reactos/drivers/fs/ntfs/blockdev.c +++ b/reactos/drivers/fs/ntfs/blockdev.c @@ -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: blockdev.c,v 1.1 2002/06/25 22:23:05 ekohl Exp $ +/* $Id: blockdev.c,v 1.2 2003/11/12 15:30:21 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -42,88 +42,8 @@ NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject, IN ULONG DiskSector, IN ULONG SectorCount, IN ULONG SectorSize, - IN OUT PUCHAR Buffer) -{ - IO_STATUS_BLOCK IoStatus; - LARGE_INTEGER Offset; - ULONG BlockSize; - KEVENT Event; - PIRP Irp; - NTSTATUS Status; - - KeInitializeEvent(&Event, - NotificationEvent, - FALSE); - - Offset.QuadPart = (LONGLONG)DiskSector * (LONGLONG)SectorSize; - BlockSize = SectorCount * SectorSize; - - DPRINT("NtfsReadSectors(DeviceObject %x, DiskSector %d, Buffer %x)\n", - DeviceObject, DiskSector, Buffer); - DPRINT("Offset %I64x BlockSize %ld\n", - Offset.QuadPart, - BlockSize); - - DPRINT("Building synchronous FSD Request...\n"); - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, - DeviceObject, - Buffer, - BlockSize, - &Offset, - &Event, - &IoStatus); - if (Irp == NULL) - { - DPRINT("IoBuildSynchronousFsdRequest failed\n"); - return(STATUS_INSUFFICIENT_RESOURCES); - } - - DPRINT("Calling IO Driver... with irp %x\n", Irp); - Status = IoCallDriver(DeviceObject, Irp); - - DPRINT("Waiting for IO Operation for %x\n", Irp); - if (Status == STATUS_PENDING) - { - DPRINT("Operation pending\n"); - KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); - DPRINT("Getting IO Status... for %x\n", Irp); - Status = IoStatus.Status; - } - - if (!NT_SUCCESS(Status)) - { - if (Status == STATUS_VERIFY_REQUIRED) - { - PDEVICE_OBJECT DeviceToVerify; - NTSTATUS NewStatus; - - DPRINT1("STATUS_VERIFY_REQUIRED\n"); - DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread()); - IoSetDeviceToVerify(PsGetCurrentThread(), NULL); - - NewStatus = IoVerifyVolume(DeviceToVerify, FALSE); - DPRINT1("IoVerifyVolume() retuned (Status %lx)\n", NewStatus); - } - - DPRINT("NtfsReadSectors() failed (Status %x)\n", Status); - DPRINT("(DeviceObject %x, DiskSector %x, Buffer %x, Offset 0x%I64x)\n", - DeviceObject, DiskSector, Buffer, - Offset.QuadPart); - return(Status); - } - - DPRINT("Block request succeeded for %x\n", Irp); - - return(STATUS_SUCCESS); -} - - -NTSTATUS -NtfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject, - IN ULONG DiskSector, - IN ULONG SectorCount, - IN ULONG SectorSize, - IN OUT PUCHAR Buffer) + IN OUT PUCHAR Buffer, + IN BOOLEAN Override) { PIO_STACK_LOCATION Stack; IO_STATUS_BLOCK IoStatus; @@ -157,11 +77,14 @@ NtfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject, if (Irp == NULL) { DPRINT("IoBuildSynchronousFsdRequest failed\n"); - return(STATUS_INSUFFICIENT_RESOURCES); + return STATUS_INSUFFICIENT_RESOURCES; } -// Stack = IoGetCurrentIrpStackLocation(Irp); -// Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME; + if (Override) + { + Stack = IoGetNextIrpStackLocation(Irp); + Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME; + } DPRINT("Calling IO Driver... with irp %x\n", Irp); Status = IoCallDriver(DeviceObject, Irp); @@ -175,18 +98,9 @@ NtfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject, Status = IoStatus.Status; } - if (!NT_SUCCESS(Status)) - { - DPRINT("NtfsReadSectors() failed (Status %x)\n", Status); - DPRINT("(DeviceObject %x, DiskSector %x, Buffer %x, Offset 0x%I64x)\n", - DeviceObject, DiskSector, Buffer, - Offset.QuadPart); - return(Status); - } + DPRINT("NtfsReadSectors() done (Status %x)\n", Status); - DPRINT("Block request succeeded for %x\n", Irp); - - return(STATUS_SUCCESS); + return Status; } @@ -196,26 +110,16 @@ NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer, - IN OUT PULONG OutputBufferSize) + IN OUT PULONG OutputBufferSize, + IN BOOLEAN Override) { - ULONG BufferSize = 0; - PKEVENT Event; - PIRP Irp; + PIO_STACK_LOCATION Stack; IO_STATUS_BLOCK IoStatus; + KEVENT Event; + PIRP Irp; NTSTATUS Status; - if (OutputBufferSize != NULL) - { - BufferSize = *OutputBufferSize; - } - - Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT)); - if (Event == NULL) - { - return(STATUS_INSUFFICIENT_RESOURCES); - } - - KeInitializeEvent(Event, NotificationEvent, FALSE); + KeInitializeEvent(&Event, NotificationEvent, FALSE); DPRINT("Building device I/O control request ...\n"); Irp = IoBuildDeviceIoControlRequest(ControlCode, @@ -223,33 +127,36 @@ NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, InputBuffer, InputBufferSize, OutputBuffer, - BufferSize, + (OutputBufferSize) ? *OutputBufferSize : 0, FALSE, - Event, + &Event, &IoStatus); if (Irp == NULL) { DPRINT("IoBuildDeviceIoControlRequest() failed\n"); - ExFreePool(Event); - return(STATUS_INSUFFICIENT_RESOURCES); + return STATUS_INSUFFICIENT_RESOURCES; + } + + if (Override) + { + Stack = IoGetNextIrpStackLocation(Irp); + Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME; } DPRINT("Calling IO Driver... with irp %x\n", Irp); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { - KeWaitForSingleObject(Event, Suspended, KernelMode, FALSE, NULL); + KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); Status = IoStatus.Status; } if (OutputBufferSize) { - *OutputBufferSize = BufferSize; + *OutputBufferSize = IoStatus.Information; } - ExFreePool(Event); - - return(Status); + return Status; } /* EOF */ diff --git a/reactos/drivers/fs/ntfs/fsctl.c b/reactos/drivers/fs/ntfs/fsctl.c index 036bb8bb5a4..737fda90c4f 100644 --- a/reactos/drivers/fs/ntfs/fsctl.c +++ b/reactos/drivers/fs/ntfs/fsctl.c @@ -16,19 +16,20 @@ * 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.8 2003/09/15 16:01:16 ea Exp $ +/* $Id: fsctl.c,v 1.9 2003/11/12 15:30:21 ekohl 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 + * Updated by Valentin Verkhovsky 2003/09/12 */ /* INCLUDES *****************************************************************/ #include +#include #define NDEBUG #include @@ -50,7 +51,7 @@ NtfsHasFileSystem(PDEVICE_OBJECT DeviceToMount) PBOOT_SECTOR BootSector; NTSTATUS Status; - DPRINT("NtfsHasFileSystem() called\n"); + DPRINT1("NtfsHasFileSystem() called\n"); Size = sizeof(DISK_GEOMETRY); Status = NtfsDeviceIoControl(DeviceToMount, @@ -58,10 +59,11 @@ NtfsHasFileSystem(PDEVICE_OBJECT DeviceToMount) NULL, 0, &DiskGeometry, - &Size); + &Size, + TRUE); if (!NT_SUCCESS(Status)) { - DPRINT("NtfsDeviceIoControl() failed (Status %lx)\n", Status); + DPRINT1("NtfsDeviceIoControl() failed (Status %lx)\n", Status); return(Status); } @@ -74,20 +76,22 @@ NtfsHasFileSystem(PDEVICE_OBJECT DeviceToMount) NULL, 0, &PartitionInfo, - &Size); + &Size, + TRUE); if (!NT_SUCCESS(Status)) { - DPRINT("NtfsDeviceIoControl() failed (Status %lx)\n", Status); + DPRINT1("NtfsDeviceIoControl() failed (Status %lx)\n", Status); return(Status); } if (PartitionInfo.PartitionType != PARTITION_IFS) { + DPRINT1("Invalid partition type\n"); return(STATUS_UNRECOGNIZED_VOLUME); } } - DPRINT("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector); + DPRINT1("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector); BootSector = ExAllocatePool(NonPagedPool, DiskGeometry.BytesPerSector); if (BootSector == NULL) @@ -95,14 +99,15 @@ NtfsHasFileSystem(PDEVICE_OBJECT DeviceToMount) return(STATUS_INSUFFICIENT_RESOURCES); } - Status = NtfsReadRawSectors(DeviceToMount, - 0, - 1, - DiskGeometry.BytesPerSector, - (PVOID)BootSector); + Status = NtfsReadSectors (DeviceToMount, + 0, + 1, + DiskGeometry.BytesPerSector, + (PVOID)BootSector, + TRUE); if (NT_SUCCESS(Status)) { - DPRINT("NTFS-identifier: [%.8s]\n", BootSector->OemName); + DPRINT1("NTFS-identifier: [%.8s]\n", BootSector->OemName); if (strncmp(BootSector->OemName, "NTFS ", 8) != 0) { Status = STATUS_UNRECOGNIZED_VOLUME; @@ -117,13 +122,17 @@ NtfsHasFileSystem(PDEVICE_OBJECT DeviceToMount) static NTSTATUS NtfsGetVolumeData(PDEVICE_OBJECT DeviceObject, - PDEVICE_EXTENSION Vcb) + PNTFS_INFO NtfsInfo) { DISK_GEOMETRY DiskGeometry; -// PUCHAR Buffer; + PFILE_RECORD_HEADER MftRecord; + PFILE_RECORD_HEADER VolumeRecord; + PVOLINFO_ATTRIBUTE VolumeInfo; + PBOOT_SECTOR BootSector; + PATTRIBUTE Attribute; + ULONG FileRecordSize; ULONG Size; NTSTATUS Status; - PBOOT_SECTOR BootSector; DPRINT("NtfsGetVolumeData() called\n"); @@ -133,7 +142,8 @@ NtfsGetVolumeData(PDEVICE_OBJECT DeviceObject, NULL, 0, &DiskGeometry, - &Size); + &Size, + TRUE); if (!NT_SUCCESS(Status)) { DPRINT("NtfsDeviceIoControl() failed (Status %lx)\n", Status); @@ -148,49 +158,151 @@ NtfsGetVolumeData(PDEVICE_OBJECT DeviceObject, return(STATUS_INSUFFICIENT_RESOURCES); } - Status = NtfsReadRawSectors(DeviceObject, - 0, /* Partition boot sector */ - 1, - DiskGeometry.BytesPerSector, - (PVOID)BootSector); - if (NT_SUCCESS(Status)) + Status = NtfsReadSectors(DeviceObject, + 0, /* Partition boot sector */ + 1, + DiskGeometry.BytesPerSector, + (PVOID)BootSector, + TRUE); + if (!NT_SUCCESS(Status)) { - /* Read data from the bootsector */ - Vcb->NtfsInfo.BytesPerSector = BootSector->BytesPerSector; - Vcb->NtfsInfo.SectorsPerCluster = BootSector->SectorsPerCluster; - Vcb->NtfsInfo.BytesPerCluster = BootSector->BytesPerSector * BootSector->SectorsPerCluster; - Vcb->NtfsInfo.SectorCount = BootSector->SectorCount; - - 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"); - DbgPrint(" BytesPerSector: %hu\n", BootSector->BytesPerSector); - DbgPrint(" SectorsPerCluster: %hu\n", BootSector->SectorsPerCluster); - - DbgPrint(" SectorCount: %I64u\n", BootSector->SectorCount); - - DbgPrint(" MftStart: %I64u\n", BootSector->MftLocation); - DbgPrint(" MftMirrStart: %I64u\n", BootSector->MftMirrLocation); - - DbgPrint(" ClustersPerMftRecord: %lx\n", BootSector->ClustersPerMftRecord); - DbgPrint(" ClustersPerIndexRecord: %lx\n", BootSector->ClustersPerIndexRecord); - - DbgPrint(" SerialNumber: %I64x\n", BootSector->SerialNumber); -//#endif - - NtfsOpenMft(DeviceObject, Vcb); - + ExFreePool(BootSector); + return Status; } + /* Read data from the bootsector */ + NtfsInfo->BytesPerSector = BootSector->BytesPerSector; + NtfsInfo->SectorsPerCluster = BootSector->SectorsPerCluster; + NtfsInfo->BytesPerCluster = BootSector->BytesPerSector * BootSector->SectorsPerCluster; + NtfsInfo->SectorCount = BootSector->SectorCount; + + NtfsInfo->MftStart.QuadPart = BootSector->MftLocation; + NtfsInfo->MftMirrStart.QuadPart = BootSector->MftMirrLocation; + NtfsInfo->SerialNumber = BootSector->SerialNumber; + NtfsInfo->ClustersPerFileRecord = BootSector->ClustersPerMftRecord; + +//#ifndef NDEBUG + DbgPrint("Boot sector information:\n"); + DbgPrint(" BytesPerSector: %hu\n", BootSector->BytesPerSector); + DbgPrint(" SectorsPerCluster: %hu\n", BootSector->SectorsPerCluster); + + DbgPrint(" SectorCount: %I64u\n", BootSector->SectorCount); + + DbgPrint(" MftStart: %I64u\n", BootSector->MftLocation); + DbgPrint(" MftMirrStart: %I64u\n", BootSector->MftMirrLocation); + + DbgPrint(" ClustersPerMftRecord: %lx\n", BootSector->ClustersPerMftRecord); + DbgPrint(" ClustersPerIndexRecord: %lx\n", BootSector->ClustersPerIndexRecord); + + DbgPrint(" SerialNumber: %I64x\n", BootSector->SerialNumber); +//#endif + ExFreePool(BootSector); - return(Status); -} + if (NtfsInfo->ClustersPerFileRecord == 0xF6) + FileRecordSize = NtfsInfo->ClustersPerFileRecord * NtfsInfo->BytesPerCluster; + else + FileRecordSize = NtfsInfo->BytesPerCluster; + MftRecord = ExAllocatePool(NonPagedPool, + FileRecordSize); + if (MftRecord == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + Status = NtfsReadSectors(DeviceObject, + NtfsInfo->MftStart.u.LowPart * NtfsInfo->SectorsPerCluster, + FileRecordSize / NtfsInfo->BytesPerSector, + NtfsInfo->BytesPerSector, + (PVOID)MftRecord, + TRUE); + if (!NT_SUCCESS(Status)) + { + ExFreePool (MftRecord); + return Status; + } + + if (NtfsInfo->ClustersPerFileRecord == 0xF6) + { + VolumeRecord = (PVOID)((ULONG_PTR)MftRecord + 3 * (NtfsInfo->BytesPerCluster / 4)); + } + else + { + VolumeRecord = ExAllocatePool(NonPagedPool, + FileRecordSize); + if (VolumeRecord == NULL) + { + ExFreePool (MftRecord); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Read cluster MftStart + 3 (Volume File) */ + Status = NtfsReadSectors(DeviceObject, + (NtfsInfo->MftStart.u.LowPart + 3) * NtfsInfo->SectorsPerCluster, + FileRecordSize / NtfsInfo->BytesPerSector, + NtfsInfo->BytesPerSector, + (PVOID)VolumeRecord, + TRUE); + if (!NT_SUCCESS(Status)) + { + ExFreePool (MftRecord); + return Status; + } + } + +#ifndef NDEBUG + DbgPrint("\n\n"); + /* Enumerate attributes */ + NtfsDumpFileAttributes (MftRecord); + DbgPrint("\n\n"); + + DbgPrint("\n\n"); + /* Enumerate attributes */ + NtfsDumpFileAttributes (VolumeRecord); + DbgPrint("\n\n"); +#endif + + /* Get volume name */ + Attribute = FindAttribute (VolumeRecord, AttributeVolumeName, NULL); + DPRINT("Attribute %p\n", Attribute); + DPRINT("Data length %lu\n", AttributeDataLength (Attribute)); + + if (Attribute != NULL && ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength != 0) + { + NtfsInfo->VolumeLabelLength = + min (((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength, MAXIMUM_VOLUME_LABEL_LENGTH); + RtlCopyMemory (NtfsInfo->VolumeLabel, + (PVOID)((ULONG_PTR)Attribute + ((PRESIDENT_ATTRIBUTE)Attribute)->ValueOffset), + NtfsInfo->VolumeLabelLength); + } + else + { + NtfsInfo->VolumeLabelLength = 0; + } + + /* Get volume information */ + Attribute = FindAttribute (VolumeRecord, AttributeVolumeInformation, NULL); + DPRINT("Attribute %p\n", Attribute); + DPRINT("Data length %lu\n", AttributeDataLength (Attribute)); + + if (Attribute != NULL && ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength != 0) + { + VolumeInfo = (PVOID)((ULONG_PTR)Attribute + ((PRESIDENT_ATTRIBUTE)Attribute)->ValueOffset); + + NtfsInfo->MajorVersion = VolumeInfo->MajorVersion; + NtfsInfo->MinorVersion = VolumeInfo->MinorVersion; + NtfsInfo->Flags = VolumeInfo->Flags; + } + + if (NtfsInfo->ClustersPerFileRecord != 0xF6) + { + ExFreePool (VolumeRecord); + } + ExFreePool (MftRecord); + + return Status; +} static NTSTATUS @@ -206,7 +318,7 @@ NtfsMountVolume(PDEVICE_OBJECT DeviceObject, PVPB Vpb; NTSTATUS Status; - DPRINT("NtfsMountVolume() called\n"); + DPRINT1("NtfsMountVolume() called\n"); if (DeviceObject != NtfsGlobalData->DeviceObject) { @@ -241,7 +353,7 @@ NtfsMountVolume(PDEVICE_OBJECT DeviceObject, sizeof(DEVICE_EXTENSION)); Status = NtfsGetVolumeData(DeviceToMount, - DeviceExt); + &DeviceExt->NtfsInfo); if (!NT_SUCCESS(Status)) goto ByeBye; @@ -309,12 +421,14 @@ NtfsMountVolume(PDEVICE_OBJECT DeviceObject, KeInitializeSpinLock(&DeviceExt->FcbListLock); InitializeListHead(&DeviceExt->FcbListHead); - /* Read serial number */ + /* Get serial number */ NewDeviceObject->Vpb->SerialNumber = DeviceExt->NtfsInfo.SerialNumber; - /* Read volume label */ -// NtfsReadVolumeLabel(DeviceExt, -// NewDeviceObject->Vpb); + /* Get volume label */ + NewDeviceObject->Vpb->VolumeLabelLength = DeviceExt->NtfsInfo.VolumeLabelLength; + RtlCopyMemory (NewDeviceObject->Vpb->VolumeLabel, + DeviceExt->NtfsInfo.VolumeLabel, + DeviceExt->NtfsInfo.VolumeLabelLength); Status = STATUS_SUCCESS; @@ -334,7 +448,7 @@ ByeBye: DPRINT("NtfsMountVolume() done (Status: %lx)\n", Status); - return(Status); + return Status; } @@ -342,95 +456,9 @@ static NTSTATUS NtfsVerifyVolume(PDEVICE_OBJECT DeviceObject, PIRP Irp) { -#if 0 - PDEVICE_OBJECT DeviceToVerify; - PIO_STACK_LOCATION Stack; - PUCHAR Buffer; - ULONG Sector; - ULONG i; - NTSTATUS Status; - - union - { - ULONG Value; - UCHAR Part[4]; - } Serial; -#endif - DPRINT1("NtfsVerifyVolume() called\n"); -#if 0 - Stack = IoGetCurrentIrpStackLocation(Irp); - DeviceToVerify = Stack->Parameters.VerifyVolume.DeviceObject; - - DPRINT("Device object %p Device to verify %p\n", DeviceObject, DeviceToVerify); - - Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION; - - Buffer = ExAllocatePool(NonPagedPool, - CDFS_BASIC_SECTOR); - if (Buffer == NULL) - { - return(STATUS_INSUFFICIENT_RESOURCES); - } - - do - { - /* Read the Primary Volume Descriptor (PVD) */ - Status = CdfsReadRawSectors(DeviceToVerify, - Sector, - 1, - Buffer); - DPRINT("CdfsReadRawSectors() status %lx\n", Status); - if (!NT_SUCCESS(Status)) - { - goto ByeBye; - } - - if (Buffer[0] == 1 && - Buffer[1] == 'C' && - Buffer[2] == 'D' && - Buffer[3] == '0' && - Buffer[4] == '0' && - Buffer[5] == '1') - { - break; - } - - Sector++; - } - while (Buffer[0] != 255); - - if (Buffer[0] == 255) - goto ByeBye; - - Status = STATUS_WRONG_VOLUME; - - /* Calculate the volume serial number */ - Serial.Value = 0; - for (i = 0; i < 2048; i += 4) - { - /* DON'T optimize this to ULONG!!! (breaks overflow) */ - Serial.Part[0] += Buffer[i+3]; - Serial.Part[1] += Buffer[i+2]; - Serial.Part[2] += Buffer[i+1]; - Serial.Part[3] += Buffer[i+0]; - } - - DPRINT("Current serial number %08lx Vpb serial number %08lx\n", - Serial.Value, DeviceToVerify->Vpb->SerialNumber); - - if (Serial.Value == DeviceToVerify->Vpb->SerialNumber) - Status = STATUS_SUCCESS; - -ByeBye: - ExFreePool(Buffer); - - DPRINT("CdfsVerifyVolume() done (Status: %lx)\n", Status); - - return(Status); -#endif - return(STATUS_UNSUCCESSFUL); + return STATUS_WRONG_VOLUME; } @@ -441,7 +469,7 @@ NtfsFileSystemControl(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION Stack; NTSTATUS Status; - DPRINT("NtfsFileSystemControl() called\n"); + DPRINT1("NtfsFileSystemControl() called\n"); Stack = IoGetCurrentIrpStackLocation(Irp); diff --git a/reactos/drivers/fs/ntfs/mft.c b/reactos/drivers/fs/ntfs/mft.c index ac21419dfcc..78aaaa888e8 100644 --- a/reactos/drivers/fs/ntfs/mft.c +++ b/reactos/drivers/fs/ntfs/mft.c @@ -16,19 +16,20 @@ * 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.2 2003/09/15 16:01:16 ea Exp $ +/* $Id: mft.c,v 1.3 2003/11/12 15:30:21 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 - * Updated by Valentin Verkhovsky 2003/09/12 + * PROGRAMMER: Eric Kohl + * Updated by Valentin Verkhovsky 2003/09/12 */ /* INCLUDES *****************************************************************/ #include +#include //#define NDEBUG #include @@ -36,306 +37,236 @@ #include "ntfs.h" -#define __min(a,b) (((a) < (b)) ? (a) : (b)) +//#define __min(a,b) (((a) < (b)) ? (a) : (b)) /* FUNCTIONS ****************************************************************/ NTSTATUS -NtfsOpenMft(PDEVICE_OBJECT DeviceObject, - PDEVICE_EXTENSION Vcb) +NtfsOpenMft (PDEVICE_EXTENSION Vcb) { - PVOID Buffer; - PVOID Bitmap; +// PVOID Bitmap; PFILE_RECORD_HEADER MftRecord; - PFILE_RECORD_HEADER file; - PATTRIBUTE Attribute; - PATTRIBUTE AttrData; - PRESIDENT_ATTRIBUTE ResAttr; + PFILE_RECORD_HEADER FileRecord; +// PATTRIBUTE Attribute; +// PATTRIBUTE AttrData; +// PRESIDENT_ATTRIBUTE ResAttr; NTSTATUS Status; - ULONG BytesPerFileRecord; - DPRINT1("NtfsOpenMft() called\n"); - ULONG n = 0; + ULONG BytesPerFileRecord; + ULONG n; + ULONG i; - BytesPerFileRecord = Vcb->NtfsInfo.ClustersPerFileRecord * - Vcb->NtfsInfo.BytesPerCluster; - - Buffer = ExAllocatePool(NonPagedPool, - BytesPerFileRecord); - if (Buffer == NULL) + DPRINT1("NtfsOpenMft() called\n"); + + BytesPerFileRecord = + Vcb->NtfsInfo.ClustersPerFileRecord * Vcb->NtfsInfo.BytesPerCluster; + + MftRecord = ExAllocatePool(NonPagedPool, + BytesPerFileRecord); + if (MftRecord == NULL) { + return STATUS_INSUFFICIENT_RESOURCES; + } + + Status = NtfsReadSectors(Vcb->StorageDevice, + Vcb->NtfsInfo.MftStart.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster, + BytesPerFileRecord / Vcb->NtfsInfo.BytesPerSector, + Vcb->NtfsInfo.BytesPerSector, + (PVOID)MftRecord, + FALSE); + if (!NT_SUCCESS(Status)) + { + ExFreePool(MftRecord); + return Status; + } + + + FixupUpdateSequenceArray(MftRecord); + +// Attribute = FindAttribute(MftRecord, AttributeBitmap, 0); + + /* Get number of file records*/ + n = AttributeDataLength (FindAttribute (MftRecord, AttributeData, 0)) + / BytesPerFileRecord; + + FileRecord = ExAllocatePool(NonPagedPool, BytesPerFileRecord); + if (FileRecord == NULL) + { + ExFreePool(MftRecord); return(STATUS_INSUFFICIENT_RESOURCES); } - - - Status = NtfsReadRawSectors(DeviceObject, - Vcb->NtfsInfo.MftStart.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster, - BytesPerFileRecord / Vcb->NtfsInfo.BytesPerSector, - Vcb->NtfsInfo.BytesPerSector, - (PVOID)Buffer); - - if (NT_SUCCESS(Status)) + /* Enumerate MFT Records */ + DPRINT("Enumerate MFT records\n"); + for ( i=0; i < n; i++) { - - DbgPrint("Enumerate MFT \n"); - MftRecord = Buffer; + ReadFileRecord(Vcb, i, FileRecord, MftRecord); - 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 */ + if (FileRecord->Ntfs.Type == NRH_FILE_TYPE && (FileRecord->Flags & FRH_IN_USE)) + { + DPRINT("\nFile %lu\n\n", i); - EnumerAttribute(file, Vcb, DeviceObject); - DbgPrint("\n"); - DbgPrint("\n"); - - - } + /* Enumerate attributtes */ + NtfsDumpFileAttributes (FileRecord); + DbgPrint("\n\n"); + } + } - } + ExFreePool(FileRecord); + ExFreePool(MftRecord); - - - } - - ExFreePool(Buffer); - - ExFreePool(file); - - - return(Status); + return Status; } -PATTRIBUTE FindAttribute(PFILE_RECORD_HEADER file, - ATTRIBUTE_TYPE type, PWSTR name) +PATTRIBUTE +FindAttribute (PFILE_RECORD_HEADER FileRecord, + ATTRIBUTE_TYPE Type, + PWSTR name) { - PATTRIBUTE attr = (PATTRIBUTE)((PVOID)file + file->AttributeOffset); - - while (attr->AttributeType !=-1) + PATTRIBUTE Attribute; + + Attribute = (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset); + while (Attribute->AttributeType != -1) + { + if (Attribute->AttributeType == Type) { - - if(attr->AttributeType == type) { - return attr; - } - attr = (PATTRIBUTE)((ULONG)attr + attr->Length); + return Attribute; } - return 0; + Attribute = (PATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Length); + } + + return NULL; } -ULONG AttributeLengthAllocated(PATTRIBUTE attr) +ULONG +AttributeAllocatedLength (PATTRIBUTE Attribute) { - - 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; - } - + if (Attribute->Nonresident) + { + return ((PNONRESIDENT_ATTRIBUTE)Attribute)->AllocatedSize; + } + return ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength; } -VOID ReadAttribute(PATTRIBUTE attr, PVOID buffer, PDEVICE_EXTENSION Vcb, - PDEVICE_OBJECT DeviceObject) + +ULONG +AttributeDataLength (PATTRIBUTE Attribute) { - if(attr->Nonresident == FALSE) - { - PRESIDENT_ATTRIBUTE ResAttr = (PRESIDENT_ATTRIBUTE)attr; - memcpy(buffer, (PRESIDENT_ATTRIBUTE)((PVOID)ResAttr + ResAttr->ValueOffset), - ResAttr->ValueLength); + if (Attribute->Nonresident) + { + return ((PNONRESIDENT_ATTRIBUTE)Attribute)->DataSize; + } - - } - - - PNONRESIDENT_ATTRIBUTE NresAttr = (PNONRESIDENT_ATTRIBUTE)attr; - ReadExternalAttribute(NresAttr, 0, (ULONG)(NresAttr->LastVcn) + 1, - buffer, Vcb, DeviceObject); - + return ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength; +} +VOID +ReadAttribute (PATTRIBUTE attr, + PVOID buffer, + PDEVICE_EXTENSION Vcb, + PDEVICE_OBJECT DeviceObject) +{ + if (attr->Nonresident == FALSE) + { + memcpy (buffer, + (PVOID)((ULONG_PTR)attr + ((PRESIDENT_ATTRIBUTE)attr)->ValueOffset), + ((PRESIDENT_ATTRIBUTE)attr)->ValueLength); + } + PNONRESIDENT_ATTRIBUTE NresAttr = (PNONRESIDENT_ATTRIBUTE)attr; + ReadExternalAttribute(Vcb, NresAttr, 0, (ULONG)(NresAttr->LastVcn) + 1, + buffer); } -ULONG AttributeLength(PATTRIBUTE attr) + + +VOID +ReadFileRecord (PDEVICE_EXTENSION Vcb, + ULONG index, + PFILE_RECORD_HEADER file, + PFILE_RECORD_HEADER Mft) { - PRESIDENT_ATTRIBUTE ResAttr; - PNONRESIDENT_ATTRIBUTE NresAttr; - - if(attr->Nonresident == FALSE) - { - ResAttr = (PRESIDENT_ATTRIBUTE)attr; - return ResAttr->ValueLength; - } + PVOID p; + ULONG clusters = Vcb->NtfsInfo.ClustersPerFileRecord; + ULONG BytesPerFileRecord = clusters * Vcb->NtfsInfo.BytesPerCluster; - else - { - NresAttr = (PNONRESIDENT_ATTRIBUTE)attr; - return NresAttr->DataSize; - } + p = ExAllocatePool(NonPagedPool, BytesPerFileRecord); + + ULONGLONG vcn = index * BytesPerFileRecord / Vcb->NtfsInfo.BytesPerCluster; + + ReadVCN (Vcb, Mft, AttributeData, vcn, clusters, p); + + 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 ReadFileRecord(ULONG index, PFILE_RECORD_HEADER file, - PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER Mft, - PDEVICE_OBJECT DeviceObject) - +VOID +ReadExternalAttribute (PDEVICE_EXTENSION Vcb, + PNONRESIDENT_ATTRIBUTE NresAttr, + ULONGLONG vcn, + ULONG count, + PVOID buffer) { - - 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; + ULONGLONG lcn; + ULONGLONG runcount; + ULONG readcount; + ULONG left; PUCHAR bytes = (PUCHAR)buffer; - for (left = count; left>0; left -=readcount) - { + for (left = count; left>0; left -=readcount) + { FindRun(NresAttr, vcn, &lcn, &runcount); - readcount = (ULONG)(__min(runcount, left)); +// readcount = (ULONG)(__min(runcount, left)); + 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); + ReadLCN(Vcb, lcn, readcount, bytes); vcn += readcount; bytes += n; - } - - + } } -BOOL FindRun(PNONRESIDENT_ATTRIBUTE NresAttr, ULONGLONG vcn, - PULONGLONG lcn, PULONGLONG count) +VOID +ReadVCN (PDEVICE_EXTENSION Vcb, + PFILE_RECORD_HEADER file, + ATTRIBUTE_TYPE type, + ULONGLONG vcn, + ULONG count, + PVOID buffer) { - 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); + attr = FindAttribute(file, type, 0); NresAttr = (PNONRESIDENT_ATTRIBUTE) attr; @@ -347,11 +278,10 @@ VOID ReadVCN(PFILE_RECORD_HEADER file, ATTRIBUTE_TYPE type, //KeDebugCheck(0); } - ReadExternalAttribute(NresAttr, vcn, count, buffer, Vcb, DeviceObject); - - + ReadExternalAttribute(Vcb, NresAttr, vcn, count, buffer); } + BOOL bitset(PUCHAR bitmap, ULONG i) { return (bitmap[i>>3] & (1 << (i & 7))) !=0; @@ -374,52 +304,22 @@ VOID FixupUpdateSequenceArray(PFILE_RECORD_HEADER file) } -VOID ReadLCN(ULONGLONG lcn, ULONG count, PVOID buffer, PDEVICE_EXTENSION Vcb, - PDEVICE_OBJECT DeviceObject) +NTSTATUS +ReadLCN (PDEVICE_EXTENSION Vcb, + ULONGLONG lcn, + ULONG count, + PVOID buffer) { - - LARGE_INTEGER DiskSector; - DiskSector.QuadPart = lcn; - - - NtfsReadRawSectors(DeviceObject, DiskSector.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster, - count * Vcb->NtfsInfo.SectorsPerCluster, Vcb->NtfsInfo.BytesPerSector, buffer); + LARGE_INTEGER DiskSector; + + DiskSector.QuadPart = lcn; + + return NtfsReadSectors (Vcb->StorageDevice, + DiskSector.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster, + count * Vcb->NtfsInfo.SectorsPerCluster, + Vcb->NtfsInfo.BytesPerSector, + buffer, + FALSE); } - -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 */ +/* EOF */ diff --git a/reactos/drivers/fs/ntfs/ntfs.h b/reactos/drivers/fs/ntfs/ntfs.h index 2e21a0bdb98..fe6c585898f 100644 --- a/reactos/drivers/fs/ntfs/ntfs.h +++ b/reactos/drivers/fs/ntfs/ntfs.h @@ -49,9 +49,15 @@ typedef struct _NTFS_INFO ULONGLONG SectorCount; ULARGE_INTEGER MftStart; ULARGE_INTEGER MftMirrStart; - ULONGLONG SerialNumber; ULONG ClustersPerFileRecord; + ULONGLONG SerialNumber; + USHORT VolumeLabelLength; + WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH]; + UCHAR MajorVersion; + UCHAR MinorVersion; + USHORT Flags; + } NTFS_INFO, *PNTFS_INFO; @@ -155,10 +161,14 @@ typedef struct { ULONG Type; /* Magic number 'FILE' */ USHORT UsaOffset; /* Offset to the update sequence */ - USHORT UsaCount; /* Size in words of Update Sequence Number & Array (S) */ + USHORT UsaCount; /* Size in words of Update Sequence Number & Array (S) */ ULONGLONG Lsn; /* $LogFile Sequence Number (LSN) */ } NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER; +/* NTFS_RECORD_HEADER.Type */ +#define NRH_FILE_TYPE 0x454C4946 /* 'FILE' */ + + typedef struct { NTFS_RECORD_HEADER Ntfs; @@ -176,10 +186,10 @@ typedef struct /* Flags in FILE_RECORD_HEADER */ -#define FRH_IN_USE 0x01 /* Record is in use */ -#define FRH_DIRECTORY 0x02 /* Record is a directory */ -#define FRH_UNKNOWN1 0x04 /* Don't know */ -#define FRH_UNKNOWN2 0x08 /* Don't know */ +#define FRH_IN_USE 0x0001 /* Record is in use */ +#define FRH_DIRECTORY 0x0002 /* Record is a directory */ +#define FRH_UNKNOWN1 0x0004 /* Don't know */ +#define FRH_UNKNOWN2 0x0008 /* Don't know */ typedef struct { @@ -281,12 +291,14 @@ extern PNTFS_GLOBAL_DATA NtfsGlobalData; /* attrib.c */ -BOOL -NtfsDumpAttribute(PATTRIBUTE Attribute); +//VOID +//NtfsDumpAttribute(PATTRIBUTE Attribute); -LONGLONG RunLCN(PUCHAR run); +//LONGLONG RunLCN(PUCHAR run); -ULONG RunLength(PUCHAR run); +//ULONG RunLength(PUCHAR run); +VOID +NtfsDumpFileAttributes (PFILE_RECORD_HEADER FileRecord); /* blockdev.c */ @@ -295,14 +307,8 @@ NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject, IN ULONG DiskSector, IN ULONG SectorCount, IN ULONG SectorSize, - IN OUT PUCHAR Buffer); - -NTSTATUS -NtfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject, - IN ULONG DiskSector, - IN ULONG SectorCount, - IN ULONG SectorSize, - IN OUT PUCHAR Buffer); + IN OUT PUCHAR Buffer, + IN BOOLEAN Override); NTSTATUS NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, @@ -310,7 +316,8 @@ NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer, - IN OUT PULONG OutputBufferSize); + IN OUT PULONG OutputBufferSize, + IN BOOLEAN Override); /* close.c */ @@ -399,45 +406,59 @@ NtfsFileSystemControl(PDEVICE_OBJECT DeviceObject, /* mft.c */ NTSTATUS -NtfsOpenMft(PDEVICE_OBJECT DeviceObject, - PDEVICE_EXTENSION Vcb); +NtfsOpenMft (PDEVICE_EXTENSION Vcb); -VOID ReadAttribute(PATTRIBUTE attr, PVOID buffer, PDEVICE_EXTENSION Vcb, +VOID +ReadAttribute(PATTRIBUTE attr, PVOID buffer, PDEVICE_EXTENSION Vcb, PDEVICE_OBJECT DeviceObject); -ULONG AttributeLength(PATTRIBUTE attr); +ULONG +AttributeDataLength(PATTRIBUTE attr); -VOID ReadFileRecord(ULONG index, PFILE_RECORD_HEADER file, - PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER Mft, - PDEVICE_OBJECT DeviceObject); +VOID +ReadFileRecord (PDEVICE_EXTENSION Vcb, + ULONG index, + PFILE_RECORD_HEADER file, + PFILE_RECORD_HEADER Mft); +PATTRIBUTE +FindAttribute(PFILE_RECORD_HEADER file, + ATTRIBUTE_TYPE type, + PWSTR name); -PATTRIBUTE FindAttribute(PFILE_RECORD_HEADER file, +ULONG +AttributeLengthAllocated(PATTRIBUTE attr); - 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 +ReadVCN (PDEVICE_EXTENSION Vcb, + PFILE_RECORD_HEADER file, + ATTRIBUTE_TYPE type, + ULONGLONG vcn, + ULONG count, + PVOID buffer); VOID FixupUpdateSequenceArray(PFILE_RECORD_HEADER file); -VOID ReadExternalAttribute(PNONRESIDENT_ATTRIBUTE NresAttr, - ULONGLONG vcn, ULONG count, PVOID buffer, - PDEVICE_EXTENSION Vcb, - PDEVICE_OBJECT DeviceObject); +VOID +ReadExternalAttribute (PDEVICE_EXTENSION Vcb, + PNONRESIDENT_ATTRIBUTE NresAttr, + ULONGLONG vcn, + ULONG count, + PVOID buffer); -VOID ReadLCN(ULONGLONG lcn, ULONG count, PVOID buffer, PDEVICE_EXTENSION Vcb, - PDEVICE_OBJECT DeviceObject); +NTSTATUS +ReadLCN (PDEVICE_EXTENSION Vcb, + ULONGLONG lcn, + ULONG count, + PVOID buffer); -VOID EnumerAttribute(PFILE_RECORD_HEADER file,PDEVICE_EXTENSION Vcb, - PDEVICE_OBJECT DeviceObject ); +VOID +EnumerAttribute(PFILE_RECORD_HEADER file, + PDEVICE_EXTENSION Vcb, + PDEVICE_OBJECT DeviceObject); #if 0 /* misc.c */ diff --git a/reactos/drivers/fs/ntfs/volinfo.c b/reactos/drivers/fs/ntfs/volinfo.c index f429bf5cfcc..bcc8d44f667 100644 --- a/reactos/drivers/fs/ntfs/volinfo.c +++ b/reactos/drivers/fs/ntfs/volinfo.c @@ -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: volinfo.c,v 1.2 2003/07/17 13:31:39 chorns Exp $ +/* $Id: volinfo.c,v 1.3 2003/11/12 15:30:21 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -42,40 +42,43 @@ NtfsGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject, PFILE_FS_VOLUME_INFORMATION FsVolumeInfo, PULONG BufferLength) { - ULONG LabelLength; - DPRINT("NtfsGetFsVolumeInformation() called\n"); DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo); DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("Vpb %p\n", DeviceObject->Vpb); - LabelLength = DeviceObject->Vpb->VolumeLabelLength; - DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR))); - DPRINT("LabelLength %lu\n", LabelLength); - DPRINT("Label %S\n", DeviceObject->Vpb->VolumeLabel); + DPRINT("Required length %lu\n", + sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength); + DPRINT("LabelLength %hu\n", + DeviceObject->Vpb->VolumeLabelLength); + DPRINT("Label %*.S\n", + DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR), + DeviceObject->Vpb->VolumeLabel); if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION)) - return(STATUS_INFO_LENGTH_MISMATCH); + return STATUS_INFO_LENGTH_MISMATCH; - if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR))) - return(STATUS_BUFFER_OVERFLOW); + if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength)) + return STATUS_BUFFER_OVERFLOW; /* valid entries */ FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber; - FsVolumeInfo->VolumeLabelLength = LabelLength * sizeof (WCHAR); - wcscpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel); + FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength; + memcpy(FsVolumeInfo->VolumeLabel, + DeviceObject->Vpb->VolumeLabel, + DeviceObject->Vpb->VolumeLabelLength); /* dummy entries */ FsVolumeInfo->VolumeCreationTime.QuadPart = 0; FsVolumeInfo->SupportsObjects = FALSE; - *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength * sizeof(WCHAR)); + *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength); DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("NtfsGetFsVolumeInformation() done\n"); - return(STATUS_SUCCESS); + return STATUS_SUCCESS; }