diff --git a/reactos/drivers/filesystems/ntfs/blockdev.c b/reactos/drivers/filesystems/ntfs/blockdev.c index 3628bb39114..ed1d6420e21 100644 --- a/reactos/drivers/filesystems/ntfs/blockdev.c +++ b/reactos/drivers/filesystems/ntfs/blockdev.c @@ -36,6 +36,7 @@ NTSTATUS NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject, IN LONGLONG StartingOffset, IN ULONG Length, + IN ULONG SectorSize, IN OUT PUCHAR Buffer, IN BOOLEAN Override) { @@ -45,20 +46,41 @@ NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject, KEVENT Event; PIRP Irp; NTSTATUS Status; + ULONGLONG RealReadOffset; + ULONG RealLength; + BOOLEAN AllocatedBuffer = FALSE; + PUCHAR ReadBuffer = Buffer; - DPRINT("NtfsReadDisk(%p, %I64x, %u, %p, %d)\n", DeviceObject, StartingOffset, Length, Buffer, Override); + DPRINT("NtfsReadDisk(%p, %I64x, %u, %u, %p, %d)\n", DeviceObject, StartingOffset, Length, SectorSize, Buffer, Override); KeInitializeEvent(&Event, NotificationEvent, FALSE); - Offset.QuadPart = StartingOffset; + RealReadOffset = (ULONGLONG)StartingOffset; + RealLength = Length; + + if ((RealReadOffset % SectorSize) != 0 || (RealLength % SectorSize) != 0) + { + RealReadOffset = ROUND_DOWN(StartingOffset, SectorSize); + RealLength = ROUND_UP(Length, SectorSize); + + ReadBuffer = ExAllocatePoolWithTag(NonPagedPool, RealLength + SectorSize, TAG_NTFS); + if (ReadBuffer == NULL) + { + DPRINT1("Not enough memory!\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + AllocatedBuffer = TRUE; + } + + Offset.QuadPart = RealReadOffset; DPRINT("Building synchronous FSD Request...\n"); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, - Buffer, - Length, + ReadBuffer, + RealLength, &Offset, &Event, &IoStatus); @@ -86,6 +108,12 @@ NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject, Status = IoStatus.Status; } + if (NT_SUCCESS(Status) && AllocatedBuffer) + { + RtlCopyMemory(Buffer, ReadBuffer + (StartingOffset - RealReadOffset), Length); + ExFreePoolWithTag(ReadBuffer, TAG_NTFS); + } + DPRINT("NtfsReadDisk() done (Status %x)\n", Status); return Status; @@ -105,7 +133,7 @@ NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject, Offset = (LONGLONG)DiskSector * (LONGLONG)SectorSize; BlockSize = SectorCount * SectorSize; - return NtfsReadDisk(DeviceObject, Offset, BlockSize, Buffer, Override); + return NtfsReadDisk(DeviceObject, Offset, BlockSize, SectorSize, Buffer, Override); } diff --git a/reactos/drivers/filesystems/ntfs/mft.c b/reactos/drivers/filesystems/ntfs/mft.c index 2b94e22d385..820cfa41dd8 100644 --- a/reactos/drivers/filesystems/ntfs/mft.c +++ b/reactos/drivers/filesystems/ntfs/mft.c @@ -106,37 +106,43 @@ FindAttributeHelper(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_RECORD ListAttrRecordEnd; // Do not handle non-resident yet - ASSERT(!(AttrRecord->IsNonResident & 1)); - - ListContext = PrepareAttributeContext(AttrRecord); - - ListSize = AttributeDataLength(&ListContext->Record); - if(ListSize <= 0xFFFFFFFF) - ListBuffer = ExAllocatePoolWithTag(NonPagedPool, (ULONG)ListSize, TAG_NTFS); - else - ListBuffer = NULL; - - if(!ListBuffer) + if (AttrRecord->IsNonResident) { - DPRINT("Failed to allocate memory: %x\n", (ULONG)ListSize); + UNIMPLEMENTED; continue; } - - ListAttrRecord = (PNTFS_ATTR_RECORD)ListBuffer; - ListAttrRecordEnd = (PNTFS_ATTR_RECORD)((PCHAR)ListBuffer + ListSize); - - if (ReadAttribute(Vcb, ListContext, 0, ListBuffer, (ULONG)ListSize) == ListSize) + else { - Context = FindAttributeHelper(Vcb, ListAttrRecord, ListAttrRecordEnd, - Type, Name, NameLength); + ListContext = PrepareAttributeContext(AttrRecord); - ReleaseAttributeContext(ListContext); - ExFreePoolWithTag(ListBuffer, TAG_NTFS); + ListSize = AttributeDataLength(&ListContext->Record); + if(ListSize <= 0xFFFFFFFF) + ListBuffer = ExAllocatePoolWithTag(NonPagedPool, (ULONG)ListSize, TAG_NTFS); + else + ListBuffer = NULL; - if (Context != NULL) + if(!ListBuffer) { - DPRINT("Found context = %p\n", Context); - return Context; + DPRINT("Failed to allocate memory: %x\n", (ULONG)ListSize); + continue; + } + + ListAttrRecord = (PNTFS_ATTR_RECORD)ListBuffer; + ListAttrRecordEnd = (PNTFS_ATTR_RECORD)((PCHAR)ListBuffer + ListSize); + + if (ReadAttribute(Vcb, ListContext, 0, ListBuffer, (ULONG)ListSize) == ListSize) + { + Context = FindAttributeHelper(Vcb, ListAttrRecord, ListAttrRecordEnd, + Type, Name, NameLength); + + ReleaseAttributeContext(ListContext); + ExFreePoolWithTag(ListBuffer, TAG_NTFS); + + if (Context != NULL) + { + DPRINT("Found context = %p\n", Context); + return Context; + } } } } @@ -310,6 +316,7 @@ ReadAttribute(PDEVICE_EXTENSION Vcb, Status = NtfsReadDisk(Vcb->StorageDevice, DataRunStartLCN * Vcb->NtfsInfo.BytesPerCluster + Offset - CurrentOffset, ReadLength, + Vcb->NtfsInfo.BytesPerSector, (PVOID)Buffer, FALSE); if (NT_SUCCESS(Status)) @@ -344,6 +351,7 @@ ReadAttribute(PDEVICE_EXTENSION Vcb, Status = NtfsReadDisk(Vcb->StorageDevice, DataRunStartLCN * Vcb->NtfsInfo.BytesPerCluster, ReadLength, + Vcb->NtfsInfo.BytesPerSector, (PVOID)Buffer, FALSE); if (!NT_SUCCESS(Status)) diff --git a/reactos/drivers/filesystems/ntfs/ntfs.h b/reactos/drivers/filesystems/ntfs/ntfs.h index 22187d65253..573b6ca186f 100644 --- a/reactos/drivers/filesystems/ntfs/ntfs.h +++ b/reactos/drivers/filesystems/ntfs/ntfs.h @@ -10,6 +10,7 @@ #define TAG_NTFS 'SFTN' #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) +#define ROUND_DOWN(N, S) ((N) - ((N) % (S))) #define DEVICE_NAME L"\\Ntfs" @@ -456,6 +457,7 @@ NTSTATUS NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject, IN LONGLONG StartingOffset, IN ULONG Length, + IN ULONG SectorSize, IN OUT PUCHAR Buffer, IN BOOLEAN Override); diff --git a/reactos/drivers/filesystems/ntfs/rw.c b/reactos/drivers/filesystems/ntfs/rw.c index fb485df6771..0ae0a280394 100644 --- a/reactos/drivers/filesystems/ntfs/rw.c +++ b/reactos/drivers/filesystems/ntfs/rw.c @@ -32,11 +32,6 @@ #define NDEBUG #include -/* GLOBALS *******************************************************************/ - -#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) -#define ROUND_DOWN(N, S) ((N) - ((N) % (S))) - /* FUNCTIONS ****************************************************************/ /*