ReactOS  0.4.14-dev-50-g13bb5e2
write.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYRIGHT.TXT
3  * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4  * FILE: write.c
5  * PROGRAMMER: Matt Wu <mattwu@163.com>
6  * HOMEPAGE: http://www.ext2fsd.com
7  * UPDATE HISTORY:
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include "ext2fs.h"
13 
14 /* GLOBALS ***************************************************************/
15 
17 
18 #define DL_FLP DL_DBG
19 
20 /* DEFINITIONS *************************************************************/
21 
22 #define EXT2_FLPFLUSH_MAGIC 'FF2E'
23 
24 typedef struct _EXT2_FLPFLUSH_CONTEXT {
25 
29 
33 
35 
36 VOID NTAPI
38 
39 VOID NTAPI
41  IN PKDPC Dpc,
45 
46 
49 
52 
55 
56 VOID
58 
59 
60 /* FUNCTIONS *************************************************************/
61 
62 VOID NTAPI
64 {
67  PEXT2_FCB Fcb;
68  PEXT2_VCB Vcb;
69 
71  FileObject = Context->FileObject;
72  Fcb = Context->Fcb;
73  Vcb = Context->Vcb;
74 
75  DEBUG(DL_FLP, ("Ext2FloppyFlushing ...\n"));
76 
78 
79  if (FileObject) {
80  ASSERT(Fcb == (PEXT2_FCB)FileObject->FsContext);
84 
85  CcFlushCache(&(Fcb->SectionObject), NULL, 0, NULL);
87 
89  }
90 
91  if (Vcb) {
92  ExAcquireResourceExclusiveLite(&Vcb->MainResource, TRUE);
93 
94  ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
95  ExReleaseResourceLite(&Vcb->PagingIoResource);
96 
98  ExReleaseResourceLite(&Vcb->MainResource);
99  }
100 
103 }
104 
105 VOID NTAPI
107  IN PKDPC Dpc,
111 )
112 {
114 
116 
117  DEBUG(DL_FLP, ("Ext2FloppyFlushDpc is to be started...\n"));
118 
120 }
121 
122 VOID
124  PEXT2_VCB Vcb,
125  PEXT2_FCB Fcb,
127 {
128  LARGE_INTEGER OneSecond;
130 
132 
134  NonPagedPool,
135  sizeof(EXT2_FLPFLUSH_CONTEXT),
137  );
138 
139  if (!Context) {
140  DEBUG(DL_ERR, ( "Ex2StartFloppy...: failed to allocate Context\n"));
141  DbgBreak();
142  return;
143  }
144 
145  KeInitializeTimer(&Context->Timer);
146 
147  KeInitializeDpc( &Context->Dpc,
149  Context );
150 
153  Context );
154 
155  Context->Vcb = Vcb;
156  Context->Fcb = Fcb;
157  Context->FileObject = FileObject;
158 
159  if (FileObject) {
161  }
162 
163  OneSecond.QuadPart = (LONGLONG)-1*1000*1000*10;
164  KeSetTimer( &Context->Timer,
165  OneSecond,
166  &Context->Dpc );
167 }
168 
169 BOOLEAN
171  IN PEXT2_IRP_CONTEXT IrpContext,
172  IN PEXT2_VCB Vcb,
175  IN PLARGE_INTEGER End
176  )
177 {
178  PEXT2_FCB Fcb;
179  PBCB Bcb;
180  PVOID Ptr;
181  ULONG Size;
182  BOOLEAN rc = TRUE;
183 
184  ASSERT (End && Start && End->QuadPart > Start->QuadPart);
185  Fcb = (PEXT2_FCB) FileObject->FsContext;
186 
187  /* skip data zero if we've already tracked unwritten part */
188  if (0 == ( End->LowPart & (BLOCK_SIZE -1)) &&
189  0 == (Start->LowPart & (BLOCK_SIZE -1))) {
190 
191  if (INODE_HAS_EXTENT(Fcb->Inode)) {
192  return TRUE;
193  } else {
194 #if !EXT2_PRE_ALLOCATION_SUPPORT
195  return TRUE;
196 #endif
197  }
198  }
199 
200  /* clear data in range [Start, End) */
201  _SEH2_TRY {
202  rc = CcZeroData(FileObject, Start, End, Ext2CanIWait());
204  DbgBreak();
205  } _SEH2_END;
206 
207  return rc;
208 }
209 
210 VOID
212 {
213  ASSERT(IrpContext->Irp == Irp);
214 
215  Ext2QueueRequest(IrpContext);
216 }
217 
218 
219 NTSTATUS
221 {
223 
224  PEXT2_VCB Vcb = NULL;
225  PEXT2_CCB Ccb = NULL;
226  PEXT2_FCBVCB FcbOrVcb = NULL;
228 
230 
231  PIRP Irp = NULL;
232  PIO_STACK_LOCATION IoStackLocation = NULL;
233 
234  ULONG Length;
236 
237  BOOLEAN PagingIo = FALSE;
238  BOOLEAN Nocache = FALSE;
239  BOOLEAN SynchronousIo = FALSE;
240  BOOLEAN MainResourceAcquired = FALSE;
241 
242  BOOLEAN bDeferred = FALSE;
243 
244  PUCHAR Buffer = NULL;
245  PEXT2_EXTENT Chain = NULL;
246  EXT2_EXTENT BlockArray;
247 
248  _SEH2_TRY {
249 
250  ASSERT(IrpContext);
251  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
252  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
253 
254  DeviceObject = IrpContext->DeviceObject;
256  ASSERT(Vcb != NULL);
257  ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
258  (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
259 
260  FileObject = IrpContext->FileObject;
261  FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
262  ASSERT(FcbOrVcb);
263 
264  if (!(FcbOrVcb->Identifier.Type == EXT2VCB && (PVOID)FcbOrVcb == (PVOID)Vcb)) {
266  _SEH2_LEAVE;
267  }
268 
269  Ccb = (PEXT2_CCB) FileObject->FsContext2;
270  Irp = IrpContext->Irp;
271  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
272 
273  Length = IoStackLocation->Parameters.Write.Length;
274  ByteOffset = IoStackLocation->Parameters.Write.ByteOffset;
275 
276  PagingIo = IsFlagOn(Irp->Flags, IRP_PAGING_IO);
277  Nocache = IsFlagOn(Irp->Flags, IRP_NOCACHE) || (Ccb != NULL);
278  SynchronousIo = IsFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);
279 
280  if (PagingIo) {
281  ASSERT(Nocache);
282  }
283 
284  DEBUG(DL_INF, ("Ext2WriteVolume: Off=%I64xh Len=%xh Paging=%xh Nocache=%xh\n",
285  ByteOffset.QuadPart, Length, PagingIo, Nocache));
286 
287  if (Length == 0) {
288  Irp->IoStatus.Information = 0;
290  _SEH2_LEAVE;
291  }
292 
293  if (Nocache &&
294  (ByteOffset.LowPart & (SECTOR_SIZE - 1) ||
295  Length & (SECTOR_SIZE - 1))) {
297  _SEH2_LEAVE;
298  }
299 
300  if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
301  ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
303  _SEH2_LEAVE;
304  }
305 
306  if (ByteOffset.QuadPart >=
307  Vcb->PartitionInformation.PartitionLength.QuadPart ) {
308  Irp->IoStatus.Information = 0;
310  _SEH2_LEAVE;
311  }
312 
313  if (!Nocache) {
314 
315  BOOLEAN bAgain = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
316  BOOLEAN bWait = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
317  BOOLEAN bQueue = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
318 
319  if ( !CcCanIWrite(
320  FileObject,
321  Length,
322  (bWait && bQueue),
323  bAgain ) ) {
324 
326  IrpContext->Irp,
327  Length,
328  IoReadAccess);
329  if (NT_SUCCESS(Status)) {
330  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
333  IrpContext,
334  Irp,
335  Length,
336  bAgain );
337 
338  bDeferred = TRUE;
340 
341  _SEH2_LEAVE;
342  }
343  }
344  }
345 
346  /*
347  * User direct volume access
348  */
349 
350  if (Ccb != NULL && !PagingIo) {
351 
353 
354  if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
356  }
357 
359  }
360 
362  if (ByteOffset.QuadPart + Length > Vcb->Header.FileSize.QuadPart) {
363  Length = (ULONG)(Vcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
364  }
365  }
366 
367  } else if (Nocache && !PagingIo && (Vcb->SectionObject.DataSectionObject != NULL)) {
368 
369  ExAcquireResourceExclusiveLite(&Vcb->MainResource, TRUE);
370  MainResourceAcquired = TRUE;
371 
372  ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
373  ExReleaseResourceLite(&Vcb->PagingIoResource);
374 
375  CcFlushCache( &(Vcb->SectionObject),
376  &ByteOffset,
377  Length,
378  &(Irp->IoStatus));
379 
380  if (!NT_SUCCESS(Irp->IoStatus.Status)) {
381  Status = Irp->IoStatus.Status;
382  _SEH2_LEAVE;
383  }
384 
385  ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
386  ExReleaseResourceLite(&Vcb->PagingIoResource);
387 
388  CcPurgeCacheSection( &(Vcb->SectionObject),
390  Length,
391  FALSE );
392 
393  ExReleaseResourceLite(&Vcb->MainResource);
394  MainResourceAcquired = FALSE;
395  }
396 
397  if ( (ByteOffset.QuadPart + Length) > Vcb->Header.FileSize.QuadPart) {
398  Length = (ULONG)(Vcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
399  }
400 
401  if (!Nocache) {
402 
403  if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
404 
406  Vcb->Volume,
407  &ByteOffset,
408  Length,
409  &Irp->MdlAddress,
410  &Irp->IoStatus );
411 
412  Status = Irp->IoStatus.Status;
413 
414  } else {
415 
417  if (Buffer == NULL) {
418  DbgBreak();
419 
421  _SEH2_LEAVE;
422  }
423 
424  if (!CcCopyWrite( Vcb->Volume,
426  Length,
427  TRUE,
428  Buffer )) {
430  _SEH2_LEAVE;
431  }
432 
433  Status = Irp->IoStatus.Status;
435  }
436 
437  if (NT_SUCCESS(Status)) {
438  Irp->IoStatus.Information = Length;
439  }
440 
441  } else if (PagingIo) {
442 
443  LONGLONG DirtyStart;
444  LONGLONG DirtyLba;
445  LONGLONG DirtyLength;
446  LONGLONG RemainLength;
447 
450 
451  Length &= ~((ULONG)SECTOR_SIZE - 1);
452 
453  Status = Ext2LockUserBuffer(IrpContext->Irp, Length, IoReadAccess);
454  if (!NT_SUCCESS(Status)) {
455  _SEH2_LEAVE;
456  }
457 
458  DirtyLba = ByteOffset.QuadPart;
459  RemainLength = (LONGLONG) Length;
460 
462 
463  while (RemainLength > 0) {
464 
465  DirtyStart = DirtyLba;
466  ASSERT(DirtyStart >= ByteOffset.QuadPart);
467  ASSERT(DirtyStart <= ByteOffset.QuadPart + Length);
468 
469  if (Ext2LookupVcbExtent(Vcb, DirtyStart, &DirtyLba, &DirtyLength)) {
470 
471  if (DirtyLba == -1) {
472 
473  DirtyLba = DirtyStart + DirtyLength;
474  if (ByteOffset.QuadPart + Length > DirtyLba) {
475  RemainLength = ByteOffset.QuadPart + Length - DirtyLba;
476  ASSERT(DirtyStart >= ByteOffset.QuadPart);
477  ASSERT(DirtyStart <= ByteOffset.QuadPart + Length);
478  } else {
479  RemainLength = 0;
480  }
481  continue;
482  }
483 
484  ASSERT(DirtyLba <= DirtyStart);
486 
487  if (!Extent) {
488  DEBUG(DL_ERR, ( "Ex2WriteVolume: failed to allocate Extent\n"));
490  _SEH2_LEAVE;
491  }
492 
493  Extent->Irp = NULL;
494  Extent->Lba = DirtyStart;
495  Extent->Offset = (ULONG)( DirtyStart + Length -
496  RemainLength - DirtyLba );
497  ASSERT(Extent->Offset <= Length);
498 
499  if (DirtyLba + DirtyLength >= DirtyStart + RemainLength) {
500  Extent->Length = (ULONG)( DirtyLba +
501  RemainLength -
502  DirtyStart );
503  ASSERT(Extent->Length <= Length);
504  RemainLength = 0;
505  } else {
506  Extent->Length = (ULONG)(DirtyLength + DirtyLba - DirtyStart);
507  RemainLength = RemainLength - Extent->Length;
508 /*
509  RemainLength = (DirtyStart + RemainLength) -
510  (DirtyLba + DirtyLength);
511 */
512  ASSERT(RemainLength <= (LONGLONG)Length);
513  ASSERT(Extent->Length <= Length);
514  }
515 
517  DirtyLba = DirtyStart + Extent->Length;
518 
519  if (List) {
520  List->Next = Extent;
521  List = Extent;
522  } else {
523  Chain = List = Extent;
524  }
525 
526  } else {
527 
528  if (RemainLength > SECTOR_SIZE) {
529  DirtyLba = DirtyStart + SECTOR_SIZE;
530  RemainLength -= SECTOR_SIZE;
531  } else {
532  RemainLength = 0;
533  }
534  }
535  }
536 
537  if (Chain) {
538  Status = Ext2ReadWriteBlocks(IrpContext,
539  Vcb,
540  Chain,
541  Length );
542  Irp = IrpContext->Irp;
543 
544  if (NT_SUCCESS(Status)) {
545  for (Extent = Chain; Extent != NULL; Extent = Extent->Next) {
547  }
548  }
549 
550  if (!Irp) {
551  _SEH2_LEAVE;
552  }
553 
554  } else {
555 
556  Irp->IoStatus.Information = Length;
558  _SEH2_LEAVE;
559  }
560 
561  } else {
562 
563  Length &= ~((ULONG)SECTOR_SIZE - 1);
564 
566  IrpContext->Irp,
567  Length,
568  IoWriteAccess );
569 
570  if (!NT_SUCCESS(Status)) {
571  _SEH2_LEAVE;
572  }
573 
574  BlockArray.Irp = NULL;
575  BlockArray.Lba = ByteOffset.QuadPart;
576  BlockArray.Offset = 0;
577  BlockArray.Length = Length;
578  BlockArray.Next = NULL;
579 
580  Status = Ext2ReadWriteBlocks(IrpContext,
581  Vcb,
582  &BlockArray,
583  Length );
584 
585  if (NT_SUCCESS(Status)) {
586  Irp->IoStatus.Information = Length;
587  }
588 
589  Irp = IrpContext->Irp;
590  if (!Irp) {
591  _SEH2_LEAVE;
592  }
593  }
594 
595  } _SEH2_FINALLY {
596 
597  if (MainResourceAcquired) {
598  ExReleaseResourceLite(&Vcb->MainResource);
599  }
600 
601  if (!IrpContext->ExceptionInProgress) {
602 
603  if (Irp) {
604 
605  if (Status == STATUS_PENDING) {
606 
607  if (!bDeferred) {
609  IrpContext->Irp,
610  Length,
611  IoReadAccess );
612 
613  if (NT_SUCCESS(Status)) {
614  Status = Ext2QueueRequest(IrpContext);
615  } else {
616  Ext2CompleteIrpContext(IrpContext, Status);
617  }
618  }
619 
620  } else {
621 
622  if (NT_SUCCESS(Status)) {
623 
624  if (SynchronousIo && !PagingIo) {
625  FileObject->CurrentByteOffset.QuadPart =
626  ByteOffset.QuadPart + Irp->IoStatus.Information;
627  }
628 
629  if (!PagingIo) {
631  }
632  }
633 
634  Ext2CompleteIrpContext(IrpContext, Status);
635  }
636 
637  } else {
638 
639  Ext2FreeIrpContext(IrpContext);
640  }
641  }
642 
643  if (Chain) {
644  Ext2DestroyExtentChain(Chain);
645  }
646  } _SEH2_END;
647 
648  return Status;
649 }
650 
651 NTSTATUS
653  IN PEXT2_IRP_CONTEXT IrpContext,
654  IN PEXT2_VCB Vcb,
655  IN PEXT2_MCB Mcb,
657  IN PVOID Buffer,
658  IN ULONG Size,
659  IN BOOLEAN bDirectIo,
661  )
662 {
663  PEXT2_EXTENT Chain = NULL;
665 
666  _SEH2_TRY {
667 
668  if (BytesWritten) {
669  *BytesWritten = 0;
670  }
671 
673  IrpContext,
674  Vcb,
675  Mcb,
676  Offset,
677  Size,
678  S_ISDIR(Mcb->Inode.i_mode) ? FALSE : TRUE,
679  &Chain
680  );
681 
682  if (!NT_SUCCESS(Status)) {
683  _SEH2_LEAVE;
684  }
685 
686  if (Chain == NULL) {
688  _SEH2_LEAVE;
689  }
690 
691  if (bDirectIo) {
692 
693  ASSERT(IrpContext != NULL);
694 
695  //
696  // We assume the offset is aligned.
697  //
698 
700  IrpContext,
701  Vcb,
702  Chain,
703  Size
704  );
705 
706  } else {
707 
709  for (Extent = Chain; Extent != NULL; Extent = Extent->Next) {
710 
711  if ( !Ext2SaveBuffer(
712  IrpContext,
713  Vcb,
714  Extent->Lba,
715  Extent->Length,
716  (PVOID)((PUCHAR)Buffer + Extent->Offset)
717  )) {
718  _SEH2_LEAVE;
719  }
720  }
721 
722  if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
723 
724  DEBUG(DL_FLP, ("Ext2WriteInode is starting FlushingDpc...\n"));
726  }
727 
729  }
730 
731  } _SEH2_FINALLY {
732 
733  if (Chain) {
734  Ext2DestroyExtentChain(Chain);
735  }
736 
737  if (NT_SUCCESS(Status) && BytesWritten) {
738  *BytesWritten = Size;
739  }
740  } _SEH2_END;
741 
742  return Status;
743 }
744 
745 
746 NTSTATUS
748 {
749  PEXT2_VCB Vcb = NULL;
750  PEXT2_FCB Fcb = NULL;
751  PEXT2_CCB Ccb = NULL;
753 
755 
756  PIRP Irp = NULL;
757  PIO_STACK_LOCATION IoStackLocation = NULL;
758  PUCHAR Buffer = NULL;
759 
761  ULONG ReturnedLength = 0;
762  ULONG Length;
763 
765 
766  BOOLEAN OpPostIrp = FALSE;
767  BOOLEAN PagingIo = FALSE;
768  BOOLEAN Nocache = FALSE;
769  BOOLEAN SynchronousIo = FALSE;
770 
771  BOOLEAN RecursiveWriteThrough = FALSE;
772  BOOLEAN MainResourceAcquired = FALSE;
773  BOOLEAN PagingIoResourceAcquired = FALSE;
774 
775  BOOLEAN bDeferred = FALSE;
776 #ifndef __REACTOS__
777  BOOLEAN UpdateFileValidSize = FALSE;
778 #endif
779  BOOLEAN FileSizesChanged = FALSE;
780  BOOLEAN rc;
781 
782 
783  _SEH2_TRY {
784 
785  ASSERT(IrpContext);
786  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
787  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
788 
789  DeviceObject = IrpContext->DeviceObject;
791  ASSERT(Vcb != NULL);
792  ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
793  (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
794 
795  FileObject = IrpContext->FileObject;
796  Fcb = (PEXT2_FCB) FileObject->FsContext;
797  Ccb = (PEXT2_CCB) FileObject->FsContext2;
798  ASSERT(Fcb);
799  ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
800  (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
801 
802  Irp = IrpContext->Irp;
803  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
804 
805  Length = IoStackLocation->Parameters.Write.Length;
806  ByteOffset = IoStackLocation->Parameters.Write.ByteOffset;
807 
808  PagingIo = IsFlagOn(Irp->Flags, IRP_PAGING_IO);
809  Nocache = IsFlagOn(Irp->Flags, IRP_NOCACHE);
810  SynchronousIo = IsFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);
811 
812  if (PagingIo) {
813  ASSERT(Nocache);
814  }
815 
816  DEBUG(DL_INF, ("Ext2WriteFile: %wZ Offset=%I64xh Length=%xh Paging=%xh Nocache=%xh\n",
817  &Fcb->Mcb->ShortName, ByteOffset.QuadPart, Length, PagingIo, Nocache));
818 
819  if (IsSpecialFile(Fcb) || IsInodeSymLink(Fcb->Inode) ) {
821  _SEH2_LEAVE;
822  }
823 
824  if (IsFileDeleted(Fcb->Mcb) ||
825  (IsSymLink(Fcb) && IsFileDeleted(Fcb->Mcb->Target)) ) {
827  _SEH2_LEAVE;
828  }
829 
830  if (Length == 0) {
831  Irp->IoStatus.Information = 0;
833  _SEH2_LEAVE;
834  }
835 
837  ByteOffset.HighPart == -1) {
838  ByteOffset = FileObject->CurrentByteOffset;
839  } else if (IsWritingToEof(ByteOffset)) {
840  ByteOffset.QuadPart = Fcb->Header.FileSize.QuadPart;
841  }
842 
843  if (Nocache && !PagingIo &&
844  ( (ByteOffset.LowPart & (SECTOR_SIZE - 1)) ||
845  (Length & (SECTOR_SIZE - 1))) ) {
847  _SEH2_LEAVE;
848  }
849 
850  if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
851  ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
853  _SEH2_LEAVE;
854  }
855 
856  if (!Nocache) {
857 
858  BOOLEAN bAgain = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
859  BOOLEAN bWait = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
860  BOOLEAN bQueue = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
861 
862  if ( !CcCanIWrite(
863  FileObject,
864  Length,
865  (bWait && bQueue),
866  bAgain ) ) {
867 
869  IrpContext->Irp,
870  Length,
871  IoReadAccess);
872 
873  if (NT_SUCCESS(Status)) {
874  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
877  IrpContext,
878  Irp,
879  Length,
880  bAgain );
881  bDeferred = TRUE;
883  _SEH2_LEAVE;
884  }
885  }
886  }
887 
888  if (IsDirectory(Fcb) && !PagingIo) {
890  _SEH2_LEAVE;
891  }
892 
893  if (IsFlagOn(Irp->Flags, IRP_SYNCHRONOUS_PAGING_IO) && !IrpContext->IsTopLevel) {
894 
895  PIRP TopIrp;
896 
897  TopIrp = IoGetTopLevelIrp();
898 
899  if ( (ULONG_PTR)TopIrp > FSRTL_MAX_TOP_LEVEL_IRP_FLAG &&
900  NodeType(TopIrp) == IO_TYPE_IRP) {
901 
902  PIO_STACK_LOCATION IrpStack;
903 
904  IrpStack = IoGetCurrentIrpStackLocation(TopIrp);
905 
906  if ((IrpStack->MajorFunction == IRP_MJ_WRITE) &&
907  (IrpStack->FileObject->FsContext == FileObject->FsContext) &&
908  !FlagOn(TopIrp->Flags, IRP_NOCACHE) ) {
909 
910  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH);
911  RecursiveWriteThrough = TRUE;
912  }
913  }
914  }
915 
916  if (PagingIo) {
917 
920  _SEH2_LEAVE;
921  }
922  PagingIoResourceAcquired = TRUE;
923 
924  if ( (ByteOffset.QuadPart + Length) > Fcb->Header.FileSize.QuadPart) {
925 
926  if (ByteOffset.QuadPart >= Fcb->Header.AllocationSize.QuadPart) {
927 
929  Irp->IoStatus.Information = 0;
930  _SEH2_LEAVE;
931 
932  } else {
933 
934  ReturnedLength = (ULONG)(Fcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
935  if (ByteOffset.QuadPart + Length > Fcb->Header.AllocationSize.QuadPart)
936  Length = (ULONG)(Fcb->Header.AllocationSize.QuadPart - ByteOffset.QuadPart);
937  }
938 
939  } else {
940 
942  }
943 
944  } else {
945 
948  _SEH2_LEAVE;
949  }
950 
951  if (IsDirectory(Fcb)) {
952  _SEH2_LEAVE;
953  }
954 
957  _SEH2_LEAVE;
958  }
959  MainResourceAcquired = TRUE;
960 
961  //
962  // Do flushing for such cases
963  //
964  if (Nocache && Ccb != NULL && Fcb->SectionObject.DataSectionObject != NULL) {
965 
968 
969  CcFlushCache( &(Fcb->SectionObject),
970  &ByteOffset,
972  &(Irp->IoStatus));
974 
975  if (!NT_SUCCESS(Irp->IoStatus.Status)) {
976  Status = Irp->IoStatus.Status;
977  _SEH2_LEAVE;
978  }
979 
982 
983  CcPurgeCacheSection( &(Fcb->SectionObject),
984  &(ByteOffset),
986  FALSE );
987  }
988 
989  if (!FsRtlCheckLockForWriteAccess(&Fcb->FileLockAnchor, Irp)) {
991  _SEH2_LEAVE;
992  }
993 
994  if (Ccb != NULL) {
995  Status = FsRtlCheckOplock( &Fcb->Oplock,
996  Irp,
997  IrpContext,
999  Ext2LockIrp );
1000 
1001  if (Status != STATUS_SUCCESS) {
1002  OpPostIrp = TRUE;
1003  _SEH2_LEAVE;
1004  }
1005 
1006  //
1007  // Set the flag indicating if Fast I/O is possible
1008  //
1009 
1010  Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
1011  }
1012 
1013  //
1014  // Extend the inode size when the i/o is beyond the file end ?
1015  //
1016 
1017  if ((ByteOffset.QuadPart + Length) > Fcb->Header.FileSize.QuadPart) {
1018 
1020 
1023  _SEH2_LEAVE;
1024  }
1025  PagingIoResourceAcquired = TRUE;
1026 
1027  /* let this irp wait, since it has to be synchronous */
1028  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
1029 
1030  Last.QuadPart = Fcb->Header.AllocationSize.QuadPart;
1031  AllocationSize.QuadPart = (LONGLONG)(ByteOffset.QuadPart + Length);
1033  (ULONGLONG)AllocationSize.QuadPart,
1035 
1036  /* tell Ext2ExpandFile to allocate unwritten extent or NULL blocks
1037  for indirect files, otherwise we might get gabage data in holes */
1038  IrpContext->MajorFunction += IRP_MJ_MAXIMUM_FUNCTION;
1039  Status = Ext2ExpandFile(IrpContext, Vcb, Fcb->Mcb, &AllocationSize);
1040  IrpContext->MajorFunction -= IRP_MJ_MAXIMUM_FUNCTION;
1041  if (AllocationSize.QuadPart > Last.QuadPart) {
1042  Fcb->Header.AllocationSize.QuadPart = AllocationSize.QuadPart;
1044  }
1046  PagingIoResourceAcquired = FALSE;
1047 
1048  if (ByteOffset.QuadPart >= Fcb->Header.AllocationSize.QuadPart) {
1049  if (NT_SUCCESS(Status)) {
1050  DbgBreak();
1052  }
1053  _SEH2_LEAVE;
1054  }
1055 
1056  if (ByteOffset.QuadPart + Length > Fcb->Header.AllocationSize.QuadPart) {
1057  Length = (ULONG)(Fcb->Header.AllocationSize.QuadPart - ByteOffset.QuadPart);
1058  }
1059 
1060  Fcb->Header.FileSize.QuadPart = Fcb->Inode->i_size = ByteOffset.QuadPart + Length;
1061  Ext2SaveInode(IrpContext, Vcb, Fcb->Inode);
1062 
1063  if (CcIsFileCached(FileObject)) {
1064  CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
1065  }
1066 
1068  FileSizesChanged = TRUE;
1069 
1070  if (Fcb->Header.FileSize.QuadPart >= 0x80000000 &&
1071  !IsFlagOn(SUPER_BLOCK->s_feature_ro_compat, EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
1072  SetFlag(SUPER_BLOCK->s_feature_ro_compat, EXT2_FEATURE_RO_COMPAT_LARGE_FILE);
1073  Ext2SaveSuper(IrpContext, Vcb);
1074  }
1075 
1076  DEBUG(DL_IO, ("Ext2WriteFile: expanding %wZ to FS: %I64xh FA: %I64xh\n",
1077  &Fcb->Mcb->ShortName, Fcb->Header.FileSize.QuadPart,
1078  Fcb->Header.AllocationSize.QuadPart));
1079  }
1080 
1082  }
1083 
1084  if (!Nocache) {
1085 
1086  if (FileObject->PrivateCacheMap == NULL) {
1088  FileObject,
1089  (PCC_FILE_SIZES)(&Fcb->Header.AllocationSize),
1090  FALSE,
1092  Fcb );
1093 
1095  FileObject,
1097  }
1098 
1099  if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
1100 
1102  FileObject,
1103  &ByteOffset,
1104  Length,
1105  &Irp->MdlAddress,
1106  &Irp->IoStatus );
1107 
1108  Status = Irp->IoStatus.Status;
1109 
1110  } else {
1111 
1113  if (Buffer == NULL) {
1114  DbgBreak();
1116  _SEH2_LEAVE;
1117  }
1118 
1119  if (ByteOffset.QuadPart > Fcb->Header.ValidDataLength.QuadPart) {
1120 
1121  /* let this irp wait, since it has to be synchronous */
1122  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
1123 
1124  rc = Ext2ZeroData(IrpContext, Vcb, FileObject,
1125  &Fcb->Header.ValidDataLength, &ByteOffset);
1126  if (!rc) {
1128  DbgBreak();
1129  _SEH2_LEAVE;
1130  }
1131  }
1132 
1134  if (Ext2CanIWait() ||
1137  DbgBreak();
1138  _SEH2_LEAVE;
1139  }
1140  }
1141 
1142  if (ByteOffset.QuadPart + Length > Fcb->Header.ValidDataLength.QuadPart ) {
1143 
1144  if (Fcb->Header.FileSize.QuadPart < ByteOffset.QuadPart + Length) {
1145  Fcb->Header.ValidDataLength.QuadPart = Fcb->Header.FileSize.QuadPart;
1146  } else {
1147  if (Fcb->Header.ValidDataLength.QuadPart < ByteOffset.QuadPart + Length)
1148  Fcb->Header.ValidDataLength.QuadPart = ByteOffset.QuadPart + Length;
1149  }
1150 
1151  CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
1152  FileSizesChanged = TRUE;
1153  }
1154 
1156  }
1157 
1158  if (NT_SUCCESS(Status)) {
1159  Irp->IoStatus.Information = Length;
1160  if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
1161  DEBUG(DL_FLP, ("Ext2WriteFile is starting FlushingDpc...\n"));
1163  }
1164  }
1165 
1166  } else {
1167 
1168  if (!PagingIo && !RecursiveWriteThrough && !IsLazyWriter(Fcb)) {
1169  if (ByteOffset.QuadPart > Fcb->Header.ValidDataLength.QuadPart) {
1170 
1171  /* let this irp wait, since it has to be synchronous */
1172  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
1173  rc = Ext2ZeroData(IrpContext, Vcb, FileObject,
1174  &Fcb->Header.ValidDataLength,
1175  &ByteOffset);
1176  if (!rc) {
1178  DbgBreak();
1179  _SEH2_LEAVE;
1180  }
1181  }
1182  }
1183 
1185  IrpContext->Irp,
1186  Length,
1187  IoReadAccess );
1188 
1189  if (!NT_SUCCESS(Status)) {
1190  _SEH2_LEAVE;
1191  }
1192 
1193  Irp->IoStatus.Status = STATUS_SUCCESS;
1194  Irp->IoStatus.Information = ReturnedLength;
1195 
1197  IrpContext,
1198  Vcb,
1199  Fcb->Mcb,
1200  (ULONGLONG)(ByteOffset.QuadPart),
1201  NULL,
1203  TRUE,
1204  &Length
1205  );
1206 
1207  Irp = IrpContext->Irp;
1208 
1209  if (NT_SUCCESS(Status) && !RecursiveWriteThrough && !IsLazyWriter(Fcb)) {
1210 
1211  if (ByteOffset.QuadPart + Length > Fcb->Header.ValidDataLength.QuadPart ) {
1212 
1213  FileSizesChanged = TRUE;
1214 
1215  if (Fcb->Header.FileSize.QuadPart < ByteOffset.QuadPart + Length) {
1216  if (!PagingIo)
1217  Fcb->Header.FileSize.QuadPart = ByteOffset.QuadPart + Length;
1218  Fcb->Header.ValidDataLength.QuadPart = Fcb->Header.FileSize.QuadPart;
1219  } else {
1220  if (Fcb->Header.ValidDataLength.QuadPart < ByteOffset.QuadPart + Length)
1221  Fcb->Header.ValidDataLength.QuadPart = ByteOffset.QuadPart + Length;
1222  }
1223 
1224  if (!PagingIo && CcIsFileCached(FileObject)) {
1225  CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
1226  }
1227 
1228  DEBUG(DL_IO, ("Ext2WriteFile: %wZ written FS: %I64xh FA: %I64xh BO: %I64xh LEN: %u\n",
1229  &Fcb->Mcb->ShortName, Fcb->Header.FileSize.QuadPart,
1230  Fcb->Header.AllocationSize.QuadPart, ByteOffset.QuadPart, Length));
1231  }
1232  }
1233  }
1234 
1235  if (FileSizesChanged) {
1237  Ext2NotifyReportChange( IrpContext, Vcb, Fcb->Mcb,
1240  }
1241 
1242  } _SEH2_FINALLY {
1243 
1244  /*
1245  * in case we got excpetions, we need revert MajorFunction
1246  * back to IRP_MJ_WRITE. The reason we do this, is to tell
1247  * Ext2ExpandFile to allocate unwritten extent or don't add
1248  * new blocks for indirect files.
1249  */
1250  if (IrpContext->MajorFunction > IRP_MJ_MAXIMUM_FUNCTION)
1251  IrpContext->MajorFunction -= IRP_MJ_MAXIMUM_FUNCTION;
1252 
1253  if (Irp) {
1254  if (PagingIoResourceAcquired) {
1256  }
1257 
1258  if (MainResourceAcquired) {
1260  }
1261  }
1262 
1263  if (!OpPostIrp && !IrpContext->ExceptionInProgress) {
1264 
1265  if (Irp) {
1266 
1267  if (Status == STATUS_PENDING ||
1268  Status == STATUS_CANT_WAIT ) {
1269 
1270  if (!bDeferred) {
1271  Status = Ext2QueueRequest(IrpContext);
1272  }
1273 
1274  } else {
1275 
1276  if (NT_SUCCESS(Status) && !PagingIo) {
1277 
1278  if (SynchronousIo) {
1279  FileObject->CurrentByteOffset.QuadPart =
1280  ByteOffset.QuadPart + Irp->IoStatus.Information;
1281  }
1282 
1285  }
1286 
1287  Ext2CompleteIrpContext(IrpContext, Status);
1288  }
1289  } else {
1290  Ext2FreeIrpContext(IrpContext);
1291  }
1292  }
1293  } _SEH2_END;
1294 
1295  DEBUG(DL_IO, ("Ext2WriteFile: %wZ written at Offset=%I64xh Length=%xh PagingIo=%d Nocache=%d "
1296  "RetLen=%xh VDL=%I64xh FileSize=%I64xh i_size=%I64xh Status=%xh\n",
1297  &Fcb->Mcb->ShortName, ByteOffset, Length, PagingIo, Nocache, ReturnedLength,
1298  Fcb->Header.ValidDataLength.QuadPart,Fcb->Header.FileSize.QuadPart,
1299  Fcb->Inode->i_size, Status));
1300 
1301  return Status;
1302 }
1303 
1304 NTSTATUS
1306 {
1309  PIRP Irp;
1311 
1312  _SEH2_TRY {
1313 
1314  ASSERT(IrpContext);
1315  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
1316  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
1317 
1318  FileObject = IrpContext->FileObject;
1319 
1320  Irp = IrpContext->Irp;
1322 
1323  CcMdlWriteComplete(FileObject, &(IrpSp->Parameters.Write.ByteOffset), Irp->MdlAddress);
1324  Irp->MdlAddress = NULL;
1326 
1327  } _SEH2_FINALLY {
1328 
1329  if (!IrpContext->ExceptionInProgress) {
1330  Ext2CompleteIrpContext(IrpContext, Status);
1331  }
1332  } _SEH2_END;
1333 
1334  return Status;
1335 }
1336 
1337 
1338 NTSTATUS
1340 {
1341  NTSTATUS Status;
1342  PEXT2_FCBVCB FcbOrVcb;
1345  PEXT2_VCB Vcb;
1346  BOOLEAN bCompleteRequest = TRUE;
1347 
1348  ASSERT(IrpContext);
1349 
1350  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
1351  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
1352 
1353  _SEH2_TRY {
1354 
1355  if (IsFlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE)) {
1356 
1357  Status = Ext2WriteComplete(IrpContext);
1358  bCompleteRequest = FALSE;
1359 
1360  } else {
1361 
1362  DeviceObject = IrpContext->DeviceObject;
1365  _SEH2_LEAVE;
1366  }
1367  FileObject = IrpContext->FileObject;
1368 
1370 
1371  if (Vcb->Identifier.Type != EXT2VCB ||
1372  Vcb->Identifier.Size != sizeof(EXT2_VCB) ) {
1374  _SEH2_LEAVE;
1375  }
1376 
1377  if (IsVcbReadOnly(Vcb)) {
1379  _SEH2_LEAVE;
1380  }
1381 
1382  if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED) &&
1383  Vcb->LockFile != FileObject ) {
1385  _SEH2_LEAVE;
1386  }
1387 
1388  FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
1389 
1390  if (FcbOrVcb->Identifier.Type == EXT2VCB) {
1391 
1392  Status = Ext2WriteVolume(IrpContext);
1393  if (!NT_SUCCESS(Status)) {
1394  DbgBreak();
1395  }
1396  bCompleteRequest = FALSE;
1397 
1398  } else if (FcbOrVcb->Identifier.Type == EXT2FCB) {
1399 
1400  if (IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
1402  _SEH2_LEAVE;
1403  }
1404 
1405  Status = Ext2WriteFile(IrpContext);
1406  if (!NT_SUCCESS(Status)) {
1407  DbgBreak();
1408  }
1409 
1410  bCompleteRequest = FALSE;
1411  } else {
1413  }
1414  }
1415 
1416  } _SEH2_FINALLY {
1417 
1418  if (bCompleteRequest) {
1419  Ext2CompleteIrpContext(IrpContext, Status);
1420  }
1421  } _SEH2_END;
1422 
1423  return Status;
1424 }
#define READ_AHEAD_GRANULARITY
Definition: btrfs_drv.h:118
struct _EXT2_FCB * PEXT2_FCB
struct _EXT2_EXTENT * Next
Definition: ext2fs.h:1115
BOOLEAN Ext2RemoveVcbExtent(IN PEXT2_VCB Vcb, IN LONGLONG Vbn, IN LONGLONG Length)
Definition: memory.c:700
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:384
#define IN
Definition: typedefs.h:38
NTSTATUS Ext2WriteComplete(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: write.c:1305
#define IsInodeSymLink(I)
Definition: ext2fs.h:281
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesWritten
Definition: fltkernel.h:1293
#define TRUE
Definition: types.h:120
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define IsSymLink(Fcb)
Definition: ext2fs.h:280
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:402
NTSTATUS Status
Definition: write.c:2817
struct _EXT2_FLPFLUSH_CONTEXT EXT2_FLPFLUSH_CONTEXT
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
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
BOOLEAN Ext2SaveSuper(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: generic.c:63
BOOLEAN Ext2ZeroData(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER Start, IN PLARGE_INTEGER End)
Definition: write.c:170
#define CEILING_ALIGNED(T, A, B)
Definition: ext2fs.h:111
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1079
VOID Ext2StartFloppyFlushDpc(PEXT2_VCB Vcb, PEXT2_FCB Fcb, PFILE_OBJECT FileObject)
Definition: write.c:123
BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:714
unsigned char * PUCHAR
Definition: retypes.h:3
LONGLONG Lba
Definition: ext2fs.h:1111
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
WORK_QUEUE_ITEM Item
Definition: write.c:32
#define IRP_CONTEXT_FLAG_DEFERRED
Definition: ext2fs.h:1082
#define IRP_NOCACHE
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
uint64 Length
Definition: DriveVolume.h:48
NTSTATUS Ext2LockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: block.c:101
VOID NTAPI Ext2FloppyFlush(IN PVOID Parameter)
Definition: write.c:63
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_USE_FILE_POINTER_POSITION
Definition: ffsdrv.h:155
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS Ext2WriteVolume(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: write.c:220
_In_ PVOID Parameter
Definition: ldrtypes.h:241
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
NTSTATUS Ext2BuildExtents(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONGLONG Offset, IN ULONG Size, IN BOOLEAN bAlloc, OUT PEXT2_EXTENT *Chain)
Definition: memory.c:1207
NTSTATUS Ext2FlushVcb(IN PEXT2_VCB Vcb)
Definition: generic.c:319
PEXT2_VCB Vcb
Definition: write.c:26
#define IsSpecialFile(Fcb)
Definition: ext2fs.h:279
_SEH2_TRY
Definition: create.c:4250
#define STATUS_END_OF_FILE
Definition: shellext.h:62
uint32_t ULONG_PTR
Definition: typedefs.h:63
EXT2_IDENTIFIER_TYPE Type
Definition: ext2fs.h:472
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1733
#define IRP_MN_COMPLETE
Definition: iotypes.h:4064
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1746
#define FO_FILE_MODIFIED
Definition: iotypes.h:1745
NTFSIDENTIFIER Identifier
Definition: ntfs.h:511
int Ext2CheckFileAccess(PEXT2_VCB Vcb, PEXT2_MCB Mcb, int attempt)
Definition: access.c:51
NTSTATUS Ext2QueueRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:150
#define CCB_ALLOW_EXTENDED_DASD_IO
Definition: ext2fs.h:1028
#define DL_FLP
Definition: write.c:18
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG Offset
Definition: ext2fs.h:1112
VOID NTAPI CcPrepareMdlWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:91
VOID(NTAPI * PCC_POST_DEFERRED_WRITE)(_In_ PVOID Context1, _In_ PVOID Context2)
Definition: cctypes.h:66
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
Definition: fssup.c:412
#define IsWritingToEof(Pos)
Definition: ext2fs.h:275
VOID Ext2FreeIrpContext(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: memory.c:114
EXT2_IDENTIFIER Identifier
Definition: ext2fs.h:624
NTSTATUS Ext2Write(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: write.c:1339
#define CcIsFileCached(FO)
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
#define FILE_ACTION_MODIFIED
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
VOID Ext2NotifyReportChange(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Filter, IN ULONG Action)
Definition: dirctl.c:1209
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define IsFileDeleted(Mcb)
Definition: ext2fs.h:959
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define ClearLongFlag(_F, _SF)
Definition: ext2fs.h:254
Definition: bufpool.h:45
FAST_IO_POSSIBLE Ext2IsFastIoPossible(IN PEXT2_FCB Fcb)
Definition: fastio.c:38
#define FCB_ALLOC_IN_WRITE
Definition: ext2fs.h:876
NodeType
Definition: Node.h:5
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
struct _EXT2_FLPFLUSH_CONTEXT * PEXT2_FLPFLUSH_CONTEXT
#define SUPER_BLOCK
Definition: ext2fs.h:90
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
int64_t LONGLONG
Definition: typedefs.h:66
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
#define BLOCK_SIZE
Definition: dlist.c:220
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
LIST_ENTRY List
Definition: psmgr.c:57
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define DL_INF
Definition: ext2fs.h:1399
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
Definition: copysup.c:214
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:193
#define IsVcbReadOnly(Vcb)
Definition: ext2fs.h:805
uint64_t ULONGLONG
Definition: typedefs.h:65
#define S_ISDIR(mode)
Definition: various.h:18
#define Vcb
Definition: cdprocs.h:1425
BOOLEAN Ext2AddVcbExtent(IN PEXT2_VCB Vcb, IN LONGLONG Vbn, IN LONGLONG Length)
Definition: memory.c:648
struct _EXT2_FCBVCB * PEXT2_FCBVCB
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define INODE_HAS_EXTENT(i)
Definition: ext4_ext.h:228
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG
Definition: fsrtltypes.h:65
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define CCB_VOLUME_DASD_PURGE
Definition: ext2fs.h:1023
* PFILE_OBJECT
Definition: iotypes.h:1955
Definition: partlist.h:33
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
ULONG Flags
Definition: ntfs.h:532
CD_MCB Mcb
Definition: cdstruc.h:1022
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
PEXT2_FCB Fcb
Definition: write.c:27
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define IO_TYPE_IRP
#define VCB_DISMOUNT_PENDING
Definition: ext2fs.h:782
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
_Must_inspect_result_ _In_ PFLT_INSTANCE _Out_ PBOOLEAN IsDirectory
Definition: fltkernel.h:1139
Definition: ketypes.h:687
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP Irp
Definition: write.c:2814
ULONG Type
Definition: ntfs.h:95
NTSTATUS Ext2WriteFile(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: write.c:747
#define IRP_MN_MDL
Definition: iotypes.h:4063
#define FCB_FILE_MODIFIED
Definition: ext2fs.h:873
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:187
NTSTATUS Ext2PurgeVolume(IN PEXT2_VCB Vcb, IN BOOLEAN FlushBeforePurge)
Definition: fsctl.c:2704
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ERESOURCE MainResource
Definition: ntfs.h:524
NTSTATUS Ext2WriteInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONGLONG Offset, IN PVOID Buffer, IN ULONG Size, IN BOOLEAN bDirectIo, OUT PULONG BytesWritten)
Definition: write.c:652
VOID NTAPI Ext2FloppyFlushDpc(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: write.c:106
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
Status
Definition: gdiplustypes.h:24
#define IRP_MN_DPC
Definition: iotypes.h:4062
#define DL_ERR
Definition: ext2fs.h:1397
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:310
BOOLEAN Ext2SaveBuffer(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN LONGLONG Offset, IN ULONG Size, IN PVOID Buf)
Definition: generic.c:862
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ULONG Length
Definition: ext2fs.h:1113
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1063
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
PEXT2_EXTENT Ext2AllocateExtent()
Definition: memory.c:488
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
_SEH2_END
Definition: create.c:4424
#define VCB_FLOPPY_DISK
Definition: ext2fs.h:797
VOID Ext2DeferWrite(IN PEXT2_IRP_CONTEXT, PIRP Irp)
Definition: write.c:211
#define Ext2CanIWait()
Definition: ext2fs.h:1091
NTSTATUS Ext2ExpandFile(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_MCB Mcb, PLARGE_INTEGER Size)
Definition: fileinfo.c:1147
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:354
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:334
#define IsLazyWriter(Fcb)
Definition: ext2fs.h:813
#define SetLongFlag(_F, _SF)
Definition: ext2fs.h:253
_SEH2_FINALLY
Definition: create.c:4395
#define DL_IO
Definition: ext2fs.h:1413
unsigned int * PULONG
Definition: retypes.h:1
PFILE_OBJECT FileObject
Definition: write.c:28
#define IRP_CONTEXT_FLAG_REQUEUED
Definition: ext2fs.h:1085
#define IRP_PAGING_IO
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define VCB_VOLUME_LOCKED
Definition: ext2fs.h:780
VOID NTAPI Ext2LockIrp(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:86
NTSTATUS Ext2ReadWriteBlocks(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_EXTENT Extent, IN ULONG Length)
Definition: block.c:240
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:306
PIRP Irp
Definition: ext2fs.h:1114
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
#define IsExt2FsDevice(DO)
Definition: ext2fs.h:607
struct tagContext Context
Definition: acpixf.h:1024
if(!find_data_address_in_chunk(Vcb, c, length, &address)) return false
unsigned int ULONG
Definition: retypes.h:1
ERESOURCE PagingIoResource
Definition: ntfs.h:523
BOOLEAN Ext2LookupVcbExtent(IN PEXT2_VCB Vcb, IN LONGLONG Vbn, OUT PLONGLONG Lbn, OUT PLONGLONG Length)
Definition: memory.c:747
#define DbgBreak()
Definition: ext2fs.h:46
VOID Ext2FreePool(IN PVOID P, IN ULONG Tag)
Definition: debug.c:2697
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
struct _EXT2_VCB * PEXT2_VCB
#define SECTOR_SIZE
Definition: fs.h:22
#define DEBUG(args)
Definition: rdesktop.h:129
#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE
Definition: ext2_fs.h:466
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
NTSTATUS NTAPI FsRtlCheckOplock(IN POPLOCK Oplock, IN PIRP Irp, IN PVOID Context, IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL)
Definition: oplock.c:1172
VOID Ext2DestroyExtentChain(IN PEXT2_EXTENT Chain)
Definition: memory.c:546
#define _SEH2_LEAVE
Definition: filesup.c:20
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
_In_ PFCB Fcb
Definition: cdprocs.h:151
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
return STATUS_SUCCESS
Definition: btrfs.c:2966
struct _EXT2_CCB * PEXT2_CCB
PVOID Ext2AllocatePool(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: debug.c:2684
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: ext2fs.h:523
#define Ext2FileCanWrite
Definition: ext2fs.h:427
VOID NTAPI Ext2OplockComplete(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:41
BOOLEAN Ext2SaveInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:548
ULONG Size
Definition: ntfs.h:96
#define STATUS_TOO_LATE
Definition: ntstatus.h:612
PVOID Ext2GetUserBuffer(IN PIRP Irp)
Definition: block.c:134
VOID NTAPI CcDeferWrite(IN PFILE_OBJECT FileObject, IN PCC_POST_DEFERRED_WRITE PostRoutine, IN PVOID Context1, IN PVOID Context2, IN ULONG BytesToWrite, IN BOOLEAN Retrying)
Definition: copysup.c:225
#define IRP_SYNCHRONOUS_PAGING_IO
LONGLONG QuadPart
Definition: typedefs.h:112
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675
#define EXT2_FLPFLUSH_MAGIC
Definition: write.c:22