ReactOS  0.4.14-dev-41-g31d7680
read.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: read.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 
23 
25 RfsdReadFile (IN PRFSD_IRP_CONTEXT IrpContext);
26 
29 
30 #ifdef ALLOC_PRAGMA
31 #pragma alloc_text(PAGE, RfsdCompleteIrpContext)
32 #pragma alloc_text(PAGE, RfsdCopyRead)
33 #pragma alloc_text(PAGE, RfsdRead)
34 #pragma alloc_text(PAGE, RfsdReadVolume)
35 #pragma alloc_text(PAGE, RfsdReadInode)
36 #pragma alloc_text(PAGE, RfsdReadFile)
37 #pragma alloc_text(PAGE, RfsdReadComplete)
38 #endif
39 
40 /* FUNCTIONS *************************************************************/
41 
43 BOOLEAN
47  IN ULONG Length,
48  IN BOOLEAN Wait,
51  )
52 {
53  BOOLEAN bRet;
54 
55  PAGED_CODE();
56 
57  bRet= CcCopyRead(FileObject,
58  FileOffset,
59  Length,
60  Wait,
61  Buffer,
62  IoStatus );
63 
64  if (bRet) {
65  ASSERT(NT_SUCCESS(IoStatus->Status));
66  }
67 
68  return bRet;
69 /*
70  PVOID Bcb = NULL;
71  PVOID Buf = NULL;
72 
73  if (CcMapData( FileObject,
74  FileOffset,
75  Length,
76  Wait,
77  &Bcb,
78  &Buf )) {
79  RtlCopyMemory(Buffer, Buf, Length);
80  IoStatus->Status = STATUS_SUCCESS;
81  IoStatus->Information = Length;
82  CcUnpinData(Bcb);
83  return TRUE;
84 
85  } else {
86  // IoStatus->Status = STATUS_
87  return FALSE;
88  }
89 */
90 }
91 
95 {
97 
98  PRFSD_VCB Vcb = 0;
99  PRFSD_CCB Ccb;
100  PRFSD_FCBVCB FcbOrVcb;
102 
104 
105  PIRP Irp;
106  PIO_STACK_LOCATION IoStackLocation;
107 
108  ULONG Length;
110 
111  BOOLEAN PagingIo;
112  BOOLEAN Nocache;
113  BOOLEAN SynchronousIo;
114  BOOLEAN MainResourceAcquired = FALSE;
115  BOOLEAN PagingIoResourceAcquired = FALSE;
116 
117  PUCHAR Buffer = NULL;
118  PRFSD_BDL rfsd_bdl = NULL;
119 
120  PAGED_CODE();
121 
122  _SEH2_TRY {
123 
124  ASSERT(IrpContext);
125 
126  ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
127  (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
128 
129  DeviceObject = IrpContext->DeviceObject;
130 
132 
133  ASSERT(Vcb != NULL);
134 
135  ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
136  (Vcb->Identifier.Size == sizeof(RFSD_VCB)));
137 
138  FileObject = IrpContext->FileObject;
139 
140  FcbOrVcb = (PRFSD_FCBVCB) FileObject->FsContext;
141 
142  ASSERT(FcbOrVcb);
143 
144  if (!(FcbOrVcb->Identifier.Type == RFSDVCB && (PVOID)FcbOrVcb == (PVOID)Vcb)) {
145 
147  _SEH2_LEAVE;
148  }
149 
150  Ccb = (PRFSD_CCB) FileObject->FsContext2;
151 
152  Irp = IrpContext->Irp;
153 
154  Irp->IoStatus.Information = 0;
155 
156  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
157 
158  Length = IoStackLocation->Parameters.Read.Length;
159  ByteOffset = IoStackLocation->Parameters.Read.ByteOffset;
160 
161  PagingIo = (Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE);
162  Nocache = (Irp->Flags & IRP_NOCACHE ? TRUE : FALSE);
163  SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO ? TRUE : FALSE);
164 
165  if (Length == 0) {
166 
167  Irp->IoStatus.Information = 0;
169  _SEH2_LEAVE;
170  }
171 
172  if (Ccb != NULL) {
173 
175  if (ByteOffset.QuadPart + Length > Vcb->Header.FileSize.QuadPart) {
176  Length = (ULONG)(Vcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
177  }
178  }
179 
180  {
181  RFSD_BDL BlockArray;
182 
183  if ((ByteOffset.LowPart & (SECTOR_SIZE - 1)) ||
184  (Length & (SECTOR_SIZE - 1)) ) {
186  _SEH2_LEAVE;
187  }
188 
190  IrpContext->Irp,
191  Length,
192  IoReadAccess );
193 
194  if (!NT_SUCCESS(Status)) {
195  _SEH2_LEAVE;
196  }
197 
198  BlockArray.Irp = NULL;
199  BlockArray.Lba = ByteOffset.QuadPart;;
200  BlockArray.Offset = 0;
201  BlockArray.Length = Length;
202 
203  Status = RfsdReadWriteBlocks(IrpContext,
204  Vcb,
205  &BlockArray,
206  Length,
207  1,
208  FALSE );
209  Irp = IrpContext->Irp;
210 
211  _SEH2_LEAVE;
212  }
213  }
214 
215  if (Nocache &&
216  ( (ByteOffset.LowPart & (SECTOR_SIZE - 1)) ||
217  (Length & (SECTOR_SIZE - 1)) )) {
218  DbgBreak();
219 
221  _SEH2_LEAVE;
222  }
223 
224  if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
225  ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
227  _SEH2_LEAVE;
228  }
229 
230  if (!PagingIo) {
232  &Vcb->MainResource,
233  IrpContext->IsSynchronous )) {
235  _SEH2_LEAVE;
236  }
237 
238  MainResourceAcquired = TRUE;
239 
240  } else {
241 
243  &Vcb->PagingIoResource,
244  IrpContext->IsSynchronous ))
245  {
247  _SEH2_LEAVE;
248  }
249 
250  PagingIoResourceAcquired = TRUE;
251  }
252 
253 
254  if (ByteOffset.QuadPart >=
255  Vcb->PartitionInformation.PartitionLength.QuadPart ) {
256  Irp->IoStatus.Information = 0;
258  _SEH2_LEAVE;
259  }
260 
261  if (!Nocache) {
262 
263  if ((ByteOffset.QuadPart + Length) >
264  Vcb->PartitionInformation.PartitionLength.QuadPart ){
265  Length = (ULONG) (
266  Vcb->PartitionInformation.PartitionLength.QuadPart -
267  ByteOffset.QuadPart);
268  Length &= ~((ULONG)SECTOR_SIZE - 1);
269  }
270 
271  if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
272 
273  CcMdlRead(
274  Vcb->StreamObj,
275  &ByteOffset,
276  Length,
277  &Irp->MdlAddress,
278  &Irp->IoStatus );
279 
280  Status = Irp->IoStatus.Status;
281 
282  } else {
283 
285 
286  if (Buffer == NULL) {
287  DbgBreak();
289  _SEH2_LEAVE;
290  }
291 
292  if (!CcCopyRead(
293  Vcb->StreamObj,
295  Length,
296  IrpContext->IsSynchronous,
297  Buffer,
298  &Irp->IoStatus )) {
300  _SEH2_LEAVE;
301  }
302 
303  Status = Irp->IoStatus.Status;
304  }
305 
306  } else {
307 
308  if ((ByteOffset.QuadPart + Length) >
309  Vcb->PartitionInformation.PartitionLength.QuadPart ) {
310  Length = (ULONG) (
311  Vcb->PartitionInformation.PartitionLength.QuadPart -
312  ByteOffset.QuadPart);
313 
314  Length &= ~((ULONG)SECTOR_SIZE - 1);
315  }
316 
318  IrpContext->Irp,
319  Length,
320  IoWriteAccess );
321 
322  if (!NT_SUCCESS(Status)) {
323  _SEH2_LEAVE;
324  }
325 
326 #if DBG
328 #endif
330 
331  if (!rfsd_bdl)
332  {
334  _SEH2_LEAVE;
335  }
336 
337  rfsd_bdl->Irp = NULL;
338  rfsd_bdl->Lba = ByteOffset.QuadPart;
339  rfsd_bdl->Length = Length;
340  rfsd_bdl->Offset = 0;
341 
342  Status = RfsdReadWriteBlocks(IrpContext,
343  Vcb,
344  rfsd_bdl,
345  Length,
346  1,
347  FALSE );
348 
349  Irp = IrpContext->Irp;
350 
351  if (!Irp)
352  _SEH2_LEAVE;
353  }
354 
355  } _SEH2_FINALLY {
356 
357  if (PagingIoResourceAcquired) {
359  &Vcb->PagingIoResource,
361  }
362 
363  if (MainResourceAcquired) {
365  &Vcb->MainResource,
367  }
368 
369  if (rfsd_bdl)
370  ExFreePool(rfsd_bdl);
371 
372  if (!IrpContext->ExceptionInProgress) {
373 
374  if (IrpContext->Irp) {
375 
376  if (Status == STATUS_PENDING &&
377  !IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED)) {
378 
380  IrpContext->Irp,
381  Length,
382  IoWriteAccess );
383 
384  if (NT_SUCCESS(Status)) {
385  Status = RfsdQueueRequest(IrpContext);
386  } else {
387  RfsdCompleteIrpContext(IrpContext, Status);
388  }
389 
390  } else {
391 
392  if (NT_SUCCESS(Status)) {
393 
394  if (!PagingIo) {
395 
396  if (SynchronousIo) {
397 
398  IrpContext->FileObject->CurrentByteOffset.QuadPart =
399  ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information;
400  }
401 
402  IrpContext->FileObject->Flags |= FO_FILE_FAST_IO_READ;
403  }
404  }
405 
406  RfsdCompleteIrpContext(IrpContext, Status);;
407  }
408 
409  } else {
410  RfsdFreeIrpContext(IrpContext);
411  }
412  }
413  } _SEH2_END;
414 
415  return Status;
416 }
417 
418 // [mark] read some goop [from the file pt'd to by inode -- from whatever blocks buildbdl makes] into the buffer
419 NTSTATUS
421  IN PRFSD_IRP_CONTEXT IrpContext, // [may be null]
422  IN PRFSD_VCB Vcb,
423  IN PRFSD_KEY_IN_MEMORY Key, // Key that identifies the data on disk to be read. This is simply forwarded through to BuildBDL. (NOTE: IN THIS CASE, THE OFFSET AND TYPE FIELDS MATTER)
424  IN PRFSD_INODE Inode, // a filled Inode / stat data structure
425  IN ULONGLONG Offset, // User's requested offset to read within the file (relative to the file)
426  IN OUT PVOID Buffer, // buffer to read out to
427  IN ULONG Size, // size of destination buffer
428  OUT PULONG dwRet ) // some kind of size [probably bytes read?]
429 {
430  PRFSD_BDL Bdl = NULL;
431  ULONG blocks, i, j;
434 
436  ULONGLONG AllocSize;
437 
438  PAGED_CODE();
439 
440  if (dwRet) {
441  *dwRet = 0;
442  }
443 
444  //
445  // Calculate the inode size
446  //
447 
448  FileSize = (ULONGLONG) Inode->i_size;
449 
450  //KdPrint(("Rfsd: RfsdReadInode: file size = %I64u, offset = %I64u, length = %u\n", FileSize, Offset, Size));
451 
452  // TODO: temporary hack to get correct alloc size for dir tails... but i doubt 8 works in all cases :-) [what i should really be using is the size of the direct item in the block header!]
453  // AllocSize = CEILING_ALIGNED(FileSize, (ULONGLONG)Vcb->BlockSize);
454  // AllocSize = CEILING_ALIGNED(FileSize, (ULONGLONG) 8);
455  AllocSize = CEILING_ALIGNED(FileSize, (ULONGLONG) 1); // temp hack to ensure that i'll read out EXACTLY the # of bytes he requested
456 
457  //
458  // Check inputed parameters: Offset / Size
459  //
460 
461  if (Offset >= AllocSize) {
462 
463  RfsdPrint((DBG_ERROR, "RfsdReadInode: beyond the file range.\n"));
464  return STATUS_SUCCESS;
465  }
466 
467  if (Offset + Size > AllocSize) {
468 
469  Size = (ULONG)(AllocSize - Offset);
470  }
471 
472 
473 //-----------------------------
474 
475  //
476  // Build the scatterred block ranges to be read
477  //
478 
480  Vcb, Key, Inode,
481  &(blocks), &(Bdl)
482  );
483 
484  if (!NT_SUCCESS(Status)) {
485  goto errorout;
486  }
487 
488  if (blocks <= 0) {
490  goto errorout;
491  }
492 
493 
494  {
495  ULONGLONG bufferPos = 0;
496 
497  for(i = 0, j = 0; i < blocks; i++) {
498  if ( // The block is needed for the user's requested contents
499  // (The user's requested offset lies within the block, or the block's start is within the user's requested range)
500  ( (Offset >= Bdl[i].Offset) && (Offset < (Bdl[i].Offset + Bdl[i].Length)) ) || // The user's offset is within the block's range
501  ( (Bdl[i].Offset >= Offset) && (Bdl[i].Offset < (Offset + Size)) ) // The block's offset is within the user's range
502  )
503  {
504  ULONGLONG offsetFromDisk = Bdl[i].Lba;
505  ULONGLONG lengthToRead = min(Size - bufferPos, Bdl[i].Length);
506  j++;
507 
508  //KdPrint(("Rfsd: blocks = %u, i = %u, j = %u\n", blocks, i, j));
509  //KdPrint(("Rfsd: Bdl[%u].Lba = %I64u, Bdl[%u].Offset = %I64u, Bdl[%u].Length = %u\n", i, Bdl[i].Lba, i, Bdl[i].Offset, i, Bdl[i].Length));
510  //KdPrint(("Rfsd: offsetFromDisk = %I64u, lengthToRead = %I64u\n", offsetFromDisk, lengthToRead));
511  //KdPrint(("Rfsd: Buffer = %p, bufferPos = %I64u\n", Buffer, bufferPos));
512 
513  IoStatus.Information = 0;
514 
515  RfsdCopyRead(
516  Vcb->StreamObj,
517  (PLARGE_INTEGER) (&offsetFromDisk), // offset (relative to partition)
518  (ULONG) lengthToRead, // length to read
519  PIN_WAIT, //
520  (PVOID)((PUCHAR)Buffer + bufferPos), // buffer to read into
521  &IoStatus );
522 
523  Status = IoStatus.Status;
524  bufferPos += IoStatus.Information;
525  //KdPrint(("Rfsd: IoStatus.Status = %#x, IoStatus.Information = %u\n", IoStatus.Status, IoStatus.Information));
526  }
527  }
528 
529  }
530 
531 errorout:
532 
533  if (Bdl) ExFreePool(Bdl);
534 
535  if (NT_SUCCESS(Status)) {
536 
537  if (dwRet) *dwRet = Size;
538  }
539 
540  return Status;
541 }
542 
544 NTSTATUS
546 {
548 
549  PRFSD_VCB Vcb;
550  PRFSD_FCB Fcb = 0;
551  PRFSD_CCB Ccb;
553  PFILE_OBJECT CacheObject;
554 
556 
557  PIRP Irp;
558  PIO_STACK_LOCATION IoStackLocation;
559 
560  ULONG Length;
563 
564  BOOLEAN PagingIo;
565  BOOLEAN Nocache;
566  BOOLEAN SynchronousIo;
567  BOOLEAN MainResourceAcquired = FALSE;
568  BOOLEAN PagingIoResourceAcquired = FALSE;
569 
570  PUCHAR Buffer;
571 
572  PAGED_CODE();
573 
574  _SEH2_TRY {
575 
576  ASSERT(IrpContext);
577 
578  ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
579  (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
580 
581  DeviceObject = IrpContext->DeviceObject;
582 
584 
585  ASSERT(Vcb != NULL);
586 
587  ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
588  (Vcb->Identifier.Size == sizeof(RFSD_VCB)));
589 
590  FileObject = IrpContext->FileObject;
591 
592  Fcb = (PRFSD_FCB) FileObject->FsContext;
593 
594  ASSERT(Fcb);
595 
596  ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
597  (Fcb->Identifier.Size == sizeof(RFSD_FCB)));
598 
599  Ccb = (PRFSD_CCB) FileObject->FsContext2;
600 
601  Irp = IrpContext->Irp;
602 
603  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
604 
605  Length = IoStackLocation->Parameters.Read.Length;
606  ByteOffset = IoStackLocation->Parameters.Read.ByteOffset;
607 
608 #if defined(_MSC_VER) && !defined(__clang__)
609  KdPrint(("$$$ " __FUNCTION__ " on key: %x,%xh to read %i bytes at the offset %xh in the file\n",
610  Fcb->RfsdMcb->Key.k_dir_id, Fcb->RfsdMcb->Key.k_objectid,
611  Length, ByteOffset.QuadPart));
612 #endif
613 
614  PagingIo = (Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE);
615  Nocache = (Irp->Flags & IRP_NOCACHE ? TRUE : FALSE);
616  SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO ? TRUE : FALSE);
617 
618 /*
619  if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED)) {
620  Status = STATUS_FILE_DELETED;
621  _SEH2_LEAVE;
622  }
623 
624  if (IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING)) {
625  Status = STATUS_DELETE_PENDING;
626  _SEH2_LEAVE;
627  }
628 */
629 
630  if (Length == 0) {
631  Irp->IoStatus.Information = 0;
633  _SEH2_LEAVE;
634  }
635 
636  if (Nocache &&
637  (ByteOffset.LowPart & (SECTOR_SIZE - 1) ||
638  Length & (SECTOR_SIZE - 1))) {
640  DbgBreak();
641  _SEH2_LEAVE;
642  }
643 
644  if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
645  ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
647  DbgBreak();
648  _SEH2_LEAVE;
649  }
650 
651  if (!PagingIo) {
653  &Fcb->MainResource,
654  IrpContext->IsSynchronous )) {
656  _SEH2_LEAVE;
657  }
658 
659  MainResourceAcquired = TRUE;
660 
662  &Fcb->FileLockAnchor,
663  Irp )) {
665  _SEH2_LEAVE;
666  }
667  } else {
670  IrpContext->IsSynchronous )) {
672  _SEH2_LEAVE;
673  }
674 
675  PagingIoResourceAcquired = TRUE;
676  }
677 
678  if (!Nocache) {
679  // Attempt cached access...
680 
681  if ((ByteOffset.QuadPart + (LONGLONG)Length) >
682  Fcb->Header.FileSize.QuadPart ) {
683  if (ByteOffset.QuadPart >= (Fcb->Header.FileSize.QuadPart)) {
684  Irp->IoStatus.Information = 0;
686  _SEH2_LEAVE;
687  }
688 
689  Length =
690  (ULONG)(Fcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
691 
692  }
693 
695 
696  if (IsDirectory(Fcb)) {
697  _SEH2_LEAVE;
698  }
699 
700  {
701  if (FileObject->PrivateCacheMap == NULL) {
703  FileObject,
704  (PCC_FILE_SIZES)(&Fcb->Header.AllocationSize),
705  FALSE,
707  Fcb );
708  }
709 
710  CacheObject = FileObject;
711  }
712 
713  if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
714  CcMdlRead(
715  CacheObject,
716  (&ByteOffset),
717  Length,
718  &Irp->MdlAddress,
719  &Irp->IoStatus );
720 
721  Status = Irp->IoStatus.Status;
722 
723  } else {
725 
726  if (Buffer == NULL) {
728  DbgBreak();
729  _SEH2_LEAVE;
730  }
731 
732  if (!CcCopyRead(
733  CacheObject, // the file object (representing the open operation performed by the thread)
734  (PLARGE_INTEGER)&ByteOffset, // starting offset IN THE FILE, from where the read should be performed
735  Length, // number of bytes requested in the read operation
736  IrpContext->IsSynchronous,
737  Buffer, // < buffer to read the contents to
738  &Irp->IoStatus )) {
740  DbgBreak();
741  _SEH2_LEAVE;
742  }
743 
744  Status = Irp->IoStatus.Status;
745  }
746 
747  } else {
748  // Attempt access without the cache...
749 
750  if ((ByteOffset.QuadPart + (LONGLONG)Length) > Fcb->Header.AllocationSize.QuadPart) {
751 
752  if (ByteOffset.QuadPart >= Fcb->Header.AllocationSize.QuadPart) {
753  Irp->IoStatus.Information = 0;
755  DbgBreak();
756  _SEH2_LEAVE;
757  }
758 
759  Length =
760  (ULONG)(Fcb->Header.AllocationSize.QuadPart- ByteOffset.QuadPart);
761  }
762 
764 
765  /* lock the user buffer into MDL and make them paged-in */
767  IrpContext->Irp,
768  Length,
769  IoWriteAccess );
770 
771  if (NT_SUCCESS(Status)) {
772 
773  /* Zero the total buffer */
774  PVOID SystemVA = RfsdGetUserBuffer(IrpContext->Irp);
775  if (SystemVA) {
776 
777  RtlZeroMemory(SystemVA, Length);
778 
779  RfsdPrint((DBG_INFO, "RfsdReadFile: Zero read buffer: Offset=%I64xh Size=%xh ... \n",
780  ByteOffset.QuadPart, Length));
781  }
782 
783  } else {
784  _SEH2_LEAVE;
785  }
786 
787  Irp->IoStatus.Status = STATUS_SUCCESS;
788  Irp->IoStatus.Information = Length;
789 
790 
792  IrpContext,
793  Vcb,
794  &(Fcb->RfsdMcb->Key),
795  Fcb->Inode,
796  ByteOffset.QuadPart,
797  RfsdGetUserBuffer(IrpContext->Irp), // NOTE: Ext2fsd just passes NULL for the buffer, and relies on the initial cache call to retrieve tha data. We'll instead be explicitly putting it into the user's buffer, via a much different mechanism.
798  Length,
799  &ReturnedLength);
800 
801  Irp = IrpContext->Irp;
802 
803  }
804 
805  } _SEH2_FINALLY {
806 
807  if (PagingIoResourceAcquired) {
811  }
812 
813  if (MainResourceAcquired) {
815  &Fcb->MainResource,
817  }
818 
819  if (!IrpContext->ExceptionInProgress) {
820  if (IrpContext->Irp) {
821  if (Status == STATUS_PENDING) {
822 
824  IrpContext->Irp,
825  Length,
826  IoWriteAccess );
827 
828  if (NT_SUCCESS(Status)) {
829  Status = RfsdQueueRequest(IrpContext);
830  } else {
831  RfsdCompleteIrpContext(IrpContext, Status);
832  }
833  } else {
834  if (NT_SUCCESS(Status)) {
835  if (!PagingIo) {
836  if (SynchronousIo) {
837  IrpContext->FileObject->CurrentByteOffset.QuadPart =
838  ByteOffset.QuadPart + IrpContext->Irp->IoStatus.Information;
839  }
840 
841  IrpContext->FileObject->Flags |= FO_FILE_FAST_IO_READ;
842  }
843  }
844 
845  RfsdCompleteIrpContext(IrpContext, Status);
846  }
847  } else {
848  RfsdFreeIrpContext(IrpContext);
849  }
850  }
851  } _SEH2_END;
852 
853  return Status;
854 }
855 
856 NTSTATUS
858 {
861  PIRP Irp;
862 
863  PAGED_CODE();
864 
865  _SEH2_TRY {
866 
867  ASSERT(IrpContext);
868 
869  ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
870  (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
871 
872  FileObject = IrpContext->FileObject;
873 
874  Irp = IrpContext->Irp;
875 
876  CcMdlReadComplete(FileObject, Irp->MdlAddress);
877 
878  Irp->MdlAddress = NULL;
879 
881 
882  } _SEH2_FINALLY {
883 
884  if (!IrpContext->ExceptionInProgress) {
885  RfsdCompleteIrpContext(IrpContext, Status);
886  }
887  } _SEH2_END;
888 
889  return Status;
890 }
891 
893 NTSTATUS
895 {
897  PRFSD_VCB Vcb;
898  PRFSD_FCBVCB FcbOrVcb;
901  BOOLEAN bCompleteRequest;
902 
903  PAGED_CODE();
904 
905  ASSERT(IrpContext);
906 
907  ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
908  (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
909 
910  _SEH2_TRY {
911 
912  if (FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE)) {
913  // Caller wants to tell the Cache Manager that a previously allocated MDL can be freed.
914  Status = RfsdReadComplete(IrpContext);
915  bCompleteRequest = FALSE;
916 
917  } else {
918 
919  DeviceObject = IrpContext->DeviceObject;
920 
923  bCompleteRequest = TRUE;
924  _SEH2_LEAVE;
925  }
926 
928 
929  if (Vcb->Identifier.Type != RFSDVCB ||
930  Vcb->Identifier.Size != sizeof(RFSD_VCB) ) {
932  bCompleteRequest = TRUE;
933 
934  _SEH2_LEAVE;
935  }
936 
937  if (IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
938 
940  bCompleteRequest = TRUE;
941  _SEH2_LEAVE;
942  }
943 
944  FileObject = IrpContext->FileObject;
945 
946  FcbOrVcb = (PRFSD_FCBVCB) FileObject->FsContext;
947 
948  if (FcbOrVcb->Identifier.Type == RFSDVCB) {
949  Status = RfsdReadVolume(IrpContext);
950  bCompleteRequest = FALSE;
951  } else if (FcbOrVcb->Identifier.Type == RFSDFCB) {
952  Status = RfsdReadFile(IrpContext);
953  bCompleteRequest = FALSE;
954  } else {
955  RfsdPrint((DBG_ERROR, "RfsdRead: INVALID PARAMETER ... \n"));
956  DbgBreak();
957 
959  bCompleteRequest = TRUE;
960  }
961  }
962 
963  } _SEH2_FINALLY {
964  if (bCompleteRequest) {
965  RfsdCompleteIrpContext(IrpContext, Status);
966  }
967  } _SEH2_END;
968 
969  return Status;
970 }
struct _RFSD_CCB * PRFSD_CCB
NTSTATUS RfsdReadInode(IN PRFSD_IRP_CONTEXT IrpContext, IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY Key, IN PRFSD_INODE Inode, IN ULONGLONG Offset, IN OUT PVOID Buffer, IN ULONG Size, OUT PULONG dwRet)
Definition: read.c:420
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: rfsd.h:400
NTSTATUS RfsdReadVolume(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: read.c:94
#define ExGetCurrentResourceThread()
Definition: env_spec_w32.h:633
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
#define IN
Definition: typedefs.h:38
PIRP Irp
Definition: rfsd.h:834
NTSTATUS RfsdCompleteIrpContext(IN PRFSD_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: memory.c:160
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS RfsdReadComplete(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: read.c:857
ULONG Length
Definition: rfsd.h:833
#define __drv_mustHoldCriticalRegion
Definition: ffsdrv.h:34
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
PFILE_OBJECT FileObject
Definition: ntfs.h:516
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
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
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_NOCACHE
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define RFSD_POOL_TAG
Definition: rfsd.h:99
VOID RfsdFreeIrpContext(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: memory.c:192
#define PIN_WAIT
NTSTATUS RfsdQueueRequest(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: dispatch.c:29
ULONGLONG Offset
Definition: rfsd.h:832
Definition: rfsd.h:323
#define PAGED_CODE()
Definition: video.h:57
PDEVICE_OBJECT DeviceObject
Definition: rfsd.h:407
_SEH2_TRY
Definition: create.c:4250
Definition: rfsd.h:324
#define STATUS_END_OF_FILE
Definition: shellext.h:62
ULONGLONG Lba
Definition: rfsd.h:831
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1733
#define IRP_MN_COMPLETE
Definition: iotypes.h:4064
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
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1752
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
__drv_mustHoldCriticalRegion NTSTATUS RfsdRead(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: read.c:894
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
NTSTATUS RfsdBuildBDL2(IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY pKey, IN PRFSD_INODE pInode, OUT PULONG out_Count, OUT PRFSD_BDL *out_ppBdl)
Definition: rfsd.c:675
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
smooth NULL
Definition: ftsmooth.c:416
RFSD_IDENTIFIER_TYPE Type
Definition: rfsd.h:336
Definition: rfsd.h:326
Definition: bufpool.h:45
static int blocks
Definition: mkdosfs.c:527
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
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 GLint GLint j
Definition: glfuncs.h:250
struct _RFSD_VCB * PRFSD_VCB
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
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
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
NTSTATUS RfsdReadFile(IN PRFSD_IRP_CONTEXT IrpContext)
Definition: read.c:545
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1955
PRFSD_GLOBAL RfsdGlobal
Definition: init.c:17
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
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
#define RfsdPrint(arg)
Definition: rfsd.h:1069
ULONG Type
Definition: ntfs.h:95
#define IRP_MN_MDL
Definition: iotypes.h:4063
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:187
_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:593
#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: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
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
_SEH2_END
Definition: create.c:4424
BOOLEAN RfsdCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: read.c:44
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
NTSTATUS RfsdLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: blockio.c:67
_SEH2_FINALLY
Definition: create.c:4395
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#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:306
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
ERESOURCE PagingIoResource
Definition: ntfs.h:523
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define DbgBreak()
Definition: ext2fs.h:46
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
RFSD_IDENTIFIER Identifier
Definition: rfsd.h:470
#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
#define __FUNCTION__
Definition: types.h:112
#define KdPrint(x)
Definition: env_spec_w32.h:288
ULONG Size
Definition: ntfs.h:96
#define STATUS_TOO_LATE
Definition: ntstatus.h:612
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716
IN BOOLEAN Wait
Definition: fatprocs.h:1529