ReactOS 0.4.15-dev-7953-g1f49173
read.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: Read.cpp
9*
10* Module: UDF File System Driver (Kernel mode execution only)
11*
12* Description:
13* Contains code to handle the "Read" dispatch entry point.
14*
15*************************************************************************/
16
17#include "udffs.h"
18
19// define the file specific bug-check id
20#define UDF_BUG_CHECK_ID UDF_FILE_READ
21
22#ifdef _M_IX86
23#if DBG
24#define OVERFLOW_READ_THRESHHOLD (0xE00)
25#else
26#define OVERFLOW_READ_THRESHHOLD (0xA00)
27#endif // UDF_DBG
28#else // defined(_M_IX86)
29#define OVERFLOW_READ_THRESHHOLD (0x1000)
30#endif // defined(_M_IX86)
31
32//#define POST_LOCK_PAGES
33
34
35/*************************************************************************
36*
37* Function: UDFRead()
38*
39* Description:
40* The I/O Manager will invoke this routine to handle a read
41* request
42*
43* Expected Interrupt Level (for execution) :
44*
45* IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
46* to be deferred to a worker thread context)
47*
48* Return Value: STATUS_SUCCESS/Error
49*
50*************************************************************************/
54 PDEVICE_OBJECT DeviceObject, // the logical volume device object
55 PIRP Irp) // I/O Request Packet
56{
58 PtrUDFIrpContext PtrIrpContext = NULL;
59 BOOLEAN AreWeTopLevel = FALSE;
60
61 TmPrint(("UDFRead: \n"));
62
65 ASSERT(Irp);
66
67 // set the top level context
68 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
69 ASSERT(!UDFIsFSDevObj(DeviceObject));
70
71 _SEH2_TRY {
72
73 // get an IRP context structure and issue the request
74 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
75 if(PtrIrpContext) {
76 RC = UDFCommonRead(PtrIrpContext, Irp);
77 } else {
79 Irp->IoStatus.Status = RC;
80 Irp->IoStatus.Information = 0;
81 // complete the IRP
83 }
84
86
87 RC = UDFExceptionHandler(PtrIrpContext, Irp);
88
90 } _SEH2_END;
91
92 if (AreWeTopLevel) {
94 }
95
97
98 return(RC);
99} // end UDFRead()
100
101
102/*************************************************************************
103*
104* Function: UDFPostStackOverflowRead()
105*
106* Description:
107* Post a read request that could not be processed by
108* the fsp thread because of stack overflow potential.
109*
110* Arguments:
111* Irp - Supplies the request to process.
112* Fcb - Supplies the file.
113*
114* Return Value: STATUS_PENDING.
115*
116*************************************************************************/
119 IN PtrUDFIrpContext PtrIrpContext,
120 IN PIRP Irp,
122 )
123{
126
127 UDFPrint(("Getting too close to stack limit pass request to Fsp\n"));
128
129 // Allocate an event and get shared on the resource we will
130 // be later using the common read.
132 if(!Event)
135
136 if ((Irp->Flags & IRP_PAGING_IO) && (Fcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource)) {
137 Resource = Fcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource;
138 } else {
139 Resource = Fcb->NTRequiredFCB->CommonFCBHeader.Resource;
140 }
141
143
144 _SEH2_TRY {
145 // If this read is the result of a verify, we have to
146 // tell the overflow read routne to temporarily
147 // hijack the Vcb->VerifyThread field so that reads
148 // can go through.
150 // And wait for the worker thread to complete the item
152
153 } _SEH2_FINALLY {
154
157 } _SEH2_END;
158
159 return STATUS_PENDING;
160
161} // end UDFPostStackOverflowRead()
162
163/*************************************************************************
164*
165* Function: UDFStackOverflowRead()
166*
167* Description:
168* Process a read request that could not be processed by
169* the fsp thread because of stack overflow potential.
170*
171* Arguments:
172* Context - Supplies the IrpContext being processed
173* Event - Supplies the event to be signaled when we are done processing this
174* request.
175*
176* Expected Interrupt Level (for execution) :
177*
178* IRQL_PASSIVE_LEVEL
179*
180* Return Value: None.
181*
182*************************************************************************/
183VOID
184NTAPI
188 )
189{
191 NTSTATUS RC;
192
193 UDFPrint(("UDFStackOverflowRead: \n"));
194 // Make it now look like we can wait for I/O to complete
196
197 // Do the read operation protected by a try-except clause
198 _SEH2_TRY {
199 UDFCommonRead(PtrIrpContext, PtrIrpContext->Irp);
201 RC = UDFExceptionHandler(PtrIrpContext, PtrIrpContext->Irp);
203 } _SEH2_END;
204
205 // Set the stack overflow item's event to tell the original
206 // thread that we're done.
207 KeSetEvent( Event, 0, FALSE );
208} // end UDFStackOverflowRead()
209
210
211/*************************************************************************
212*
213* Function: UDFCommonRead()
214*
215* Description:
216* The actual work is performed here. This routine may be invoked in one
217* of the two possible contexts:
218* (a) in the context of a system worker thread
219* (b) in the context of the original caller
220*
221* Expected Interrupt Level (for execution) :
222*
223* IRQL_PASSIVE_LEVEL
224*
225* Return Value: STATUS_SUCCESS/Error
226*
227*************************************************************************/
230 PtrUDFIrpContext PtrIrpContext,
231 PIRP Irp
232 )
233{
237 ULONG ReadLength = 0, TruncatedLength = 0;
238 SIZE_T NumberBytesRead = 0;
242 PVCB Vcb = NULL;
244 PERESOURCE PtrResourceAcquired = NULL;
245 PERESOURCE PtrResourceAcquired2 = NULL;
246 PVOID SystemBuffer = NULL;
247 PIRP TopIrp;
248// uint32 KeyValue = 0;
249
250 ULONG Res1Acq = 0;
251 ULONG Res2Acq = 0;
252
253 BOOLEAN CacheLocked = FALSE;
254
255 BOOLEAN CanWait = FALSE;
256 BOOLEAN PagingIo = FALSE;
257 BOOLEAN NonBufferedIo = FALSE;
258 BOOLEAN SynchronousIo = FALSE;
259
260 TmPrint(("UDFCommonRead: irp %x\n", Irp));
261
262 _SEH2_TRY {
263
264 TopIrp = IoGetTopLevelIrp();
265 switch((ULONG_PTR)TopIrp) {
267 UDFPrint((" FSRTL_FSP_TOP_LEVEL_IRP\n"));
268 break;
270 UDFPrint((" FSRTL_CACHE_TOP_LEVEL_IRP\n"));
271 break;
273 UDFPrint((" FSRTL_MOD_WRITE_TOP_LEVEL_IRP\n"));
274// BrutePoint()
275 break;
277 UDFPrint((" FSRTL_FAST_IO_TOP_LEVEL_IRP\n"));
278// BrutePoint()
279 break;
280 case NULL:
281 UDFPrint((" NULL TOP_LEVEL_IRP\n"));
282 break;
283 default:
284 if(TopIrp == Irp) {
285 UDFPrint((" TOP_LEVEL_IRP\n"));
286 } else {
287 UDFPrint((" RECURSIVE_IRP, TOP = %x\n", TopIrp));
288 }
289 break;
290 }
291 // First, get a pointer to the current I/O stack location
293 ASSERT(IrpSp);
294 MmPrint((" Enter Irp, MDL=%x\n", Irp->MdlAddress));
295 if(Irp->MdlAddress) {
296 UDFTouch(Irp->MdlAddress);
297 }
298
299 // If this happens to be a MDL read complete request, then
300 // there is not much processing that the FSD has to do.
302 // Caller wants to tell the Cache Manager that a previously
303 // allocated MDL can be freed.
304 UDFMdlComplete(PtrIrpContext, Irp, IrpSp, TRUE);
305 // The IRP has been completed.
307 }
308
309 // If this is a request at IRQL DISPATCH_LEVEL, then post
310 // the request (your FSD may choose to process it synchronously
311 // if you implement the support correctly; obviously you will be
312 // quite constrained in what you can do at such IRQL).
315 }
316
319
320 // Get the FCB and CCB pointers
321 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
322 ASSERT(Ccb);
323 Fcb = Ccb->Fcb;
324 ASSERT(Fcb);
325 Vcb = Fcb->Vcb;
326
327 if(Fcb->FCBFlags & UDF_FCB_DELETED) {
328 ASSERT(FALSE);
330 }
331
332 // check for stack overflow
333 if (IoGetRemainingStackSize() < OVERFLOW_READ_THRESHHOLD) {
334 RC = UDFPostStackOverflowRead( PtrIrpContext, Irp, Fcb );
335 try_return(RC);
336 }
337
338 // Disk based file systems might decide to verify the logical volume
339 // (if required and only if removable media are supported) at this time
340 // As soon as Tray is locked, we needn't call UDFVerifyVcb()
341
342 ByteOffset = IrpSp->Parameters.Read.ByteOffset;
343
344 CanWait = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE;
345 PagingIo = (Irp->Flags & IRP_PAGING_IO) ? TRUE : FALSE;
346 NonBufferedIo = (Irp->Flags & IRP_NOCACHE) ? TRUE : FALSE;
347 SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO) ? TRUE : FALSE;
348 UDFPrint((" Flags: %s %s %s %s\n",
349 CanWait ? "W" : "w", PagingIo ? "Pg" : "pg",
350 NonBufferedIo ? "NBuf" : "buff", SynchronousIo ? "Snc" : "Asc"));
351
352 if(!NonBufferedIo &&
353 (Fcb->NodeIdentifier.NodeType != UDF_NODE_TYPE_VCB)) {
354 if(UDFIsAStream(Fcb->FileInfo)) {
358 } else {
362 }
363 }
364
365 // Get some of the parameters supplied to us
367 if (ReadLength == 0) {
368 // a 0 byte read can be immediately succeeded
369 try_return(RC);
370 }
371 UDFPrint((" ByteOffset = %I64x, ReadLength = %x\n", ByteOffset.QuadPart, ReadLength));
372
373 // Is this a read of the volume itself ?
374 if (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) {
375 // Yup, we need to send this on to the disk driver after
376 // validation of the offset and length.
377 Vcb = (PVCB)Fcb;
378 Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
379 if(!CanWait)
381
382
384
385 UDFPrint((" UDF_IRP_CONTEXT_FLUSH2_REQUIRED\n"));
386 PtrIrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_FLUSH2_REQUIRED;
387
388 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)) {
389 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
390 }
391#ifdef UDF_DELAYED_CLOSE
393#endif //UDF_DELAYED_CLOSE
394
395 }
396
398
399 UDFPrint((" UDF_IRP_CONTEXT_FLUSH_REQUIRED\n"));
400 PtrIrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_FLUSH_REQUIRED;
401
402 // Acquire the volume resource exclusive
403 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
404 PtrResourceAcquired = &(Vcb->VCBResource);
405
407
408 UDFReleaseResource(PtrResourceAcquired);
409 PtrResourceAcquired = NULL;
410 }
411
412 // Acquire the volume resource shared ...
413 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
414 PtrResourceAcquired = &(Vcb->VCBResource);
415
416#if 0
417 if(PagingIo) {
418 CollectStatistics(Vcb, MetaDataReads);
419 CollectStatisticsEx(Vcb, MetaDataReadBytes, NumberBytesRead);
420 }
421#endif
422
423 // Forward the request to the lower level driver
424 // Lock the callers buffer
425 if (!NT_SUCCESS(RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, ReadLength))) {
426 try_return(RC);
427 }
428 SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
429 if(!SystemBuffer) {
431 }
432 if(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) {
433 RC = UDFReadData(Vcb, TRUE, ByteOffset.QuadPart,
434 ReadLength, FALSE, (PCHAR)SystemBuffer,
435 &NumberBytesRead);
436 } else {
437 RC = UDFTRead(Vcb, SystemBuffer, ReadLength,
438 (ULONG)(ByteOffset.QuadPart >> Vcb->BlockSizeBits),
439 &NumberBytesRead);
440 }
441 UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
442 try_return(RC);
443 }
444 Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
445
446 // If the read request is directed to a page file (if your FSD
447 // supports paging files), send the request directly to the disk
448 // driver. For requests directed to a page file, you have to trust
449 // that the offsets will be set correctly by the VMM. You should not
450 // attempt to acquire any FSD resources either.
451 if(Fcb->FCBFlags & UDF_FCB_PAGE_FILE) {
452 NonBufferedIo = TRUE;
453 }
454
455 if(ByteOffset.HighPart == -1) {
457 ByteOffset = FileObject->CurrentByteOffset;
458 }
459 }
460
461 // If this read is directed to a directory, it is not allowed
462 // by the UDF FSD.
463 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
465 try_return(RC);
466 }
467
468 NtReqFcb = Fcb->NTRequiredFCB;
469
470 Res1Acq = UDFIsResourceAcquired(&(NtReqFcb->MainResource));
471 if(!Res1Acq) {
472 Res1Acq = PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_RES1_ACQ;
473 }
474 Res2Acq = UDFIsResourceAcquired(&(NtReqFcb->PagingIoResource));
475 if(!Res2Acq) {
476 Res2Acq = PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_RES2_ACQ;
477 }
478
479#if 0
480 if(PagingIo) {
481 CollectStatistics(Vcb, UserFileReads);
482 CollectStatisticsEx(Vcb, UserFileReadBytes, NumberBytesRead);
483 }
484#endif
485
486 // This is a good place for oplock related processing.
487
488 // If this is the normal file we have to check for
489 // write access according to the current state of the file locks.
490 if (!PagingIo &&
491 !FsRtlCheckLockForReadAccess( &(NtReqFcb->FileLock), Irp )) {
493 }
494
495 // Validate start offset and length supplied.
496 // If start offset is > end-of-file, return an appropriate error. Note
497 // that since a FCB resource has already been acquired, and since all
498 // file size changes require acquisition of both FCB resources,
499 // the contents of the FCB and associated data structures
500 // can safely be examined.
501
502 // Also note that we are using the file size in the "Common FCB Header"
503 // to perform the check. However, your FSD might decide to keep a
504 // separate copy in the FCB (or some other representation of the
505 // file associated with the FCB).
506
507 TruncatedLength = ReadLength;
508 if (ByteOffset.QuadPart >= NtReqFcb->CommonFCBHeader.FileSize.QuadPart) {
509 // Starting offset is >= file size
511 }
512 // We can also go ahead and truncate the read length here
513 // such that it is contained within the file size
514 if( NtReqFcb->CommonFCBHeader.FileSize.QuadPart < (ByteOffset.QuadPart + ReadLength) ) {
515 TruncatedLength = (ULONG)(NtReqFcb->CommonFCBHeader.FileSize.QuadPart - ByteOffset.QuadPart);
516 // we can't get ZERO here
517 }
518 UDFPrint((" TruncatedLength = %x\n", TruncatedLength));
519
520 // There are certain complications that arise when the same file stream
521 // has been opened for cached and non-cached access. The FSD is then
522 // responsible for maintaining a consistent view of the data seen by
523 // the caller.
524 // Also, it is possible for file streams to be mapped in both as data files
525 // and as an executable. This could also lead to consistency problems since
526 // there now exist two separate sections (and pages) containing file
527 // information.
528
529 // The test below flushes the data cached in system memory if the current
530 // request madates non-cached access (file stream must be cached) and
531 // (a) the current request is not paging-io which indicates it is not
532 // a recursive I/O operation OR originating in the Cache Manager
533 // (b) OR the current request is paging-io BUT it did not originate via
534 // the Cache Manager (or is a recursive I/O operation) and we do
535 // have an image section that has been initialized.
536#define UDF_REQ_NOT_VIA_CACHE_MGR(ptr) (!MmIsRecursiveIoFault() && ((ptr)->ImageSectionObject != NULL))
537
538 if(NonBufferedIo &&
539 (NtReqFcb->SectionObject.DataSectionObject != NULL)) {
540 if(!PagingIo) {
541
542/* // We hold the main resource exclusive here because the flush
543 // may generate a recursive write in this thread. The PagingIo
544 // resource is held shared so the drop-and-release serialization
545 // below will work.
546 if(!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
547 try_return(RC = STATUS_PENDING);
548 }
549 PtrResourceAcquired = &(NtReqFcb->MainResource);
550
551 // We hold PagingIo shared around the flush to fix a
552 // cache coherency problem.
553 UDFAcquireResourceShared(&(NtReqFcb->PagingIoResource), TRUE );*/
554
555 MmPrint((" CcFlushCache()\n"));
556 CcFlushCache(&(NtReqFcb->SectionObject), &ByteOffset, TruncatedLength, &(Irp->IoStatus));
557
558/* UDFReleaseResource(&(NtReqFcb->PagingIoResource));
559 UDFReleaseResource(PtrResourceAcquired);
560 PtrResourceAcquired = NULL;
561 // If the flush failed, return error to the caller
562 if(!NT_SUCCESS(RC = Irp->IoStatus.Status)) {
563 try_return(RC);
564 }
565
566 // Acquiring and immediately dropping the resource serializes
567 // us behind any other writes taking place (either from the
568 // lazy writer or modified page writer).*/
569 if(!Res2Acq) {
570 UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), TRUE );
571 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
572 }
573 }
574 }
575
576 // Acquire the appropriate FCB resource shared
577 if (PagingIo) {
578 // Try to acquire the FCB PagingIoResource shared
579 if(!Res2Acq) {
580 if (!UDFAcquireResourceShared(&(NtReqFcb->PagingIoResource), CanWait)) {
582 }
583 // Remember the resource that was acquired
584 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
585 }
586 } else {
587 // Try to acquire the FCB MainResource shared
588 if(NonBufferedIo) {
589 if(!Res2Acq) {
590 if(!UDFAcquireSharedWaitForExclusive(&(NtReqFcb->PagingIoResource), CanWait)) {
592 }
593 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
594 }
595 } else {
596 if(!Res1Acq) {
598 if(!UDFAcquireResourceShared(&(NtReqFcb->MainResource), CanWait)) {
600 }
601 // Remember the resource that was acquired
602 PtrResourceAcquired = &(NtReqFcb->MainResource);
603 }
604 }
605 }
606
607 // This is also a good place to set whether fast-io can be performed
608 // on this particular file or not. Your FSD must make it's own
609 // determination on whether or not to allow fast-io operations.
610 // Commonly, fast-io is not allowed if any byte range locks exist
611 // on the file or if oplocks prevent fast-io. Practically any reason
612 // choosen by your FSD could result in your setting FastIoIsNotPossible
613 // OR FastIoIsQuestionable instead of FastIoIsPossible.
614
615 NtReqFcb->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
616/* if(NtReqFcb->CommonFCBHeader.IsFastIoPossible == FastIoIsPossible)
617 NtReqFcb->CommonFCBHeader.IsFastIoPossible = FastIoIsQuestionable;*/
618
619#ifdef UDF_DISABLE_SYSTEM_CACHE_MANAGER
620 NonBufferedIo = TRUE;
621#endif
622
623 if(Fcb && Fcb->FileInfo && Fcb->FileInfo->Dloc) {
624 AdPrint(("UDFCommonRead: DataLoc %x, Mapping %x\n", &Fcb->FileInfo->Dloc->DataLoc, Fcb->FileInfo->Dloc->DataLoc.Mapping));
625 }
626
627 // Branch here for cached vs non-cached I/O
628 if (!NonBufferedIo) {
629
630 if(FileObject->Flags & FO_WRITE_THROUGH) {
631 CanWait = TRUE;
632 }
633 // The caller wishes to perform cached I/O. Initiate caching if
634 // this is the first cached I/O operation using this file object
635 if (!(FileObject->PrivateCacheMap)) {
636 // This is the first cached I/O operation. You must ensure
637 // that the FCB Common FCB Header contains valid sizes at this time
638 MmPrint((" CcInitializeCacheMap()\n"));
639 CcInitializeCacheMap(FileObject, (PCC_FILE_SIZES)(&(NtReqFcb->CommonFCBHeader.AllocationSize)),
640 FALSE, // We will not utilize pin access for this file
641 &(UDFGlobalData.CacheMgrCallBacks), // callbacks
642 NtReqFcb); // The context used in callbacks
643 MmPrint((" CcSetReadAheadGranularity()\n"));
644 CcSetReadAheadGranularity(FileObject, Vcb->SystemCacheGran);
645 }
646
647 // Check and see if this request requires a MDL returned to the caller
649 // Caller does want a MDL returned. Note that this mode
650 // implies that the caller is prepared to block
651 MmPrint((" CcMdlRead()\n"));
652// CcMdlRead(FileObject, &ByteOffset, TruncatedLength, &(Irp->MdlAddress), &(Irp->IoStatus));
653// NumberBytesRead = Irp->IoStatus.Information;
654// RC = Irp->IoStatus.Status;
655 NumberBytesRead = 0;
657
658 try_return(RC);
659 }
660
661 // This is a regular run-of-the-mill cached I/O request. Let the
662 // Cache Manager worry about it!
663 // First though, we need a buffer pointer (address) that is valid
664 SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
665 if(!SystemBuffer)
667 ASSERT(SystemBuffer);
668 MmPrint((" CcCopyRead()\n"));
669 if (!CcCopyRead(FileObject, &(ByteOffset), TruncatedLength, CanWait, SystemBuffer, &(Irp->IoStatus))) {
670 // The caller was not prepared to block and data is not immediately
671 // available in the system cache
673 }
674
675 UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
676 // We have the data
677 RC = Irp->IoStatus.Status;
678 NumberBytesRead = Irp->IoStatus.Information;
679
680 try_return(RC);
681
682 } else {
683
684 MmPrint((" Read NonBufferedIo\n"));
685
686#if 1
688 UDFPrint(("FSRTL_MOD_WRITE_TOP_LEVEL_IRP => CanWait\n"));
689 CanWait = TRUE;
690 } else
691 if((ULONG_PTR)TopIrp == FSRTL_CACHE_TOP_LEVEL_IRP) {
692 UDFPrint(("FSRTL_CACHE_TOP_LEVEL_IRP => CanWait\n"));
693 CanWait = TRUE;
694 }
695
696 if(NtReqFcb->AcqSectionCount || NtReqFcb->AcqFlushCount) {
697 MmPrint((" AcqCount (%d/%d)=> CanWait ?\n", NtReqFcb->AcqSectionCount, NtReqFcb->AcqFlushCount));
698 CanWait = TRUE;
699 } else
700 {}
701/* if((TopIrp != Irp)) {
702 UDFPrint(("(TopIrp != Irp) => CanWait\n"));
703 CanWait = TRUE;
704 } else*/
705#endif
707 MmPrint((" !PASSIVE_LEVEL\n"));
708 CanWait = FALSE;
710 }
711 if(!CanWait && UDFIsFileCached__(Vcb, Fcb->FileInfo, ByteOffset.QuadPart, TruncatedLength, FALSE)) {
712 MmPrint((" Locked => CanWait\n"));
713 CacheLocked = TRUE;
714 CanWait = TRUE;
715 }
716
717 // Send the request to lower level drivers
718 if(!CanWait) {
720 }
721
722// ASSERT(NT_SUCCESS(RC));
723 if(!Res2Acq) {
724 if(UDFAcquireResourceSharedWithCheck(&(NtReqFcb->PagingIoResource)))
725 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
726 }
727
728 RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, TruncatedLength);
729 if(!NT_SUCCESS(RC)) {
730 try_return(RC);
731 }
732
733 SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
734 if(!SystemBuffer) {
736 }
737
738 RC = UDFReadFile__(Vcb, Fcb->FileInfo, ByteOffset.QuadPart, TruncatedLength,
739 CacheLocked, (PCHAR)SystemBuffer, &NumberBytesRead);
740/* // AFAIU, CacheManager wants this:
741 if(!NT_SUCCESS(RC)) {
742 NumberBytesRead = 0;
743 }*/
744
745 UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
746
747#if 0
748 if(PagingIo) {
749 CollectStatistics(Vcb, UserDiskReads);
750 } else {
751 CollectStatistics2(Vcb, NonCachedDiskReads);
752 }
753#endif
754
755 try_return(RC);
756
757 // For paging-io, the FSD has to trust the VMM to do the right thing
758
759 // Here is a common method used by Windows NT native file systems
760 // that are in the process of sending a request to the disk driver.
761 // First, mark the IRP as pending, then invoke the lower level driver
762 // after setting a completion routine.
763 // Meanwhile, this particular thread can immediately return a
764 // STATUS_PENDING return code.
765 // The completion routine is then responsible for completing the IRP
766 // and unlocking appropriate resources
767
768 // Also, at this point, the FSD might choose to utilize the
769 // information contained in the ValidDataLength field to simply
770 // return zeroes to the caller for reads extending beyond current
771 // valid data length.
772
773 }
774
775try_exit: NOTHING;
776
777 } _SEH2_FINALLY {
778
779 if(CacheLocked) {
780 WCacheEODirect__(&(Vcb->FastCache), Vcb);
781 }
782
783 // Release any resources acquired here ...
784 if(PtrResourceAcquired2) {
785 UDFReleaseResource(PtrResourceAcquired2);
786 }
787 if(PtrResourceAcquired) {
788 if(NtReqFcb &&
789 (PtrResourceAcquired ==
790 &(NtReqFcb->MainResource))) {
792 }
793 UDFReleaseResource(PtrResourceAcquired);
794 }
795
796 // Post IRP if required
797 if(RC == STATUS_PENDING) {
798
799 // Lock the callers buffer here. Then invoke a common routine to
800 // perform the post operation.
801 if (!(IrpSp->MinorFunction & IRP_MN_MDL)) {
802 RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, ReadLength);
803 ASSERT(NT_SUCCESS(RC));
804 }
805 if(PagingIo) {
806 if(Res1Acq) {
808 }
809 if(Res2Acq) {
811 }
812 }
813 // Perform the post operation which will mark the IRP pending
814 // and will return STATUS_PENDING back to us
815 RC = UDFPostRequest(PtrIrpContext, Irp);
816
817 } else {
818 // For synchronous I/O, the FSD must maintain the current byte offset
819 // Do not do this however, if I/O is marked as paging-io
820 if (SynchronousIo && !PagingIo && NT_SUCCESS(RC)) {
821 FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + NumberBytesRead;
822 }
823 // If the read completed successfully and this was not a paging-io
824 // operation, set a flag in the CCB that indicates that a read was
825 // performed and that the file time should be updated at cleanup
826 if (NT_SUCCESS(RC) && !PagingIo) {
828 Ccb->CCBFlags |= UDF_CCB_ACCESSED;
829 }
830
832 Irp->IoStatus.Status = RC;
833 Irp->IoStatus.Information = NumberBytesRead;
834 UDFPrint((" NumberBytesRead = %x\n", NumberBytesRead));
835 // Free up the Irp Context
836 UDFReleaseIrpContext(PtrIrpContext);
837 // complete the IRP
838 MmPrint((" Complete Irp, MDL=%x\n", Irp->MdlAddress));
839 if(Irp->MdlAddress) {
840 UDFTouch(Irp->MdlAddress);
841 }
843 }
844 } // can we complete the IRP ?
845 } _SEH2_END; // end of "__finally" processing
846
847 return(RC);
848} // end UDFCommonRead()
849
850
851#ifdef UDF_DBG
852ULONG LockBufferCounter = 0;
853ULONG BuildMdlCounter = 0;
854#endif //UDF_DBG
855
856/*************************************************************************
857*
858* Function: UDFGetCallersBuffer()
859*
860* Description:
861* Obtain a pointer to the caller's buffer.
862*
863* Expected Interrupt Level (for execution) :
864*
865* IRQL_PASSIVE_LEVEL
866*
867* Return Value: STATUS_SUCCESS/Error
868*
869*************************************************************************/
870PVOID
872 PtrUDFIrpContext PtrIrpContext,
873 PIRP Irp
874 )
875{
876 VOID *ReturnedBuffer = NULL;
877
878 UDFPrint(("UDFGetCallersBuffer: \n"));
879
880 // If an MDL is supplied, use it.
881 if(Irp->MdlAddress) {
882 MmPrint((" UDFGetCallersBuffer: MmGetSystemAddressForMdl(Irp->MdlAddress) MDL=%x\n", Irp->MdlAddress));
883// ReturnedBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
884 ReturnedBuffer = MmGetSystemAddressForMdlSafer(Irp->MdlAddress);
885 } else
886 if (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_BUFFER_LOCKED) {
887 // Free buffer
888#ifndef POST_LOCK_PAGES
889 MmPrint((" UDFGetCallersBuffer: MmGetSystemAddressForMdl(PtrIrpContext->PtrMdl) MDL=%x\n", PtrIrpContext->PtrMdl));
890 ReturnedBuffer = MmGetSystemAddressForMdlSafe(PtrIrpContext->PtrMdl, NormalPagePriority);
891#else //POST_LOCK_PAGES
892 if(PtrIrpContext->TransitionBuffer) {
893 MmPrint((" UDFGetCallersBuffer: TransitionBuffer\n"));
894 return PtrIrpContext->TransitionBuffer;
895 }
896
897 _SEH2_TRY {
898 MmPrint((" MmProbeAndLockPages()\n"));
899 MmProbeAndLockPages(PtrIrpContext->PtrMdl, Irp->RequestorMode,
900 ((PtrIrpContext->MajorFunction == IRP_MJ_READ) ? IoWriteAccess:IoReadAccess));
901#ifdef UDF_DBG
902 LockBufferCounter++;
903#endif //UDF_DBG
905 //RC = STATUS_INVALID_USER_BUFFER;
906 BrutePoint();
907 return NULL;
908 } _SEH2_END;
909
910 MmPrint((" MmGetSystemAddressForMdlSafer()\n"));
911 ReturnedBuffer = MmGetSystemAddressForMdlSafer(PtrIrpContext->PtrMdl);
912#endif //POST_LOCK_PAGES
913 } else {
914 MmPrint((" UDFGetCallersBuffer: Irp->UserBuffer\n"));
915 ReturnedBuffer = Irp->UserBuffer;
916 }
917
918 return(ReturnedBuffer);
919} // end UDFGetCallersBuffer()
920
921/*************************************************************************
922*
923* Function: UDFLockCallersBuffer()
924*
925* Description:
926* Obtain a MDL that describes the buffer. Lock pages for I/O
927*
928* Expected Interrupt Level (for execution) :
929*
930* IRQL_PASSIVE_LEVEL
931*
932* Return Value: STATUS_SUCCESS/Error
933*
934*************************************************************************/
937 PtrUDFIrpContext PtrIrpContext,
938 PIRP Irp,
939 BOOLEAN IsReadOperation,
941 )
942{
944 PMDL PtrMdl = NULL;
945
946 UDFPrint(("UDFLockCallersBuffer: \n"));
947
948 ASSERT(Irp);
949
950 _SEH2_TRY {
951 // Is a MDL already present in the IRP
952 if (!(Irp->MdlAddress)) {
953 // Allocate a MDL
954/*
955 if(!IsReadOperation) {
956 MmPrint((" Allocate TransitionBuffer\n"));
957 PtrIrpContext->TransitionBuffer = (PCHAR)DbgAllocatePool(NonPagedPool, Length);
958 if(!PtrIrpContext->TransitionBuffer) {
959 RC = STATUS_INSUFFICIENT_RESOURCES;
960 try_return(RC);
961 }
962 _SEH2_TRY {
963 RtlCopyMemory(PtrIrpContext->TransitionBuffer, Irp->UserBuffer, Length);
964 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
965 RC = STATUS_INVALID_USER_BUFFER;
966 } _SEH2_END;
967 } else*/ {
968
969 MmPrint((" IoAllocateMdl()\n"));
970// if (!(PtrMdl = IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, NULL))) {
971
972 // This will place allocated Mdl to Irp
973 if (!(PtrMdl = IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp))) {
975 try_return(RC);
976 }
977 MmPrint((" Alloc MDL=%x\n", PtrMdl));
978#ifdef UDF_DBG
979 BuildMdlCounter++;
980#endif //UDF_DBG
981 }
982 // Probe and lock the pages described by the MDL
983 // We could encounter an exception doing so, swallow the exception
984 // NOTE: The exception could be due to an unexpected (from our
985 // perspective), invalidation of the virtual addresses that comprise
986 // the passed in buffer
987#ifndef POST_LOCK_PAGES
988 _SEH2_TRY {
989 MmPrint((" MmProbeAndLockPages()\n"));
990 MmProbeAndLockPages(PtrMdl, Irp->RequestorMode, (IsReadOperation ? IoWriteAccess:IoReadAccess));
992 MmPrint((" MmProbeAndLockPages() failed\n"));
993 Irp->MdlAddress = NULL;
995 } _SEH2_END;
996#endif //POST_LOCK_PAGES
997
998 if(NT_SUCCESS(RC)) {
1000 PtrIrpContext->PtrMdl = PtrMdl;
1001 }
1002 } else {
1003 MmPrint((" UDFLockCallersBuffer: do nothing, MDL=%x\n", Irp->MdlAddress));
1004 UDFTouch(Irp->MdlAddress);
1005 }
1006
1007try_exit: NOTHING;
1008
1009 } _SEH2_FINALLY {
1010 if (!NT_SUCCESS(RC) && PtrMdl) {
1011 MmPrint((" Free MDL=%x\n", PtrMdl));
1012 IoFreeMdl(PtrMdl);
1013 }
1014 } _SEH2_END;
1015
1016 return(RC);
1017} // end UDFLockCallersBuffer()
1018
1019/*************************************************************************
1020*
1021* Function: UDFUnlockCallersBuffer()
1022*
1023* Description:
1024* Obtain a MDL that describes the buffer. Lock pages for I/O
1025*
1026* Expected Interrupt Level (for execution) :
1027*
1028* IRQL_PASSIVE_LEVEL
1029*
1030* Return Value: STATUS_SUCCESS/Error
1031*
1032*************************************************************************/
1035 PtrUDFIrpContext PtrIrpContext,
1036 PIRP Irp,
1037 PVOID SystemBuffer
1038 )
1039{
1041
1042 UDFPrint(("UDFUnlockCallersBuffer: \n"));
1043
1044 ASSERT(Irp);
1045
1046 _SEH2_TRY {
1047 // Is a nonPaged buffer already present in the IRP
1048 if (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_BUFFER_LOCKED) {
1049
1050 UDFPrint((" UDF_IRP_CONTEXT_BUFFER_LOCKED MDL=%x, Irp MDL=%x\n", PtrIrpContext->PtrMdl, Irp->MdlAddress));
1051 if(PtrIrpContext->TransitionBuffer) {
1052 MmPrint((" UDFUnlockCallersBuffer: free TransitionBuffer\n"));
1053 DbgFreePool(PtrIrpContext->TransitionBuffer);
1054 PtrIrpContext->TransitionBuffer = NULL;
1055 PtrIrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_BUFFER_LOCKED;
1056 try_return(RC);
1057 }
1058 // Free buffer
1059 KeFlushIoBuffers( PtrIrpContext->PtrMdl, TRUE, FALSE );
1060// MmPrint((" IrpCtx->Mdl, MmUnmapLockedPages()\n"));
1061// MmUnmapLockedPages(SystemBuffer, PtrIrpContext->PtrMdl);
1062
1063 // This will be done in IoCompleteIrp !!!
1064
1065 //MmPrint((" MmUnlockPages()\n"));
1066 //MmUnlockPages(PtrIrpContext->PtrMdl);
1067
1068#ifdef UDF_DBG
1069 LockBufferCounter--;
1070#endif //UDF_DBG
1071
1072 // This will be done in IoCompleteIrp !!!
1073
1074 //IoFreeMdl(PtrIrpContext->PtrMdl);
1075
1076#ifdef UDF_DBG
1077 BuildMdlCounter--;
1078#endif //UDF_DBG
1079 UDFTouch(PtrIrpContext->PtrMdl);
1080 PtrIrpContext->PtrMdl = NULL;
1081 PtrIrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_BUFFER_LOCKED;
1082 } else
1083 if(Irp->MdlAddress) {
1084// MmPrint((" Irp->Mdl, MmUnmapLockedPages()\n"));
1085// MmUnmapLockedPages(SystemBuffer, Irp->MdlAddress);
1086 UDFPrint((" UDF_IRP_CONTEXT_BUFFER_LOCKED MDL=%x, Irp MDL=%x\n", PtrIrpContext->PtrMdl, Irp->MdlAddress));
1087 UDFTouch(Irp->MdlAddress);
1088 KeFlushIoBuffers( Irp->MdlAddress,
1090 FALSE );
1091 } else
1092 { ; }
1093
1094try_exit: NOTHING;
1095
1096 } _SEH2_FINALLY {
1097 NOTHING;
1098 } _SEH2_END;
1099
1100 return(RC);
1101} // end UDFUnlockCallersBuffer()
1102
1103/*************************************************************************
1104*
1105* Function: UDFMdlComplete()
1106*
1107* Description:
1108* Tell Cache Manager to release MDL (and possibly flush).
1109*
1110* Expected Interrupt Level (for execution) :
1111*
1112* IRQL_PASSIVE_LEVEL
1113*
1114* Return Value: None.
1115*
1116*************************************************************************/
1118PtrUDFIrpContext PtrIrpContext,
1119PIRP Irp,
1121BOOLEAN ReadCompletion)
1122{
1125
1126 UDFPrint(("UDFMdlComplete: \n"));
1127
1130
1131 UDFTouch(Irp->MdlAddress);
1132 // Not much to do here.
1133 if (ReadCompletion) {
1134 MmPrint((" CcMdlReadComplete() MDL=%x\n", Irp->MdlAddress));
1135 CcMdlReadComplete(FileObject, Irp->MdlAddress);
1136 } else {
1137 // The Cache Manager needs the byte offset in the I/O stack location.
1138 MmPrint((" CcMdlWriteComplete() MDL=%x\n", Irp->MdlAddress));
1139 CcMdlWriteComplete(FileObject, &(IrpSp->Parameters.Write.ByteOffset), Irp->MdlAddress);
1140 }
1141
1142 // Clear the MDL address field in the IRP so the IoCompleteRequest()
1143 // does not __try to play around with the MDL.
1144 Irp->MdlAddress = NULL;
1145
1146 // Free up the Irp Context.
1147 UDFReleaseIrpContext(PtrIrpContext);
1148
1149 // Complete the IRP.
1150 Irp->IoStatus.Status = RC;
1151 Irp->IoStatus.Information = 0;
1153
1154 return;
1155}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
ULONG ReadLength
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
unsigned int uint32
Definition: types.h:32
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
#define try_return(S)
Definition: cdprocs.h:2179
struct _VCB * PVCB
Definition: fatstruc.h:557
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
ULONG UDFIsResourceAcquired(IN PERESOURCE Resource)
Definition: misc.cpp:2518
BOOLEAN UDFAcquireResourceSharedWithCheck(IN PERESOURCE Resource)
Definition: misc.cpp:2556
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
#define CollectStatistics(VCB, Field)
Definition: env_spec.h:120
__inline VOID UDFNotifyFullReportChange(PVCB V, PUDF_FILE_INFO FI, ULONG E, ULONG A)
Definition: env_spec.h:99
#define CollectStatisticsEx(VCB, Field, a)
Definition: env_spec.h:124
#define CollectStatistics2(VCB, Field)
Definition: env_spec.h:128
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define PKEVENT
Definition: env_spec_w32.h:70
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define DbgWaitForSingleObject(o, to)
Definition: env_spec_w32.h:479
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
#define UDFTouch(a)
Definition: env_spec_w32.h:303
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define TmPrint(_x_)
Definition: env_spec_w32.h:290
#define DbgFreePool
Definition: env_spec_w32.h:334
#define UDFAcquireSharedWaitForExclusive(Resource, CanWait)
Definition: env_spec_w32.h:671
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
#define NonPagedPool
Definition: env_spec_w32.h:307
#define BrutePoint()
Definition: env_spec_w32.h:504
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible(IN PtrUDFFCB Fcb)
Definition: fastio.cpp:118
#define NtReqFcb
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:672
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
ULONG UDFFlushLogicalVolume(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PVCB Vcb, IN ULONG FlushFlags)
Definition: flush.cpp:506
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:61
#define FSRTL_FAST_IO_TOP_LEVEL_IRP
Definition: fsrtltypes.h:62
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define NOTHING
Definition: input_list.c:10
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define MyFreePool__(addr)
Definition: mem_tools.h:152
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
#define ASSERT(a)
Definition: mode.c:44
@ NormalPagePriority
Definition: imports.h:56
#define FILE_USE_FILE_POINTER_POSITION
Definition: nt_native.h:780
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
__inline PVOID MmGetSystemAddressForMdlSafer(IN PMDL Mdl)
Definition: ntifs_ex.h:101
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 IoCompleteRequest
Definition: irp.c:1240
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:320
#define STATUS_PENDING
Definition: ntstatus.h:82
#define Vcb
Definition: cdprocs.h:1415
OSSTATUS UDFTRead(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T ReadBytes, IN uint32 Flags)
Definition: phys_lib.cpp:596
OSSTATUS UDFReadData(IN PVCB Vcb, IN BOOLEAN Translate, IN LONGLONG Offset, IN ULONG Length, IN BOOLEAN Direct, OUT PCHAR Buffer, OUT PSIZE_T ReadBytes)
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)
Definition: protos.h:99
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define IRP_MJ_READ
Definition: rdpdr.c:46
NTSTATUS NTAPI UDFRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: read.cpp:53
NTSTATUS UDFLockCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp, BOOLEAN IsReadOperation, uint32 Length)
Definition: read.cpp:936
VOID UDFMdlComplete(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN ReadCompletion)
Definition: read.cpp:1117
NTSTATUS UDFPostStackOverflowRead(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PtrUDFFCB Fcb)
Definition: read.cpp:118
#define OVERFLOW_READ_THRESHHOLD
Definition: read.cpp:29
PVOID UDFGetCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:871
NTSTATUS UDFUnlockCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVOID SystemBuffer)
Definition: read.cpp:1034
NTSTATUS UDFCommonRead(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:229
VOID NTAPI UDFStackOverflowRead(IN PVOID Context, IN PKEVENT Event)
Definition: read.cpp:185
#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation)
Definition: ke.h:174
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI FsRtlPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
Definition: stackovf.c:232
#define UDF_IRP_CONTEXT_BUFFER_LOCKED
Definition: struct.h:398
#define UDF_IRP_CONTEXT_RES1_ACQ
Definition: struct.h:395
#define UDF_IRP_CONTEXT_FLUSH2_REQUIRED
Definition: struct.h:393
#define UDF_IRP_CONTEXT_FLUSH_REQUIRED
Definition: struct.h:392
#define UDF_FCB_PAGE_FILE
Definition: struct.h:302
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
#define UDF_FCB_DELETED
Definition: struct.h:314
#define UDF_IRP_CONTEXT_FORCED_POST
Definition: struct.h:397
struct _UDFIrpContext * PtrUDFIrpContext
struct _UDFContextControlBlock * PtrUDFCCB
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
#define UDF_CCB_ACCESSED
Definition: struct.h:149
#define UDF_IRP_CONTEXT_RES2_ACQ
Definition: struct.h:396
ULONG Flags
Definition: ntfs.h:536
PVCB Vcb
Definition: cdstruc.h:933
ERESOURCE PagingIoResource
Definition: ntfs.h:527
struct _FCB::@720::@723 Fcb
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@3983 Write
struct _IO_STACK_LOCATION::@3978::@3982 Read
PMDL PtrMdl
Definition: struct.h:380
uint32 IrpContextFlags
Definition: struct.h:364
PCHAR TransitionBuffer
Definition: struct.h:381
uint8 MajorFunction
Definition: struct.h:366
Definition: cdstruc.h:498
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
#define UDF_VCB_SKIP_EJECT_CHECK
Definition: udf_common.h:470
#define UDFIsFileCached__(Vcb, FileInfo, Offset, Length, ForWrite)
Definition: udf_info.h:839
__inline OSSTATUS UDFReadFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, OUT int8 *Buffer, OUT PSIZE_T ReadBytes)
Definition: udf_info.h:666
#define UDFIsAStream(FI)
Definition: udf_info.h:1002
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:260
#define UDFPrint(Args)
Definition: udffs.h:223
OSSTATUS WCacheEODirect__(IN PW_CACHE Cache, IN PVOID Context)
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define FILE_ACTION_MODIFIED_STREAM
#define FILE_ACTION_MODIFIED
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_PAGING_IO
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1795
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_MN_MDL
Definition: iotypes.h:4419
#define IRP_MN_DPC
Definition: iotypes.h:4418
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define IRP_NOCACHE
@ IoReadAccess
Definition: ketypes.h:863
@ IoWriteAccess
Definition: ketypes.h:864
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)