37#define NTFS_GROW_AHEAD_MIN (64 * 1024)
38#define NTFS_GROW_AHEAD_MAX (4 * 1024 * 1024)
91 DPRINT(
"NtfsReadWriteVolume(%p, %u, %p, %lu, %I64u, %p, %p)\n",
94 *LengthTransferred = 0;
106 DeviceExt->NtfsInfo.BytesPerSector,
139 ULONG RealLengthRead;
145 DPRINT(
"NtfsReadFile(%p, %p, %p, %lu, %I64u, %lx, %p)\n", DeviceExt,
FileObject,
Buffer,
Length,
ReadOffset, IrpFlags, LengthRead);
171 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
172 if (FileRecord ==
NULL)
174 DPRINT1(
"Not enough memory!\n");
181 DPRINT1(
"Can't find record!\n");
182 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
194 DPRINT1(
"No '%S' data stream associated with file '%wS' (MFT record %I64u, record flags 0x%x)!\n",
216 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
223 DPRINT(
"Reading beyond stream end!\n");
225 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
236 if ((
ReadOffset % DeviceExt->NtfsInfo.BytesPerSector) != 0 || (ToRead % DeviceExt->NtfsInfo.BytesPerSector) != 0)
239 RealLength =
ROUND_UP(ToRead, DeviceExt->NtfsInfo.BytesPerSector);
243 if (RealReadOffset + RealLength + DeviceExt->NtfsInfo.BytesPerSector <=
AttributeAllocatedLength(DataContext->pRecord))
244 RealLength += DeviceExt->NtfsInfo.BytesPerSector;
251 DPRINT1(
"Not enough memory!\n");
253 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
256 AllocatedBuffer =
TRUE;
259 DPRINT(
"Effective read: %lu at %I64u for stream '%S'\n", RealLength, RealReadOffset,
Fcb->
Stream);
269 if (RealLengthRead == 0)
273 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
282 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
284 *LengthRead = ToRead;
286 DPRINT(
"%lu got read\n", *LengthRead);
404 ULONG ReturnedReadLength = 0;
409 DPRINT(
"NtfsRead(IrpContext %p)\n", IrpContext);
426 Irp->IoStatus.Information = 0;
439 &ReturnedReadLength);
444 Irp->IoStatus.Information = 0;
450 Irp->IoStatus.Information = 0;
460 &ReturnedReadLength);
484 &ReturnedReadLength);
494 Irp->IoStatus.Information = ReturnedReadLength;
498 Irp->IoStatus.Information = 0;
529 if (DataContext->pRecord->IsNonResident &&
625 ULONG AttributeOffset;
627 ULONG RequestedLength = 0;
629 DPRINT(
"NtfsWriteFile(%p, %p, %p, %lu, %I64u, %x, %s, %p)\n",
636 (CaseSensitive ?
"TRUE" :
"FALSE"),
661 DPRINT(
"Compressed file!\n");
667 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
668 if (FileRecord ==
NULL)
675 DPRINT(
"Reading file record...\n");
681 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
688 DPRINT(
"Finding Data Attribute...\n");
699 DPRINT1(
"No '%S' data stream associated with file '%wS' (MFT record %I64u, record flags 0x%x)!\n",
722 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
749 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
762 DPRINT(
"Paging write entirely past the end of the stream; nothing to do\n");
765 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
770 DPRINT(
"Clamping paging write of %lu bytes at %I64u to stream size %I64u\n",
780 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
799 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
805 if (*LengthWritten !=
Length)
807 DPRINT1(
"\a\tNTFS DRIVER ERROR: length written (%lu) differs from requested (%lu), but no error was indicated!\n",
815 *LengthWritten = RequestedLength;
818 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
836 ULONG AttributeOffset;
839 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
840 if (FileRecord ==
NULL)
854 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
905 if (WriteEnd > OldValidData.
QuadPart)
973 ULONG ReturnedWriteLength = 0;
978 ULONG BytesPerSector;
980 DPRINT(
"NtfsWrite(IrpContext %p)\n", IrpContext);
989 DPRINT1(
"\t\t\t\tNtfsWrite is called with the main device object.\n");
991 Irp->IoStatus.Information = 0;
1000 DPRINT(
"NTFS Version: %d.%d\n",
Fcb->
Vcb->NtfsInfo.MajorVersion,
Fcb->
Vcb->NtfsInfo.MinorVersion);
1006 BytesPerSector = DeviceExt->StorageDevice->SectorSize;
1017 DPRINT(
"ByteOffset: %I64u\tLength: %lu\tBytes per sector: %lu\n",
ByteOffset.QuadPart,
1032 if (
ByteOffset.u.LowPart % BytesPerSector != 0 ||
Length % BytesPerSector != 0)
1034 DPRINT1(
"Non-cached writes and non-buffered writes must be sector aligned!\n");
1057 DPRINT1(
"Unable to lock user buffer!\n");
1068 Irp->IoStatus.Information = 0;
1079 Irp->IoStatus.Information = 0;
1089 &ReturnedWriteLength);
1105 Resource = &DeviceExt->DirResource;
1138 DPRINT1(
"Unable to lock user buffer!\n");
1145 DPRINT(
"About to write the data. Length: %lu\n",
Length);
1153 Irp->IoStatus.Information = 0;
1167 &ReturnedWriteLength);
1173 Irp->IoStatus.Information = 0;
1196 &ReturnedWriteLength);
1216 DPRINT1(
"Write not Succesful!\tReturned length: %lu\n", ReturnedWriteLength);
1219 Irp->IoStatus.Information = ReturnedWriteLength;
#define ReadBuffer(BaseIoAddress, Buffer, Count)
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
#define STATUS_NOT_IMPLEMENTED
#define NT_SUCCESS(StatCode)
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
NTSTATUS FindFirstAttribute(PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
VOID FindCloseAttribute(PFIND_ATTR_CONTXT Context)
NTSTATUS FindNextAttribute(PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
NTSTATUS NtfsLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
PVOID NtfsGetUserBuffer(PIRP Irp, BOOLEAN Paging)
PNTFS_GLOBAL_DATA NtfsGlobalData
FORCEINLINE NTSTATUS NtfsMarkIrpContextForQueue(PNTFS_IRP_CONTEXT IrpContext)
#define VCB_VOLUME_DISMOUNTED
#define NTFS_FILENAME_UPDATE_SIZES
#define IRPCONTEXT_CANWAIT
NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, const PUCHAR Buffer, ULONG Length, ULONGLONG WriteOffset, ULONG IrpFlags, BOOLEAN CaseSensitive, PIRP Irp, PULONG LengthWritten)
static NTSTATUS NTAPI NtfsCachedWrite(_In_ PNTFS_IRP_CONTEXT IrpContext, _In_ PNTFS_FCB Fcb, _In_reads_bytes_(Length) PVOID Buffer, _In_ ULONG Length, _In_ PLARGE_INTEGER WriteOffset, _In_ BOOLEAN CaseSensitive, _Out_ PULONG LengthWritten)
static NTSTATUS NtfsReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PUCHAR Buffer, ULONG Length, ULONGLONG ReadOffset, ULONG IrpFlags, PIRP Irp, PULONG LengthRead)
static NTSTATUS NTAPI NtfsGrowStream(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILE_OBJECT FileObject, _In_ PNTFS_FCB Fcb, _In_ PNTFS_ATTR_CONTEXT DataContext, _In_ ULONG AttributeOffset, _Inout_ PFILE_RECORD_HEADER FileRecord, _In_ ULONGLONG NewEnd, _In_ BOOLEAN CaseSensitive)
static NTSTATUS NTAPI NtfsGrowFileForWrite(_In_ PFILE_OBJECT FileObject, _In_ PNTFS_FCB Fcb, _In_ ULONGLONG NewEnd, _In_ BOOLEAN CaseSensitive)
#define NTFS_GROW_AHEAD_MIN
NTSTATUS NtfsRead(PNTFS_IRP_CONTEXT IrpContext)
NTSTATUS NtfsWrite(PNTFS_IRP_CONTEXT IrpContext)
static VOID NTAPI NtfsEnsureCacheMap(_In_ PFILE_OBJECT FileObject, _In_ PNTFS_FCB Fcb)
static NTSTATUS NtfsReadWriteVolume(PDEVICE_EXTENSION DeviceExt, UCHAR MajorFunction, PUCHAR Buffer, ULONG Length, LONGLONG Offset, PIRP Irp, PULONG LengthTransferred)
#define NTFS_GROW_AHEAD_MAX
static NTSTATUS NTAPI NtfsCachedRead(_In_ PNTFS_IRP_CONTEXT IrpContext, _In_ PNTFS_FCB Fcb, _Out_writes_bytes_(Length) PVOID Buffer, _In_ ULONG Length, _In_ PLARGE_INTEGER ReadOffset, _Out_ PULONG LengthRead)
#define ExAllocatePoolWithTag(hernya, size, tag)
#define ExAcquireResourceExclusiveLite(res, wait)
#define ExAcquireResourceSharedLite(res, wait)
#define ROUND_UP(n, align)
#define ROUND_DOWN(n, align)
#define FILE_WRITE_TO_END_OF_FILE
#define BooleanFlagOn(F, SF)
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
#define FILE_NO_INTERMEDIATE_BUFFERING
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
#define EXCEPTION_EXECUTE_HANDLER
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
NTSTATUS NtfsUpdateDuplicatedInformation(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, ULONGLONG MFTIndex, ULONG Flags, BOOLEAN CaseSensitive)
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
NTSTATUS NtfsExtendAllocation(_In_ PDEVICE_EXTENSION Vcb, _In_ PNTFS_ATTR_CONTEXT AttrContext, _In_ ULONG AttrOffset, _In_ PFILE_RECORD_HEADER FileRecord, _In_ ULONGLONG AllocationSize)
ULONGLONG AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord)
NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, PNTFS_ATTR_CONTEXT *AttrCtx, PULONG Offset)
NTSTATUS WriteAttributeFromIrp(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, const PUCHAR Buffer, ULONG Length, PULONG RealLengthWritten, PFILE_RECORD_HEADER FileRecord, PIRP Irp)
ULONGLONG AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord)
ULONG ReadAttributeToIrp(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length, PIRP Irp)
NTSTATUS SetAttributeDataLength(PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, PLARGE_INTEGER DataSize)
#define ExFreePoolWithTag(_P, _T)
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
#define _In_reads_bytes_(s)
#define _Out_writes_bytes_(s)
_In_ ULONG _In_ ULONG Offset
_In_ ULONG _In_ ULONG _In_ ULONG Length
VOID NtfsFreeIoRunList(IN OUT PNTFS_IO_RUN_LIST RunList)
NTSTATUS NtfsAddIoRun(IN OUT PNTFS_IO_RUN_LIST RunList, IN LONGLONG Lbo, IN ULONG ByteCount)
VOID NtfsInitIoRunList(OUT PNTFS_IO_RUN_LIST RunList)
NTSTATUS NtfsPerformIrpIoRuns(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MajorFunction, IN ULONG SectorSize, IN PIRP Irp, IN OUT PUCHAR Buffer, IN PNTFS_IO_RUN_LIST RunList, IN BOOLEAN Override, OUT PULONG BytesTransferred)
BOOLEAN NtfsFCBIsDirectory(PNTFS_FCB Fcb)
BOOLEAN NtfsFCBIsEncrypted(PNTFS_FCB Fcb)
BOOLEAN NTAPI NtfsIsRegularFileObject(_In_ PFILE_OBJECT FileObject)
BOOLEAN NtfsFCBIsCompressed(PNTFS_FCB Fcb)
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
#define STATUS_FILE_LOCK_CONFLICT
#define STATUS_VOLUME_DISMOUNTED
#define STATUS_UNEXPECTED_IO_ERROR
#define _SEH2_GetExceptionCode()
#define _SEH2_EXCEPT(...)
#define STATUS_END_OF_FILE
PDEVICE_OBJECT DeviceObject
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks
PDEVICE_OBJECT DeviceObject
LARGE_INTEGER ValidDataLength
LARGE_INTEGER AllocationSize
FSRTL_COMMON_FCB_HEADER RFCB
ERESOURCE PagingIoResource
SECTION_OBJECT_POINTERS SectionObjectPointers
struct _IO_STACK_LOCATION::@5020::@5025 Write
union _IO_STACK_LOCATION::@1814 Parameters
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define STATUS_INVALID_DEVICE_REQUEST
#define STATUS_ACCESS_DENIED
#define STATUS_INVALID_PARAMETER
#define STATUS_UNSUCCESSFUL
#define STATUS_INSUFFICIENT_RESOURCES
_In_ PDEVICE_OBJECT DeviceObject
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET ReadOffset
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET WriteOffset
#define IO_DISK_INCREMENT
#define FO_NO_INTERMEDIATE_BUFFERING
#define FO_SYNCHRONOUS_IO
#define SL_CASE_SENSITIVE