ReactOS 0.4.16-dev-297-gc569aee
fastio.cpp
Go to the documentation of this file.
1
2// 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*************************************************************************/
51 )
52{
53 BOOLEAN ReturnedStatus = FALSE;
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 */
117NTAPI
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"));
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*************************************************************************/
158NTAPI
165 )
166{
167 BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
169 PtrUDFIrpContext PtrIrpContext = NULL;
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;
212try_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*************************************************************************/
249NTAPI
256{
257 BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
259 PtrUDFIrpContext PtrIrpContext = NULL;
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*************************************************************************/
340VOID
341NTAPI
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*************************************************************************/
385VOID
386NTAPI
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*************************************************************************/
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*************************************************************************/
470VOID
471NTAPI
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*************************************************************************/
513NTAPI
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*************************************************************************/
556VOID
557NTAPI
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*************************************************************************/
600NTAPI
601UDFFastIoQueryNetInfo(
607{
608 BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
610 PtrUDFIrpContext PtrIrpContext = NULL;
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;
653try_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(
690IN PFILE_OBJECT FileObject,
691IN PLARGE_INTEGER FileOffset,
692IN ULONG Length,
693IN ULONG LockKey,
694OUT PMDL* MdlChain,
695OUT PIO_STATUS_BLOCK IoStatus,
696IN 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(
750IN PFILE_OBJECT FileObject,
751OUT PMDL MdlChain,
752IN 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
803UDFFastIoPrepareMdlWrite(
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(
864IN PFILE_OBJECT FileObject,
865IN PLARGE_INTEGER FileOffset,
866OUT PMDL MdlChain,
867IN 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*************************************************************************/
919NTAPI
920UDFFastIoAcqModWrite(
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*************************************************************************/
991NTAPI
992UDFFastIoRelModWrite(
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*************************************************************************/
1038NTAPI
1039UDFFastIoAcqCcFlush(
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*************************************************************************/
1084NTAPI
1085UDFFastIoRelCcFlush(
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
1114UDFFastIoDeviceControl (
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
1158BOOLEAN
1159NTAPI
1163 IN ULONG Length,
1164 IN BOOLEAN Wait,
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()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define HandleToUlong(h)
Definition: basetsd.h:79
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define try_return(S)
Definition: cdprocs.h:2179
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
BOOLEAN NTAPI UDFAcqReadAhead(IN PVOID Context, IN BOOLEAN Wait)
Definition: fastio.cpp:514
VOID NTAPI UDFFastIoRelCreateSec(IN PFILE_OBJECT FileObject)
Definition: fastio.cpp:387
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
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible(IN PtrUDFFCB Fcb)
Definition: fastio.cpp:118
VOID NTAPI UDFRelReadAhead(IN PVOID Context)
Definition: fastio.cpp:558
BOOLEAN NTAPI UDFAcqLazyWrite(IN PVOID Context, IN BOOLEAN Wait)
Definition: fastio.cpp:423
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
VOID NTAPI UDFRelLazyWrite(IN PVOID Context)
Definition: fastio.cpp:472
VOID NTAPI UDFFastIoAcqCreateSec(IN PFILE_OBJECT FileObject)
Definition: fastio.cpp:342
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
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
#define NtReqFcb
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2666
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN CheckForReadOperation
Definition: fatprocs.h:2667
NTSTATUS UDFGetBasicInformation(IN PFILE_OBJECT FileObject, IN PtrUDFFCB Fcb, IN PFILE_BASIC_INFORMATION PtrBuffer, IN OUT LONG *PtrReturnedLength)
Definition: fileinfo.cpp:532
NTSTATUS UDFGetNetworkInformation(IN PtrUDFFCB Fcb, IN PFILE_NETWORK_OPEN_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:676
NTSTATUS UDFGetStandardInformation(IN PtrUDFFCB Fcb, IN PFILE_STANDARD_INFORMATION PtrBuffer, IN OUT LONG *PtrReturnedLength)
Definition: fileinfo.cpp:614
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:782
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:748
PsGetCurrentThreadId
Definition: CrNtStubs.h:8
struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define FsRtlAreThereCurrentFileLocks(FL)
Definition: fsrtlfuncs.h:1584
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
@ FastIoIsQuestionable
Definition: fsrtltypes.h:242
@ FastIoIsNotPossible
Definition: fsrtltypes.h:240
@ FastIoIsPossible
Definition: fsrtltypes.h:241
enum _FAST_IO_POSSIBLE FAST_IO_POSSIBLE
#define NOTHING
Definition: input_list.c:10
#define ASSERT(a)
Definition: mode.c:44
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1624
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
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
long LONG
Definition: pedump.c:60
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define STATUS_SUCCESS
Definition: shellext.h:65
#define UDF_FCB_PAGE_FILE
Definition: struct.h:302
struct _UDFNTRequiredFCB * PtrUDFNTRequiredFCB
struct _UDFContextControlBlock * PtrUDFCCB
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
PVCB Vcb
Definition: cdstruc.h:933
struct _FCB::@729::@732 Fcb
FILE_LOCK FileLock
Definition: fatstruc.h:1071
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
#define UDF_MAX_VERIFY_CACHE
Definition: udf_info.h:1255
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:260
#define UDFPrint(Args)
Definition: udffs.h:223
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_In_ PLARGE_INTEGER _Out_ struct _ERESOURCE ** ResourceToRelease
Definition: iotypes.h:1598
* PFILE_OBJECT
Definition: iotypes.h:1998
_In_ PLARGE_INTEGER EndingOffset
Definition: iotypes.h:1597
#define PsGetCurrentProcess
Definition: psfuncs.h:17