ReactOS  0.4.13-dev-563-g0561610
fastio.cpp
Go to the documentation of this file.
1 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 // This file was released under the GPLv2 on June 2015.
6 /*************************************************************************
7 *
8 * File: Fastio.cpp
9 *
10 * Module: UDF File System Driver (Kernel mode execution only)
11 *
12 * Description:
13 * Contains code to handle the various "fast-io" calls.
14 *
15 *************************************************************************/
16 
17 #include "udffs.h"
18 
19 // define the file specific bug-check id
20 #define UDF_BUG_CHECK_ID UDF_FILE_FAST_IO
21 
22 
23 
24 /*************************************************************************
25 *
26 * Function: UDFFastIoCheckIfPossible()
27 *
28 * Description:
29 * To fast-io or not to fast-io, that is the question ...
30 * This routine helps the I/O Manager determine whether the FSD wishes
31 * to permit fast-io on a specific file stream.
32 *
33 * Expected Interrupt Level (for execution) :
34 *
35 * IRQL_PASSIVE_LEVEL
36 *
37 * Return Value: TRUE/FALSE
38 *
39 *************************************************************************/
40 BOOLEAN
41 NTAPI
45  IN ULONG Length,
46  IN BOOLEAN Wait,
51  )
52 {
53  BOOLEAN ReturnedStatus = FALSE;
54  PtrUDFFCB Fcb = NULL;
55  PtrUDFCCB Ccb = NULL;
56  LARGE_INTEGER IoLength;
57 
58  // Obtain a pointer to the FCB and CCB for the file stream.
59  Ccb = (PtrUDFCCB)(FileObject->FsContext2);
60  ASSERT(Ccb);
61  Fcb = Ccb->Fcb;
62  ASSERT(Fcb);
63 
64  // Validate that this is a fast-IO request to a regular file.
65  // The UDF FSD for example, will not allow fast-IO requests
66  // to volume objects, or to directories.
67  if ((Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
68  (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
69  // This is not allowed.
71  MmPrint((" UDFFastIoCheckIfPossible() TRUE, Failed\n"));
72  return FALSE;
73  }
74 /*
75  // back pressure for very smart and fast system cache ;)
76  if(Fcb->Vcb->VerifyCtx.ItemCount >= UDF_MAX_VERIFY_CACHE) {
77  AdPrint((" Verify queue overflow -> UDFFastIoCheckIfPossible() = FALSE\n"));
78  return FALSE;
79  }
80 */
81  IoLength.QuadPart = Length;
82 
83  // The FSD can determine the checks that it needs to perform.
84  // Typically, a FSD will check whether there exist any byte-range
85  // locks that would prevent a fast-IO operation from proceeding.
86 
87  // ... (FSD specific checks go here).
88 
90  // The following routine is exported by the FSRTL
91  // package and it returns TRUE if the read operation should be
92  // allowed to proceed based on the status of the current byte-range
93  // locks on the file stream. If we do not use the FSRTL package
94  // for byte-range locking support, then we must substitute our
95  // own checks over here.
96  ReturnedStatus = FsRtlFastCheckLockForRead(&(Fcb->NTRequiredFCB->FileLock),
97  FileOffset, &IoLength, LockKey, FileObject,
99  } else {
100 // if(Fcb->Vcb->VCBFlags );
101  // This is a write request. Invoke the FSRTL byte-range lock package
102  // to see whether the write should be allowed to proceed.
103  ReturnedStatus = FsRtlFastCheckLockForWrite(&(Fcb->NTRequiredFCB->FileLock),
104  FileOffset, &IoLength, LockKey, FileObject,
106  }
107 
108  MmPrint((" UDFFastIoCheckIfPossible() %s\n", ReturnedStatus ? "TRUE" : "FALSE"));
109  return(ReturnedStatus);
110 // return FALSE;
111 
112 } // end UDFFastIoCheckIfPossible()
113 
114 /*
115  */
117 NTAPI
120  )
121 {
122  if( !(Fcb->Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) /*||
123  !FsRtlOplockIsFastIoPossible(&(Fcb->Oplock))*/ ) {
124  UDFPrint((" FastIoIsNotPossible\n"));
125  return FastIoIsNotPossible;
126  }
127 /*
128  // back pressure for very smart and fast system cache ;)
129  if(Fcb->Vcb->VerifyCtx.ItemCount >= UDF_MAX_VERIFY_CACHE) {
130  AdPrint((" Verify queue overflow -> UDFIsFastIoPossible() = FastIoIsNotPossible\n"));
131  return FastIoIsNotPossible;
132  }
133 */
134  if(FsRtlAreThereCurrentFileLocks(&(Fcb->NTRequiredFCB->FileLock)) ) {
135  UDFPrint((" FastIoIsQuestionable\n"));
136  return FastIoIsQuestionable;
137  }
138  UDFPrint((" FastIoIsPossible\n"));
139  return FastIoIsPossible;
140 } // end UDFIsFastIoPossible()
141 
142 /*************************************************************************
143 *
144 * Function: UDFFastIoQueryBasicInfo()
145 *
146 * Description:
147 * Bypass the traditional IRP method to perform a query basic
148 * information operation.
149 *
150 * Expected Interrupt Level (for execution) :
151 *
152 * IRQL_PASSIVE_LEVEL
153 *
154 * Return Value: TRUE/FALSE
155 *
156 *************************************************************************/
157 BOOLEAN
158 NTAPI
161  IN BOOLEAN Wait,
165  )
166 {
167  BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
169  PtrUDFIrpContext PtrIrpContext = NULL;
171  PtrUDFFCB Fcb;
172  PtrUDFCCB Ccb;
174  BOOLEAN MainResourceAcquired = FALSE;
175 
177 
178  UDFPrint(("UDFFastIo \n"));
179  // if the file is already opended we can satisfy this request
180  // immediately 'cause all the data we need must be cached
181  _SEH2_TRY {
182 
183  _SEH2_TRY {
184 
185  // Get the FCB and CCB pointers.
186  Ccb = (PtrUDFCCB)(FileObject->FsContext2);
187  ASSERT(Ccb);
188  Fcb = Ccb->Fcb;
189  ASSERT(Fcb);
190  NtReqFcb = Fcb->NTRequiredFCB;
191  //Fcb->Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
192 
193  if (!(Fcb->FCBFlags & UDF_FCB_PAGE_FILE)) {
194  // Acquire the MainResource shared.
196  if (!UDFAcquireResourceShared(&(NtReqFcb->MainResource), Wait)) {
198  }
199  MainResourceAcquired = TRUE;
200  }
201 
202  ReturnedStatus =
204 
206 
207  RC = UDFExceptionHandler(PtrIrpContext, NULL);
208 
210 
211  } _SEH2_END;
212 try_exit: NOTHING;
213  } _SEH2_FINALLY {
214  if (MainResourceAcquired) {
216  UDFReleaseResource(&(NtReqFcb->MainResource));
217  MainResourceAcquired = FALSE;
218  }
219  IoStatus->Status = RC;
220  if(ReturnedStatus) {
221  IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
222  } else {
223  IoStatus->Information = 0;
224  }
225  } _SEH2_END;
226 
228 
229  return(ReturnedStatus);
230 } // end UDFFastIoQueryBasicInfo()
231 
232 
233 /*************************************************************************
234 *
235 * Function: UDFFastIoQueryStdInfo()
236 *
237 * Description:
238 * Bypass the traditional IRP method to perform a query standard
239 * information operation.
240 *
241 * Expected Interrupt Level (for execution) :
242 *
243 * IRQL_PASSIVE_LEVEL
244 *
245 * Return Value: TRUE/FALSE
246 *
247 *************************************************************************/
248 BOOLEAN
249 NTAPI
252  IN BOOLEAN Wait,
256 {
257  BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
259  PtrUDFIrpContext PtrIrpContext = NULL;
261  PtrUDFFCB Fcb;
262  PtrUDFCCB Ccb;
263 // PtrUDFNTRequiredFCB NtReqFcb = NULL;
264 // BOOLEAN MainResourceAcquired = FALSE;
265 
267 
268  UDFPrint(("UDFFastIo \n"));
269  // if the file is already opended we can satisfy this request
270  // immediately 'cause all the data we need must be cached
271  _SEH2_TRY {
272 
273  _SEH2_TRY {
274 
275  // Get the FCB and CCB pointers.
276  Ccb = (PtrUDFCCB)(FileObject->FsContext2);
277  ASSERT(Ccb);
278  Fcb = Ccb->Fcb;
279  ASSERT(Fcb);
280 // NtReqFcb = Fcb->NTRequiredFCB;
281  //Fcb->Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
282 
283 /*
284  if (!(Fcb->FCBFlags & UDF_FCB_PAGE_FILE)) {
285  // Acquire the MainResource shared.
286  UDF_CHECK_PAGING_IO_RESOURCE(NtReqFcb);
287  if (!UDFAcquireResourceShared(&(NtReqFcb->MainResource), Wait)) {
288  try_return(RC = STATUS_CANT_WAIT);
289  }
290  MainResourceAcquired = TRUE;
291  }
292 */
293  ReturnedStatus =
295 
297 
298  RC = UDFExceptionHandler(PtrIrpContext, NULL);
299 
301 
302  } _SEH2_END;
303 //try_exit: NOTHING;
304  } _SEH2_FINALLY {
305 /*
306  if (MainResourceAcquired) {
307  UDFReleaseResource(&(NtReqFcb->MainResource));
308  MainResourceAcquired = FALSE;
309  }
310 */
311  IoStatus->Status = RC;
312  if(ReturnedStatus) {
313  IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);
314  } else {
315  IoStatus->Information = 0;
316  }
317  } _SEH2_END;
318 
320 
321  return(ReturnedStatus);
322 } // end UDFFastIoQueryStdInfo()
323 
324 
325 /*************************************************************************
326 *
327 * Function: UDFFastIoAcqCreateSec()
328 *
329 * Description:
330 * Not really a fast-io operation. Used by the VMM to acquire FSD resources
331 * before processing a file map (create section object) request.
332 *
333 * Expected Interrupt Level (for execution) :
334 *
335 * IRQL_PASSIVE_LEVEL
336 *
337 * Return Value: None (we must be prepared to handle VMM initiated calls)
338 *
339 *************************************************************************/
340 VOID
341 NTAPI
344  )
345 {
347 
348  MmPrint((" AcqForCreateSection()\n"));
349  // Acquire the MainResource exclusively for the file stream
350  if(!ExIsResourceAcquiredExclusiveLite(&(NtReqFcb->MainResource)) ||
351  !ExIsResourceAcquiredExclusiveLite(&(NtReqFcb->PagingIoResource)) ) {
353  } else {
354  MmPrint((" already acquired\n"));
355  }
356  UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), TRUE);
357 
358  // Although this is typically not required, the UDF FSD will
359  // also acquire the PagingIoResource exclusively at this time
360  // to conform with the resource acquisition described in the set
361  // file information routine. Once again though, we will probably
362  // not need to do this.
363  UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), TRUE);
364  NtReqFcb->AcqSectionCount++;
365 
366  return;
367 } // end UDFFastIoAcqCreateSec()
368 
369 
370 /*************************************************************************
371 *
372 * Function: UDFFastIoRelCreateSec()
373 *
374 * Description:
375 * Not really a fast-io operation. Used by the VMM to release FSD resources
376 * after processing a file map (create section object) request.
377 *
378 * Expected Interrupt Level (for execution) :
379 *
380 * IRQL_PASSIVE_LEVEL
381 *
382 * Return Value: None
383 *
384 *************************************************************************/
385 VOID
386 NTAPI
389 {
391 
392  MmPrint((" RelFromCreateSection()\n"));
393 
394  NtReqFcb->AcqSectionCount--;
395  // Release the PagingIoResource for the file stream
396  UDFReleaseResource(&(NtReqFcb->PagingIoResource));
397 
398  // Release the MainResource for the file stream
399  UDFReleaseResource(&(NtReqFcb->MainResource));
400 
401  return;
402 } // end UDFFastIoRelCreateSec()
403 
404 
405 /*************************************************************************
406 *
407 * Function: UDFAcqLazyWrite()
408 *
409 * Description:
410 * Not really a fast-io operation. Used by the NT Cache Mgr to acquire FSD
411 * resources before performing a delayed write (write behind/lazy write)
412 * operation.
413 * NOTE: this function really must succeed since the Cache Manager will
414 * typically ignore failure and continue on ...
415 *
416 * Expected Interrupt Level (for execution) :
417 *
418 * IRQL_PASSIVE_LEVEL
419 *
420 * Return Value: TRUE/FALSE (Cache Manager does not tolerate FALSE well)
421 *
422 *************************************************************************/
424  IN PVOID Context,
425  IN BOOLEAN Wait)
426 {
427  // The context is whatever we passed to the Cache Manager when invoking
428  // the CcInitializeCacheMaps() function. In the case of the UDF FSD
429  // implementation, this context is a pointer to the NT_REQ_FCB structure.
431 
432  MmPrint((" UDFAcqLazyWrite()\n"));
433 
434  // Acquire the PagingIoResource in the NT_REQ_FCB exclusively. Then, set the
435  // lazy-writer thread id in the NT_REQ_FCB structure for identification
436  // when an actual write request is received by the FSD.
437  // Note: The lazy-writer typically always supplies WAIT set to TRUE.
438  if (!UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), Wait))
439  return FALSE;
440 
441  // Now, set the lazy-writer thread id.
442  ASSERT(!(NtReqFcb->LazyWriterThreadID));
443  NtReqFcb->LazyWriterThreadID = HandleToUlong(PsGetCurrentThreadId());
444 
447 
448  // If our FSD needs to perform some special preparations in anticipation
449  // of receving a lazy-writer request, do so now.
450  return TRUE;
451 } // end UDFAcqLazyWrite()
452 
453 
454 /*************************************************************************
455 *
456 * Function: UDFRelLazyWrite()
457 *
458 * Description:
459 * Not really a fast-io operation. Used by the NT Cache Mgr to release FSD
460 * resources after performing a delayed write (write behind/lazy write)
461 * operation.
462 *
463 * Expected Interrupt Level (for execution) :
464 *
465 * IRQL_PASSIVE_LEVEL
466 *
467 * Return Value: None
468 *
469 *************************************************************************/
470 VOID
471 NTAPI
473  IN PVOID Context)
474 {
475  // The context is whatever we passed to the Cache Manager when invoking
476  // the CcInitializeCacheMaps() function. In the case of the UDF FSD
477  // implementation, this context is a pointer to the NT_REQ_FCB structure.
479 
480  MmPrint((" UDFRelLazyWrite()\n"));
481 
482  // Remove the current thread-id from the NT_REQ_FCB
483  // and release the MainResource.
484  ASSERT((NtReqFcb->LazyWriterThreadID) == HandleToUlong(PsGetCurrentThreadId()));
485  NtReqFcb->LazyWriterThreadID = 0;
486 
487  // Release the acquired resource.
488  UDFReleaseResource(&(NtReqFcb->PagingIoResource));
489 
491  return;
492 } // end UDFRelLazyWrite()
493 
494 
495 /*************************************************************************
496 *
497 * Function: UDFAcqReadAhead()
498 *
499 * Description:
500 * Not really a fast-io operation. Used by the NT Cache Mgr to acquire FSD
501 * resources before performing a read-ahead operation.
502 * NOTE: this function really must succeed since the Cache Manager will
503 * typically ignore failure and continue on ...
504 *
505 * Expected Interrupt Level (for execution) :
506 *
507 * IRQL_PASSIVE_LEVEL
508 *
509 * Return Value: TRUE/FALSE (Cache Manager does not tolerate FALSE well)
510 *
511 *************************************************************************/
512 BOOLEAN
513 NTAPI
515  IN PVOID Context,
516  IN BOOLEAN Wait
517  )
518 {
519  // The context is whatever we passed to the Cache Manager when invoking
520  // the CcInitializeCacheMaps() function. In the case of the UDF FSD
521  // implementation, this context is a pointer to the NT_REQ_FCB structure.
522 #define NtReqFcb ((PtrUDFNTRequiredFCB)Context)
523 
524  MmPrint((" AcqForReadAhead()\n"));
525 
526  // Acquire the MainResource in the NT_REQ_FCB shared.
527  // Note: The read-ahead thread typically always supplies WAIT set to TRUE.
529  if (!UDFAcquireResourceShared(&(NtReqFcb->MainResource), Wait))
530  return FALSE;
531 
534 
535  return TRUE;
536 #undef NtReqFcb
537 
538 } // end UDFAcqReadAhead()
539 
540 
541 /*************************************************************************
542 *
543 * Function: UDFRelReadAhead()
544 *
545 * Description:
546 * Not really a fast-io operation. Used by the NT Cache Mgr to release FSD
547 * resources after performing a read-ahead operation.
548 *
549 * Expected Interrupt Level (for execution) :
550 *
551 * IRQL_PASSIVE_LEVEL
552 *
553 * Return Value: None
554 *
555 *************************************************************************/
556 VOID
557 NTAPI
559  IN PVOID Context)
560 {
561  // The context is whatever we passed to the Cache Manager when invoking
562  // the CcInitializeCacheMaps() function. In the case of the UDF FSD
563  // implementation, this context is a pointer to the NT_REQ_FCB structure.
564 #define NtReqFcb ((PtrUDFNTRequiredFCB)Context)
565 
566  MmPrint((" RelFromReadAhead()\n"));
567 
568  // Release the acquired resource.
570  UDFReleaseResource(&(NtReqFcb->MainResource));
571 
572  // Of course, the FSD should undo whatever else seems appropriate at this
573  // time.
575 
576  return;
577 #undef NtReqFcb
578 } // end UDFRelReadAhead()
579 
580 /* the remaining are only valid under NT Version 4.0 and later */
581 #if(_WIN32_WINNT >= 0x0400)
582 
583 
584 /*************************************************************************
585 *
586 * Function: UDFFastIoQueryNetInfo()
587 *
588 * Description:
589 * Get information requested by a redirector across the network. This call
590 * will originate from the LAN Manager server.
591 *
592 * Expected Interrupt Level (for execution) :
593 *
594 * IRQL_PASSIVE_LEVEL
595 *
596 * Return Value: TRUE/FALSE
597 *
598 *************************************************************************/
599 BOOLEAN
600 NTAPI
601 UDFFastIoQueryNetInfo(
603  IN BOOLEAN Wait,
607 {
608  BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
610  PtrUDFIrpContext PtrIrpContext = NULL;
612  PtrUDFFCB Fcb;
613  PtrUDFCCB Ccb;
615  BOOLEAN MainResourceAcquired = FALSE;
616 
618 
619  UDFPrint(("UDFFastIo \n"));
620  // if the file is already opended we can satisfy this request
621  // immediately 'cause all the data we need must be cached
622  _SEH2_TRY {
623 
624  _SEH2_TRY {
625 
626  // Get the FCB and CCB pointers.
627  Ccb = (PtrUDFCCB)(FileObject->FsContext2);
628  ASSERT(Ccb);
629  Fcb = Ccb->Fcb;
630  ASSERT(Fcb);
631  NtReqFcb = Fcb->NTRequiredFCB;
632  //Fcb->Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
633 
634  if (!(Fcb->FCBFlags & UDF_FCB_PAGE_FILE)) {
635  // Acquire the MainResource shared.
637  if (!UDFAcquireResourceShared(&(NtReqFcb->MainResource), Wait)) {
639  }
640  MainResourceAcquired = TRUE;
641  }
642 
643  ReturnedStatus =
645 
647 
648  RC = UDFExceptionHandler(PtrIrpContext, NULL);
649 
651 
652  } _SEH2_END;
653 try_exit: NOTHING;
654  } _SEH2_FINALLY {
655  if (MainResourceAcquired) {
657  UDFReleaseResource(&(NtReqFcb->MainResource));
658  MainResourceAcquired = FALSE;
659  }
660  IoStatus->Status = RC;
661  if(ReturnedStatus) {
662  IoStatus->Information = sizeof(FILE_NETWORK_OPEN_INFORMATION);
663  } else {
664  IoStatus->Information = 0;
665  }
666  } _SEH2_END;
667 
669 
670  return(ReturnedStatus);
671 
672 } // end UDFFastIoQueryNetInfo()
673 
674 
675 /*************************************************************************
676 *
677 * Function: UDFFastIoMdlRead()
678 *
679 * Description:
680 * Bypass the traditional IRP method to perform a MDL read operation.
681 *
682 * Expected Interrupt Level (for execution) :
683 *
684 * IRQL_PASSIVE_LEVEL
685 *
686 * Return Value: TRUE/FALSE
687 *
688 *************************************************************************/
689 /*BOOLEAN UDFFastIoMdlRead(
690 IN PFILE_OBJECT FileObject,
691 IN PLARGE_INTEGER FileOffset,
692 IN ULONG Length,
693 IN ULONG LockKey,
694 OUT PMDL* MdlChain,
695 OUT PIO_STATUS_BLOCK IoStatus,
696 IN PDEVICE_OBJECT DeviceObject)
697 {
698  BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
699  NTSTATUS RC = STATUS_SUCCESS;
700  PtrUDFIrpContext PtrIrpContext = NULL;
701 
702  FsRtlEnterFileSystem();
703 
704  _SEH2_TRY {
705 
706  _SEH2_TRY {
707 
708  // See description in UDFFastIoRead() before filling-in the
709  // stub here.
710  NOTHING;
711 
712 
713  } __except (UDFExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
714 
715  RC = UDFExceptionHandler(PtrIrpContext, NULL);
716 
717  UDFLogEvent(UDF_ERROR_INTERNAL_ERROR, RC);
718 
719  }
720 
721  //try_exit: NOTHING;
722 
723  } _SEH2_FINALLY {
724 
725  }
726 
727  FsRtlExitFileSystem();
728 
729  return(ReturnedStatus);
730 }*/
731 
732 
733 /*************************************************************************
734 *
735 * Function: UDFFastIoMdlReadComplete()
736 *
737 * Description:
738 * Bypass the traditional IRP method to inform the NT Cache Manager and the
739 * FSD that the caller no longer requires the data locked in the system cache
740 * or the MDL to stay around anymore ..
741 *
742 * Expected Interrupt Level (for execution) :
743 *
744 * IRQL_PASSIVE_LEVEL
745 *
746 * Return Value: TRUE/FALSE
747 *
748 *************************************************************************/
749 /*BOOLEAN UDFFastIoMdlReadComplete(
750 IN PFILE_OBJECT FileObject,
751 OUT PMDL MdlChain,
752 IN PDEVICE_OBJECT DeviceObject)
753 {
754  BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
755  NTSTATUS RC = STATUS_SUCCESS;
756  PtrUDFIrpContext PtrIrpContext = NULL;
757 
758  FsRtlEnterFileSystem();
759 
760  _SEH2_TRY {
761 
762  _SEH2_TRY {
763 
764  // See description in UDFFastIoRead() before filling-in the
765  // stub here.
766  NOTHING;
767 
768  } __except (UDFExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
769 
770  RC = UDFExceptionHandler(PtrIrpContext, NULL);
771 
772  UDFLogEvent(UDF_ERROR_INTERNAL_ERROR, RC);
773 
774  }
775 
776  //try_exit: NOTHING;
777 
778  } _SEH2_FINALLY {
779 
780  }
781 
782  FsRtlExitFileSystem();
783 
784  return(ReturnedStatus);
785 }*/
786 
787 
788 /*************************************************************************
789 *
790 * Function: UDFFastIoPrepareMdlWrite()
791 *
792 * Description:
793 * Bypass the traditional IRP method to prepare for a MDL write operation.
794 *
795 * Expected Interrupt Level (for execution) :
796 *
797 * IRQL_PASSIVE_LEVEL
798 *
799 * Return Value: TRUE/FALSE
800 *
801 *************************************************************************/
802 /*BOOLEAN
803 UDFFastIoPrepareMdlWrite(
804  IN PFILE_OBJECT FileObject,
805  IN PLARGE_INTEGER FileOffset,
806  IN ULONG Length,
807  IN ULONG LockKey,
808  OUT PMDL *MdlChain,
809  OUT PIO_STATUS_BLOCK IoStatus,
810  IN PDEVICE_OBJECT DeviceObject
811  )
812 {
813  BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
814  NTSTATUS RC = STATUS_SUCCESS;
815  PtrUDFIrpContext PtrIrpContext = NULL;
816 
817  FsRtlEnterFileSystem();
818 
819  _SEH2_TRY {
820 
821  _SEH2_TRY {
822 
823  // See description in UDFFastIoRead() before filling-in the
824  // stub here.
825  NOTHING;
826 
827  } __except (UDFExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
828 
829  RC = UDFExceptionHandler(PtrIrpContext, NULL);
830 
831  UDFLogEvent(UDF_ERROR_INTERNAL_ERROR, RC);
832 
833  }
834 
835  //try_exit: NOTHING;
836 
837  } _SEH2_FINALLY {
838 
839  }
840 
841  FsRtlExitFileSystem();
842 
843  return(ReturnedStatus);
844 }*/
845 
846 
847 /*************************************************************************
848 *
849 * Function: UDFFastIoMdlWriteComplete()
850 *
851 * Description:
852 * Bypass the traditional IRP method to inform the NT Cache Manager and the
853 * FSD that the caller has updated the contents of the MDL. This data can
854 * now be asynchronously written out to secondary storage by the Cache Mgr.
855 *
856 * Expected Interrupt Level (for execution) :
857 *
858 * IRQL_PASSIVE_LEVEL
859 *
860 * Return Value: TRUE/FALSE
861 *
862 *************************************************************************/
863 /*BOOLEAN UDFFastIoMdlWriteComplete(
864 IN PFILE_OBJECT FileObject,
865 IN PLARGE_INTEGER FileOffset,
866 OUT PMDL MdlChain,
867 IN PDEVICE_OBJECT DeviceObject)
868 {
869  BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
870  NTSTATUS RC = STATUS_SUCCESS;
871  PtrUDFIrpContext PtrIrpContext = NULL;
872 
873  FsRtlEnterFileSystem();
874 
875  _SEH2_TRY {
876 
877  _SEH2_TRY {
878 
879  // See description in UDFFastIoRead() before filling-in the
880  // stub here.
881  NOTHING;
882 
883  } __except (UDFExceptionFilter(PtrIrpContext, GetExceptionInformation())) {
884 
885  RC = UDFExceptionHandler(PtrIrpContext, NULL);
886 
887  UDFLogEvent(UDF_ERROR_INTERNAL_ERROR, RC);
888 
889  }
890 
891  //try_exit: NOTHING;
892 
893  } _SEH2_FINALLY {
894 
895  }
896 
897  FsRtlExitFileSystem();
898 
899  return(ReturnedStatus);
900 }*/
901 
902 
903 /*************************************************************************
904 *
905 * Function: UDFFastIoAcqModWrite()
906 *
907 * Description:
908 * Not really a fast-io operation. Used by the VMM to acquire FSD resources
909 * before initiating a write operation via the Modified Page/Block Writer.
910 *
911 * Expected Interrupt Level (for execution) :
912 *
913 * IRQL_PASSIVE_LEVEL
914 *
915 * Return Value: STATUS_SUCCESS/Error (__try not to return an error, will 'ya ? :-)
916 *
917 *************************************************************************/
918 NTSTATUS
919 NTAPI
920 UDFFastIoAcqModWrite(
925 {
927 
929 
930  MmPrint((" AcqModW %I64x\n", EndingOffset->QuadPart));
931 
932 #define NtReqFcb ((PtrUDFNTRequiredFCB)(FileObject->FsContext))
933 
934  // We must determine which resource(s) we would like to
935  // acquire at this time. We know that a write is imminent;
936  // we will probably therefore acquire appropriate resources
937  // exclusively.
938 
939  // We must first get the FCB and CCB pointers from the file object
940  // that is passed in to this function (as an argument). Note that
941  // the ending offset (when examined in conjunction with current valid data
942  // length) may help us in determining the appropriate resource(s) to acquire.
943 
944  // For example, if the ending offset is beyond current valid data length,
945  // We may decide to acquire *both* the MainResource and the PagingIoResource
946  // exclusively; otherwise, we may decide simply to acquire the PagingIoResource.
947 
948  // Consult the text for more information on synchronization in FSDs.
949 
950  // One final note; the VMM expects that we will return a pointer to
951  // the resource that we acquired (single return value). This pointer
952  // will be returned back to we in the release call (below).
953 
954  if(UDFAcquireResourceShared(&(NtReqFcb->PagingIoResource), FALSE)) {
955  if(EndingOffset->QuadPart <= NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart) {
956  UDFReleaseResource(&(NtReqFcb->PagingIoResource));
957  RC = STATUS_CANT_WAIT;
958  } else {
959  NtReqFcb->AcqFlushCount++;
960  (*ResourceToRelease) = &(NtReqFcb->PagingIoResource);
961  MmPrint((" AcqModW OK\n"));
962  }
963  } else {
964  RC = STATUS_CANT_WAIT;
965  }
966 
967 #undef NtReqFcb
968 
970 
971  return RC;
972 } // end UDFFastIoAcqModWrite()
973 
974 
975 /*************************************************************************
976 *
977 * Function: UDFFastIoRelModWrite()
978 *
979 * Description:
980 * Not really a fast-io operation. Used by the VMM to release FSD resources
981 * after processing a modified page/block write operation.
982 *
983 * Expected Interrupt Level (for execution) :
984 *
985 * IRQL_PASSIVE_LEVEL
986 *
987 * Return Value: STATUS_SUCCESS/Error (an error returned here is really not expected!)
988 *
989 *************************************************************************/
990 NTSTATUS
991 NTAPI
992 UDFFastIoRelModWrite(
996 {
998 
999  MmPrint((" RelModW\n"));
1000 
1001 #define NtReqFcb ((PtrUDFNTRequiredFCB)(FileObject->FsContext))
1002 
1003  // The MPW has complete the write for modified pages and therefore
1004  // wants us to release pre-acquired resource(s).
1005 
1006  // We must undo here whatever it is that we did in the
1007  // UDFFastIoAcqModWrite() call above.
1008 
1009  NtReqFcb->AcqFlushCount--;
1010  ASSERT(ResourceToRelease == &(NtReqFcb->PagingIoResource));
1012 
1013 #undef NtReqFcb
1014 
1016 
1017  return(STATUS_SUCCESS);
1018 } // end UDFFastIoRelModWrite()
1019 
1020 
1021 /*************************************************************************
1022 *
1023 * Function: UDFFastIoAcqCcFlush()
1024 *
1025 * Description:
1026 * Not really a fast-io operation. Used by the NT Cache Mgr to acquire FSD
1027 * resources before performing a CcFlush() operation on a specific file
1028 * stream.
1029 *
1030 * Expected Interrupt Level (for execution) :
1031 *
1032 * IRQL_PASSIVE_LEVEL
1033 *
1034 * Return Value: STATUS_SUCCESS/Error
1035 *
1036 *************************************************************************/
1037 NTSTATUS
1038 NTAPI
1039 UDFFastIoAcqCcFlush(
1042 {
1043 // NTSTATUS RC = STATUS_SUCCESS;
1044 
1046 
1047  MmPrint((" AcqCcFlush\n"));
1048 
1049  // Acquire appropriate resources that will allow correct synchronization
1050  // with a flush call (and avoid deadlock).
1051 
1052 #define NtReqFcb ((PtrUDFNTRequiredFCB)(FileObject->FsContext))
1053 
1054 // UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), TRUE);
1055  UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), TRUE);
1056 // ASSERT(!(NtReqFcb->AcqFlushCount));
1057  NtReqFcb->AcqFlushCount++;
1058 
1059 #undef NtReqFcb
1060 
1062 
1063  return(STATUS_SUCCESS);
1064 
1065 } // end UDFFastIoAcqCcFlush()
1066 
1067 /*************************************************************************
1068 *
1069 * Function: UDFFastIoRelCcFlush()
1070 *
1071 * Description:
1072 * Not really a fast-io operation. Used by the NT Cache Mgr to acquire FSD
1073 * resources before performing a CcFlush() operation on a specific file
1074 * stream.
1075 *
1076 * Expected Interrupt Level (for execution) :
1077 *
1078 * IRQL_PASSIVE_LEVEL
1079 *
1080 * Return Value: STATUS_SUCCESS/Error
1081 *
1082 *************************************************************************/
1083 NTSTATUS
1084 NTAPI
1085 UDFFastIoRelCcFlush(
1088  )
1089 {
1090 // NTSTATUS RC = STATUS_SUCCESS;
1091 
1093 
1094  MmPrint((" RelCcFlush\n"));
1095 
1096 #define NtReqFcb ((PtrUDFNTRequiredFCB)(FileObject->FsContext))
1097 
1098  // Release resources acquired in UDFFastIoAcqCcFlush() above.
1099 
1100  NtReqFcb->AcqFlushCount--;
1101  UDFReleaseResource(&(NtReqFcb->PagingIoResource));
1102 // UDFReleaseResource(&(NtReqFcb->MainResource));
1103 
1104 #undef NtReqFcb
1105 
1107 
1108  return(STATUS_SUCCESS);
1109 
1110 } // end UDFFastIoRelCcFlush()
1111 
1112 
1113 /*BOOLEAN
1114 UDFFastIoDeviceControl (
1115  IN PFILE_OBJECT FileObject,
1116  IN BOOLEAN Wait,
1117  IN PVOID InputBuffer OPTIONAL,
1118  IN ULONG InputBufferLength,
1119  OUT PVOID OutputBuffer OPTIONAL,
1120  IN ULONG OutputBufferLength,
1121  IN ULONG IoControlCode,
1122  OUT PIO_STATUS_BLOCK IoStatus,
1123  IN PDEVICE_OBJECT DeviceObject
1124  )
1125 {
1126  switch(IoControlCode) {
1127  case FSCTL_ALLOW_EXTENDED_DASD_IO: {
1128  IoStatus->Information = 0;
1129  IoStatus->Status = STATUS_SUCCESS;
1130  break;
1131  }
1132  case FSCTL_IS_VOLUME_MOUNTED: {
1133  PtrUDFFCB Fcb;
1134  PtrUDFCCB Ccb;
1135 
1136  Ccb = (PtrUDFCCB)(FileObject->FsContext2);
1137  Fcb = Ccb->Fcb;
1138 
1139  if(Fcb &&
1140  !(Fcb->Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
1141  !(Fcb->Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED) ) {
1142  return FALSE;
1143  }
1144 
1145  IoStatus->Information = 0;
1146  IoStatus->Status = STATUS_SUCCESS;
1147 
1148  break;
1149  }
1150  default:
1151  return FALSE;
1152  }
1153  return TRUE;
1154 }*/
1155 
1156 #endif //_WIN32_WINNT >= 0x0400
1157 
1158 BOOLEAN
1159 NTAPI
1163  IN ULONG Length,
1164  IN BOOLEAN Wait,
1165  IN ULONG LockKey,
1166  IN PVOID Buffer,
1169  )
1170 {
1171  PtrUDFFCB Fcb = NULL;
1172  PtrUDFCCB Ccb = NULL;
1173 
1174  // Obtain a pointer to the FCB and CCB for the file stream.
1175  Ccb = (PtrUDFCCB)(FileObject->FsContext2);
1176  ASSERT(Ccb);
1177  Fcb = Ccb->Fcb;
1178  ASSERT(Fcb);
1179 
1180  // back pressure for very smart and fast system cache ;)
1181  if(Fcb->Vcb->VerifyCtx.QueuedCount ||
1182  Fcb->Vcb->VerifyCtx.ItemCount >= UDF_MAX_VERIFY_CACHE) {
1183  AdPrint((" Verify queue overflow -> UDFFastIoCopyWrite() = FALSE\n"));
1184  return FALSE;
1185  }
1186  if(Fcb->NTRequiredFCB->SectionObject.DataSectionObject &&
1187  Length >= 0x10000 &&
1188  FileOffset->LowPart &&
1189  !(FileOffset->LowPart & 0x00ffffff)) {
1190 
1191  MmPrint((" no FastIo 16Mb\n"));
1192  return FALSE;
1193  }
1195 
1196 } // end UDFFastIoCopyWrite()
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
_In_ PLARGE_INTEGER EndingOffset
Definition: iotypes.h:1553
VOID NTAPI UDFRelReadAhead(IN PVOID Context)
Definition: fastio.cpp:558
FILE_LOCK FileLock
Definition: fatstruc.h:1067
#define IN
Definition: typedefs.h:38
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
struct _UDFContextControlBlock * PtrUDFCCB
BOOLEAN NTAPI FsRtlFastCheckLockForRead(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:752
#define FsRtlEnterFileSystem
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
VOID NTAPI UDFFastIoAcqCreateSec(IN PFILE_OBJECT FileObject)
Definition: fastio.cpp:342
#define FsRtlExitFileSystem
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
enum _FAST_IO_POSSIBLE FAST_IO_POSSIBLE
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PLARGE_INTEGER _Out_ struct _ERESOURCE ** ResourceToRelease
Definition: iotypes.h:1554
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
LONG NTSTATUS
Definition: precomp.h:26
#define HandleToUlong(h)
Definition: basetsd.h:79
NTSTATUS UDFGetBasicInformation(IN PFILE_OBJECT FileObject, IN PtrUDFFCB Fcb, IN PFILE_BASIC_INFORMATION PtrBuffer, IN OUT LONG *PtrReturnedLength)
Definition: fileinfo.cpp:532
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN CheckForReadOperation
Definition: fatprocs.h:2650
struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION
VOID NTAPI UDFFastIoRelCreateSec(IN PFILE_OBJECT FileObject)
Definition: fastio.cpp:387
_SEH2_TRY
Definition: create.c:4250
BOOLEAN NTAPI UDFAcqReadAhead(IN PVOID Context, IN BOOLEAN Wait)
Definition: fastio.cpp:514
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
BOOLEAN NTAPI UDFFastIoQueryBasicInfo(IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, OUT PFILE_BASIC_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.cpp:159
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
PsGetCurrentThreadId
Definition: CrNtStubs.h:7
Definition: bufpool.h:45
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define FsRtlAreThereCurrentFileLocks(FL)
Definition: fsrtlfuncs.h:1584
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
#define UDF_MAX_VERIFY_CACHE
Definition: udf_info.h:1255
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2650
BOOLEAN NTAPI UDFFastIoCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.cpp:1160
#define try_return(S)
Definition: cdprocs.h:2189
NTSTATUS UDFGetStandardInformation(IN PtrUDFFCB Fcb, IN PFILE_STANDARD_INFORMATION PtrBuffer, IN OUT LONG *PtrReturnedLength)
Definition: fileinfo.cpp:614
VOID NTAPI UDFRelLazyWrite(IN PVOID Context)
Definition: fastio.cpp:472
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1954
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define NtReqFcb
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
BOOLEAN NTAPI UDFFastIoCheckIfPossible(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN BOOLEAN CheckForReadOperation, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.cpp:42
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
BOOLEAN NTAPI UDFAcqLazyWrite(IN PVOID Context, IN BOOLEAN Wait)
Definition: fastio.cpp:423
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define NOTHING
Definition: env_spec_w32.h:461
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
#define UDF_FCB_PAGE_FILE
Definition: struct.h:302
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible(IN PtrUDFFCB Fcb)
Definition: fastio.cpp:118
struct _FCB::@691::@694 Fcb
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
_SEH2_END
Definition: create.c:4424
NTSTATUS UDFGetNetworkInformation(IN PtrUDFFCB Fcb, IN PFILE_NETWORK_OPEN_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:676
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:262
_SEH2_FINALLY
Definition: create.c:4395
BOOLEAN NTAPI FsRtlCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:264
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
PVCB Vcb
Definition: cdstruc.h:939
BOOLEAN NTAPI UDFFastIoQueryStdInfo(IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, OUT PFILE_STANDARD_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.cpp:250
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
_In_ PFCB Fcb
Definition: cdprocs.h:151
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
return STATUS_SUCCESS
Definition: btrfs.c:2777
BOOLEAN NTAPI FsRtlFastCheckLockForWrite(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:786
struct _UDFNTRequiredFCB * PtrUDFNTRequiredFCB
LONGLONG QuadPart
Definition: typedefs.h:112
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438
IN BOOLEAN Wait
Definition: fatprocs.h:1529
#define FILE_BASIC_INFORMATION
Definition: disk.h:53