Author: pschweitzer
Date: Sun Dec 14 18:13:57 2014
New Revision: 65645
URL:
http://svn.reactos.org/svn/reactos?rev=65645&view=rev
Log:
[NTFS]
Implement GetVolumeBitmap().
This allows NFI to find which file is at which LCN:
http://www.heisspiter.net/~Pierre/rostests/NTFS_NFI_LCN.png
So far, NFI is not as verbose as it is on Windows in such cases, because
FILE_OPEN_BY_FILE_ID is *still* unimplemented (you should consider implementing it Pierre
;-)).
I checked with Windows, the correct file is found though!
CORE-8725
Modified:
trunk/reactos/drivers/filesystems/ntfs/fsctl.c
Modified: trunk/reactos/drivers/filesystems/ntfs/fsctl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/ntfs/f…
==============================================================================
--- trunk/reactos/drivers/filesystems/ntfs/fsctl.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/ntfs/fsctl.c [iso-8859-1] Sun Dec 14 18:13:57 2014
@@ -666,6 +666,11 @@
PIO_STACK_LOCATION Stack;
PVOLUME_BITMAP_BUFFER BitmapBuffer;
LONGLONG StartingLcn;
+ PFILE_RECORD_HEADER BitmapRecord;
+ PNTFS_ATTR_CONTEXT DataContext;
+ ULONGLONG TotalClusters;
+ ULONGLONG ToCopy;
+ BOOLEAN Overflow = FALSE;
DPRINT1("GetVolumeBitmap(%p, %p)\n", DeviceExt, Irp);
@@ -722,8 +727,59 @@
return STATUS_INVALID_PARAMETER;
}
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ /* Round down to a multiple of 8 */
+ StartingLcn = StartingLcn & ~7;
+ TotalClusters = DeviceExt->NtfsInfo.ClusterCount - StartingLcn;
+ ToCopy = TotalClusters / 8;
+ if ((ToCopy + FIELD_OFFSET(VOLUME_BITMAP_BUFFER, Buffer)) >
Stack->Parameters.FileSystemControl.OutputBufferLength)
+ {
+ DPRINT1("Buffer too small: %x, needed: %x\n",
Stack->Parameters.FileSystemControl.OutputBufferLength, (ToCopy +
FIELD_OFFSET(VOLUME_BITMAP_BUFFER, Buffer)));
+ Overflow = TRUE;
+ ToCopy = Stack->Parameters.FileSystemControl.OutputBufferLength -
FIELD_OFFSET(VOLUME_BITMAP_BUFFER, Buffer);
+ }
+
+ BitmapRecord = ExAllocatePoolWithTag(NonPagedPool,
+ DeviceExt->NtfsInfo.BytesPerFileRecord,
+ TAG_NTFS);
+ if (BitmapRecord == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = ReadFileRecord(DeviceExt, NTFS_FILE_BITMAP, BitmapRecord);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed reading volume bitmap: %lx\n", Status);
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+ return Status;
+ }
+
+ Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0,
&DataContext);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed find $DATA for bitmap: %lx\n", Status);
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+ return Status;
+ }
+
+ BitmapBuffer->StartingLcn.QuadPart = StartingLcn;
+ BitmapBuffer->BitmapSize.QuadPart = ToCopy * 8;
+
+ Irp->IoStatus.Information = FIELD_OFFSET(VOLUME_BITMAP_BUFFER, Buffer);
+ _SEH2_TRY
+ {
+ Irp->IoStatus.Information += ReadAttribute(DeviceExt, DataContext, StartingLcn
/ 8, (PCHAR)BitmapBuffer->Buffer, ToCopy);
+ Status = (Overflow ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ ReleaseAttributeContext(DataContext);
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+
+ return STATUS_SUCCESS;
}