ReactOS  0.4.15-dev-1171-gab82533
write.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
3  * PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
4  * FILE: write.c
5  * PURPOSE:
6  * PROGRAMMER: Mark Piper, Matt Wu, Bo BrantÚn.
7  * HOMEPAGE:
8  * UPDATE HISTORY:
9  */
10 
11 /* INCLUDES *****************************************************************/
12 
13 #include "rfsd.h"
14 
15 /* GLOBALS ***************************************************************/
16 
18 
19 /* DEFINITIONS *************************************************************/
20 
21 typedef struct _RFSD_FLPFLUSH_CONTEXT {
22 
26 
30 
32 
33 #ifdef _PREFAST_
34 WORKER_THREAD_ROUTINE RfsdFloppyFlush;
35 #endif // _PREFAST_
36 
37 #ifndef __REACTOS__
38 VOID
40 #else
41 VOID
42 NTAPI
44 #endif
45 
46 #ifdef _PREFAST_
47 KDEFERRED_ROUTINE RfsdFloppyFlushDpc;
48 #endif // _PREFAST_
49 
50 #ifndef __REACTOS__
51 VOID
53  IN PKDPC Dpc,
57 #else
58 VOID
59 NTAPI
61  _In_ PKDPC Dpc,
65 #endif
66 
69 
72 
75 
76 VOID
78 
79 #ifdef ALLOC_PRAGMA
80 #if !RFSD_READ_ONLY
81 #pragma alloc_text(PAGE, RfsdFloppyFlush)
82 #pragma alloc_text(PAGE, RfsdStartFloppyFlushDpc)
83 #pragma alloc_text(PAGE, RfsdZeroHoles)
84 #pragma alloc_text(PAGE, RfsdWrite)
85 #pragma alloc_text(PAGE, RfsdWriteVolume)
86 #pragma alloc_text(PAGE, RfsdWriteInode)
87 #pragma alloc_text(PAGE, RfsdWriteFile)
88 #pragma alloc_text(PAGE, RfsdWriteComplete)
89 #endif // !RFSD_READ_ONLY
90 #endif
91 
92 /* FUNCTIONS *************************************************************/
93 
94 #if !RFSD_READ_ONLY
95 
96 VOID
98 {
101  PRFSD_FCB Fcb;
102  PRFSD_VCB Vcb;
103 
104  PAGED_CODE();
105 
107  FileObject = Context->FileObject;
108  Fcb = Context->Fcb;
109  Vcb = Context->Vcb;
110 
111  RfsdPrint((DBG_USER, "RfsdFloppyFlushing ...\n"));
112 
114 
116 
117  if (Vcb) {
118  ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
119  ExReleaseResourceLite(&Vcb->PagingIoResource);
120 
121  CcFlushCache(&(Vcb->SectionObject), NULL, 0, NULL);
122  }
123 
124  if (FileObject) {
125  ASSERT(Fcb == (PRFSD_FCB)FileObject->FsContext);
126 
129 
130  CcFlushCache(&(Fcb->SectionObject), NULL, 0, NULL);
131 
133  }
134 
136 
138 
140 }
141 
142 VOID
144  IN PKDPC Dpc,
148  )
149 {
151 
153 
154  RfsdPrint((DBG_USER, "RfsdFloppyFlushDpc is to be started...\n"));
155 
158  Context );
159 
161 }
162 
163 VOID
165  PRFSD_VCB Vcb,
166  PRFSD_FCB Fcb,
168 {
169  LARGE_INTEGER OneSecond;
171 
172  PAGED_CODE();
173 
175 
177 
178  if (!Context) {
179  DbgBreak();
180  return;
181  }
182 
183  KeInitializeTimer(&Context->Timer);
184 
185  KeInitializeDpc( &Context->Dpc,
187  Context );
188 
189  Context->Vcb = Vcb;
190  Context->Fcb = Fcb;
191  Context->FileObject = FileObject;
192 
193  if (FileObject) {
195  }
196 
197  OneSecond.QuadPart = (LONGLONG)-1*1000*1000*10;
198  KeSetTimer( &Context->Timer,
199  OneSecond,
200  &Context->Dpc );
201 }
202 
203 BOOLEAN
205  IN PRFSD_IRP_CONTEXT IrpContext,
206  IN PRFSD_VCB Vcb,
210  )
211 {
212  LARGE_INTEGER StartAddr = {0,0};
213  LARGE_INTEGER EndAddr = {0,0};
214 
215  PAGED_CODE();
216 
217  StartAddr.QuadPart = (Offset + (SECTOR_SIZE - 1)) &
218  ~((LONGLONG)SECTOR_SIZE - 1);
219 
220  EndAddr.QuadPart = (Offset + Count + (SECTOR_SIZE - 1)) &
221  ~((LONGLONG)SECTOR_SIZE - 1);
222 
223  if (StartAddr.QuadPart < EndAddr.QuadPart) {
224  return CcZeroData( FileObject,
225  &StartAddr,
226  &EndAddr,
227  IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
228  }
229 
230  return TRUE;
231 }
232 
233 VOID
235 {
236  ASSERT(IrpContext->Irp == Irp);
237 
238  RfsdQueueRequest(IrpContext);
239 }
240 
241 NTSTATUS
243 {
245 
246  PRFSD_VCB Vcb;
247  PRFSD_CCB Ccb;
248  PRFSD_FCBVCB FcbOrVcb;
250 
252 
253  PIRP Irp;
254  PIO_STACK_LOCATION IoStackLocation;
255 
256  ULONG Length;
258 
259  BOOLEAN PagingIo;
260  BOOLEAN Nocache;
261  BOOLEAN SynchronousIo;
262  BOOLEAN MainResourceAcquired = FALSE;
263  BOOLEAN PagingIoResourceAcquired = FALSE;
264 
265  BOOLEAN bDeferred = FALSE;
266 
267  PUCHAR Buffer;
268 
269  PAGED_CODE();
270 
271  _SEH2_TRY {
272 
273  ASSERT(IrpContext);
274 
275  ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
276  (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
277 
278  DeviceObject = IrpContext->DeviceObject;
279 
280  Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
281 
282  ASSERT(Vcb != NULL);
283 
284  ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
285  (Vcb->Identifier.Size == sizeof(RFSD_VCB)));
286 
287  FileObject = IrpContext->FileObject;
288 
289  FcbOrVcb = (PRFSD_FCBVCB) FileObject->FsContext;
290 
291  ASSERT(FcbOrVcb);
292 
293  if (!(FcbOrVcb->Identifier.Type == RFSDVCB && (PVOID)FcbOrVcb == (PVOID)Vcb)) {
295  _SEH2_LEAVE;
296  }
297 
298  Ccb = (PRFSD_CCB) FileObject->FsContext2;
299 
300  Irp = IrpContext->Irp;
301 
302  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
303 
304  Length = IoStackLocation->Parameters.Write.Length;
305  ByteOffset = IoStackLocation->Parameters.Write.ByteOffset;
306 
307  PagingIo = (Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE);
308  Nocache = (Irp->Flags & IRP_NOCACHE ? TRUE : FALSE);
309  SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO ? TRUE : FALSE);
310 
311  RfsdPrint((DBG_INFO, "RfsdWriteVolume: Off=%I64xh Len=%xh Paging=%xh Nocache=%xh\n",
312  ByteOffset.QuadPart, Length, PagingIo, Nocache));
313 
314  if (Length == 0) {
315  Irp->IoStatus.Information = 0;
317  _SEH2_LEAVE;
318  }
319 
320  // For the case of "Direct Access Storage Device", we
321  // need flush/purge the cache
322 
323  if (Ccb != NULL) {
324 
325  ExAcquireResourceExclusiveLite(&Vcb->MainResource, TRUE);
326  MainResourceAcquired = TRUE;
327 
329 
330  ExReleaseResourceLite(&Vcb->MainResource);
331  MainResourceAcquired = FALSE;
332 
334  if (ByteOffset.QuadPart + Length > Vcb->Header.FileSize.QuadPart) {
335  Length = (ULONG)(Vcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
336  }
337  }
338 
339  {
340  RFSD_BDL BlockArray;
341 
342  if ((ByteOffset.LowPart & (SECTOR_SIZE - 1)) ||
343  (Length & (SECTOR_SIZE - 1)) ) {
345  _SEH2_LEAVE;
346  }
347 
349  IrpContext->Irp,
350  Length,
351  IoReadAccess );
352 
353  if (!NT_SUCCESS(Status)) {
354  _SEH2_LEAVE;
355  }
356 
357  BlockArray.Irp = NULL;
358  BlockArray.Lba = ByteOffset.QuadPart;;
359  BlockArray.Offset = 0;
360  BlockArray.Length = Length;
361 
362  Status = RfsdReadWriteBlocks(IrpContext,
363  Vcb,
364  &BlockArray,
365  Length,
366  1,
367  FALSE );
368  Irp = IrpContext->Irp;
369 
370  _SEH2_LEAVE;
371  }
372  }
373 
374  if (Nocache &&
375  (ByteOffset.LowPart & (SECTOR_SIZE - 1) ||
376  Length & (SECTOR_SIZE - 1))) {
378  _SEH2_LEAVE;
379  }
380 
381  if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
382  ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
384  _SEH2_LEAVE;
385  }
386 
387  if (ByteOffset.QuadPart >=
388  Vcb->PartitionInformation.PartitionLength.QuadPart ) {
389  Irp->IoStatus.Information = 0;
391  _SEH2_LEAVE;
392  }
393 
394 #if FALSE
395 
396  if (!Nocache) {
397 
398  BOOLEAN bAgain = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
399  BOOLEAN bWait = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
400  BOOLEAN bQueue = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
401 
402  if ( !CcCanIWrite(
403  FileObject,
404  Length,
405  (bWait && bQueue),
406  bAgain ) ) {
407 
408  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
409 
412  IrpContext,
413  Irp,
414  Length,
415  bAgain );
416 
417  bDeferred = TRUE;
418 
419  DbgBreak();
420 
422 
423  _SEH2_LEAVE;
424  }
425  }
426 
427 #endif
428 
429  if (Nocache && !PagingIo && (Vcb->SectionObject.DataSectionObject != NULL)) {
430 
431  ExAcquireResourceExclusiveLite(&Vcb->MainResource, TRUE);
432  MainResourceAcquired = TRUE;
433 
434  ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
435  ExReleaseResourceLite(&Vcb->PagingIoResource);
436 
437  CcFlushCache( &(Vcb->SectionObject),
438  &ByteOffset,
439  Length,
440  &(Irp->IoStatus));
441 
442  if (!NT_SUCCESS(Irp->IoStatus.Status)) {
443  Status = Irp->IoStatus.Status;
444  _SEH2_LEAVE;
445  }
446 
447  ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
448  ExReleaseResourceLite(&Vcb->PagingIoResource);
449 
450  CcPurgeCacheSection( &(Vcb->SectionObject),
452  Length,
453  FALSE );
454 
455  ExReleaseResourceLite(&Vcb->MainResource);
456  MainResourceAcquired = FALSE;
457  }
458 
459  if (!PagingIo) {
460 
461 #pragma prefast( suppress: 28137, "by design" )
463  &Vcb->MainResource,
464  IrpContext->IsSynchronous )) {
466  _SEH2_LEAVE;
467  }
468 
469  MainResourceAcquired = TRUE;
470 
471  } else {
472 
473 /*
474  ULONG ResShCnt, ResExCnt;
475  ResShCnt = ExIsResourceAcquiredSharedLite(&Vcb->PagingIoResource);
476  ResExCnt = ExIsResourceAcquiredExclusiveLite(&Vcb->PagingIoResource);
477 
478  RfsdPrint((DBG_USER, "PagingIoRes: %xh:%xh Synchronous=%xh\n", ResShCnt, ResExCnt, IrpContext->IsSynchronous));
479 */
480 
481  if (Ccb) {
482 
484  &Vcb->PagingIoResource,
485  IrpContext->IsSynchronous )) {
487  _SEH2_LEAVE;
488  }
489 
490  PagingIoResourceAcquired = TRUE;
491  }
492  }
493 
494  if (!Nocache) {
495 
496  if ( (ByteOffset.QuadPart + Length) >
497  Vcb->PartitionInformation.PartitionLength.QuadPart ){
498  Length = (ULONG) (
499  Vcb->PartitionInformation.PartitionLength.QuadPart -
500  ByteOffset.QuadPart);
501 
502  Length &= ~((ULONG)SECTOR_SIZE - 1);
503  }
504 
505  if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
506 
508  Vcb->StreamObj,
509  &ByteOffset,
510  Length,
511  &Irp->MdlAddress,
512  &Irp->IoStatus );
513 
514  Status = Irp->IoStatus.Status;
515 
516  } else {
517 
519 
520  if (Buffer == NULL) {
521  DbgBreak();
522 
524  _SEH2_LEAVE;
525  }
526 
527  if (!CcCopyWrite( Vcb->StreamObj,
529  Length,
530  TRUE,
531  Buffer )) {
533  _SEH2_LEAVE;
534  }
535 
536  Status = Irp->IoStatus.Status;
538  }
539 
540  if (NT_SUCCESS(Status)) {
541  Irp->IoStatus.Information = Length;
542  }
543 
544  } else {
545 
546  PRFSD_BDL rfsd_bdl = NULL;
547  ULONG Blocks = 0;
548 
549  LONGLONG DirtyStart;
550  LONGLONG DirtyLba;
551  LONGLONG DirtyLength;
552  LONGLONG RemainLength;
553 
554  if ((ByteOffset.QuadPart + Length) >
555  Vcb->PartitionInformation.PartitionLength.QuadPart ) {
556  Length = (ULONG) (
557  Vcb->PartitionInformation.PartitionLength.QuadPart -
558  ByteOffset.QuadPart);
559 
560  Length &= ~((ULONG)SECTOR_SIZE - 1);
561  }
562 
564  IrpContext->Irp,
565  Length,
566  IoReadAccess );
567 
568  if (!NT_SUCCESS(Status)) {
569  _SEH2_LEAVE;
570  }
571 
572  rfsd_bdl = ExAllocatePoolWithTag(PagedPool,
573  (Length / Vcb->BlockSize) *
574  sizeof(RFSD_BDL), RFSD_POOL_TAG);
575 
576  if (!rfsd_bdl) {
578  _SEH2_LEAVE;
579  }
580 
581  DirtyLba = ByteOffset.QuadPart;
582  RemainLength = (LONGLONG) Length;
583 
584  while (RemainLength > 0) {
585 
586  DirtyStart = DirtyLba;
587 
588  if (RfsdLookupMcbEntry( Vcb,
589  DirtyStart,
590  &DirtyLba,
591  &DirtyLength,
592  (PLONGLONG)NULL,
593  (PLONGLONG)NULL,
594  (PULONG)NULL) ) {
595 
596  if (DirtyLba == -1) {
597  DirtyLba = DirtyStart + DirtyLength;
598 
599  RemainLength = ByteOffset.QuadPart +
600  (LONGLONG)Length -
601  DirtyLba;
602  continue;
603  }
604 
605  rfsd_bdl[Blocks].Irp = NULL;
606  rfsd_bdl[Blocks].Lba = DirtyLba;
607  rfsd_bdl[Blocks].Offset = (ULONG)( (LONGLONG)Length +
608  DirtyStart -
609  RemainLength -
610  DirtyLba );
611 
612  if (DirtyLba + DirtyLength > DirtyStart + RemainLength) {
613  rfsd_bdl[Blocks].Length = (ULONG)( DirtyStart +
614  RemainLength -
615  DirtyLba );
616  RemainLength = 0;
617  } else {
618  rfsd_bdl[Blocks].Length = (ULONG)DirtyLength;
619  RemainLength = (DirtyStart + RemainLength) -
620  (DirtyLba + DirtyLength);
621  }
622 
623  DirtyLba = DirtyStart + DirtyLength;
624  Blocks++;
625 
626  } else {
627 
628  if (Blocks == 0) {
629 
630  if (rfsd_bdl)
631  ExFreePool(rfsd_bdl);
632 
633  //
634  // Lookup fails at the first time, ie.
635  // no dirty blocks in the run
636  //
637 
638  DbgBreak();
639 
640  if (RemainLength == (LONGLONG)Length)
642  else
644 
645  _SEH2_LEAVE;
646 
647  } else {
648  break;
649  }
650  }
651  }
652 
653  if (Blocks > 0) {
654 
655  Status = RfsdReadWriteBlocks(IrpContext,
656  Vcb,
657  rfsd_bdl,
658  Length,
659  Blocks,
660  FALSE );
661  Irp = IrpContext->Irp;
662 
663  if (NT_SUCCESS(Status)) {
664  ULONG i;
665 
666  for (i=0; i<Blocks;i++) {
668  rfsd_bdl[i].Lba,
669  rfsd_bdl[i].Length );
670  }
671  }
672 
673  if (rfsd_bdl)
674  ExFreePool(rfsd_bdl);
675 
676  if (!Irp)
677  _SEH2_LEAVE;
678 
679  } else {
680 
681  if (rfsd_bdl)
682  ExFreePool(rfsd_bdl);
683 
684  Irp->IoStatus.Information = Length;
685 
687  _SEH2_LEAVE;
688  }
689  }
690  } _SEH2_FINALLY {
691 
692  if (PagingIoResourceAcquired) {
694  &Vcb->PagingIoResource,
696  }
697 
698  if (MainResourceAcquired) {
700  &Vcb->MainResource,
702  }
703 
704  if (!IrpContext->ExceptionInProgress) {
705  if (Irp) {
706  if (Status == STATUS_PENDING) {
707  if(!bDeferred) {
709  IrpContext->Irp,
710  Length,
711  IoReadAccess );
712 
713  if (NT_SUCCESS(Status)) {
714  Status = RfsdQueueRequest(IrpContext);
715  } else {
716  RfsdCompleteIrpContext(IrpContext, Status);
717  }
718  }
719 
720  } else {
721 
722  if (NT_SUCCESS(Status)) {
723  if (SynchronousIo && !PagingIo) {
724  FileObject->CurrentByteOffset.QuadPart =
725  ByteOffset.QuadPart + Irp->IoStatus.Information;
726  }
727 
728  if (!PagingIo) {
730  }
731  }
732 
733  RfsdCompleteIrpContext(IrpContext, Status);
734  }
735  } else {
736  RfsdFreeIrpContext(IrpContext);
737  }
738  }
739  } _SEH2_END;
740 
741  return Status;
742 }
743 
744 NTSTATUS
746  IN PRFSD_IRP_CONTEXT IrpContext,
747  IN PRFSD_VCB Vcb,
748  IN ULONG InodeNo,
749  IN PRFSD_INODE Inode,
751  IN PVOID Buffer,
752  IN ULONG Size,
753  IN BOOLEAN bWriteToDisk,
754  OUT PULONG dwRet
755  )
756 {
757  PRFSD_BDL rfsd_bdl = NULL;
758  ULONG blocks, i;
760 
762  ULONGLONG AllocSize;
763 
764  BOOLEAN bAlloc = FALSE;
765 
766  PAGED_CODE();
767 #if 0
768  if (dwRet) {
769  *dwRet = 0;
770  }
771 
772  //
773  // For file/non pagingio, we support the allocation on writing.
774  //
775 
776  if (S_ISREG(Inode->i_mode)) {
777 
778  if (!(IrpContext->Irp->Flags & IRP_PAGING_IO)) {
779  bAlloc = TRUE;
780  }
781  }
782 
783  //
784  // Initialize the FileSize / AllocationSize ...
785  //
786 
787  FileSize = (ULONGLONG) Inode->i_size;
788  if (S_ISREG(Inode->i_mode))
789  FileSize |= ((ULONGLONG)(Inode->i_size_high) << 32);
790  AllocSize = CEILING_ALIGNED(FileSize, (ULONGLONG)Vcb->BlockSize);
791 
792 
793  //
794  // Check the inputed parameters ...
795  //
796 
797  if (!bAlloc) {
798 
799  if (Offset >= AllocSize) {
800  RfsdPrint((DBG_ERROR, "RfsdWritenode: beyond the file range.\n"));
801  return STATUS_SUCCESS;
802  }
803 
804  if (Offset + Size > AllocSize) {
805  Size = (ULONG)(AllocSize - Offset);
806  }
807  }
808 
809  Status = RfsdBuildBDL (
810  IrpContext,
811  Vcb,
812  InodeNo,
813  Inode,
814  Offset,
815  Size,
816  bAlloc,
817  &rfsd_bdl,
818  &blocks
819  );
820 
821  if (blocks <= 0) {
823  goto errorout;
824  }
825 
826  if (bWriteToDisk) {
827 
828  //
829  // We assume the offset is aligned.
830  //
831 
833  IrpContext,
834  Vcb,
835  rfsd_bdl,
836  Size,
837  blocks,
838  FALSE
839  );
840 
841  } else {
842 
843  for(i = 0; i < blocks; i++) {
844 
845  if( !RfsdSaveBuffer(
846  IrpContext,
847  Vcb,
848  rfsd_bdl[i].Lba,
849  rfsd_bdl[i].Length,
850  (PVOID)((PUCHAR)Buffer + rfsd_bdl[i].Offset)
851  )) {
852  goto errorout;
853  }
854  }
855 
856  if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
857 
858  RfsdPrint((DBG_USER, "RfsdWriteInode is starting FlushingDpc...\n"));
860  }
861 
863  }
864 
865 errorout:
866 
867  if (rfsd_bdl)
868  ExFreePool(rfsd_bdl);
869 
870  if (NT_SUCCESS(Status)) {
871  if (dwRet) *dwRet = Size;
872  }
873 #endif // 0
874  return Status;
875 }
876 
877 NTSTATUS
879 {
881 
882  PRFSD_VCB Vcb;
883  PRFSD_FCB Fcb;
884  PRFSD_CCB Ccb;
886  PFILE_OBJECT CacheObject;
887 
889 
890  PIRP Irp;
891  PIO_STACK_LOCATION IoStackLocation;
892 
893  ULONG Length;
896 
897  BOOLEAN PagingIo;
898  BOOLEAN Nocache;
899  BOOLEAN SynchronousIo;
900  BOOLEAN MainResourceAcquired = FALSE;
901  BOOLEAN PagingIoResourceAcquired = FALSE;
902 
903  BOOLEAN bNeedExtending = FALSE;
904  BOOLEAN bAppendFile = FALSE;
905 
906  BOOLEAN bDeferred = FALSE;
907 
908  PUCHAR Buffer;
909 
910  PAGED_CODE();
911 #if 0
912  _SEH2_TRY {
913 
914  ASSERT(IrpContext);
915 
916  ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
917  (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
918 
919  DeviceObject = IrpContext->DeviceObject;
920 
921  Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
922 
923  ASSERT(Vcb != NULL);
924 
925  ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
926  (Vcb->Identifier.Size == sizeof(RFSD_VCB)));
927 
928  FileObject = IrpContext->FileObject;
929 
930  Fcb = (PRFSD_FCB) FileObject->FsContext;
931 
932  ASSERT(Fcb);
933 
934  ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
935  (Fcb->Identifier.Size == sizeof(RFSD_FCB)));
936 
937  Ccb = (PRFSD_CCB) FileObject->FsContext2;
938 
939  Irp = IrpContext->Irp;
940 
941  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
942 
943  Length = IoStackLocation->Parameters.Write.Length;
944  ByteOffset = IoStackLocation->Parameters.Write.ByteOffset;
945 
946  PagingIo = (Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE);
947  Nocache = (Irp->Flags & IRP_NOCACHE ? TRUE : FALSE);
948  SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO ? TRUE : FALSE);
949 
950  RfsdPrint((DBG_INFO, "RfsdWriteFile: Off=%I64xh Len=%xh Paging=%xh Nocache=%xh\n",
951  ByteOffset.QuadPart, Length, PagingIo, Nocache));
952 
953 /*
954  if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED))
955  {
956  Status = STATUS_FILE_DELETED;
957  _SEH2_LEAVE;
958  }
959 
960  if (IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING))
961  {
962  Status = STATUS_DELETE_PENDING;
963  _SEH2_LEAVE;
964  }
965 */
966  if (Length == 0) {
967  Irp->IoStatus.Information = 0;
969  _SEH2_LEAVE;
970  }
971 
972  if (Nocache &&
973  (ByteOffset.LowPart & (SECTOR_SIZE - 1) ||
974  Length & (SECTOR_SIZE - 1))) {
976  _SEH2_LEAVE;
977  }
978 
979  if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
980  ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
982  _SEH2_LEAVE;
983  }
984 
985 #if FALSE
986  if (!Nocache) {
987 
988  BOOLEAN bAgain = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
989  BOOLEAN bWait = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
990  BOOLEAN bQueue = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
991 
992  if ( !CcCanIWrite(
993  FileObject,
994  Length,
995  (bWait && bQueue),
996  bAgain ) ) {
997  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
998 
1001  IrpContext,
1002  Irp,
1003  Length,
1004  bAgain );
1005 
1006  bDeferred = TRUE;
1007 
1008  DbgBreak();
1009 
1011  _SEH2_LEAVE;
1012  }
1013  }
1014 
1015 #endif
1016 
1017  if (IsEndOfFile(ByteOffset)) {
1018  bAppendFile = TRUE;
1019  ByteOffset.QuadPart = Fcb->Header.FileSize.QuadPart;
1020  }
1021 
1022  if ( FlagOn(Fcb->RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY) && !PagingIo) {
1024  _SEH2_LEAVE;
1025  }
1026 
1027  //
1028  // Do flushing for such cases
1029  //
1030  if (Nocache && !PagingIo && (Fcb->SectionObject.DataSectionObject != NULL)) {
1031 
1033  IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));
1034 
1035  MainResourceAcquired = TRUE;
1036 
1039 
1040  CcFlushCache( &(Fcb->SectionObject),
1041  &ByteOffset,
1042  Length,
1043  &(Irp->IoStatus));
1045 
1046  if (!NT_SUCCESS(Irp->IoStatus.Status))
1047  {
1048  Status = Irp->IoStatus.Status;
1049  _SEH2_LEAVE;
1050  }
1051 
1054 
1055  CcPurgeCacheSection( &(Fcb->SectionObject),
1057  Length,
1058  FALSE );
1059 
1061  MainResourceAcquired = FALSE;
1062  }
1063 
1064  if (!PagingIo) {
1065 
1067  &Fcb->MainResource,
1068  IrpContext->IsSynchronous )) {
1070  _SEH2_LEAVE;
1071  }
1072 
1073  MainResourceAcquired = TRUE;
1074 
1075  } else {
1076 
1077 /*
1078  ULONG ResShCnt, ResExCnt;
1079  ResShCnt = ExIsResourceAcquiredSharedLite(&Fcb->PagingIoResource);
1080  ResExCnt = ExIsResourceAcquiredExclusiveLite(&Fcb->PagingIoResource);
1081 
1082  RfsdPrint((DBG_USER, "RfsdWriteFile: Inode=%xh %S PagingIo: %xh:%xh Synchronous=%xh\n",
1083  Fcb->RfsdMcb->Inode, Fcb->RfsdMcb->ShortName.Buffer, ResShCnt, ResExCnt, IrpContext->IsSynchronous));
1084 */
1087  IrpContext->IsSynchronous )) {
1089  _SEH2_LEAVE;
1090  }
1091 
1092  PagingIoResourceAcquired = TRUE;
1093  }
1094 
1095  if (!PagingIo) {
1097  &Fcb->FileLockAnchor,
1098  Irp )) {
1100  _SEH2_LEAVE;
1101  }
1102  }
1103 
1104  if (Nocache) {
1105 
1106  if ( (ByteOffset.QuadPart + Length) >
1107  Fcb->Header.AllocationSize.QuadPart) {
1108 
1109  if ( ByteOffset.QuadPart >=
1110  Fcb->Header.AllocationSize.QuadPart) {
1111 
1113  Irp->IoStatus.Information = 0;
1114  _SEH2_LEAVE;
1115 
1116  } else {
1117 
1118  if (Length > (ULONG)(Fcb->Header.AllocationSize.QuadPart
1119  - ByteOffset.QuadPart)) {
1120  Length = (ULONG)(Fcb->Header.AllocationSize.QuadPart
1121  - ByteOffset.QuadPart);
1122  }
1123  }
1124  }
1125  }
1126 
1127  if (!Nocache) {
1128 
1129  if (FlagOn(Fcb->RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {
1130  _SEH2_LEAVE;
1131  }
1132 
1133  if (FileObject->PrivateCacheMap == NULL) {
1134 
1136  FileObject,
1137  (PCC_FILE_SIZES)(&Fcb->Header.AllocationSize),
1138  FALSE,
1140  Fcb );
1141 
1143  FileObject,
1145 
1147  FileObject,
1148  (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
1149  }
1150 
1151  CacheObject = FileObject;
1152 
1153  //
1154  // Need extending the size of inode ?
1155  //
1156  if ( (bAppendFile) || ((ByteOffset.QuadPart + Length) >
1157  (Fcb->Header.FileSize.QuadPart)) ) {
1158 
1159  LARGE_INTEGER ExtendSize;
1161 
1162  bNeedExtending = TRUE;
1163  FileSize = Fcb->Header.FileSize;
1164  ExtendSize.QuadPart = (LONGLONG)(ByteOffset.QuadPart + Length);
1165 
1166  if (ExtendSize.QuadPart > Fcb->Header.AllocationSize.QuadPart) {
1167  Status = RfsdExpandFile(IrpContext, Vcb, Fcb, &ExtendSize);
1168  if (!NT_SUCCESS(Status)) {
1169  _SEH2_LEAVE;
1170  }
1171  }
1172 
1173  {
1174  Fcb->Header.FileSize.QuadPart = ExtendSize.QuadPart;
1175  Fcb->Inode->i_size = ExtendSize.LowPart;
1176  Fcb->Inode->i_size_high = (ULONG) ExtendSize.HighPart;
1177  }
1178 
1179  if (FileObject->PrivateCacheMap) {
1180 
1181  CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
1182 
1183  if (ByteOffset.QuadPart > FileSize.QuadPart) {
1184  RfsdZeroHoles( IrpContext, Vcb, FileObject, FileSize.QuadPart,
1185  ByteOffset.QuadPart - FileSize.QuadPart);
1186  }
1187 
1188  if (Fcb->Header.AllocationSize.QuadPart > ExtendSize.QuadPart) {
1189  RfsdZeroHoles(IrpContext, Vcb, FileObject, ExtendSize.QuadPart,
1190  Fcb->Header.AllocationSize.QuadPart - ExtendSize.QuadPart);
1191  }
1192  }
1193 
1194  if (RfsdSaveInode(IrpContext, Vcb, Fcb->RfsdMcb->Inode, Fcb->Inode)) {
1196  }
1197 
1199  IrpContext,
1200  Vcb,
1201  Fcb,
1204  }
1205 
1206  if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
1208  CacheObject,
1209  (&ByteOffset),
1210  Length,
1211  &Irp->MdlAddress,
1212  &Irp->IoStatus );
1213 
1214  Status = Irp->IoStatus.Status;
1215 
1216  } else {
1217 
1219 
1220  if (Buffer == NULL) {
1221  DbgBreak();
1223  _SEH2_LEAVE;
1224  }
1225 
1226  if (!CcCopyWrite(
1227  CacheObject,
1229  Length,
1230  IrpContext->IsSynchronous,
1231  Buffer )) {
1233  _SEH2_LEAVE;
1234  }
1235 
1236  Status = Irp->IoStatus.Status;
1237  }
1238 
1239  if (NT_SUCCESS(Status)) {
1240 
1241  Irp->IoStatus.Information = Length;
1242 
1243  if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
1244  RfsdPrint((DBG_USER, "RfsdWriteFile is starting FlushingDpc...\n"));
1246  }
1247  }
1248 
1249  } else {
1250 
1252 
1254  IrpContext->Irp,
1255  Length,
1256  IoReadAccess );
1257 
1258  if (!NT_SUCCESS(Status)) {
1259  _SEH2_LEAVE;
1260  }
1261 
1262  Irp->IoStatus.Status = STATUS_SUCCESS;
1263  Irp->IoStatus.Information = Length;
1264 
1266  IrpContext,
1267  Vcb,
1268  Fcb->RfsdMcb->Inode,
1269  Fcb->Inode,
1270  (ULONGLONG)(ByteOffset.QuadPart),
1271  NULL,
1272  Length,
1273  TRUE,
1275  );
1276 
1277  Irp = IrpContext->Irp;
1278 
1279  }
1280 
1281  } _SEH2_FINALLY {
1282 
1283  if (PagingIoResourceAcquired) {
1287  }
1288 
1289  if (MainResourceAcquired) {
1291  &Fcb->MainResource,
1293  }
1294 
1295  if (!IrpContext->ExceptionInProgress) {
1296  if (Irp) {
1297  if (Status == STATUS_PENDING) {
1298  if (!bDeferred) {
1300  IrpContext->Irp,
1301  Length,
1302  IoReadAccess );
1303 
1304  if (NT_SUCCESS(Status)) {
1305  Status = RfsdQueueRequest(IrpContext);
1306  } else {
1307  RfsdCompleteIrpContext(IrpContext, Status);
1308  }
1309  }
1310  } else {
1311  if (NT_SUCCESS(Status)) {
1312  if (SynchronousIo && !PagingIo) {
1313  FileObject->CurrentByteOffset.QuadPart =
1314  ByteOffset.QuadPart + Irp->IoStatus.Information;
1315  }
1316 
1317  if (!PagingIo)
1318  {
1321  }
1322  }
1323 
1324  RfsdCompleteIrpContext(IrpContext, Status);
1325  }
1326  } else {
1327  RfsdFreeIrpContext(IrpContext);
1328  }
1329  }
1330  } _SEH2_END;
1331 #endif // 0
1332  return Status;
1333 }
1334 
1335 NTSTATUS
1337 {
1340  PIRP Irp;
1342 
1343  PAGED_CODE();
1344 
1345  _SEH2_TRY {
1346 
1347  ASSERT(IrpContext);
1348 
1349  ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
1350  (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
1351 
1352  FileObject = IrpContext->FileObject;
1353 
1354  Irp = IrpContext->Irp;
1356 
1357  CcMdlWriteComplete(FileObject, &(IrpSp->Parameters.Write.ByteOffset), Irp->MdlAddress);
1358 
1359  Irp->MdlAddress = NULL;
1360 
1362 
1363  } _SEH2_FINALLY {
1364 
1365  if (!IrpContext->ExceptionInProgress) {
1366  RfsdCompleteIrpContext(IrpContext, Status);
1367  }
1368  } _SEH2_END;
1369 
1370  return Status;
1371 }
1372 
1373 NTSTATUS
1375 {
1376  NTSTATUS Status;
1377  PRFSD_FCBVCB FcbOrVcb;
1380  PRFSD_VCB Vcb;
1381  BOOLEAN bCompleteRequest = TRUE;
1382 
1383  PAGED_CODE();
1384 
1385  ASSERT(IrpContext);
1386 
1387  ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
1388  (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
1389 
1390  _SEH2_TRY {
1391 
1392  if (FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE)) {
1393 
1394  Status = RfsdWriteComplete(IrpContext);
1395  bCompleteRequest = FALSE;
1396 
1397  } else {
1398 
1399  DeviceObject = IrpContext->DeviceObject;
1400 
1403  _SEH2_LEAVE;
1404  }
1405 
1406  Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
1407 
1408  if (Vcb->Identifier.Type != RFSDVCB ||
1409  Vcb->Identifier.Size != sizeof(RFSD_VCB) ) {
1411  _SEH2_LEAVE;
1412  }
1413 
1414  ASSERT(IsMounted(Vcb));
1415 
1416  if (IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
1418  _SEH2_LEAVE;
1419  }
1420 
1421  if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
1423  _SEH2_LEAVE;
1424  }
1425 
1426  FileObject = IrpContext->FileObject;
1427 
1428  FcbOrVcb = (PRFSD_FCBVCB) FileObject->FsContext;
1429 
1430  if (FcbOrVcb->Identifier.Type == RFSDVCB) {
1431 
1432  Status = RfsdWriteVolume(IrpContext);
1433 
1434  if (!NT_SUCCESS(Status)) {
1435  DbgBreak();
1436  }
1437 
1438  bCompleteRequest = FALSE;
1439  } else if (FcbOrVcb->Identifier.Type == RFSDFCB) {
1440  Status = RfsdWriteFile(IrpContext);
1441 
1442  if (!NT_SUCCESS(Status)) {
1443  DbgBreak();
1444  }
1445 
1446  bCompleteRequest = FALSE;
1447  } else {
1449  }
1450  }
1451 
1452  } _SEH2_FINALLY {
1453 
1454  if (bCompleteRequest) {
1455  RfsdCompleteIrpContext(IrpContext, Status);
1456  }
1457  } _SEH2_END;
1458 
1459  return Status;
1460 }
1461 
1462 #endif // !RFSD_READ_ONLY
struct _RFSD_CCB * PRFSD_CCB
#define READ_AHEAD_GRANULARITY
Definition: btrfs_drv.h:118
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: rfsd.h:400
VOID RfsdDeferWrite(IN PRFSD_IRP_CONTEXT, PIRP Irp)
Definition: write.c:234
#define ExGetCurrentResourceThread()
Definition: env_spec_w32.h:633
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
#define IN
Definition: typedefs.h:39
PIRP Irp
Definition: rfsd.h:834
#define IsMounted(Vcb)
Definition: ext2fs.h:803
NTSTATUS RfsdExpandFile(PRFSD_IRP_CONTEXT IrpContext, PRFSD_VCB Vcb, PRFSD_FCB Fcb, PLARGE_INTEGER AllocationSize)
Definition: fileinfo.c:964
NTSTATUS RfsdCompleteIrpContext(IN PRFSD_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: memory.c:160
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
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
#define FsRtlEnterFileSystem
NTSTATUS Status
Definition: write.c:2803
ULONG Length
Definition: rfsd.h:833
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
#define FsRtlExitFileSystem
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
#define CEILING_ALIGNED(T, A, B)
Definition: ext2fs.h:111
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
VOID RfsdNotifyReportChange(IN PRFSD_IRP_CONTEXT IrpContext, IN PRFSD_VCB Vcb, IN PRFSD_FCB Fcb, IN ULONG Filter, IN ULONG Action)
Definition: dirctl.c:745
BOOLEAN RfsdSaveBuffer(IN PRFSD_IRP_CONTEXT IrpContext, IN PRFSD_VCB Vcb, IN LONGLONG Offset, IN ULONG Size, IN PVOID Buf)
NTSTATUS RfsdReadWriteBlocks(IN PRFSD_IRP_CONTEXT IrpContext, IN PRFSD_VCB Vcb, IN PRFSD_BDL RfsdBDL, IN ULONG Length, IN ULONG Count, IN BOOLEAN bVerify)
Definition: blockio.c:200
BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:714
unsigned char * PUCHAR
Definition: retypes.h:3
BOOLEAN RfsdAddMcbEntry(IN PRFSD_VCB Vcb, IN LONGLONG Lba, IN LONGLONG Length)
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_CONTEXT_FLAG_DEFERRED
Definition: ext2fs.h:1082
#define IRP_NOCACHE
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
BOOLEAN RfsdLookupMcbEntry(IN PRFSD_VCB Vcb, IN LONGLONG Offset, OUT PLONGLONG Lba OPTIONAL, OUT PLONGLONG Length OPTIONAL, OUT PLONGLONG RunStart OPTIONAL, OUT PLONGLONG RunLength OPTIONAL, OUT PULONG Index OPTIONAL)
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
#define RFSD_POOL_TAG
Definition: rfsd.h:99
VOID RfsdFreeIrpContext(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: memory.c:192
#define FILE_NOTIFY_CHANGE_SIZE
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS RfsdQueueRequest(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: dispatch.c:29
VOID RfsdFloppyFlush(IN PVOID Parameter)
Definition: write.c:97
_In_ PVOID Parameter
Definition: ldrtypes.h:241
ULONGLONG Offset
Definition: rfsd.h:832
NTSTATUS RfsdWriteComplete(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: write.c:1336
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
NTSTATUS RfsdBuildBDL(IN PRFSD_IRP_CONTEXT IrpContext, IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY InodeNo, IN PRFSD_INODE Inode, IN ULONGLONG Offset, IN ULONG Size, IN BOOLEAN bAlloc, OUT PRFSD_BDL *Bdls, OUT PULONG Count)
Definition: rfsd.h:323
#define _In_opt_
Definition: no_sal2.h:213
PDEVICE_OBJECT DeviceObject
Definition: rfsd.h:407
VOID RfsdFloppyFlushDpc(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: write.c:143
_SEH2_TRY
Definition: create.c:4226
Definition: rfsd.h:324
#define STATUS_END_OF_FILE
Definition: shellext.h:67
ULONGLONG Lba
Definition: rfsd.h:831
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1756
#define IRP_MN_COMPLETE
Definition: iotypes.h:4399
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
__GNU_EXTENSION typedef __int64 * PLONGLONG
Definition: ntbasedef.h:383
#define FO_FILE_MODIFIED
Definition: iotypes.h:1768
struct _RFSD_FCB * PRFSD_FCB
NTFSIDENTIFIER Identifier
Definition: ntfs.h:511
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define CCB_ALLOW_EXTENDED_DASD_IO
Definition: ext2fs.h:1028
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
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
#define FALSE
Definition: types.h:117
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:414
WORK_QUEUE_ITEM Item
Definition: write.c:29
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
#define FILE_ACTION_MODIFIED
__drv_mustHoldCriticalRegion NTSTATUS RfsdPurgeVolume(IN PRFSD_VCB Vcb, IN BOOLEAN FlushBeforePurge)
Definition: fsctl.c:1085
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
RFSD_IDENTIFIER_TYPE Type
Definition: rfsd.h:336
PFILE_OBJECT FileObject
Definition: write.c:25
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
Definition: rfsd.h:326
Definition: bufpool.h:45
static int blocks
Definition: mkdosfs.c:527
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
BOOLEAN RfsdZeroHoles(IN PRFSD_IRP_CONTEXT IrpContext, IN PRFSD_VCB Vcb, IN PFILE_OBJECT FileObject, IN LONGLONG Offset, IN LONGLONG Count)
Definition: write.c:204
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define IsEndOfFile(Pos)
Definition: ffsdrv.h:157
struct _RFSD_VCB * PRFSD_VCB
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
PRFSD_VCB Vcb
Definition: write.c:23
int64_t LONGLONG
Definition: typedefs.h:68
NTSTATUS RfsdWriteInode(IN PRFSD_IRP_CONTEXT IrpContext, IN PRFSD_VCB Vcb, IN ULONG InodeNo, IN PRFSD_INODE Inode, IN ULONGLONG Offset, IN PVOID Buffer, IN ULONG Size, IN BOOLEAN bWriteToDisk, OUT PULONG dwRet)
Definition: write.c:745
#define DBG_USER
Definition: ffsdrv.h:1032
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:511
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
Definition: copysup.c:214
VOID RfsdStartFloppyFlushDpc(PRFSD_VCB Vcb, PRFSD_FCB Fcb, PFILE_OBJECT FileObject)
Definition: write.c:164
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
uint64_t ULONGLONG
Definition: typedefs.h:67
#define Vcb
Definition: cdprocs.h:1415
struct _RFSD_FLPFLUSH_CONTEXT RFSD_FLPFLUSH_CONTEXT
struct _RFSD_FLPFLUSH_CONTEXT * PRFSD_FLPFLUSH_CONTEXT
BOOLEAN RfsdSaveInode(IN PRFSD_IRP_CONTEXT IrpContext, IN PRFSD_VCB Vcb, IN ULONG inode, IN PRFSD_INODE Inode)
_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
* PFILE_OBJECT
Definition: iotypes.h:1978
struct _RFSD_FCBVCB * PRFSD_FCBVCB
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
ULONG Flags
Definition: ntfs.h:532
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Status
Definition: gdiplustypes.h:24
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define VCB_DISMOUNT_PENDING
Definition: ext2fs.h:782
Definition: ketypes.h:687
#define RfsdPrint(arg)
Definition: rfsd.h:1069
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP Irp
Definition: write.c:2800
ULONG Type
Definition: ntfs.h:95
#define IRP_MN_MDL
Definition: iotypes.h:4398
#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
ULONG LowPart
Definition: typedefs.h:106
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:588
#define DBG_ERROR
Definition: ffsdrv.h:1031
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
ERESOURCE MainResource
Definition: ntfs.h:524
NTSTATUS RfsdWrite(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: write.c:1374
#define VCB_READ_ONLY
Definition: ext2fs.h:795
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
#define IRP_MN_DPC
Definition: iotypes.h:4397
_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
NTSTATUS RfsdWriteVolume(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: write.c:242
#define _In_
Definition: no_sal2.h:204
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:2789
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4400
#define VCB_FLOPPY_DISK
Definition: ext2fs.h:797
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
NTSTATUS RfsdLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: blockio.c:67
_SEH2_FINALLY
Definition: create.c:4371
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
#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
PVOID RfsdGetUserBuffer(IN PIRP Irp)
Definition: blockio.c:109
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:320
VOID RfsdRemoveMcbEntry(IN PRFSD_VCB Vcb, IN LONGLONG Lba, IN LONGLONG Length)
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
struct tagContext Context
Definition: acpixf.h:1034
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
#define DbgBreak()
Definition: ext2fs.h:46
PRFSD_GLOBAL RfsdGlobal
Definition: init.c:17
VOID NTAPI ExReleaseResourceForThreadLite(IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread)
Definition: resource.c:1844
#define DBG_INFO
Definition: ffsdrv.h:1034
#define SECTOR_SIZE
Definition: fs.h:22
ExFreePool(ed)
RFSD_IDENTIFIER Identifier
Definition: rfsd.h:470
#define _SEH2_LEAVE
Definition: filesup.c:20
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
_In_ PFCB Fcb
Definition: cdprocs.h:159
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define S_ISREG(mode)
Definition: various.h:17
NTSTATUS RfsdWriteFile(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: write.c:878
ULONG Size
Definition: ntfs.h:96
#define STATUS_TOO_LATE
Definition: ntstatus.h:626
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
PRFSD_FCB Fcb
Definition: write.c:24
LONGLONG QuadPart
Definition: typedefs.h:114
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:725
#define PAGED_CODE()
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675