ReactOS  0.4.14-dev-52-g6116262
read.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: read.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 /* DEFINITIONS *************************************************************/
19 
22 
24 Ext2ReadFile (IN PEXT2_IRP_CONTEXT IrpContext);
25 
28 
29 /* FUNCTIONS *************************************************************/
30 
33  IN PEXT2_IRP_CONTEXT IrpContext,
35 {
36  PIRP Irp = NULL;
37  BOOLEAN bPrint;
38 
39  Irp = IrpContext->Irp;
40 
41  if (Irp != NULL) {
42 
43  if (NT_ERROR(Status)) {
44  Irp->IoStatus.Information = 0;
45  }
46 
47  Irp->IoStatus.Status = Status;
48  bPrint = !IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
49 
51  Irp, bPrint, (CCHAR)(NT_SUCCESS(Status)?
53 
54  IrpContext->Irp = NULL;
55  }
56 
57  Ext2FreeIrpContext(IrpContext);
58 
59  return Status;
60 }
61 
62 
65 {
67 
68  PEXT2_VCB Vcb = NULL;
69  PEXT2_CCB Ccb = NULL;
70  PEXT2_FCBVCB FcbOrVcb = NULL;
72 
74 
75  PIRP Irp = NULL;
76  PIO_STACK_LOCATION IoStackLocation = NULL;
77 
78  ULONG Length;
80 
81  BOOLEAN PagingIo;
82  BOOLEAN Nocache;
83  BOOLEAN SynchronousIo;
84  BOOLEAN MainResourceAcquired = FALSE;
85 
86  PUCHAR Buffer = NULL;
87  EXT2_EXTENT BlockArray;
88 
89  _SEH2_TRY {
90 
91  ASSERT(IrpContext);
92  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
93  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
94 
95  DeviceObject = IrpContext->DeviceObject;
97  ASSERT(Vcb != NULL);
98  ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
99  (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
100 
101  FileObject = IrpContext->FileObject;
102  FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
103  ASSERT(FcbOrVcb);
104 
105  if (!(FcbOrVcb->Identifier.Type == EXT2VCB && (PVOID)FcbOrVcb == (PVOID)Vcb)) {
106 
108  _SEH2_LEAVE;
109  }
110 
111  Ccb = (PEXT2_CCB) FileObject->FsContext2;
112  Irp = IrpContext->Irp;
113  Irp->IoStatus.Information = 0;
114  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
115 
116  Length = IoStackLocation->Parameters.Read.Length;
117  ByteOffset = IoStackLocation->Parameters.Read.ByteOffset;
118 
119  PagingIo = IsFlagOn(Irp->Flags, IRP_PAGING_IO);
120  Nocache = IsFlagOn(Irp->Flags, IRP_NOCACHE) || (Ccb != NULL);
121  SynchronousIo = IsFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);
122 
123  if (PagingIo) {
124  ASSERT(Nocache);
125  }
126 
127  if (Length == 0) {
128  Irp->IoStatus.Information = 0;
130  _SEH2_LEAVE;
131  }
132 
133  if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
134  ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
136  _SEH2_LEAVE;
137  }
138 
139  if (ByteOffset.QuadPart >=
140  Vcb->PartitionInformation.PartitionLength.QuadPart ) {
141  Irp->IoStatus.Information = 0;
143  _SEH2_LEAVE;
144  }
145 
146  if (ByteOffset.QuadPart + Length > Vcb->Header.FileSize.QuadPart) {
147  Length = (ULONG)(Vcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
148  }
149 
150  /*
151  * User direct volume access
152  */
153 
154  if (Ccb != NULL && !PagingIo) {
155 
157  &Vcb->MainResource,
158  IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
160  _SEH2_LEAVE;
161  }
162  MainResourceAcquired = TRUE;
163 
165 
166  if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
167  Ext2FlushVolume(IrpContext, Vcb, FALSE);
168  }
169 
171  }
172 
173  ExReleaseResourceLite(&Vcb->MainResource);
174  MainResourceAcquired = FALSE;
175 
176  /* will do Nocache i/o */
177  }
178 
179  /*
180  * I/O to volume StreamObject
181  */
182 
183  if (!Nocache) {
184 
185  if (IsFlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
186 
187  CcMdlRead(
188  Vcb->Volume,
189  &ByteOffset,
190  Length,
191  &Irp->MdlAddress,
192  &Irp->IoStatus );
193 
194  Status = Irp->IoStatus.Status;
195 
196  } else {
197 
199  if (Buffer == NULL) {
200  DbgBreak();
202  _SEH2_LEAVE;
203  }
204 
205  if (!CcCopyRead(
206  Vcb->Volume,
207  &ByteOffset,
208  Length,
209  Ext2CanIWait(),
210  Buffer,
211  &Irp->IoStatus )) {
213  _SEH2_LEAVE;
214  }
215 
216  Status = Irp->IoStatus.Status;
217  }
218 
219  } else {
220 
221  Length &= ~((ULONG)SECTOR_SIZE - 1);
223  IrpContext->Irp,
224  Length,
225  IoWriteAccess );
226 
227  if (!NT_SUCCESS(Status)) {
228  _SEH2_LEAVE;
229  }
230 
231  BlockArray.Irp = NULL;
232  BlockArray.Lba = ByteOffset.QuadPart;
233  BlockArray.Offset = 0;
234  BlockArray.Length = Length;
235  BlockArray.Next = NULL;
236 
237  Status = Ext2ReadWriteBlocks(IrpContext,
238  Vcb,
239  &BlockArray,
240  Length );
241 
242  Irp = IrpContext->Irp;
243  if (!Irp) {
244  _SEH2_LEAVE;
245  }
246  }
247 
248  } _SEH2_FINALLY {
249 
250  if (MainResourceAcquired) {
251  ExReleaseResourceLite(&Vcb->MainResource);
252  }
253 
254  if (!IrpContext->ExceptionInProgress) {
255 
256  if (Irp) {
257 
258  if (Status == STATUS_PENDING &&
259  !IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED)) {
260 
262  IrpContext->Irp,
263  Length,
264  IoWriteAccess );
265 
266  if (NT_SUCCESS(Status)) {
267  Status = Ext2QueueRequest(IrpContext);
268  } else {
269  Ext2CompleteIrpContext(IrpContext, Status);
270  }
271 
272  } else {
273 
274  if (NT_SUCCESS(Status)) {
275 
276  if (!PagingIo) {
277 
278  if (SynchronousIo) {
279 
280  FileObject->CurrentByteOffset.QuadPart =
281  ByteOffset.QuadPart + Irp->IoStatus.Information;
282  }
283 
285  }
286  }
287 
288  Ext2CompleteIrpContext(IrpContext, Status);;
289  }
290 
291  } else {
292  Ext2FreeIrpContext(IrpContext);
293  }
294  }
295  } _SEH2_END;
296 
297  return Status;
298 }
299 
300 
301 #define SafeZeroMemory(AT,BYTE_COUNT) { \
302  _SEH2_TRY { \
303  if (AT) \
304  RtlZeroMemory((AT), (BYTE_COUNT)); \
305  } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \
306  Ext2RaiseStatus( IrpContext, STATUS_INVALID_USER_BUFFER ); \
307  } _SEH2_END; \
308 }
309 
310 NTSTATUS
312  IN PEXT2_IRP_CONTEXT IrpContext,
313  IN PEXT2_VCB Vcb,
314  IN PEXT2_MCB Mcb,
316  IN PVOID Buffer,
317  IN ULONG Size,
318  IN BOOLEAN bDirectIo,
320 )
321 {
322  PEXT2_EXTENT Chain = NULL;
323  PEXT2_EXTENT Extent = NULL, Prev = NULL;
324 
327  ULONG RealSize ;
328 
329  if (BytesRead) {
330  *BytesRead = 0;
331  }
332 
333  _SEH2_TRY {
334 
335  Ext2ReferMcb(Mcb);
336 
337  ASSERT((Mcb->Identifier.Type == EXT2MCB) &&
338  (Mcb->Identifier.Size == sizeof(EXT2_MCB)));
339 
340  if ((Mcb->Identifier.Type != EXT2MCB) ||
341  (Mcb->Identifier.Size != sizeof(EXT2_MCB))) {
342  _SEH2_LEAVE;
343  }
344 
345  if (Buffer == NULL && IrpContext != NULL)
346  Buffer = Ext2GetUserBuffer(IrpContext->Irp);
347 
348 
349  /* handle fast symlinks */
350  if (S_ISLNK(Mcb->Inode.i_mode) && 0 == Mcb->Inode.i_blocks) {
351 
352  PUCHAR Data = (PUCHAR) (&Mcb->Inode.i_block[0]);
353  if (!Buffer) {
355  _SEH2_LEAVE;
356  }
357 
363  } else {
365  }
366  _SEH2_LEAVE;
367  }
368 
369  //
370  // Build the scatterred block ranges to be read
371  //
372 
373  if (bDirectIo) {
374  RealSize = CEILING_ALIGNED(ULONG, Size, SECTOR_SIZE - 1);
375  } else {
376  RealSize = Size;
377  }
378 
380  IrpContext,
381  Vcb,
382  Mcb,
383  Offset,
384  RealSize,
385  FALSE,
386  &Chain
387  );
388 
389  if (!NT_SUCCESS(Status)) {
390  _SEH2_LEAVE;
391  }
392 
393  if (Chain == NULL) {
396  _SEH2_LEAVE;
397  }
398 
399  /* for sparse file, we need zero the gaps */
400  for (Extent = Chain; Buffer != NULL && Extent != NULL; Extent = Extent->Next) {
401  if (NULL == Prev) {
402  ASSERT(Extent == Chain);
403  if (Extent->Offset) {
404  SafeZeroMemory((PCHAR)Buffer, Extent->Offset);
405  }
406  } else if (Extent->Offset > (Prev->Offset + Prev->Length)) {
407  SafeZeroMemory((PCHAR)Buffer + Prev->Offset + Prev->Length,
408  Extent->Offset - Prev->Offset - Prev->Length);
409  }
410  if (NULL == Extent->Next) {
411  if (Extent->Offset + Extent->Length < Size) {
413  Size - Extent->Offset - Extent->Length);
414  }
415  }
416  Prev = Extent;
417  }
418 
419  if (bDirectIo) {
420 
421  ASSERT(IrpContext != NULL);
422 
423  // Offset should be SECTOR_SIZE aligned ...
425  IrpContext,
426  Vcb,
427  Chain,
428  Size
429  );
430  } else {
431 
432  for (Extent = Chain; Extent != NULL; Extent = Extent->Next) {
433 
434  if (!CcCopyRead(
435  Vcb->Volume,
436  (PLARGE_INTEGER)(&(Extent->Lba)),
437  Extent->Length,
438  PIN_WAIT,
439  (PVOID)((PUCHAR)Buffer + Extent->Offset),
440  &IoStatus
441  )) {
443  } else {
444  Status = IoStatus.Status;
445  }
446 
447  if (!NT_SUCCESS(Status)) {
448  break;
449  }
450  }
451  }
452 
453  } _SEH2_FINALLY {
454 
455  if (Chain) {
456  Ext2DestroyExtentChain(Chain);
457  }
458 
459  Ext2DerefMcb(Mcb);
460  } _SEH2_END;
461 
462  if (NT_SUCCESS(Status)) {
463  if (BytesRead)
464  *BytesRead = Size;
465  }
466 
467  return Status;
468 }
469 
470 NTSTATUS
472 {
474 
475  PEXT2_VCB Vcb = NULL;
476  PEXT2_FCB Fcb = NULL;
477  PEXT2_CCB Ccb = NULL;
479 
481 
482  PIRP Irp = NULL;
483  PIO_STACK_LOCATION IoStackLocation = NULL;
484 
485  ULONG Length;
486  ULONG ReturnedLength = 0;
488 
489  BOOLEAN OpPostIrp = FALSE;
490  BOOLEAN PagingIo;
491  BOOLEAN Nocache;
492  BOOLEAN SynchronousIo;
493  BOOLEAN MainResourceAcquired = FALSE;
494  BOOLEAN PagingIoResourceAcquired = FALSE;
495 
496  PUCHAR Buffer;
497 
498  _SEH2_TRY {
499 
500  ASSERT(IrpContext);
501  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
502  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
503 
504  DeviceObject = IrpContext->DeviceObject;
506  ASSERT(Vcb != NULL);
507  ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
508  (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
509 
510  FileObject = IrpContext->FileObject;
511  Fcb = (PEXT2_FCB) FileObject->FsContext;
512  ASSERT(Fcb);
513  ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
514  (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
515 
516  Ccb = (PEXT2_CCB) FileObject->FsContext2;
517 
518  Irp = IrpContext->Irp;
519  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
520 
521  Length = IoStackLocation->Parameters.Read.Length;
522  ByteOffset = IoStackLocation->Parameters.Read.ByteOffset;
523 
524  PagingIo = IsFlagOn(Irp->Flags, IRP_PAGING_IO);
525  Nocache = IsFlagOn(Irp->Flags, IRP_NOCACHE);
526  SynchronousIo = IsFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);
527 
528  if (PagingIo) {
529  ASSERT(Nocache);
530  }
531 
532  DEBUG(DL_INF, ("Ext2ReadFile: reading %wZ Off=%I64xh Len=%xh Paging=%xh Nocache=%xh\n",
533  &Fcb->Mcb->ShortName, ByteOffset.QuadPart, Length, PagingIo, Nocache));
534 
535  if (IsSpecialFile(Fcb) || IsInodeSymLink(Fcb->Inode) ) {
537  _SEH2_LEAVE;
538  }
539 
540  if ((IsSymLink(Fcb) && IsFileDeleted(Fcb->Mcb->Target)) ||
541  IsFileDeleted(Fcb->Mcb)) {
543  _SEH2_LEAVE;
544  }
545 
546  if (Length == 0) {
547  Irp->IoStatus.Information = 0;
549  _SEH2_LEAVE;
550  }
551 
553  ByteOffset.HighPart == -1) {
554  ByteOffset = FileObject->CurrentByteOffset;
555  }
556 
557  if (Nocache && (ByteOffset.LowPart & (SECTOR_SIZE - 1) ||
558  Length & (SECTOR_SIZE - 1))) {
560  DbgBreak();
561  _SEH2_LEAVE;
562  }
563 
564  if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
565  ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
567  DbgBreak();
568  _SEH2_LEAVE;
569  }
570 
572 
573  if (PagingIo) {
574 
577  IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
579  _SEH2_LEAVE;
580  }
581  PagingIoResourceAcquired = TRUE;
582 
583  } else {
584 
585  if (Nocache && Ccb != NULL && Fcb->SectionObject.DataSectionObject) {
586 
588  &Fcb->MainResource,
589  IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
591  _SEH2_LEAVE;
592  }
593  MainResourceAcquired = TRUE;
594 
595  CcFlushCache(&Fcb->SectionObject,
596  &ByteOffset,
597  Length,
598  &Irp->IoStatus );
599  if (!NT_SUCCESS(Irp->IoStatus.Status))
600  _SEH2_LEAVE;
602 
605  }
606  CcPurgeCacheSection( &Fcb->SectionObject,
607  NULL,
608  0,
609  FALSE );
610 
612 
613  } else {
614 
616  &Fcb->MainResource,
617  IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
619  _SEH2_LEAVE;
620  }
621  MainResourceAcquired = TRUE;
622  }
623 
625  &Fcb->FileLockAnchor,
626  Irp )) {
628  _SEH2_LEAVE;
629  }
630  }
631 
632  if ((ByteOffset.QuadPart + (LONGLONG)Length) > Fcb->Header.FileSize.QuadPart) {
633  if (ByteOffset.QuadPart >= Fcb->Header.FileSize.QuadPart) {
634  Irp->IoStatus.Information = 0;
636  _SEH2_LEAVE;
637  }
638  ReturnedLength = (ULONG)(Fcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
639  }
640 
641 
642  if (!IsDirectory(Fcb) && Ccb != NULL) {
643  Status = FsRtlCheckOplock( &Fcb->Oplock,
644  Irp,
645  IrpContext,
647  Ext2LockIrp );
648 
649  if (Status != STATUS_SUCCESS) {
650  OpPostIrp = TRUE;
651  _SEH2_LEAVE;
652  }
653 
654  //
655  // Set the flag indicating if Fast I/O is possible
656  //
657 
658  Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
659  }
660 
661  if (!Nocache) {
662 
663  if (IsDirectory(Fcb)) {
664  _SEH2_LEAVE;
665  }
666 
667  if (FileObject->PrivateCacheMap == NULL) {
669  FileObject,
670  (PCC_FILE_SIZES)(&Fcb->Header.AllocationSize),
671  FALSE,
673  Fcb );
675  FileObject,
677  }
678 
679  if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
680  CcMdlRead(
681  FileObject,
682  (&ByteOffset),
684  &Irp->MdlAddress,
685  &Irp->IoStatus );
686 
687  Status = Irp->IoStatus.Status;
688 
689  } else {
690 
692  if (Buffer == NULL) {
694  DbgBreak();
695  _SEH2_LEAVE;
696  }
697 
699  Ext2CanIWait(), Buffer, &Irp->IoStatus)) {
700 
703  Buffer, &Irp->IoStatus)) {
705  DbgBreak();
706  _SEH2_LEAVE;
707  }
708  }
709  Status = Irp->IoStatus.Status;
710  }
711 
712  } else {
713 
715  PUCHAR SystemVA = Ext2GetUserBuffer(IrpContext->Irp);
716 
717  if (ByteOffset.QuadPart + BytesRead > Fcb->Header.ValidDataLength.QuadPart) {
718 
719  if (ByteOffset.QuadPart >= Fcb->Header.ValidDataLength.QuadPart) {
720  if (SystemVA) {
721  SafeZeroMemory(SystemVA, Length);
722  }
723  Irp->IoStatus.Information = ReturnedLength;
725  _SEH2_LEAVE;
726  } else {
727  BytesRead = (ULONG)(Fcb->Header.ValidDataLength.QuadPart - ByteOffset.QuadPart);
728  if (SystemVA) {
729  SafeZeroMemory(SystemVA + BytesRead, Length - BytesRead);
730  }
731  }
732  }
733 
735  IrpContext->Irp,
736  BytesRead,
737  IoReadAccess );
738 
739  if (!NT_SUCCESS(Status)) {
740  _SEH2_LEAVE;
741  }
742 
744  IrpContext,
745  Vcb,
746  Fcb->Mcb,
747  ByteOffset.QuadPart,
748  NULL,
749  BytesRead,
750  TRUE,
751  NULL );
752 
753  /* we need re-queue this request in case STATUS_CANT_WAIT
754  and fail it in other failure cases */
755  if (!NT_SUCCESS(Status)) {
756  _SEH2_LEAVE;
757  }
758 
759  /* pended by low level device */
760  if (Status == STATUS_PENDING) {
761  IrpContext->Irp = Irp = NULL;
762  _SEH2_LEAVE;
763  }
764 
765  Irp = IrpContext->Irp;
766  ASSERT(Irp);
767  Status = Irp->IoStatus.Status;
768 
769  if (!NT_SUCCESS(Status)) {
770  Ext2NormalizeAndRaiseStatus(IrpContext, Status);
771  }
772  }
773 
774  Irp->IoStatus.Information = ReturnedLength;
775 
776  } _SEH2_FINALLY {
777 
778  if (Irp) {
779  if (PagingIoResourceAcquired) {
781  }
782 
783  if (MainResourceAcquired) {
785  }
786  }
787 
788  if (!OpPostIrp && !IrpContext->ExceptionInProgress) {
789 
790  if (Irp) {
791  if ( Status == STATUS_PENDING ||
793 
795  IrpContext->Irp,
796  Length,
797  IoWriteAccess );
798 
799  if (NT_SUCCESS(Status)) {
800  Status = Ext2QueueRequest(IrpContext);
801  } else {
802  Ext2CompleteIrpContext(IrpContext, Status);
803  }
804  } else {
805  if (NT_SUCCESS(Status)) {
806  if (!PagingIo) {
807  if (SynchronousIo) {
808  FileObject->CurrentByteOffset.QuadPart =
809  ByteOffset.QuadPart + Irp->IoStatus.Information;
810  }
812  }
813  }
814 
815  Ext2CompleteIrpContext(IrpContext, Status);
816  }
817 
818  } else {
819 
820  Ext2FreeIrpContext(IrpContext);
821  }
822  }
823  } _SEH2_END;
824 
825  DEBUG(DL_IO, ("Ext2ReadFile: %wZ fetch at Off=%I64xh Len=%xh Paging=%xh Nocache=%xh Returned=%xh Status=%xh\n",
826  &Fcb->Mcb->ShortName, ByteOffset.QuadPart, Length, PagingIo, Nocache, ReturnedLength, Status));
827  return Status;
828 
829 }
830 
831 NTSTATUS
833 {
836  PIRP Irp;
837 
838  _SEH2_TRY {
839 
840  ASSERT(IrpContext);
841  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
842  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
843 
844  FileObject = IrpContext->FileObject;
845  Irp = IrpContext->Irp;
846 
847  CcMdlReadComplete(FileObject, Irp->MdlAddress);
848  Irp->MdlAddress = NULL;
850 
851  } _SEH2_FINALLY {
852 
853  if (!IrpContext->ExceptionInProgress) {
854  Ext2CompleteIrpContext(IrpContext, Status);
855  }
856  } _SEH2_END;
857 
858  return Status;
859 }
860 
861 
862 NTSTATUS
864 {
866  PEXT2_VCB Vcb;
867  PEXT2_FCBVCB FcbOrVcb;
870  BOOLEAN bCompleteRequest;
871 
872  ASSERT(IrpContext);
873 
874  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
875  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
876 
877  _SEH2_TRY {
878 
879  if (FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE)) {
880 
881  Status = Ext2ReadComplete(IrpContext);
882  bCompleteRequest = FALSE;
883 
884  } else {
885 
886  DeviceObject = IrpContext->DeviceObject;
887 
890  bCompleteRequest = TRUE;
891  _SEH2_LEAVE;
892  }
893 
895  if (Vcb->Identifier.Type != EXT2VCB ||
896  Vcb->Identifier.Size != sizeof(EXT2_VCB) ) {
898  bCompleteRequest = TRUE;
899 
900  _SEH2_LEAVE;
901  }
902 
903  FileObject = IrpContext->FileObject;
904 
905  if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED) &&
906  Vcb->LockFile != FileObject ) {
908  _SEH2_LEAVE;
909  }
910 
911  FcbOrVcb = (PEXT2_FCBVCB) FileObject->FsContext;
912 
913  if (FcbOrVcb->Identifier.Type == EXT2VCB) {
914 
915  Status = Ext2ReadVolume(IrpContext);
916  bCompleteRequest = FALSE;
917 
918  } else if (FcbOrVcb->Identifier.Type == EXT2FCB) {
919 
920  if (IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
922  bCompleteRequest = TRUE;
923  _SEH2_LEAVE;
924  }
925 
926  Status = Ext2ReadFile(IrpContext);
927  bCompleteRequest = FALSE;
928  } else {
929  DEBUG(DL_ERR, ( "Ext2Read: Inavlid FileObject (Vcb or Fcb corrupted)\n"));
930  DbgBreak();
931 
933  bCompleteRequest = TRUE;
934  }
935  }
936 
937  } _SEH2_FINALLY {
938  if (bCompleteRequest) {
939  Ext2CompleteIrpContext(IrpContext, Status);
940  }
941  } _SEH2_END;
942 
943  return Status;
944 }
signed char * PCHAR
Definition: retypes.h:7
struct _EXT2_FCB * PEXT2_FCB
struct _EXT2_EXTENT * Next
Definition: ext2fs.h:1115
#define Ext2DerefMcb(Mcb)
Definition: ext2fs.h:987
NTSTATUS Ext2Read(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: read.c:863
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:384
VOID NTAPI CcMdlRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
Definition: mdlsup.c:64
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
#define IN
Definition: typedefs.h:38
#define IsInodeSymLink(I)
Definition: ext2fs.h:281
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define IsSymLink(Fcb)
Definition: ext2fs.h:280
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ExConvertExclusiveToShared
Definition: exfuncs.h:344
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
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
#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
unsigned char * PUCHAR
Definition: retypes.h:3
LONGLONG Lba
Definition: ext2fs.h:1111
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_NOCACHE
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define Ext2ReferMcb(Mcb)
Definition: ext2fs.h:986
uint64 Length
Definition: DriveVolume.h:48
#define PIN_WAIT
NTSTATUS Ext2LockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: block.c:101
#define READ_AHEAD_GRANULARITY
Definition: read.c:60
#define FILE_USE_FILE_POINTER_POSITION
Definition: ffsdrv.h:155
NTSTATUS Ext2FlushVolume(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bShutDown)
Definition: flush.c:39
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
#define IsSpecialFile(Fcb)
Definition: ext2fs.h:279
NTSTATUS Ext2ReadFile(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: read.c:471
_SEH2_TRY
Definition: create.c:4250
#define STATUS_END_OF_FILE
Definition: shellext.h:62
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 S_ISLNK(m)
Definition: ext2fs.h:368
NTFSIDENTIFIER Identifier
Definition: ntfs.h:511
NTSTATUS Ext2QueueRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:150
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG Offset
Definition: ext2fs.h:1112
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1752
VOID Ext2FreeIrpContext(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: memory.c:114
EXT2_IDENTIFIER Identifier
Definition: ext2fs.h:624
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
NTSTATUS Ext2ReadVolume(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: read.c:64
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
NTSTATUS Ext2ReadComplete(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: read.c:832
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
#define IsFileDeleted(Mcb)
Definition: ext2fs.h:959
smooth NULL
Definition: ftsmooth.c:416
#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 SafeZeroMemory(AT, BYTE_COUNT)
Definition: read.c:301
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
int64_t LONGLONG
Definition: typedefs.h:66
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define DL_INF
Definition: ext2fs.h:1399
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
char CCHAR
Definition: typedefs.h:50
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:676
uint64_t ULONGLONG
Definition: typedefs.h:65
#define Vcb
Definition: cdprocs.h:1425
struct _EXT2_FCBVCB * PEXT2_FCBVCB
#define Ext2CompleteRequest(Irp, bPrint, PriorityBoost)
Definition: ext2fs.h:1438
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define NT_ERROR(Status)
Definition: umtypes.h:106
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define EXT2_LINKLEN_IN_INODE
Definition: ext2fs.h:76
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
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
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
#define VCB_DISMOUNT_PENDING
Definition: ext2fs.h:782
_Must_inspect_result_ _In_ PFLT_INSTANCE _Out_ PBOOLEAN IsDirectory
Definition: fltkernel.h:1139
ULONG Type
Definition: ntfs.h:95
#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
_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
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 PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ULONG Length
Definition: ext2fs.h:1113
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define Ext2NormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: ext2fs.h:263
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4424
#define Ext2CanIWait()
Definition: ext2fs.h:1091
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:334
_SEH2_FINALLY
Definition: create.c:4395
#define DL_IO
Definition: ext2fs.h:1413
unsigned int * PULONG
Definition: retypes.h:1
#define IRP_CONTEXT_FLAG_REQUEUED
Definition: ext2fs.h:1085
NTSTATUS Ext2ReadInode(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 BytesRead)
Definition: read.c:311
#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 IsExt2FsDevice(DO)
Definition: ext2fs.h:607
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
ERESOURCE PagingIoResource
Definition: ntfs.h:523
#define DbgBreak()
Definition: ext2fs.h:46
struct _EXT2_VCB * PEXT2_VCB
#define SECTOR_SIZE
Definition: fs.h:22
#define DEBUG(args)
Definition: rdesktop.h:129
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
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2966
struct _EXT2_CCB * PEXT2_CCB
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: ext2fs.h:523
VOID NTAPI Ext2OplockComplete(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:41
ULONG Size
Definition: ntfs.h:96
#define STATUS_TOO_LATE
Definition: ntstatus.h:612
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
PVOID Ext2GetUserBuffer(IN PIRP Irp)
Definition: block.c:134
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