ReactOS 0.4.17-dev-1190-g4c812f4
rw.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2002, 2014 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 * COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS kernel
21 * FILE: drivers/filesystem/ntfs/rw.c
22 * PURPOSE: NTFS filesystem driver
23 * PROGRAMMERS: Art Yerkes
24 * Pierre Schweitzer (pierre@reactos.org)
25 * Trevor Thompson
26 */
27
28/* INCLUDES *****************************************************************/
29
30#include <ntddk.h>
31#include "ntfs.h"
32
33#define NDEBUG
34#include <debug.h>
35
36/* Bounds on how far a growing file is allocated past its end */
37#define NTFS_GROW_AHEAD_MIN (64 * 1024)
38#define NTFS_GROW_AHEAD_MAX (4 * 1024 * 1024)
39
40/* FUNCTIONS ****************************************************************/
41
78static
85 PIRP Irp,
86 PULONG LengthTransferred)
87{
88 NTFS_IO_RUN_LIST RunList;
90
91 DPRINT("NtfsReadWriteVolume(%p, %u, %p, %lu, %I64u, %p, %p)\n",
92 DeviceExt, MajorFunction, Buffer, Length, Offset, Irp, LengthTransferred);
93
94 *LengthTransferred = 0;
95
96 if (Length == 0)
97 return STATUS_SUCCESS;
98
99 NtfsInitIoRunList(&RunList);
100
101 Status = NtfsAddIoRun(&RunList, Offset, Length);
102 if (NT_SUCCESS(Status))
103 {
104 Status = NtfsPerformIrpIoRuns(DeviceExt->StorageDevice,
106 DeviceExt->NtfsInfo.BytesPerSector,
107 Irp,
108 Buffer,
109 &RunList,
110 FALSE,
111 LengthTransferred);
112 }
113
114 NtfsFreeIoRunList(&RunList);
115
116 return Status;
117}
118
119/*
120 * FUNCTION: Reads data from a file
121 */
122static
129 ULONG IrpFlags,
130 PIRP Irp,
131 PULONG LengthRead)
132{
135 PFILE_RECORD_HEADER FileRecord;
136 PNTFS_ATTR_CONTEXT DataContext = NULL;
137 ULONG RealLength;
138 ULONGLONG RealReadOffset;
139 ULONG RealLengthRead;
140 ULONG ToRead;
141 BOOLEAN AllocatedBuffer = FALSE;
143 ULONGLONG StreamSize;
144
145 DPRINT("NtfsReadFile(%p, %p, %p, %lu, %I64u, %lx, %p)\n", DeviceExt, FileObject, Buffer, Length, ReadOffset, IrpFlags, LengthRead);
146
147 *LengthRead = 0;
148
149 if (Length == 0)
150 {
151 DPRINT1("Null read!\n");
152 return STATUS_SUCCESS;
153 }
154
155 Fcb = (PNTFS_FCB)FileObject->FsContext;
156
158 {
159 DPRINT1("Compressed file!\n");
162 }
163
165 {
166 DPRINT1("Encrypted file!\n");
169 }
170
171 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
172 if (FileRecord == NULL)
173 {
174 DPRINT1("Not enough memory!\n");
176 }
177
178 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
179 if (!NT_SUCCESS(Status))
180 {
181 DPRINT1("Can't find record!\n");
182 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
183 return Status;
184 }
185
186
187 Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext, NULL);
188 if (!NT_SUCCESS(Status))
189 {
190 NTSTATUS BrowseStatus;
192 PNTFS_ATTR_RECORD Attribute;
193
194 DPRINT1("No '%S' data stream associated with file '%wS' (MFT record %I64u, record flags 0x%x)!\n",
195 Fcb->Stream, Fcb->ObjectName, Fcb->MFTIndex, FileRecord->Flags);
196
197 BrowseStatus = FindFirstAttribute(&Context, DeviceExt, FileRecord, FALSE, &Attribute);
198 while (NT_SUCCESS(BrowseStatus))
199 {
200 if (Attribute->Type == AttributeData)
201 {
203
204 Name.Length = Attribute->NameLength * sizeof(WCHAR);
205 Name.MaximumLength = Name.Length;
206 Name.Buffer = (PWCHAR)((ULONG_PTR)Attribute + Attribute->NameOffset);
207 DPRINT1("Data stream: '%wZ' available\n", &Name);
208 }
209
210 BrowseStatus = FindNextAttribute(&Context, &Attribute);
211 }
213
214 /* FindAttribute() failed, so DataContext was never set; there is
215 * nothing to release here. */
216 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
217 return Status;
218 }
219
220 StreamSize = AttributeDataLength(DataContext->pRecord);
221 if (ReadOffset >= StreamSize)
222 {
223 DPRINT("Reading beyond stream end!\n");
224 ReleaseAttributeContext(DataContext);
225 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
226 return STATUS_END_OF_FILE;
227 }
228
229 ToRead = Length;
230 if (ReadOffset + Length > StreamSize)
231 ToRead = (ULONG)(StreamSize - ReadOffset);
232
233 RealReadOffset = ReadOffset;
234 RealLength = ToRead;
235
236 if ((ReadOffset % DeviceExt->NtfsInfo.BytesPerSector) != 0 || (ToRead % DeviceExt->NtfsInfo.BytesPerSector) != 0)
237 {
238 RealReadOffset = ROUND_DOWN(ReadOffset, DeviceExt->NtfsInfo.BytesPerSector);
239 RealLength = ROUND_UP(ToRead, DeviceExt->NtfsInfo.BytesPerSector);
240 /* do we need to extend RealLength by one sector? */
241 if (RealLength + RealReadOffset < ReadOffset + Length)
242 {
243 if (RealReadOffset + RealLength + DeviceExt->NtfsInfo.BytesPerSector <= AttributeAllocatedLength(DataContext->pRecord))
244 RealLength += DeviceExt->NtfsInfo.BytesPerSector;
245 }
246
247
249 if (ReadBuffer == NULL)
250 {
251 DPRINT1("Not enough memory!\n");
252 ReleaseAttributeContext(DataContext);
253 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
255 }
256 AllocatedBuffer = TRUE;
257 }
258
259 DPRINT("Effective read: %lu at %I64u for stream '%S'\n", RealLength, RealReadOffset, Fcb->Stream);
260 /* Only hand the IRP down when reading straight into its buffer: a
261 * forwarded transfer lands at the start of the IRP's MDL, so a bounced
262 * read would end up in the wrong place */
263 RealLengthRead = ReadAttributeToIrp(DeviceExt,
264 DataContext,
265 RealReadOffset,
267 RealLength,
268 AllocatedBuffer ? NULL : Irp);
269 if (RealLengthRead == 0)
270 {
271 DPRINT1("Read failure!\n");
272 ReleaseAttributeContext(DataContext);
273 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
274 if (AllocatedBuffer)
275 {
277 }
278 return Status;
279 }
280
281 ReleaseAttributeContext(DataContext);
282 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
283
284 *LengthRead = ToRead;
285
286 DPRINT("%lu got read\n", *LengthRead);
287
288 if (AllocatedBuffer)
289 {
290 RtlCopyMemory(Buffer, ReadBuffer + (ULONG)(ReadOffset - RealReadOffset), ToRead);
291 }
292
293 if (ToRead != Length)
294 {
295 RtlZeroMemory(Buffer + ToRead, Length - ToRead);
296 }
297
298 if (AllocatedBuffer)
299 {
301 }
302
303 return STATUS_SUCCESS;
304}
305
306/* Sets up the cache map of a handle on its first cached I/O */
307static
308VOID
309NTAPI
313{
314 if (FileObject->PrivateCacheMap == NULL)
315 {
318 FALSE,
320 Fcb);
321 }
322}
323
324static
326NTAPI
328 _In_ PNTFS_IRP_CONTEXT IrpContext,
333 _Out_ PULONG LengthRead)
334{
335 PFILE_OBJECT FileObject = IrpContext->FileObject;
336 BOOLEAN CanWait = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT);
339 BOOLEAN Done = FALSE;
340
341 *LengthRead = 0;
342
344 {
347 }
348
350 goto Post;
351
352 if (ReadOffset->QuadPart >= Fcb->RFCB.FileSize.QuadPart)
353 {
355 return STATUS_END_OF_FILE;
356 }
357
358 if (Length > Fcb->RFCB.FileSize.QuadPart - ReadOffset->QuadPart)
359 Length = (ULONG)(Fcb->RFCB.FileSize.QuadPart - ReadOffset->QuadPart);
360
362 {
364
366 Status = Done ? IoStatus.Status : STATUS_PENDING;
367 }
369 {
370 Done = TRUE;
372 }
373 _SEH2_END;
374
376
377 if (Done)
378 {
379 if (NT_SUCCESS(Status))
380 *LengthRead = (ULONG)IoStatus.Information;
381
382 return Status;
383 }
384
385Post:
386 /* The data isn't in yet, read it from a worker that can wait */
387 Status = NtfsLockUserBuffer(IrpContext->Irp, Length, IoWriteAccess);
388 if (!NT_SUCCESS(Status))
389 return Status;
390
391 return NtfsMarkIrpContextForQueue(IrpContext);
392}
393
394
397{
398 PDEVICE_EXTENSION DeviceExt;
404 ULONG ReturnedReadLength = 0;
406 PIRP Irp;
408
409 DPRINT("NtfsRead(IrpContext %p)\n", IrpContext);
410
411 DeviceObject = IrpContext->DeviceObject;
412 Irp = IrpContext->Irp;
413 Stack = IrpContext->Stack;
414 FileObject = IrpContext->FileObject;
415
416 DeviceExt = DeviceObject->DeviceExtension;
417 ReadLength = Stack->Parameters.Read.Length;
418 ReadOffset = Stack->Parameters.Read.ByteOffset;
420
421 /* Once dismounted the metadata can't be trusted; only raw volume access
422 * is still served */
423 if ((DeviceExt->Flags & VCB_VOLUME_DISMOUNTED) &&
424 !(((PNTFS_FCB)FileObject->FsContext)->Flags & FCB_IS_VOLUME))
425 {
426 Irp->IoStatus.Information = 0;
428 }
429
430 /* A handle on the volume itself is raw access to the partition. */
431 if (((PNTFS_FCB)FileObject->FsContext)->Flags & FCB_IS_VOLUME)
432 {
433 Status = NtfsReadWriteVolume(DeviceExt,
435 Buffer,
437 ReadOffset.QuadPart,
438 Irp,
439 &ReturnedReadLength);
440 }
441 else if (NtfsFCBIsDirectory((PNTFS_FCB)FileObject->FsContext))
442 {
443 /* A directory has no data stream to read */
444 Irp->IoStatus.Information = 0;
446 }
447 else if (!(Irp->Flags & IRP_PAGING_IO) && NtfsIsRegularFileObject(FileObject) &&
448 !FsRtlCheckLockForReadAccess(&((PNTFS_FCB)FileObject->FsContext)->FileLock, Irp))
449 {
450 Irp->IoStatus.Information = 0;
452 }
454 {
455 Status = NtfsCachedRead(IrpContext,
456 (PNTFS_FCB)FileObject->FsContext,
457 Buffer,
459 &ReadOffset,
460 &ReturnedReadLength);
461 if (Status == STATUS_PENDING)
462 return Status;
463 }
464 else
465 {
466 PNTFS_FCB Fcb = (PNTFS_FCB)FileObject->FsContext;
467
468 /* A non cached read must not miss what is still dirty in the cache */
471 {
473
475 }
476
477 Status = NtfsReadFile(DeviceExt,
479 Buffer,
481 ReadOffset.QuadPart,
482 Irp->Flags,
483 Irp,
484 &ReturnedReadLength);
485 }
486 if (NT_SUCCESS(Status))
487 {
488 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
489 {
490 FileObject->CurrentByteOffset.QuadPart =
491 ReadOffset.QuadPart + ReturnedReadLength;
492 }
493
494 Irp->IoStatus.Information = ReturnedReadLength;
495 }
496 else
497 {
498 Irp->IoStatus.Information = 0;
499 }
500
501 return Status;
502}
503
504/* Grows the stream to NewEnd. The caller holds the main resource exclusive. */
505static
507NTAPI
509 _In_ PDEVICE_EXTENSION DeviceExt,
512 _In_ PNTFS_ATTR_CONTEXT DataContext,
513 _In_ ULONG AttributeOffset,
514 _Inout_ PFILE_RECORD_HEADER FileRecord,
515 _In_ ULONGLONG NewEnd,
516 _In_ BOOLEAN CaseSensitive)
517{
520
521 DataSize.QuadPart = NewEnd;
522
523 /* Paging writes look the runs up again, keep them out while those change */
525
526 /* Reserve room past the new end, so the appends that follow fit
527 * without touching the bitmap or the run list. Cleanup gives back
528 * what's left over. */
529 if (DataContext->pRecord->IsNonResident &&
530 (ULONGLONG)DataSize.QuadPart > DataContext->pRecord->NonResident.AllocatedSize)
531 {
532 ULONGLONG Ahead;
533
534 Ahead = min(max(DataSize.QuadPart / 4, NTFS_GROW_AHEAD_MIN), NTFS_GROW_AHEAD_MAX);
535 Status = NtfsExtendAllocation(DeviceExt,
536 DataContext,
537 AttributeOffset,
538 FileRecord,
539 ROUND_UP(DataSize.QuadPart + Ahead, DeviceExt->NtfsInfo.BytesPerCluster));
540 if (!NT_SUCCESS(Status))
541 {
542 /* Not fatal; SetAttributeDataLength() still allocates what's needed */
543 DPRINT("Couldn't reserve ahead of %wS (Status %lx)\n", Fcb->ObjectName, Status);
544 }
545 }
546
547 // set the attribute data length
548 Status = SetAttributeDataLength(FileObject, Fcb, DataContext, AttributeOffset, FileRecord, &DataSize);
549
551
552 if (!NT_SUCCESS(Status))
553 return Status;
554
555 // The file grew, so every copy of its size has to follow.
556 // TODO: adapt this to every filename / hardlink in the record.
558 FileRecord,
559 Fcb->MFTIndex,
561 CaseSensitive);
562
563 return STATUS_SUCCESS;
564}
565
613 const PUCHAR Buffer,
616 ULONG IrpFlags,
617 BOOLEAN CaseSensitive,
618 PIRP Irp,
619 PULONG LengthWritten)
620{
623 PFILE_RECORD_HEADER FileRecord;
624 PNTFS_ATTR_CONTEXT DataContext = NULL;
625 ULONG AttributeOffset;
626 ULONGLONG StreamSize;
627 ULONG RequestedLength = 0;
628
629 DPRINT("NtfsWriteFile(%p, %p, %p, %lu, %I64u, %x, %s, %p)\n",
630 DeviceExt,
632 Buffer,
633 Length,
635 IrpFlags,
636 (CaseSensitive ? "TRUE" : "FALSE"),
637 LengthWritten);
638
639 *LengthWritten = 0;
640
641 ASSERT(DeviceExt);
642
643 if (Length == 0)
644 {
645 if (Buffer == NULL)
646 return STATUS_SUCCESS;
647 else
649 }
650
651 // get the File control block
652 Fcb = (PNTFS_FCB)FileObject->FsContext;
653 ASSERT(Fcb);
654
655 DPRINT("Fcb->PathName: %wS\n", Fcb->PathName);
656 DPRINT("Fcb->ObjectName: %wS\n", Fcb->ObjectName);
657
658 // we don't yet handle compression
660 {
661 DPRINT("Compressed file!\n");
664 }
665
666 // allocate non-paged memory for the FILE_RECORD_HEADER
667 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
668 if (FileRecord == NULL)
669 {
670 DPRINT1("Not enough memory! Can't write %wS!\n", Fcb->PathName);
672 }
673
674 // read the FILE_RECORD_HEADER from the drive (or cache)
675 DPRINT("Reading file record...\n");
676 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
677 if (!NT_SUCCESS(Status))
678 {
679 // We couldn't get the file's record. Free the memory and return the error
680 DPRINT1("Can't find record for %wS!\n", Fcb->ObjectName);
681 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
682 return Status;
683 }
684
685 DPRINT("Found record for %wS\n", Fcb->ObjectName);
686
687 // Find the attribute with the data stream for our file
688 DPRINT("Finding Data Attribute...\n");
689 Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext,
690 &AttributeOffset);
691
692 // Did we fail to find the attribute?
693 if (!NT_SUCCESS(Status))
694 {
695 NTSTATUS BrowseStatus;
697 PNTFS_ATTR_RECORD Attribute;
698
699 DPRINT1("No '%S' data stream associated with file '%wS' (MFT record %I64u, record flags 0x%x)!\n",
700 Fcb->Stream, Fcb->ObjectName, Fcb->MFTIndex, FileRecord->Flags);
701
702 // Couldn't find the requested data stream; print a list of streams available
703 BrowseStatus = FindFirstAttribute(&Context, DeviceExt, FileRecord, FALSE, &Attribute);
704 while (NT_SUCCESS(BrowseStatus))
705 {
706 if (Attribute->Type == AttributeData)
707 {
709
710 Name.Length = Attribute->NameLength * sizeof(WCHAR);
711 Name.MaximumLength = Name.Length;
712 Name.Buffer = (PWCHAR)((ULONG_PTR)Attribute + Attribute->NameOffset);
713 DPRINT1("Data stream: '%wZ' available\n", &Name);
714 }
715
716 BrowseStatus = FindNextAttribute(&Context, &Attribute);
717 }
719
720 /* FindAttribute() failed, so DataContext was never set; there is
721 * nothing to release here. */
722 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
723 return Status;
724 }
725
726 // Get the size of the stream on disk
727 StreamSize = AttributeDataLength(DataContext->pRecord);
728
729 DPRINT("WriteOffset: %I64u\tStreamSize: %I64u\n", WriteOffset, StreamSize);
730
731 // Are we trying to write beyond the end of the stream?
732 if (WriteOffset + Length > StreamSize)
733 {
734 // is increasing the stream size allowed?
735 if (!(Fcb->Flags & FCB_IS_VOLUME) &&
736 !(IrpFlags & IRP_PAGING_IO))
737 {
738 Status = NtfsGrowStream(DeviceExt,
740 Fcb,
741 DataContext,
742 AttributeOffset,
743 FileRecord,
745 CaseSensitive);
746 if (!NT_SUCCESS(Status))
747 {
748 ReleaseAttributeContext(DataContext);
749 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
750 *LengthWritten = 0;
751 return Status;
752 }
753 }
754 else if (IrpFlags & IRP_PAGING_IO)
755 {
756 /* Mm flushes whole pages, so a file's last page routinely reaches
757 * past its end. A paging write must not change the file size, so
758 * clamp instead of failing - refusing it would lose the valid
759 * bytes before the end too. */
760 if (WriteOffset >= StreamSize)
761 {
762 DPRINT("Paging write entirely past the end of the stream; nothing to do\n");
763
764 ReleaseAttributeContext(DataContext);
765 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
766 *LengthWritten = Length;
767 return STATUS_SUCCESS;
768 }
769
770 DPRINT("Clamping paging write of %lu bytes at %I64u to stream size %I64u\n",
771 Length, WriteOffset, StreamSize);
772
773 RequestedLength = Length;
774 Length = (ULONG)(StreamSize - WriteOffset);
775 }
776 else
777 {
778 /* The volume stream is the size of the volume and cannot grow */
779 ReleaseAttributeContext(DataContext);
780 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
781 *LengthWritten = 0;
783 }
784 }
785
786 DPRINT("Length: %lu\tWriteOffset: %I64u\tStreamSize: %I64u\n", Length, WriteOffset, StreamSize);
787
788 // Write the data to the attribute
789 /* Buffer is the system mapping of this IRP's MDL, so hand the IRP down too
790 * and let the run layer borrow it instead of locking these pages twice,
791 * which the paging path forbids */
792 Status = WriteAttributeFromIrp(DeviceExt, DataContext, WriteOffset, Buffer, Length, LengthWritten, FileRecord, Irp);
793
794 // Did the write fail?
795 if (!NT_SUCCESS(Status))
796 {
797 DPRINT1("Write failure!\n");
798 ReleaseAttributeContext(DataContext);
799 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
800
801 return Status;
802 }
803
804 // This should never happen:
805 if (*LengthWritten != Length)
806 {
807 DPRINT1("\a\tNTFS DRIVER ERROR: length written (%lu) differs from requested (%lu), but no error was indicated!\n",
808 *LengthWritten, Length);
810 }
811
812 // A clamped paging write stored all the stream had room for, so as far as
813 // Mm is concerned the whole page is done
814 if (RequestedLength != 0 && NT_SUCCESS(Status))
815 *LengthWritten = RequestedLength;
816
817 ReleaseAttributeContext(DataContext);
818 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
819
820 return Status;
821}
822
823/* Grows the file for a cached write ending at NewEnd */
824static
826NTAPI
830 _In_ ULONGLONG NewEnd,
831 _In_ BOOLEAN CaseSensitive)
832{
833 PDEVICE_EXTENSION DeviceExt = Fcb->Vcb;
834 PFILE_RECORD_HEADER FileRecord;
835 PNTFS_ATTR_CONTEXT DataContext;
836 ULONG AttributeOffset;
838
839 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
840 if (FileRecord == NULL)
842
843 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
844 if (NT_SUCCESS(Status))
845 {
846 Status = FindAttribute(DeviceExt, FileRecord, AttributeData, Fcb->Stream, wcslen(Fcb->Stream), &DataContext, &AttributeOffset);
847 if (NT_SUCCESS(Status))
848 {
849 Status = NtfsGrowStream(DeviceExt, FileObject, Fcb, DataContext, AttributeOffset, FileRecord, NewEnd, CaseSensitive);
850 ReleaseAttributeContext(DataContext);
851 }
852 }
853
854 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
855
856 return Status;
857}
858
859static
861NTAPI
863 _In_ PNTFS_IRP_CONTEXT IrpContext,
868 _In_ BOOLEAN CaseSensitive,
869 _Out_ PULONG LengthWritten)
870{
871 PFILE_OBJECT FileObject = IrpContext->FileObject;
872 LONGLONG WriteEnd = WriteOffset->QuadPart + Length;
873 LARGE_INTEGER OldValidData;
874 BOOLEAN HideNewData = FALSE;
876
877 *LengthWritten = 0;
878
880 {
883 }
884
885 /* Let Cc throttle us before we hold anything */
887
889
891 {
893
894 OldValidData = Fcb->RFCB.ValidDataLength;
895
896 if (WriteEnd > Fcb->RFCB.FileSize.QuadPart)
897 {
898 Status = NtfsGrowFileForWrite(FileObject, Fcb, WriteEnd, CaseSensitive);
899 if (!NT_SUCCESS(Status))
901 }
902
903 /* Don't let Cc read from disk what we are about to overwrite, and
904 * make whatever lies before the write read as zeroes */
905 if (WriteEnd > OldValidData.QuadPart)
906 {
907 CC_FILE_SIZES Sizes;
908
910 Sizes.FileSize = Fcb->RFCB.FileSize;
911 Sizes.ValidDataLength = OldValidData;
912 CcSetFileSizes(FileObject, &Sizes);
913 HideNewData = TRUE;
914
915 if (WriteOffset->QuadPart > OldValidData.QuadPart)
916 CcZeroData(FileObject, &OldValidData, WriteOffset, TRUE);
917 }
918
920 {
923 }
924
925 *LengthWritten = Length;
926 }
928 {
930 }
931 _SEH2_END;
932
933 /* Back to the real valid data length, or a page Mm drops would read back as zeroes */
934 if (HideNewData)
936
938
939 return Status;
940}
941
966{
972 ULONG Length = 0;
973 ULONG ReturnedWriteLength = 0;
975 PDEVICE_EXTENSION DeviceExt = NULL;
977 PIRP Irp = NULL;
978 ULONG BytesPerSector;
979
980 DPRINT("NtfsWrite(IrpContext %p)\n", IrpContext);
981 ASSERT(IrpContext);
982
983 // get the I/O request packet
984 Irp = IrpContext->Irp;
985
986 // This request is not allowed on the main device object
987 if (IrpContext->DeviceObject == NtfsGlobalData->DeviceObject)
988 {
989 DPRINT1("\t\t\t\tNtfsWrite is called with the main device object.\n");
990
991 Irp->IoStatus.Information = 0;
993 }
994
995 // get the File control block
996 Fcb = (PNTFS_FCB)IrpContext->FileObject->FsContext;
997 ASSERT(Fcb);
998
999 DPRINT("About to write %wS\n", Fcb->ObjectName);
1000 DPRINT("NTFS Version: %d.%d\n", Fcb->Vcb->NtfsInfo.MajorVersion, Fcb->Vcb->NtfsInfo.MinorVersion);
1001
1002 // setup some more locals
1003 FileObject = IrpContext->FileObject;
1004 DeviceObject = IrpContext->DeviceObject;
1005 DeviceExt = DeviceObject->DeviceExtension;
1006 BytesPerSector = DeviceExt->StorageDevice->SectorSize;
1007 Length = IrpContext->Stack->Parameters.Write.Length;
1008
1009 // get the file offset we'll be writing to
1010 ByteOffset = IrpContext->Stack->Parameters.Write.ByteOffset;
1011 if (ByteOffset.u.LowPart == FILE_WRITE_TO_END_OF_FILE &&
1012 ByteOffset.u.HighPart == -1)
1013 {
1014 ByteOffset.QuadPart = Fcb->RFCB.FileSize.QuadPart;
1015 }
1016
1017 DPRINT("ByteOffset: %I64u\tLength: %lu\tBytes per sector: %lu\n", ByteOffset.QuadPart,
1018 Length, BytesPerSector);
1019
1020 /* Offsets are 64 bits all the way down, only reject what can't be a file position */
1021 if (ByteOffset.QuadPart < 0 || ByteOffset.QuadPart + Length < ByteOffset.QuadPart)
1022 {
1023 DPRINT1("Invalid write offset %I64d, length %lu\n", ByteOffset.QuadPart, Length);
1025 }
1026
1027 // Is this a non-cached write? A non-buffered write?
1028 if (IrpContext->Irp->Flags & (IRP_PAGING_IO | IRP_NOCACHE) || (Fcb->Flags & FCB_IS_VOLUME) ||
1029 IrpContext->FileObject->Flags & FILE_NO_INTERMEDIATE_BUFFERING)
1030 {
1031 // non-cached and non-buffered writes must be sector aligned
1032 if (ByteOffset.u.LowPart % BytesPerSector != 0 || Length % BytesPerSector != 0)
1033 {
1034 DPRINT1("Non-cached writes and non-buffered writes must be sector aligned!\n");
1036 }
1037 }
1038
1039 /* A zero length write is a valid no-op */
1040 if (Length == 0)
1041 {
1042 // FIXME: Update last write time
1043 IrpContext->Irp->IoStatus.Information = 0;
1044 return STATUS_SUCCESS;
1045 }
1046
1047 /* Is this an async request to a file? Serving a write means reading the
1048 * file record, walking its attributes and possibly growing the allocation,
1049 * all of it blocking metadata I/O, so post it to a worker thread which
1050 * runs the same path with IRPCONTEXT_CANWAIT set. Lock the user buffer
1051 * here, while we're still in the requesting thread's address space. */
1052 if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT) && !(Fcb->Flags & FCB_IS_VOLUME))
1053 {
1055 if (!NT_SUCCESS(Status))
1056 {
1057 DPRINT1("Unable to lock user buffer!\n");
1058 return Status;
1059 }
1060
1061 return NtfsMarkIrpContextForQueue(IrpContext);
1062 }
1063
1064 /* Byte range locks only stop other handles, never Mm or Cc */
1067 {
1068 Irp->IoStatus.Information = 0;
1070 }
1071
1072 /* Regular writes go through the cache, the lazy writer brings them to disk */
1073 if (!(Irp->Flags & (IRP_PAGING_IO | IRP_NOCACHE)) &&
1076 {
1077 if (DeviceExt->Flags & VCB_VOLUME_DISMOUNTED)
1078 {
1079 Irp->IoStatus.Information = 0;
1081 }
1082
1083 Status = NtfsCachedWrite(IrpContext,
1084 Fcb,
1086 Length,
1087 &ByteOffset,
1089 &ReturnedWriteLength);
1090 if (NT_SUCCESS(Status))
1091 {
1092 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1093 FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + ReturnedWriteLength;
1094
1095 IrpContext->PriorityBoost = IO_DISK_INCREMENT;
1096 }
1097
1098 Irp->IoStatus.Information = NT_SUCCESS(Status) ? ReturnedWriteLength : 0;
1099 return Status;
1100 }
1101
1102 // get the Resource
1103 if (Fcb->Flags & FCB_IS_VOLUME)
1104 {
1105 Resource = &DeviceExt->DirResource;
1106 }
1107 else if (IrpContext->Irp->Flags & IRP_PAGING_IO)
1108 {
1110 }
1111 else
1112 {
1114 }
1115
1116 /* Paging writes never change the sizes, and Cc or Mm may already hold the
1117 * paging resource shared for us. Size changes take it exclusive. */
1118 if (Resource == &Fcb->PagingIoResource)
1119 {
1121 return STATUS_CANT_WAIT;
1122 }
1124 {
1125 return STATUS_CANT_WAIT;
1126 }
1127
1128 // get the buffer of data the user is trying to write
1130 ASSERT(Buffer);
1131
1132 // lock the buffer
1134
1135 // were we unable to lock the buffer?
1136 if (!NT_SUCCESS(Status))
1137 {
1138 DPRINT1("Unable to lock user buffer!\n");
1139
1141 return Status;
1142 }
1143
1144 DPRINT("Existing File Size(Fcb->RFCB.FileSize.QuadPart): %I64u\n", Fcb->RFCB.FileSize.QuadPart);
1145 DPRINT("About to write the data. Length: %lu\n", Length);
1146
1147
1148 /* See NtfsRead() */
1149 if ((DeviceExt->Flags & VCB_VOLUME_DISMOUNTED) &&
1150 !(Fcb->Flags & FCB_IS_VOLUME))
1151 {
1153 Irp->IoStatus.Information = 0;
1155 }
1156
1157 // write the file
1158 if (Fcb->Flags & FCB_IS_VOLUME)
1159 {
1160 /* Raw access to the partition, including after a dismount. */
1161 Status = NtfsReadWriteVolume(DeviceExt,
1163 Buffer,
1164 Length,
1165 ByteOffset.QuadPart,
1166 Irp,
1167 &ReturnedWriteLength);
1168 }
1169 else if (NtfsFCBIsDirectory(Fcb))
1170 {
1171 /* A directory has no data stream to write */
1173 Irp->IoStatus.Information = 0;
1175 }
1176 else
1177 {
1178 /* What goes straight to disk must not be overwritten by stale cached data later */
1181 {
1183
1186 }
1187
1188 Status = NtfsWriteFile(DeviceExt,
1189 FileObject,
1190 Buffer,
1191 Length,
1192 ByteOffset.QuadPart,
1193 Irp->Flags,
1195 Irp,
1196 &ReturnedWriteLength);
1197 }
1198
1199 IrpContext->Irp->IoStatus.Status = Status;
1200
1201 // was the write successful?
1202 if (NT_SUCCESS(Status))
1203 {
1204 // TODO: Update timestamps
1205
1206 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1207 {
1208 // advance the file pointer
1209 FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + ReturnedWriteLength;
1210 }
1211
1212 IrpContext->PriorityBoost = IO_DISK_INCREMENT;
1213 }
1214 else
1215 {
1216 DPRINT1("Write not Succesful!\tReturned length: %lu\n", ReturnedWriteLength);
1217 }
1218
1219 Irp->IoStatus.Information = ReturnedWriteLength;
1220
1221 // Note: We leave the user buffer that we locked alone, it's up to the I/O manager to unlock and free it
1222
1224
1225 return Status;
1226}
1227
1228/* EOF */
ULONG ReadLength
unsigned char BOOLEAN
Definition: actypes.h:127
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
Definition: bufpool.h:45
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
NTSTATUS FindFirstAttribute(PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1413
VOID FindCloseAttribute(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1495
NTSTATUS FindNextAttribute(PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1461
NTSTATUS NtfsLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: misc.c:158
PVOID NtfsGetUserBuffer(PIRP Irp, BOOLEAN Paging)
Definition: misc.c:120
PNTFS_GLOBAL_DATA NtfsGlobalData
Definition: ntfs.c:36
FORCEINLINE NTSTATUS NtfsMarkIrpContextForQueue(PNTFS_IRP_CONTEXT IrpContext)
Definition: ntfs.h:652
#define VCB_VOLUME_DISMOUNTED
Definition: ntfs.h:148
#define NTFS_FILENAME_UPDATE_SIZES
Definition: ntfs.h:1332
#define IRPCONTEXT_CANWAIT
Definition: ntfs.h:505
@ AttributeData
Definition: ntfs.h:195
struct _FCB * PNTFS_FCB
#define TAG_NTFS
Definition: ntfs.h:12
#define FCB_IS_VOLUME
Definition: ntfs.h:585
NTSTATUS NtfsWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, const PUCHAR Buffer, ULONG Length, ULONGLONG WriteOffset, ULONG IrpFlags, BOOLEAN CaseSensitive, PIRP Irp, PULONG LengthWritten)
Definition: rw.c:611
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)
Definition: rw.c:862
static NTSTATUS NtfsReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PUCHAR Buffer, ULONG Length, ULONGLONG ReadOffset, ULONG IrpFlags, PIRP Irp, PULONG LengthRead)
Definition: rw.c:124
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)
Definition: rw.c:508
static NTSTATUS NTAPI NtfsGrowFileForWrite(_In_ PFILE_OBJECT FileObject, _In_ PNTFS_FCB Fcb, _In_ ULONGLONG NewEnd, _In_ BOOLEAN CaseSensitive)
Definition: rw.c:827
#define NTFS_GROW_AHEAD_MIN
Definition: rw.c:37
NTSTATUS NtfsRead(PNTFS_IRP_CONTEXT IrpContext)
Definition: rw.c:396
NTSTATUS NtfsWrite(PNTFS_IRP_CONTEXT IrpContext)
Definition: rw.c:965
static VOID NTAPI NtfsEnsureCacheMap(_In_ PFILE_OBJECT FileObject, _In_ PNTFS_FCB Fcb)
Definition: rw.c:310
static NTSTATUS NtfsReadWriteVolume(PDEVICE_EXTENSION DeviceExt, UCHAR MajorFunction, PUCHAR Buffer, ULONG Length, LONGLONG Offset, PIRP Irp, PULONG LengthTransferred)
Definition: rw.c:80
#define NTFS_GROW_AHEAD_MAX
Definition: rw.c:38
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)
Definition: rw.c:327
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
#define FILE_WRITE_TO_END_OF_FILE
Definition: ext2fs.h:278
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:732
BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:712
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:672
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
Definition: fssup.c:414
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
Status
Definition: gdiplustypes.h:24
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
_In_ PIRP Irp
Definition: kse.h:79
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
if(dx< 0)
Definition: linetemp.h:194
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
Definition: mft.c:1936
NTSTATUS NtfsUpdateDuplicatedInformation(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, ULONGLONG MFTIndex, ULONG Flags, BOOLEAN CaseSensitive)
Definition: mft.c:1995
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
Definition: mft.c:104
NTSTATUS NtfsExtendAllocation(_In_ PDEVICE_EXTENSION Vcb, _In_ PNTFS_ATTR_CONTEXT AttrContext, _In_ ULONG AttrOffset, _In_ PFILE_RECORD_HEADER FileRecord, _In_ ULONGLONG AllocationSize)
Definition: mft.c:753
ULONGLONG AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:259
NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, PNTFS_ATTR_CONTEXT *AttrCtx, PULONG Offset)
Definition: mft.c:131
NTSTATUS WriteAttributeFromIrp(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, const PUCHAR Buffer, ULONG Length, PULONG RealLengthWritten, PFILE_RECORD_HEADER FileRecord, PIRP Irp)
Definition: mft.c:1677
ULONGLONG AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:249
ULONG ReadAttributeToIrp(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length, PIRP Irp)
Definition: mft.c:1556
NTSTATUS SetAttributeDataLength(PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, PLARGE_INTEGER DataSize)
Definition: mft.c:615
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define min(a, b)
Definition: monoChain.cc:55
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
VOID NtfsFreeIoRunList(IN OUT PNTFS_IO_RUN_LIST RunList)
Definition: blockdev.c:140
NTSTATUS NtfsAddIoRun(IN OUT PNTFS_IO_RUN_LIST RunList, IN LONGLONG Lbo, IN ULONG ByteCount)
Definition: blockdev.c:74
VOID NtfsInitIoRunList(OUT PNTFS_IO_RUN_LIST RunList)
Definition: blockdev.c:40
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)
Definition: blockdev.c:743
BOOLEAN NtfsFCBIsDirectory(PNTFS_FCB Fcb)
Definition: fcb.c:144
BOOLEAN NtfsFCBIsEncrypted(PNTFS_FCB Fcb)
Definition: fcb.c:179
BOOLEAN NTAPI NtfsIsRegularFileObject(_In_ PFILE_OBJECT FileObject)
Definition: fcb.c:153
BOOLEAN NtfsFCBIsCompressed(PNTFS_FCB Fcb)
Definition: fcb.c:173
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
Definition: copysup.c:214
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)
Definition: copysup.c:43
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define STATUS_CANT_WAIT
Definition: ntstatus.h:546
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:414
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:869
#define STATUS_UNEXPECTED_IO_ERROR
Definition: ntstatus.h:563
short WCHAR
Definition: pedump.c:58
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_LEAVE
Definition: pseh2_64.h:206
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
USHORT NameOffset
Definition: ntfs.h:138
UCHAR NameLength
Definition: ntfs.h:137
ULONG Type
Definition: ntfs.h:134
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:175
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks
Definition: ntfs.h:176
PFILE_OBJECT FileObject
Definition: ntfs.h:564
ULONG Flags
Definition: ntfs.h:556
PIO_STACK_LOCATION Stack
Definition: ntfs.h:557
CCHAR PriorityBoost
Definition: ntfs.h:566
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:563
LARGE_INTEGER FileSize
Definition: cctypes.h:16
LARGE_INTEGER ValidDataLength
Definition: cctypes.h:17
LARGE_INTEGER AllocationSize
Definition: cctypes.h:15
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:618
PVCB Vcb
Definition: cdstruc.h:933
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:593
ULONGLONG MFTIndex
Definition: ntfs.h:622
WCHAR Stream[MAX_PATH]
Definition: ntfs.h:602
ERESOURCE PagingIoResource
Definition: ntfs.h:606
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:597
WCHAR * ObjectName
Definition: ntfs.h:603
FILE_LOCK FileLock
Definition: fatstruc.h:1071
WCHAR PathName[MAX_PATH]
Definition: ntfs.h:604
ERESOURCE MainResource
Definition: ntfs.h:607
USHORT Flags
Definition: ntfs.h:287
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
struct _IO_STACK_LOCATION::@5020::@5025 Write
union _IO_STACK_LOCATION::@1814 Parameters
IO_STATUS_BLOCK IoStatus
#define max(a, b)
Definition: svc.c:63
#define STATUS_PENDING
Definition: telnetd.h:14
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: typedefs.h:53
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
uint64_t ULONGLONG
Definition: typedefs.h:67
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1703
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET ReadOffset
Definition: wdfusb.h:2003
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET WriteOffset
Definition: wdfusb.h:1921
#define IRP_PAGING_IO
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1778
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define IRP_NOCACHE
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1820
@ IoReadAccess
Definition: ketypes.h:931
@ IoWriteAccess
Definition: ketypes.h:932