ULONG ToRead;
BOOLEAN AllocatedBuffer = FALSE;
PCHAR ReadBuffer = (PCHAR)Buffer;
+ ULONGLONG StreamSize;
DPRINT1("NtfsReadFile(%p, %p, %p, %u, %u, %x, %p)\n", DeviceExt, FileObject, Buffer, Length, ReadOffset, IrpFlags, LengthRead);
Fcb = (PNTFS_FCB)FileObject->FsContext;
- if (ReadOffset >= Fcb->Entry.AllocatedSize)
+ if (NtfsFCBIsCompressed(Fcb))
{
- DPRINT1("Reading beyond file end!\n");
- return STATUS_END_OF_FILE;
- }
-
- ToRead = Length;
- if (ReadOffset + Length > Fcb->Entry.AllocatedSize)
- ToRead = Fcb->Entry.AllocatedSize - ReadOffset;
-
- RealReadOffset = ReadOffset;
- RealLength = ToRead;
-
- if ((ReadOffset % DeviceExt->NtfsInfo.BytesPerSector) != 0 || (ToRead % DeviceExt->NtfsInfo.BytesPerSector) != 0)
- {
- RealReadOffset = ROUND_DOWN(ReadOffset, DeviceExt->NtfsInfo.BytesPerSector);
- RealLength = ROUND_UP(ToRead, DeviceExt->NtfsInfo.BytesPerSector);
-
- ReadBuffer = ExAllocatePoolWithTag(NonPagedPool, RealLength + DeviceExt->NtfsInfo.BytesPerSector, TAG_NTFS);
- if (ReadBuffer == NULL)
- {
- DPRINT1("Not enough memory!\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- AllocatedBuffer = TRUE;
+ DPRINT1("Compressed file!\n");
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
FileRecord = ExAllocatePoolWithTag(NonPagedPool, DeviceExt->NtfsInfo.BytesPerFileRecord, TAG_NTFS);
return Status;
}
- Status = FindAttribute(DeviceExt, FileRecord, AttributeData, L"", 0, &DataContext);
+
+ Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext);
if (!NT_SUCCESS(Status))
{
- DPRINT1("No data associated with file!\n");
+ NTSTATUS BrowseStatus;
+ FIND_ATTR_CONTXT Context;
+ PNTFS_ATTR_RECORD Attribute;
+
+ DPRINT1("No '%S' data stream associated with file!\n", Fcb->Stream);
+
+ BrowseStatus = FindFirstAttribute(&Context, DeviceExt, FileRecord, FALSE, &Attribute);
+ while (NT_SUCCESS(BrowseStatus))
+ {
+ if (Attribute->Type == AttributeData)
+ {
+ UNICODE_STRING Name;
+
+ Name.Length = Attribute->NameLength * sizeof(WCHAR);
+ Name.MaximumLength = Name.Length;
+ Name.Buffer = (PWCHAR)((ULONG_PTR)Attribute + Attribute->NameOffset);
+ DPRINT1("Data stream: '%wZ' available\n", &Name);
+ }
+
+ BrowseStatus = FindNextAttribute(&Context, &Attribute);
+ }
+ FindCloseAttribute(&Context);
+
+ ReleaseAttributeContext(DataContext);
ExFreePoolWithTag(FileRecord, TAG_NTFS);
return Status;
}
- DPRINT1("Effective read: %lu at %lu\n", RealLength, RealReadOffset);
+ StreamSize = AttributeDataLength(&DataContext->Record);
+ if (ReadOffset >= StreamSize)
+ {
+ DPRINT1("Reading beyond stream end!\n");
+ ReleaseAttributeContext(DataContext);
+ ExFreePoolWithTag(FileRecord, TAG_NTFS);
+ return STATUS_END_OF_FILE;
+ }
+
+ ToRead = Length;
+ if (ReadOffset + Length > StreamSize)
+ ToRead = StreamSize - ReadOffset;
+
+ RealReadOffset = ReadOffset;
+ RealLength = ToRead;
+
+ if ((ReadOffset % DeviceExt->NtfsInfo.BytesPerSector) != 0 || (ToRead % DeviceExt->NtfsInfo.BytesPerSector) != 0)
+ {
+ RealReadOffset = ROUND_DOWN(ReadOffset, DeviceExt->NtfsInfo.BytesPerSector);
+ RealLength = ROUND_UP(ToRead, DeviceExt->NtfsInfo.BytesPerSector);
+ /* do we need to extend RealLength by one sector? */
+ if (RealLength + RealReadOffset < ReadOffset + Length)
+ RealLength += DeviceExt->NtfsInfo.BytesPerSector;
+
+
+ ReadBuffer = ExAllocatePoolWithTag(NonPagedPool, RealLength + (DeviceExt->NtfsInfo.BytesPerSector * 2), TAG_NTFS);
+ if (ReadBuffer == NULL)
+ {
+ DPRINT1("Not enough memory!\n");
+ ReleaseAttributeContext(DataContext);
+ ExFreePoolWithTag(FileRecord, TAG_NTFS);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ AllocatedBuffer = TRUE;
+ }
+
+ DPRINT1("Effective read: %lu at %lu for stream '%S'\n", RealLength, RealReadOffset, Fcb->Stream);
RealLengthRead = ReadAttribute(DeviceExt, DataContext, RealReadOffset, (PCHAR)ReadBuffer, RealLength);
- if (RealLengthRead != RealLength)
+ if (RealLengthRead == 0)
{
DPRINT1("Read failure!\n");
ReleaseAttributeContext(DataContext);
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
- DPRINT("NtfsRead(DeviceObject %p)\n", IrpContext);
+ DPRINT("NtfsRead(IrpContext %p)\n", IrpContext);
DeviceObject = IrpContext->DeviceObject;
Irp = IrpContext->Irp;
DeviceExt = DeviceObject->DeviceExtension;
ReadLength = Stack->Parameters.Read.Length;
ReadOffset = Stack->Parameters.Read.ByteOffset;
- Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+ Buffer = NtfsGetUserBuffer(Irp, BooleanFlagOn(Irp->Flags, IRP_PAGING_IO));
Status = NtfsReadFile(DeviceExt,
FileObject,
NTSTATUS
-NTAPI
-NtfsFsdWrite(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+NtfsWrite(PNTFS_IRP_CONTEXT IrpContext)
{
- DPRINT("NtfwWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
+ DPRINT("NtfsWrite(IrpContext %p)\n",IrpContext);
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- Irp->IoStatus.Information = 0;
+ IrpContext->Irp->IoStatus.Information = 0;
return STATUS_NOT_SUPPORTED;
}