ReactOS 0.4.16-dev-122-g325d74c
close.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: Close.cpp
9*
10* Module: UDF File System Driver (Kernel mode execution only)
11*
12* Description:
13* Contains code to handle the "Close" 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_CLOSE
21
23#define TREE_ITEM_LIST_GRAN 32
24
27 IN PVCB Vcb,
29 IN PCHECK_TREE_ITEM CheckItemProc,
30 IN PUDF_DATALOC_INFO** PassedList,
31 IN PULONG PassedListSize,
32 IN PUDF_DATALOC_INFO** FoundList,
33 IN PULONG FoundListSize);
34
35// callbacks, can't be __fastcall
39
43
44/*************************************************************************
45*
46* Function: UDFClose()
47*
48* Description:
49* The I/O Manager will invoke this routine to handle a close
50* request
51*
52* Expected Interrupt Level (for execution) :
53*
54* IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
55* to be deferred to a worker thread context)
56*
57* Return Value: STATUS_SUCCESS
58*
59*************************************************************************/
63 PDEVICE_OBJECT DeviceObject, // the logical volume device object
64 PIRP Irp // I/O Request Packet
65 )
66{
68 PtrUDFIrpContext PtrIrpContext = NULL;
69 BOOLEAN AreWeTopLevel = FALSE;
70
71 AdPrint(("UDFClose: \n"));
72
75 ASSERT(Irp);
76
77 // If we were called with our file system device object instead of a
78 // volume device object, just complete this request with STATUS_SUCCESS
79 if (UDFIsFSDevObj(DeviceObject)) {
80 // this is a close of the FSD itself
81 Irp->IoStatus.Status = RC;
82 Irp->IoStatus.Information = 0;
83
86 return(RC);
87 }
88
89 // set the top level context
90 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
91
92 _SEH2_TRY {
93
94 // get an IRP context structure and issue the request
95 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
96 ASSERT(PtrIrpContext);
97
98 RC = UDFCommonClose(PtrIrpContext, Irp);
99
101
102 RC = UDFExceptionHandler(PtrIrpContext, Irp);
103
105 } _SEH2_END;
106
107 if (AreWeTopLevel) {
109 }
110
112
113 return(RC);
114}
115
116
117
118
119/*************************************************************************
120*
121* Function: UDFCommonClose()
122*
123* Description:
124* The actual work is performed here. This routine may be invoked in one'
125* of the two possible contexts:
126* (a) in the context of a system worker thread
127* (b) in the context of the original caller
128*
129* Expected Interrupt Level (for execution) :
130*
131* IRQL_PASSIVE_LEVEL
132*
133* Return Value: must be STATUS_SUCCESS
134*
135*************************************************************************/
138 PtrUDFIrpContext PtrIrpContext,
139 PIRP Irp
140 )
141{
147 PVCB Vcb = NULL;
148// PERESOURCE PtrResourceAcquired = NULL;
149 BOOLEAN AcquiredVcb = FALSE;
150 BOOLEAN AcquiredGD = FALSE;
152 ULONG i = 0;
153// ULONG clean_stat = 0;
154
155// BOOLEAN CompleteIrp = TRUE;
156 BOOLEAN PostRequest = FALSE;
157
158#ifdef UDF_DBG
159 UNICODE_STRING CurName;
160 PDIR_INDEX_HDR DirNdx;
161#endif
162
163 AdPrint(("UDFCommonClose: \n"));
164
165 _SEH2_TRY {
166 if (Irp) {
167
168 // If this is the first (IOManager) request
169 // First, get a pointer to the current I/O stack location
171 ASSERT(IrpSp);
172
175
176 // Get the FCB and CCB pointers
177 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
178 ASSERT(Ccb);
179 if(Ccb->CCBFlags & UDF_CCB_READ_ONLY) {
181 }
182 Fcb = Ccb->Fcb;
183 } else {
184 // If this is a queued call (for our dispatch)
185 // Get saved Fcb address
186 Fcb = PtrIrpContext->Fcb;
187 i = PtrIrpContext->TreeLength;
188 }
189
190 ASSERT(Fcb);
191 Vcb = (PVCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
192 ASSERT(Vcb);
193 ASSERT(Vcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
194// Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
195
196 // Steps we shall take at this point are:
197 // (a) Acquire the VCB shared
198 // (b) Acquire the FCB's CCB list exclusively
199 // (c) Delete the CCB structure (free memory)
200 // (d) If this is the last close, release the FCB structure
201 // (unless we keep these around for "delayed close" functionality.
202 // Note that it is often the case that the close dispatch entry point is invoked
203 // in the most inconvenient of situations (when it is not possible, for example,
204 // to safely acquire certain required resources without deadlocking or waiting).
205 // Therefore, be extremely careful in implementing this close dispatch entry point.
206 // Also note that we do not have the option of returning a failure code from the
207 // close dispatch entry point; the system expects that the close will always succeed.
208
209 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
210 AcquiredVcb = TRUE;
211
212 // Is this is the first (IOManager) request ?
213 if (Irp) {
214 PtrIrpContext->TreeLength =
215 i = Ccb->TreeLength;
216 // remember the number of incomplete Close requests
217 InterlockedIncrement((PLONG)&(Fcb->CcbCount));
218 // we can release CCB in any case
220 FileObject->FsContext2 = NULL;
221#ifdef DBG
222/* } else {
223 ASSERT(Fcb->NTRequiredFCB);
224 if(Fcb->NTRequiredFCB) {
225 ASSERT(Fcb->NTRequiredFCB->FileObject);
226 if(Fcb->NTRequiredFCB->FileObject) {
227 ASSERT(!Fcb->NTRequiredFCB->FileObject->FsContext2);
228 }
229 }*/
230#endif //DBG
231 }
232
233#ifdef UDF_DELAYED_CLOSE
234 // check if this is the last Close (no more Handles)
235 // and try to Delay it....
236 if((Fcb->FCBFlags & UDF_FCB_DELAY_CLOSE) &&
237 (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) &&
238 !(Vcb->VCBFlags & UDF_VCB_FLAGS_NO_DELAYED_CLOSE) &&
239 !(Fcb->OpenHandleCount)) {
240 UDFReleaseResource(&(Vcb->VCBResource));
241 AcquiredVcb = FALSE;
242 if((RC = UDFQueueDelayedClose(PtrIrpContext,Fcb)) == STATUS_SUCCESS)
244 // do standard Close if we can't Delay this opeartion
245 AdPrint((" Cant queue Close Irp, status=%x\n", RC));
246 }
247#endif //UDF_DELAYED_CLOSE
248
249 if(Irp) {
250 // We should post actual procesing if this is a recursive call
251 if((PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_NOT_TOP_LEVEL) ||
252 (Fcb->NTRequiredFCB->AcqFlushCount)) {
253 AdPrint((" post NOT_TOP_LEVEL Irp\n"));
254 PostRequest = TRUE;
256 }
257 }
258
259 // Close request is near completion, Vcb is acquired.
260 // Now we can safely decrease CcbCount, because no Rename
261 // operation can run until Vcb release.
262 InterlockedDecrement((PLONG)&(Fcb->CcbCount));
263
264 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
265 if(PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_READ_ONLY)
266 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCountRO));
267
268 if(!i || (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB)) {
269
270 AdPrint(("UDF: Closing volume\n"));
271 AdPrint(("UDF: ReferenceCount: %x\n",Fcb->ReferenceCount));
272
273 if (Vcb->VCBOpenCount > UDF_RESIDUAL_REFERENCE) {
274 ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
275 UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
276 ASSERT(Fcb->NTRequiredFCB);
277 UDFInterlockedDecrement((PLONG)&(Fcb->NTRequiredFCB->CommonRefCount));
278
280 }
281
282 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
283
284 if(AcquiredVcb) {
285 UDFReleaseResource(&(Vcb->VCBResource));
286 AcquiredVcb = FALSE;
287 } else {
288 BrutePoint();
289 }
290 // Acquire GlobalDataResource
291 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
292 AcquiredGD = TRUE;
293// // Acquire Vcb
294 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
295 AcquiredVcb = TRUE;
296
297 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
298
299
300 ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
301 UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
302 ASSERT(Fcb->NTRequiredFCB);
303 UDFInterlockedDecrement((PLONG)&(Fcb->NTRequiredFCB->CommonRefCount));
304
305 //AdPrint(("UDF: Closing volume, reset driver (e.g. stop BGF)\n"));
306 //UDFResetDeviceDriver(Vcb, Vcb->TargetDeviceObject, FALSE);
307
308 AdPrint(("UDF: Closing volume, reset write status\n"));
309 RC = UDFPhSendIOCTL(IOCTL_CDRW_RESET_WRITE_STATUS, Vcb->TargetDeviceObject,
310 NULL, 0, NULL, 0, TRUE, NULL);
311
312 if((Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) ||
313 ((!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) && (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE))) {
314 // Try to KILL dismounted volume....
315 // w2k requires this, NT4 - recomends
316 AcquiredVcb = UDFCheckForDismount(PtrIrpContext, Vcb, TRUE);
317 }
318
320 }
321
322 fi = Fcb->FileInfo;
323#ifdef UDF_DBG
324 if(!fi) {
325 BrutePoint();
326 }
327
328 DirNdx = UDFGetDirIndexByFileInfo(fi);
329 if(DirNdx) {
330 CurName.Buffer = UDFDirIndex(DirNdx,fi->Index)->FName.Buffer;
331 if(CurName.Buffer) {
332 AdPrint(("Closing file: %ws %8.8x\n", CurName.Buffer, FileObject));
333 } else {
334 AdPrint(("Closing file: ??? \n"));
335 }
336 }
337 AdPrint(("UDF: ReferenceCount: %x\n",Fcb->ReferenceCount));
338#endif // UDF_DBG
339 // try to clean up as long chain as it is possible
341
342try_exit: NOTHING;
343
344 } _SEH2_FINALLY {
345
346 if(AcquiredVcb) {
347 UDFReleaseResource(&(Vcb->VCBResource));
348 }
349 if(AcquiredGD) {
350 UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
351 }
352
353 // Post IRP if required
354 if (PostRequest) {
355
356 // Perform the post operation & complete the IRP
357 // if this is first call of UDFCommonClose
358 // and will return STATUS_SUCCESS back to us
359 PtrIrpContext->Irp = NULL;
360 PtrIrpContext->Fcb = Fcb;
361 UDFPostRequest(PtrIrpContext, NULL);
362 }
363
365 // If this is not async close complete the IRP
366 if (Irp) {
367/* if( FileObject ) {
368 if(clean_stat & UDF_CLOSE_NTREQFCB_DELETED) {
369// ASSERT(!FileObject->FsContext2);
370 FileObject->FsContext = NULL;
371#ifdef DBG
372 } else {
373 UDFNTRequiredFCB* NtReqFcb = ((UDFNTRequiredFCB*)(FileObject->FsContext));
374 if(NtReqFcb->FileObject == FileObject) {
375 NtReqFcb->FileObject = NULL;
376 }
377#endif //DBG
378 }
379 }*/
380 Irp->IoStatus.Status = STATUS_SUCCESS;
381 Irp->IoStatus.Information = 0;
383 }
384 // Free up the Irp Context
385 if(!PostRequest)
386 UDFReleaseIrpContext(PtrIrpContext);
387 }
388
389 } _SEH2_END; // end of "__finally" processing
390
391 return STATUS_SUCCESS ;
392} // end UDFCommonClose()
393
394/*
395 This routine walks through the tree to RootDir & kills all unreferenced
396 structures....
397 imho, Useful feature
398 */
399ULONG
401 IN PVCB Vcb,
403 IN ULONG TreeLength,
404 IN BOOLEAN VcbAcquired
405 )
406{
409 PUDF_FILE_INFO ParentFI;
411 ULONG CleanCode;
412 LONG RefCount, ComRefCount;
414 ULONG ret_val = 0;
415
417 AdPrint(("UDFCleanUpFcbChain\n"));
418
419 ASSERT(TreeLength);
420
421 // we can't process Tree until we can acquire Vcb
422 if(!VcbAcquired)
423 UDFAcquireResourceShared(&(Vcb->VCBResource),TRUE);
424
425 // cleanup parent chain (if any & unused)
426 while(fi) {
427
428 // acquire parent
429 if((ParentFI = fi->ParentFile)) {
430 ASSERT(fi->Fcb);
431 ParentFcb = fi->Fcb->ParentFcb;
433 ASSERT(ParentFcb->NTRequiredFCB);
436 } else {
437 // we get to RootDir, it has no parent
438 if(!VcbAcquired)
439 UDFAcquireResourceShared(&(Vcb->VCBResource),TRUE);
440 }
441 Fcb = fi->Fcb;
442 ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_FCB);
443
444 NtReqFcb = Fcb->NTRequiredFCB;
445 ASSERT(NtReqFcb->CommonFCBHeader.NodeTypeCode == UDF_NODE_TYPE_NT_REQ_FCB);
446
447 // acquire current file/dir
448 // we must assure that no more threads try to re-use this object
449#ifdef UDF_DBG
450 _SEH2_TRY {
451#endif // UDF_DBG
453 UDFAcquireResourceExclusive(&(NtReqFcb->MainResource),TRUE);
454#ifdef UDF_DBG
456 BrutePoint();
457 if(ParentFI) {
459 UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
460 } else {
461 if(!VcbAcquired)
462 UDFReleaseResource(&(Vcb->VCBResource));
463 }
464 break;
465 } _SEH2_END;
466#endif // UDF_DBG
467 ASSERT_REF((Fcb->ReferenceCount > fi->RefCount) || !TreeLength);
468 // If we haven't pass through all files opened
469 // in UDFCommonCreate before target file (TreeLength specfies
470 // the number of such files) dereference them.
471 // Otherwise we'll just check if the file has no references.
472#ifdef UDF_DBG
473 if(Fcb) {
474 if(TreeLength) {
475 ASSERT(Fcb->ReferenceCount);
476 ASSERT(NtReqFcb->CommonRefCount);
477 RefCount = UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
478 ComRefCount = UDFInterlockedDecrement((PLONG)&(NtReqFcb->CommonRefCount));
479 }
480 } else {
481 BrutePoint();
482 }
483 if(TreeLength)
484 TreeLength--;
485 ASSERT(Fcb->OpenHandleCount <= Fcb->ReferenceCount);
486#else
487 if(TreeLength) {
488 RefCount = UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
489 ComRefCount = UDFInterlockedDecrement((PLONG)&(NtReqFcb->CommonRefCount));
490 TreeLength--;
491 }
492#endif
493
494/* if(Fcb && Fcb->FCBName && Fcb->FCBName->ObjectName.Buffer) {
495 AdPrint((" %ws (%x)\n",
496 Fcb->FCBName->ObjectName.Buffer,Fcb->ReferenceCount));
497 } else if (Fcb) {
498 AdPrint((" ??? (%x)\n",Fcb->ReferenceCount));
499 } else {
500 AdPrint((" ??? (??)\n"));
501 }*/
502 // ...and delete if it has gone
503
504 if(!RefCount && !Fcb->OpenHandleCount) {
505 // no more references... current file/dir MUST DIE!!!
506 BOOLEAN AutoInherited = UDFIsAStreamDir(fi) || UDFIsAStream(fi);
507
508 if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
509 // do nothing
510 } else
511#ifndef UDF_READ_ONLY_BUILD
512 if(Delete) {
513/* if(!(Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
514 // set file size to zero (for UdfInfo package)
515 // we should not do this for directories
516 UDFResizeFile__(Vcb, fi, 0);
517 }*/
519 ASSERT(Fcb->ReferenceCount < fi->RefCount);
520 UDFFlushFile__(Vcb, fi);
522 UDFCloseFile__(Vcb, fi);
523 ASSERT(Fcb->ReferenceCount == fi->RefCount);
524 Fcb->FCBFlags |= UDF_FCB_DELETED;
525 Delete = FALSE;
526 } else
527#endif //UDF_READ_ONLY_BUILD
528 if(!(Fcb->FCBFlags & UDF_FCB_DELETED)) {
529 UDFFlushFile__(Vcb, fi);
530 } else {
531// BrutePoint();
532 }
533#ifndef UDF_READ_ONLY_BUILD
534 // check if we should try to delete Parent for the next time
535 if(Fcb->FCBFlags & UDF_FCB_DELETE_PARENT)
536 Delete = TRUE;
537#endif //UDF_READ_ONLY_BUILD
538
539 // remove references to OS-specific structures
540 // to let UDF_INFO release FI & Co
541 fi->Fcb = NULL;
542 if(!ComRefCount) {
543 // CommonFcb is also completly dereferenced
544 // Kill it!
545 fi->Dloc->CommonFcb = NULL;
546 }
547
548 if((CleanCode = UDFCleanUpFile__(Vcb, fi))) {
549 // Check, if we can uninitialize & deallocate CommonFcb part
550 // kill some cross links
551 Fcb->FileInfo = NULL;
552 // release allocated resources
553 if(CleanCode & UDF_FREE_DLOC) {
554 // Obviously, it is a good time & place to release
555 // CommonFcb structure
556
557// NtReqFcb->NtReqFCBFlags &= ~UDF_NTREQ_FCB_VALID;
558 // Unitialize byte-range locks support structure
560 // Remove resources
562 UDFReleaseResource(&(NtReqFcb->MainResource));
563 if(NtReqFcb->CommonFCBHeader.Resource) {
564 UDFDeleteResource(&(NtReqFcb->MainResource));
565 UDFDeleteResource(&(NtReqFcb->PagingIoResource));
566 }
567 NtReqFcb->CommonFCBHeader.Resource =
568 NtReqFcb->CommonFCBHeader.PagingIoResource = NULL;
569 UDFDeassignAcl(NtReqFcb, AutoInherited);
570 UDFPrint(("UDFReleaseNtReqFCB: %x\n", NtReqFcb));
571#ifdef DBG
572// NtReqFcb->FileObject->FsContext2 = NULL;
573// ASSERT(NtReqFcb->FileObject);
574/* if(NtReqFcb->FileObject) {
575 ASSERT(!NtReqFcb->FileObject->FsContext2);
576 NtReqFcb->FileObject->FsContext = NULL;
577 NtReqFcb->FileObject->SectionObjectPointer = NULL;
578 }*/
579#endif //DBG
582 } else {
583 // we usually get here when the file has some opened links
585 UDFReleaseResource(&(NtReqFcb->MainResource));
586 }
587 // remove some references & free Fcb structure
588 Fcb->NTRequiredFCB = NULL;
589 Fcb->ParentFcb = NULL;
591 MyFreePool__(fi);
592 ret_val |= UDF_CLOSE_FCB_DELETED;
593 // get pointer to parent FCB
594 fi = ParentFI;
595 // free old parent's resource...
596 if(fi) {
598 UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
599 } else {
600 if(!VcbAcquired)
601 UDFReleaseResource(&(Vcb->VCBResource));
602 }
603 } else {
604 // Stop cleaning up
605
606 // Restore pointers
607 fi->Fcb = Fcb;
608 fi->Dloc->CommonFcb = NtReqFcb;
609 // free all acquired resources
611 UDFReleaseResource(&(NtReqFcb->MainResource));
612 fi = ParentFI;
613 if(fi) {
615 UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
616 } else {
617 if(!VcbAcquired)
618 UDFReleaseResource(&(Vcb->VCBResource));
619 }
620 // If we have dereferenced all parents 'associated'
621 // with input file & current file is still in use
622 // then it isn't worth walking down the tree
623 // 'cause in this case all the rest files are also used
624 if(!TreeLength)
625 break;
626// AdPrint(("Stop on referenced File/Dir\n"));
627 }
628 } else {
629 // we get to referenced file/dir. Stop search & release resource
631 UDFReleaseResource(&(NtReqFcb->MainResource));
632 if(ParentFI) {
634 UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
635 } else {
636 if(!VcbAcquired)
637 UDFReleaseResource(&(Vcb->VCBResource));
638 }
639 Delete = FALSE;
640 if(!TreeLength)
641 break;
642 fi = ParentFI;
643 }
644 }
645 if(fi) {
646 Fcb = fi->Fcb;
647 for(;TreeLength && fi;TreeLength--) {
648 if(Fcb) {
650 ASSERT(Fcb->ReferenceCount);
651 ASSERT(Fcb->NTRequiredFCB->CommonRefCount);
652 ASSERT_REF(Fcb->ReferenceCount > fi->RefCount);
653 UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
654 UDFInterlockedDecrement((PLONG)&(Fcb->NTRequiredFCB->CommonRefCount));
655#ifdef UDF_DBG
656 } else {
657 BrutePoint();
658#endif
659 }
660 Fcb = ParentFcb;
661 }
662 }
663 if(!VcbAcquired)
664 UDFReleaseResource(&(Vcb->VCBResource));
665 return ret_val;
666
667} // end UDFCleanUpFcbChain()
668
669VOID
671 IN PtrUDFIrpContextLite NextIrpContextLite
672 )
673{
674 PtrUDFIrpContext IrpContext;
675
676 AdPrint((" UDFDoDelayedClose\n"));
677 UDFInitializeIrpContextFromLite(&IrpContext,NextIrpContextLite);
678 IrpContext->Fcb->IrpContextLite = NULL;
679 MyFreePool__(NextIrpContextLite);
680 IrpContext->Fcb->FCBFlags &= ~UDF_FCB_DELAY_CLOSE;
681 UDFCommonClose(IrpContext,NULL);
682} // end UDFDoDelayedClose()
683
684/*
685 This routine removes request from Delayed Close queue.
686 It operates until reach lower threshold
687 */
688VOID
689NTAPI
692 )
693{
695 PtrUDFIrpContextLite NextIrpContextLite;
696
697 AdPrint((" UDFDelayedClose\n"));
698 // Acquire DelayedCloseResource
699 UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
700
701 while (UDFGlobalData.ReduceDelayedClose &&
702 (UDFGlobalData.DelayedCloseCount > UDFGlobalData.MinDelayedCloseCount)) {
703
704 Entry = UDFGlobalData.DelayedCloseQueue.Flink;
705
706 if (!IsListEmpty(Entry)) {
707 // Extract the IrpContext.
708 NextIrpContextLite = CONTAINING_RECORD( Entry,
710 DelayedCloseLinks );
711
713 UDFGlobalData.DelayedCloseCount--;
714 UDFDoDelayedClose(NextIrpContextLite);
715 } else {
716 BrutePoint();
717 }
718 }
719
720 while (UDFGlobalData.ReduceDirDelayedClose &&
721 (UDFGlobalData.DirDelayedCloseCount > UDFGlobalData.MinDirDelayedCloseCount)) {
722
723 Entry = UDFGlobalData.DirDelayedCloseQueue.Flink;
724
725 if (!IsListEmpty(Entry)) {
726 // Extract the IrpContext.
727 NextIrpContextLite = CONTAINING_RECORD( Entry,
729 DelayedCloseLinks );
730
732 UDFGlobalData.DirDelayedCloseCount--;
733 UDFDoDelayedClose(NextIrpContextLite);
734 } else {
735 BrutePoint();
736 }
737 }
738
739 UDFGlobalData.FspCloseActive = FALSE;
740 UDFGlobalData.ReduceDelayedClose = FALSE;
741 UDFGlobalData.ReduceDirDelayedClose = FALSE;
742
743 // Release DelayedCloseResource
744 UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
745
746 return;
747} // end UDFDelayedClose()
748
749/*
750 This routine performs Close operation for all files from
751 Delayed Close queue.
752 */
753VOID
755 IN PVCB Vcb
756 )
757{
759 PtrUDFIrpContextLite NextIrpContextLite;
760 BOOLEAN GlobalDataAcquired = FALSE;
761
762 AdPrint((" UDFCloseAllDelayed\n"));
763 // Acquire DelayedCloseResource
764 if (!ExIsResourceAcquiredExclusive(&UDFGlobalData.GlobalDataResource)) {
765 UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
766 GlobalDataAcquired = TRUE;
767 }
768
769 Entry = UDFGlobalData.DelayedCloseQueue.Flink;
770
771 while (Entry != &UDFGlobalData.DelayedCloseQueue) {
772 // Extract the IrpContext.
773 NextIrpContextLite = CONTAINING_RECORD( Entry,
775 DelayedCloseLinks );
776 Entry = Entry->Flink;
777 if (NextIrpContextLite->Fcb->Vcb == Vcb) {
778 RemoveEntryList( &(NextIrpContextLite->DelayedCloseLinks) );
779 UDFGlobalData.DelayedCloseCount--;
780 UDFDoDelayedClose(NextIrpContextLite);
781 }
782 }
783
784 Entry = UDFGlobalData.DirDelayedCloseQueue.Flink;
785
786 while (Entry != &UDFGlobalData.DirDelayedCloseQueue) {
787 // Extract the IrpContext.
788 NextIrpContextLite = CONTAINING_RECORD( Entry,
790 DelayedCloseLinks );
791 Entry = Entry->Flink;
792 if (NextIrpContextLite->Fcb->Vcb == Vcb) {
793 RemoveEntryList( &(NextIrpContextLite->DelayedCloseLinks) );
794 UDFGlobalData.DirDelayedCloseCount--;
795 UDFDoDelayedClose(NextIrpContextLite);
796 }
797 }
798
799 // Release DelayedCloseResource
800 if(GlobalDataAcquired)
801 UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
802
803} // end UDFCloseAllDelayed()
804
807 IN PVCB Vcb,
809 IN PCHECK_TREE_ITEM CheckItemProc,
810 IN PUDF_FILE_INFO** PassedList,
811 IN PULONG PassedListSize,
812 IN PUDF_FILE_INFO** FoundList,
813 IN PULONG FoundListSize
814 )
815{
816 PDIR_INDEX_HDR hDirNdx;
817 PUDF_FILE_INFO SDirInfo;
818 ULONG i;
819
820 UDFPrint((" UDFBuildTreeItemsList():\n"));
821 if(!(*PassedList) || !(*FoundList)) {
822
823 (*PassedList) = (PUDF_FILE_INFO*)
825 if(!(*PassedList))
827 (*PassedListSize) = 0;
828
829 (*FoundList) = (PUDF_FILE_INFO*)
831 if(!(*FoundList)) {
832 MyFreePool__(*PassedList);
833 *PassedList = NULL;
835 }
836 (*FoundListSize) = 0;
837 }
838
839 // check if already passed
840 for(i=0;i<(*PassedListSize);i++) {
841 if( ((*PassedList)[i]) == FileInfo )
842 return STATUS_SUCCESS;
843 }
844 // remember passed object
845 // we should not proceed linked objects twice
846 (*PassedListSize)++;
847 if( !((*PassedListSize) & (TREE_ITEM_LIST_GRAN - 1)) ) {
848 if(!MyReallocPool__((PCHAR)(*PassedList), (*PassedListSize)*sizeof(PUDF_FILE_INFO),
849 (PCHAR*)PassedList, ((*PassedListSize)+TREE_ITEM_LIST_GRAN)*sizeof(PUDF_FILE_INFO))) {
851 }
852 }
853 (*PassedList)[(*PassedListSize)-1] = FileInfo;
854
855 // check if this object matches our conditions
856 if(CheckItemProc(FileInfo)) {
857 // remember matched object
858 (*FoundListSize)++;
859 if( !((*FoundListSize) & (TREE_ITEM_LIST_GRAN - 1)) ) {
860 if(!MyReallocPool__((PCHAR)(*FoundList), (*FoundListSize)*sizeof(PUDF_DATALOC_INFO),
861 (PCHAR*)FoundList, ((*FoundListSize)+TREE_ITEM_LIST_GRAN)*sizeof(PUDF_DATALOC_INFO))) {
863 }
864 }
865 (*FoundList)[(*FoundListSize)-1] = FileInfo;
866 }
867
868 // walk through SDir (if any)
869 if((SDirInfo = FileInfo->Dloc->SDirInfo))
870 UDFBuildTreeItemsList(Vcb, SDirInfo, CheckItemProc,
871 PassedList, PassedListSize, FoundList, FoundListSize);
872
873 // walk through subsequent objects (if any)
874 if((hDirNdx = FileInfo->Dloc->DirIndex)) {
875
876 // scan DirIndex
877 UDF_DIR_SCAN_CONTEXT ScanContext;
878 PDIR_INDEX_ITEM DirNdx;
879 PUDF_FILE_INFO CurFileInfo;
880
881 if(UDFDirIndexInitScan(FileInfo, &ScanContext, 2)) {
882 while((DirNdx = UDFDirIndexScan(&ScanContext, &CurFileInfo))) {
883 if(!CurFileInfo)
884 continue;
885 UDFBuildTreeItemsList(Vcb, CurFileInfo, CheckItemProc,
886 PassedList, PassedListSize, FoundList, FoundListSize);
887 }
888 }
889
890 }
891 return STATUS_SUCCESS;
892} // end UDFBuildTreeItemsList()
893
897{
899 return (FileInfo->Fcb && FileInfo->Fcb->IrpContextLite);
900} // end UDFIsInDelayedCloseQueue()
901
905{
907 PtrUDFFCB Fcb = FileInfo->Fcb;
908 if( Fcb &&
910 Fcb->ReferenceCount &&
911 Fcb->NTRequiredFCB->SectionObject.DataSectionObject) {
912 return TRUE;
913 }
914 return FALSE;
915} // UDFIsLastClose()
916
919 IN PVCB Vcb,
921 IN BOOLEAN System
922 )
923{
924 PUDF_FILE_INFO* PassedList = NULL;
925 ULONG PassedListSize = 0;
926 PUDF_FILE_INFO* FoundList = NULL;
927 ULONG FoundListSize = 0;
928 NTSTATUS RC;
929 ULONG i;
931 _SEH2_VOLATILE BOOLEAN AcquiredVcb = FALSE;
933 PUDF_FILE_INFO CurFileInfo;
934 PFE_LIST_ENTRY CurListPtr;
935 PFE_LIST_ENTRY* ListPtrArray = NULL;
936
937 _SEH2_TRY {
938
939 UDFPrint((" UDFCloseAllXXXDelayedInDir(): Acquire DelayedCloseResource\n"));
940 // Acquire DelayedCloseResource
941 UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
942 ResAcq = TRUE;
943
944 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
945 AcquiredVcb = TRUE;
946
949 &PassedList, &PassedListSize, &FoundList, &FoundListSize);
950
951 if(!NT_SUCCESS(RC)) {
952 UDFPrint((" UDFBuildTreeItemsList(): error %x\n", RC));
953 try_return(RC);
954 }
955
956 if(!FoundList || !FoundListSize) {
958 }
959
960 // build array of referenced pointers
961 ListPtrArray = (PFE_LIST_ENTRY*)(MyAllocatePool__(NonPagedPool, FoundListSize*sizeof(PFE_LIST_ENTRY)));
962 if(!ListPtrArray) {
963 UDFPrint((" Can't alloc ListPtrArray for %x items\n", FoundListSize));
965 }
966
967 for(i=0;i<FoundListSize;i++) {
968
969 _SEH2_TRY {
970
971 CurFileInfo = FoundList[i];
972 if(!CurFileInfo->ListPtr) {
974 if(!CurFileInfo->ListPtr) {
975 UDFPrint((" Can't alloc ListPtrEntry for items %x\n", i));
977 }
978 CurFileInfo->ListPtr->FileInfo = CurFileInfo;
979 CurFileInfo->ListPtr->EntryRefCount = 0;
980 }
981 CurFileInfo->ListPtr->EntryRefCount++;
982 ListPtrArray[i] = CurFileInfo->ListPtr;
983
985 BrutePoint();
986 } _SEH2_END;
987 }
988
989 UDFReleaseResource(&(Vcb->VCBResource));
990 AcquiredVcb = FALSE;
991
992 if(System) {
993 // Remove from system queue
996 BOOLEAN NoDelayed = (Vcb->VCBFlags & UDF_VCB_FLAGS_NO_DELAYED_CLOSE) ?
997 TRUE : FALSE;
998
1000 for(i=FoundListSize;i>0;i--) {
1001 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
1002 AcquiredVcb = TRUE;
1003 _SEH2_TRY {
1004
1005 CurListPtr = ListPtrArray[i-1];
1006 CurFileInfo = CurListPtr->FileInfo;
1007 if(CurFileInfo &&
1008 (Fcb = CurFileInfo->Fcb)) {
1009 NtReqFcb = Fcb->NTRequiredFCB;
1010 ASSERT((ULONG_PTR)NtReqFcb > 0x1000);
1011// ASSERT((ULONG)(NtReqFcb->SectionObject) > 0x1000);
1012 if(!(NtReqFcb->NtReqFCBFlags & UDF_NTREQ_FCB_DELETED) &&
1013 (NtReqFcb->NtReqFCBFlags & UDF_NTREQ_FCB_MODIFIED)) {
1014 MmPrint((" CcFlushCache()\n"));
1015 CcFlushCache(&(NtReqFcb->SectionObject), NULL, 0, &IoStatus);
1016 }
1017 if(NtReqFcb->SectionObject.ImageSectionObject) {
1018 MmPrint((" MmFlushImageSection()\n"));
1019 MmFlushImageSection(&(NtReqFcb->SectionObject), MmFlushForWrite);
1020 }
1021 if(NtReqFcb->SectionObject.DataSectionObject) {
1022 MmPrint((" CcPurgeCacheSection()\n"));
1023 CcPurgeCacheSection( &(NtReqFcb->SectionObject), NULL, 0, FALSE );
1024 }
1025 } else {
1026 MmPrint((" Skip item: deleted\n"));
1027 }
1028 CurListPtr->EntryRefCount--;
1029 if(!CurListPtr->EntryRefCount) {
1030 if(CurListPtr->FileInfo)
1031 CurListPtr->FileInfo->ListPtr = NULL;
1032 MyFreePool__(CurListPtr);
1033 }
1035 BrutePoint();
1036 } _SEH2_END;
1037 UDFReleaseResource(&(Vcb->VCBResource));
1038 AcquiredVcb = FALSE;
1039 }
1040 if(!NoDelayed)
1041 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_NO_DELAYED_CLOSE;
1042 } else {
1043 // Remove from internal queue
1044 PtrUDFIrpContextLite NextIrpContextLite;
1045
1046 for(i=FoundListSize;i>0;i--) {
1047
1048 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
1049 AcquiredVcb = TRUE;
1050
1051 CurListPtr = ListPtrArray[i-1];
1052 CurFileInfo = CurListPtr->FileInfo;
1053
1054 if(CurFileInfo &&
1055 CurFileInfo->Fcb &&
1056 (NextIrpContextLite = CurFileInfo->Fcb->IrpContextLite)) {
1057 RemoveEntryList( &(NextIrpContextLite->DelayedCloseLinks) );
1058 if (NextIrpContextLite->Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
1059// BrutePoint();
1060 UDFGlobalData.DirDelayedCloseCount--;
1061 } else {
1062 UDFGlobalData.DelayedCloseCount--;
1063 }
1064 UDFDoDelayedClose(NextIrpContextLite);
1065 }
1066 CurListPtr->EntryRefCount--;
1067 if(!CurListPtr->EntryRefCount) {
1068 if(CurListPtr->FileInfo)
1069 CurListPtr->FileInfo->ListPtr = NULL;
1070 MyFreePool__(CurListPtr);
1071 }
1072 UDFReleaseResource(&(Vcb->VCBResource));
1073 AcquiredVcb = FALSE;
1074 }
1075 }
1076 RC = STATUS_SUCCESS;
1077
1078try_exit: NOTHING;
1079
1080 } _SEH2_FINALLY {
1081 // release Vcb
1082 if(AcquiredVcb)
1083 UDFReleaseResource(&(Vcb->VCBResource));
1084 // Release DelayedCloseResource
1085 if(ResAcq)
1086 UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
1087
1088 if(ListPtrArray)
1089 MyFreePool__(ListPtrArray);
1090 if(PassedList)
1091 MyFreePool__(PassedList);
1092 if(FoundList)
1093 MyFreePool__(FoundList);
1094 } _SEH2_END;
1095
1096 return RC;
1097} // end UDFCloseAllXXXDelayedInDir(
1098
1099
1100/*
1101 This routine adds request to Delayed Close queue.
1102 If number of queued requests exceeds higher threshold it fires
1103 UDFDelayedClose()
1104 */
1107 PtrUDFIrpContext IrpContext,
1109 )
1110{
1111 PtrUDFIrpContextLite IrpContextLite;
1112 BOOLEAN StartWorker = FALSE;
1113 _SEH2_VOLATILE BOOLEAN AcquiredVcb = FALSE;
1114 NTSTATUS RC;
1115
1116 AdPrint((" UDFQueueDelayedClose\n"));
1117
1118 _SEH2_TRY {
1119 // Acquire DelayedCloseResource
1120 UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
1121
1122 UDFAcquireResourceShared(&(Fcb->Vcb->VCBResource), TRUE);
1123 AcquiredVcb = TRUE;
1124
1125 if(Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE) {
1127 }
1128
1129 if(Fcb->IrpContextLite ||
1130 Fcb->FCBFlags & UDF_FCB_POSTED_RENAME) {
1131// BrutePoint();
1133 }
1134
1135 if(!NT_SUCCESS(RC = UDFInitializeIrpContextLite(&IrpContextLite,IrpContext,Fcb))) {
1136 try_return(RC);
1137 }
1138
1139 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
1140 InsertTailList( &UDFGlobalData.DirDelayedCloseQueue,
1141 &IrpContextLite->DelayedCloseLinks );
1142 UDFGlobalData.DirDelayedCloseCount++;
1143 } else {
1144 InsertTailList( &UDFGlobalData.DelayedCloseQueue,
1145 &IrpContextLite->DelayedCloseLinks );
1146 UDFGlobalData.DelayedCloseCount++;
1147 }
1148 Fcb->IrpContextLite = IrpContextLite;
1149
1150 // If we are above our threshold then start the delayed
1151 // close operation.
1152 if(UDFGlobalData.DelayedCloseCount > UDFGlobalData.MaxDelayedCloseCount) {
1153
1154 UDFGlobalData.ReduceDelayedClose = TRUE;
1155
1156 if(!UDFGlobalData.FspCloseActive) {
1157
1158 UDFGlobalData.FspCloseActive = TRUE;
1159 StartWorker = TRUE;
1160 }
1161 }
1162 // If we are above our threshold then start the delayed
1163 // close operation.
1164 if(UDFGlobalData.DirDelayedCloseCount > UDFGlobalData.MaxDirDelayedCloseCount) {
1165
1166 UDFGlobalData.ReduceDirDelayedClose = TRUE;
1167
1168 if(!UDFGlobalData.FspCloseActive) {
1169
1170 UDFGlobalData.FspCloseActive = TRUE;
1171 StartWorker = TRUE;
1172 }
1173 }
1174 // Start the FspClose thread if we need to.
1175 if(StartWorker) {
1177 }
1178 RC = STATUS_SUCCESS;
1179
1180try_exit: NOTHING;
1181
1182 } _SEH2_FINALLY {
1183
1184 if(!NT_SUCCESS(RC)) {
1185 Fcb->FCBFlags &= ~UDF_FCB_DELAY_CLOSE;
1186 }
1187 if(AcquiredVcb) {
1188 UDFReleaseResource(&(Fcb->Vcb->VCBResource));
1189 }
1190 // Release DelayedCloseResource
1191 UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
1192 } _SEH2_END;
1193 return RC;
1194} // end UDFQueueDelayedClose()
1195
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
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 ParentFcb
Definition: cdprocs.h:736
_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
#define IOCTL_CDRW_RESET_WRITE_STATUS
Definition: cdrw_usr.h:102
struct _VCB * PVCB
Definition: fatstruc.h:557
VOID NTAPI UDFDelayedClose(PVOID unused)
Definition: close.cpp:690
NTSTATUS UDFCloseAllXXXDelayedInDir(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN System)
Definition: close.cpp:918
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
NTSTATUS NTAPI UDFClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: close.cpp:62
NTSTATUS UDFQueueDelayedClose(PtrUDFIrpContext IrpContext, PtrUDFFCB Fcb)
Definition: close.cpp:1106
VOID UDFDoDelayedClose(IN PtrUDFIrpContextLite NextIrpContextLite)
Definition: close.cpp:670
ULONG UDFCleanUpFcbChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: close.cpp:400
BOOLEAN(* PCHECK_TREE_ITEM)(IN PUDF_FILE_INFO FileInfo)
Definition: close.cpp:22
NTSTATUS UDFCommonClose(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: close.cpp:137
NTSTATUS UDFBuildTreeItemsList(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN PCHECK_TREE_ITEM CheckItemProc, IN PUDF_DATALOC_INFO **PassedList, IN PULONG PassedListSize, IN PUDF_DATALOC_INFO **FoundList, IN PULONG FoundListSize)
BOOLEAN UDFIsLastClose(PUDF_FILE_INFO FileInfo)
Definition: close.cpp:903
#define TREE_ITEM_LIST_GRAN
Definition: close.cpp:23
BOOLEAN UDFIsInDelayedCloseQueue(PUDF_FILE_INFO FileInfo)
Definition: close.cpp:895
_In_ PIRP Irp
Definition: csq.h:116
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:1092
PDIR_INDEX_ITEM UDFDirIndexScan(PUDF_DIR_SCAN_CONTEXT Context, PUDF_FILE_INFO *_FileInfo)
Definition: dirtree.cpp:378
BOOLEAN UDFDirIndexInitScan(IN PUDF_FILE_INFO DirInfo, OUT PUDF_DIR_SCAN_CONTEXT Context, IN uint_di Index)
Definition: dirtree.cpp:347
#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:33
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
VOID __fastcall UDFCleanUpFCB(PtrUDFFCB Fcb)
Definition: misc.cpp:908
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
VOID __fastcall UDFCleanUpCCB(PtrUDFCCB Ccb)
Definition: misc.cpp:805
VOID UDFInitializeIrpContextFromLite(OUT PtrUDFIrpContext *IrpContext, IN PtrUDFIrpContextLite IrpContextLite)
Definition: misc.cpp:2419
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
NTSTATUS UDFInitializeIrpContextLite(OUT PtrUDFIrpContextLite *IrpContextLite, IN PtrUDFIrpContext IrpContext, IN PtrUDFFCB Fcb)
Definition: misc.cpp:2457
NTSTATUS NTAPI UDFPhSendIOCTL(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
Definition: env_spec.cpp:511
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define ValidateFileInfo(fi)
Definition: env_spec_w32.h:516
#define UDFDeleteResource(Resource)
Definition: env_spec_w32.h:663
#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
#define UDFInterlockedDecrement(addr)
Definition: env_spec_w32.h:677
#define NonPagedPool
Definition: env_spec_w32.h:307
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
#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
#define NtReqFcb
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1279
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define 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
ULONG MyReallocPool__(PCHAR addr, ULONG len, PCHAR *pnewaddr, ULONG newlen)
Definition: mem_tools.h:230
#define ASSERT(a)
Definition: mode.c:44
WORD unused[29]
Definition: crypt.c:1155
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define BOOLEAN
Definition: pedump.c:73
long LONG
Definition: pedump.c:60
#define Vcb
Definition: cdprocs.h:1415
VOID UDFDeassignAcl(IN PtrUDFNTRequiredFCB NtReqFcb, IN BOOLEAN AutoInherited)
Definition: secursup.cpp:772
#define UDF_CLOSE_NTREQFCB_DELETED
Definition: protos.h:80
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:629
#define UDF_CLOSE_FCB_DELETED
Definition: protos.h:81
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:166
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#define _SEH2_VOLATILE
Definition: pseh2_64.h:169
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4361
#define STATUS_SUCCESS
Definition: shellext.h:65
base of all file and directory entries
Definition: entries.h:83
#define UDF_NODE_TYPE_NT_REQ_FCB
Definition: struct.h:57
#define UDF_IRP_CONTEXT_NOT_TOP_LEVEL
Definition: struct.h:390
#define UDF_CCB_READ_ONLY
Definition: struct.h:170
#define UDF_FCB_DELETED
Definition: struct.h:314
#define UDF_FCB_POSTED_RENAME
Definition: struct.h:317
struct _UDFContextControlBlock * PtrUDFCCB
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336
#define UDF_NTREQ_FCB_DELETED
Definition: struct.h:235
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDF_NTREQ_FCB_MODIFIED
Definition: struct.h:236
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define UDF_FCB_DELETE_ON_CLOSE
Definition: struct.h:309
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
#define UDF_IRP_CONTEXT_READ_ONLY
Definition: struct.h:394
#define UDF_FCB_DELETE_PARENT
Definition: struct.h:319
#define UDF_FCB_DELAY_CLOSE
Definition: struct.h:313
PVOID DeviceExtension
Definition: env_spec_w32.h:418
UNICODE_STRING FName
Definition: udf_rel.h:173
struct _FCB * ParentFcb
Definition: cdstruc.h:940
PVCB Vcb
Definition: cdstruc.h:933
LONG RefCount
Definition: ntfs.h:535
struct _FCB::@729::@732 Fcb
ULONG OpenHandleCount
Definition: ntfs.h:537
ERESOURCE MainResource
Definition: ntfs.h:528
Definition: udf_rel.h:414
ULONG EntryRefCount
Definition: udf_rel.h:416
PUDF_FILE_INFO FileInfo
Definition: udf_rel.h:415
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
Definition: typedefs.h:120
struct _UDFVolumeControlBlock * Vcb
Definition: struct.h:259
struct _UDFIrpContextLite * IrpContextLite
Definition: struct.h:291
LIST_ENTRY DelayedCloseLinks
Definition: struct.h:410
_UDFFileControlBlock * Fcb
Definition: struct.h:408
_UDFFileControlBlock * Fcb
Definition: struct.h:378
uint32 IrpContextFlags
Definition: struct.h:364
ULONG TreeLength
Definition: struct.h:379
PDEVICE_OBJECT TargetDeviceObject
Definition: struct.h:374
struct _FE_LIST_ENTRY * ListPtr
Definition: udf_rel.h:411
struct _UDFFileControlBlock * Fcb
Definition: udf_rel.h:362
struct _UDF_FILE_INFO * ParentFile
Definition: udf_rel.h:381
uint_di Index
Definition: udf_rel.h:392
Definition: cdstruc.h:498
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define UDF_VCB_FLAGS_NO_DELAYED_CLOSE
Definition: udf_common.h:480
#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_FLAGS_BEING_DISMOUNTED
Definition: udf_common.h:461
#define ASSERT_REF(_a_)
Definition: udf_dbg.h:267
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
OSSTATUS UDFFlushFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN ULONG FlushFlags)
Definition: udf_info.cpp:4119
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
OSSTATUS UDFUnlinkFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN FreeSpace)
Definition: udf_info.cpp:1766
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
#define UDFIsAStreamDir(FI)
Definition: udf_info.h:998
#define UDF_FREE_DLOC
Definition: udf_info.h:650
#define UDFIsAStream(FI)
Definition: udf_info.h:1002
struct _FE_LIST_ENTRY * PFE_LIST_ENTRY
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#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
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347
@ CriticalWorkQueue
Definition: extypes.h:189
#define IO_NO_INCREMENT
Definition: iotypes.h:598
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IO_DISK_INCREMENT
Definition: iotypes.h:600