mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 22:23:01 +00:00
[NTFS]
- Move the ROUND_UP & ROUND_DOWN macro definition to header - Make NtfsReadDisk() sector size aware so that it can properly align read on the disk (and thus prevent them from failing) - If $ATTRIBUTE_LIST is non resident, then display a message and continue, don't assert on it. This is to be implemented later on. This fixes directory enumeration on a Windows 7 NTFS volume. svn path=/trunk/; revision=65240
This commit is contained in:
parent
217a030519
commit
099910fd83
4 changed files with 67 additions and 34 deletions
|
@ -36,6 +36,7 @@ NTSTATUS
|
||||||
NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
|
NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN LONGLONG StartingOffset,
|
IN LONGLONG StartingOffset,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
|
IN ULONG SectorSize,
|
||||||
IN OUT PUCHAR Buffer,
|
IN OUT PUCHAR Buffer,
|
||||||
IN BOOLEAN Override)
|
IN BOOLEAN Override)
|
||||||
{
|
{
|
||||||
|
@ -45,20 +46,41 @@ NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
NTSTATUS Status;
|
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,
|
KeInitializeEvent(&Event,
|
||||||
NotificationEvent,
|
NotificationEvent,
|
||||||
FALSE);
|
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");
|
DPRINT("Building synchronous FSD Request...\n");
|
||||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
||||||
DeviceObject,
|
DeviceObject,
|
||||||
Buffer,
|
ReadBuffer,
|
||||||
Length,
|
RealLength,
|
||||||
&Offset,
|
&Offset,
|
||||||
&Event,
|
&Event,
|
||||||
&IoStatus);
|
&IoStatus);
|
||||||
|
@ -86,6 +108,12 @@ NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
|
||||||
Status = IoStatus.Status;
|
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);
|
DPRINT("NtfsReadDisk() done (Status %x)\n", Status);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -105,7 +133,7 @@ NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
|
||||||
Offset = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
|
Offset = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
|
||||||
BlockSize = SectorCount * SectorSize;
|
BlockSize = SectorCount * SectorSize;
|
||||||
|
|
||||||
return NtfsReadDisk(DeviceObject, Offset, BlockSize, Buffer, Override);
|
return NtfsReadDisk(DeviceObject, Offset, BlockSize, SectorSize, Buffer, Override);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -106,37 +106,43 @@ FindAttributeHelper(PDEVICE_EXTENSION Vcb,
|
||||||
PNTFS_ATTR_RECORD ListAttrRecordEnd;
|
PNTFS_ATTR_RECORD ListAttrRecordEnd;
|
||||||
|
|
||||||
// Do not handle non-resident yet
|
// Do not handle non-resident yet
|
||||||
ASSERT(!(AttrRecord->IsNonResident & 1));
|
if (AttrRecord->IsNonResident)
|
||||||
|
|
||||||
ListContext = PrepareAttributeContext(AttrRecord);
|
|
||||||
|
|
||||||
ListSize = AttributeDataLength(&ListContext->Record);
|
|
||||||
if(ListSize <= 0xFFFFFFFF)
|
|
||||||
ListBuffer = ExAllocatePoolWithTag(NonPagedPool, (ULONG)ListSize, TAG_NTFS);
|
|
||||||
else
|
|
||||||
ListBuffer = NULL;
|
|
||||||
|
|
||||||
if(!ListBuffer)
|
|
||||||
{
|
{
|
||||||
DPRINT("Failed to allocate memory: %x\n", (ULONG)ListSize);
|
UNIMPLEMENTED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
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,
|
ListContext = PrepareAttributeContext(AttrRecord);
|
||||||
Type, Name, NameLength);
|
|
||||||
|
|
||||||
ReleaseAttributeContext(ListContext);
|
ListSize = AttributeDataLength(&ListContext->Record);
|
||||||
ExFreePoolWithTag(ListBuffer, TAG_NTFS);
|
if(ListSize <= 0xFFFFFFFF)
|
||||||
|
ListBuffer = ExAllocatePoolWithTag(NonPagedPool, (ULONG)ListSize, TAG_NTFS);
|
||||||
|
else
|
||||||
|
ListBuffer = NULL;
|
||||||
|
|
||||||
if (Context != NULL)
|
if(!ListBuffer)
|
||||||
{
|
{
|
||||||
DPRINT("Found context = %p\n", Context);
|
DPRINT("Failed to allocate memory: %x\n", (ULONG)ListSize);
|
||||||
return Context;
|
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,
|
Status = NtfsReadDisk(Vcb->StorageDevice,
|
||||||
DataRunStartLCN * Vcb->NtfsInfo.BytesPerCluster + Offset - CurrentOffset,
|
DataRunStartLCN * Vcb->NtfsInfo.BytesPerCluster + Offset - CurrentOffset,
|
||||||
ReadLength,
|
ReadLength,
|
||||||
|
Vcb->NtfsInfo.BytesPerSector,
|
||||||
(PVOID)Buffer,
|
(PVOID)Buffer,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
|
@ -344,6 +351,7 @@ ReadAttribute(PDEVICE_EXTENSION Vcb,
|
||||||
Status = NtfsReadDisk(Vcb->StorageDevice,
|
Status = NtfsReadDisk(Vcb->StorageDevice,
|
||||||
DataRunStartLCN * Vcb->NtfsInfo.BytesPerCluster,
|
DataRunStartLCN * Vcb->NtfsInfo.BytesPerCluster,
|
||||||
ReadLength,
|
ReadLength,
|
||||||
|
Vcb->NtfsInfo.BytesPerSector,
|
||||||
(PVOID)Buffer,
|
(PVOID)Buffer,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define TAG_NTFS 'SFTN'
|
#define TAG_NTFS 'SFTN'
|
||||||
|
|
||||||
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
|
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
|
||||||
|
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
|
||||||
|
|
||||||
#define DEVICE_NAME L"\\Ntfs"
|
#define DEVICE_NAME L"\\Ntfs"
|
||||||
|
|
||||||
|
@ -456,6 +457,7 @@ NTSTATUS
|
||||||
NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
|
NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN LONGLONG StartingOffset,
|
IN LONGLONG StartingOffset,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
|
IN ULONG SectorSize,
|
||||||
IN OUT PUCHAR Buffer,
|
IN OUT PUCHAR Buffer,
|
||||||
IN BOOLEAN Override);
|
IN BOOLEAN Override);
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,6 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
|
||||||
|
|
||||||
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
|
|
||||||
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
|
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue