ReactOS 0.4.15-dev-7674-gc0b4db1
fileinfo.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: Fileinfo.cpp
9*
10* Module: UDF File System Driver (Kernel mode execution only)
11*
12* Description:
13* Contains code to handle the "set/query file information" dispatch
14* entry points.
15*
16*************************************************************************/
17
18#include "udffs.h"
19
20// define the file specific bug-check id
21#define UDF_BUG_CHECK_ID UDF_FILE_INFORMATION
22
23#define MEM_USREN_TAG "US_Ren"
24#define MEM_USREN2_TAG "US_Ren2"
25#define MEM_USFIDC_TAG "US_FIDC"
26#define MEM_USHL_TAG "US_HL"
27
28/*************************************************************************
29*
30* Function: UDFFileInfo()
31*
32* Description:
33* The I/O Manager will invoke this routine to handle a set/query file
34* information request
35*
36* Expected Interrupt Level (for execution) :
37*
38* IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
39* to be deferred to a worker thread context)
40*
41* Return Value: STATUS_SUCCESS/Error
42*
43*************************************************************************/
47 PDEVICE_OBJECT DeviceObject, // the logical volume device object
48 PIRP Irp // I/O Request Packet
49 )
50{
52 PtrUDFIrpContext PtrIrpContext = NULL;
53 BOOLEAN AreWeTopLevel = FALSE;
54
55 TmPrint(("UDFFileInfo: \n"));
56
59 ASSERT(Irp);
60
61 // set the top level context
62 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
63 ASSERT(!UDFIsFSDevObj(DeviceObject));
64
65 _SEH2_TRY {
66
67 // get an IRP context structure and issue the request
68 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
69 if(PtrIrpContext) {
70 RC = UDFCommonFileInfo(PtrIrpContext, Irp);
71 } else {
73 Irp->IoStatus.Status = RC;
74 Irp->IoStatus.Information = 0;
75 // complete the IRP
77 }
78
80
81 RC = UDFExceptionHandler(PtrIrpContext, Irp);
82
84 } _SEH2_END;
85
86 if(AreWeTopLevel) {
88 }
89
91
92 return(RC);
93} // end UDFFileInfo()
94
95
96/*************************************************************************
97*
98* Function: UDFCommonFileInfo()
99*
100* Description:
101* The actual work is performed here. This routine may be invoked in one'
102* of the two possible contexts:
103* (a) in the context of a system worker thread
104* (b) in the context of the original caller
105*
106* Expected Interrupt Level (for execution) :
107*
108* IRQL_PASSIVE_LEVEL
109*
110* Return Value: STATUS_SUCCESS/Error
111*
112*************************************************************************/
115 PtrUDFIrpContext PtrIrpContext,
116 PIRP Irp
117 )
118{
124 PVCB Vcb = NULL;
126 BOOLEAN MainResourceAcquired = FALSE;
127 BOOLEAN ParentResourceAcquired = FALSE;
128 BOOLEAN PagingIoResourceAcquired = FALSE;
129 PVOID PtrSystemBuffer = NULL;
130 LONG BufferLength = 0;
131 FILE_INFORMATION_CLASS FunctionalityRequested;
132 BOOLEAN CanWait = FALSE;
133 BOOLEAN PostRequest = FALSE;
134 BOOLEAN AcquiredVcb = FALSE;
135 PIRP TopIrp;
136
137 TmPrint(("UDFCommonFileInfo: irp %x\n", Irp));
138
139 TopIrp = IoGetTopLevelIrp();
140 switch((ULONG_PTR)TopIrp) {
142 UDFPrint((" FSRTL_FSP_TOP_LEVEL_IRP\n"));
143 break;
145 UDFPrint((" FSRTL_CACHE_TOP_LEVEL_IRP\n"));
146 break;
148 UDFPrint((" FSRTL_MOD_WRITE_TOP_LEVEL_IRP\n"));
149 break;
151 UDFPrint((" FSRTL_FAST_IO_TOP_LEVEL_IRP\n"));
152 BrutePoint()
153 break;
154 case NULL:
155 UDFPrint((" NULL TOP_LEVEL_IRP\n"));
156 break;
157 default:
158 if(TopIrp == Irp) {
159 UDFPrint((" TOP_LEVEL_IRP\n"));
160 } else {
161 UDFPrint((" RECURSIVE_IRP, TOP = %x\n", TopIrp));
162 }
163 }
164
165 _SEH2_TRY {
166 // First, get a pointer to the current I/O stack location.
168 ASSERT(IrpSp);
169
172
173 // Get the FCB and CCB pointers.
174 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
175 ASSERT(Ccb);
176 if(!Ccb) {
177 // some applications sends us FO without Ccb
178 // This is not allowed...
180 try_return(RC);
181 }
182 Fcb = Ccb->Fcb;
183 ASSERT(Fcb);
184
185 NtReqFcb = Fcb->NTRequiredFCB;
186
187 CanWait = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE;
188
189 // If the caller has opened a logical volume and is attempting to
190 // query information for it as a file stream, return an error.
191 if(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) {
192 // This is not allowed. Caller must use get/set volume information instead.
194 try_return(RC);
195 }
196
197
199 ASSERT(Vcb);
200 ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_FCB);
201 //Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
202
203 // The NT I/O Manager always allocates and supplies a system
204 // buffer for query and set file information calls.
205 // Copying information to/from the user buffer and the system
206 // buffer is performed by the I/O Manager and the FSD need not worry about it.
207 PtrSystemBuffer = Irp->AssociatedIrp.SystemBuffer;
208
210 if(!UDFAcquireResourceShared(&(Vcb->VCBResource), CanWait)) {
211 PostRequest = TRUE;
213 }
214 AcquiredVcb = TRUE;
215
217 // Now, obtain some parameters.
218 BufferLength = IrpSp->Parameters.QueryFile.Length;
219 FunctionalityRequested = IrpSp->Parameters.QueryFile.FileInformationClass;
220#ifdef UDF_ENABLE_SECURITY
222 Ccb->PreviouslyGrantedAccess,
223 PtrIrpContext->MajorFunction,
224 PtrIrpContext->MinorFunction,
225 0,
226 &FunctionalityRequested,
227 NULL);
228 if(!NT_SUCCESS(RC)) {
229 try_return(RC);
230 }
231#endif //UDF_ENABLE_SECURITY
232 // Acquire the MainResource shared (NOTE: for paging-IO on a
233 // page file, we should avoid acquiring any resources and simply
234 // trust the VMM to do the right thing, else we could possibly
235 // run into deadlocks).
236 if(!(Fcb->FCBFlags & UDF_FCB_PAGE_FILE)) {
237 // Acquire the MainResource shared.
239 UDFAcquireResourceShared(&(NtReqFcb->MainResource), TRUE);
240 MainResourceAcquired = TRUE;
241 }
242
243 // Do whatever the caller asked us to do
244 switch (FunctionalityRequested) {
247 break;
250 break;
251#if(_WIN32_WINNT >= 0x0400)
254 break;
255#endif // _WIN32_WINNT >= 0x0400
257 RC = UDFGetInternalInformation(PtrIrpContext, Fcb, Ccb, (PFILE_INTERNAL_INFORMATION) PtrSystemBuffer, &BufferLength);
258 break;
260 RC = UDFGetEaInformation(PtrIrpContext, Fcb, (PFILE_EA_INFORMATION) PtrSystemBuffer, &BufferLength);
261 break;
264 break;
267 break;
268// case FileCompressionInformation:
269// // RC = UDFGetCompressionInformation(...);
270// break;
273 break;
276 break;
278 // The I/O Manager supplies the Mode, Access, and Alignment
279 // information. The rest is up to us to provide.
280 // Therefore, decrement the BufferLength appropriately (assuming
281 // that the above 3 types on information are already in the
282 // buffer)
283 {
284 PFILE_ALL_INFORMATION PtrAllInfo = (PFILE_ALL_INFORMATION)PtrSystemBuffer;
285
289
290 // Get the remaining stuff.
293 !NT_SUCCESS(RC = UDFGetInternalInformation(PtrIrpContext, Fcb, Ccb, &(PtrAllInfo->InternalInformation), &BufferLength)) ||
294 !NT_SUCCESS(RC = UDFGetEaInformation(PtrIrpContext, Fcb, &(PtrAllInfo->EaInformation), &BufferLength)) ||
297 )
298 try_return(RC);
299 }
300 break;
301 default:
303 try_return(RC);
304 }
305
306#ifndef UDF_READ_ONLY_BUILD
307 } else {
308// if(IrpSp->MajorFunction == IRP_MJ_SET_INFORMATION) {
309 Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
311 // Now, obtain some parameters.
312 FunctionalityRequested = IrpSp->Parameters.SetFile.FileInformationClass;
313 if((Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) &&
314 (FunctionalityRequested != FilePositionInformation)) {
316 }
317#ifdef UDF_ENABLE_SECURITY
319 Ccb->PreviouslyGrantedAccess,
320 PtrIrpContext->MajorFunction,
321 PtrIrpContext->MinorFunction,
322 0,
323 &FunctionalityRequested,
324 NULL);
325 if(!NT_SUCCESS(RC)) {
326 try_return(RC);
327 }
328#endif //UDF_ENABLE_SECURITY
329 // If the FSD supports opportunistic locking,
330 // then we should check whether the oplock state
331 // allows the caller to proceed.
332
333 // Rename, and link operations require creation of a directory
334 // entry and possibly deletion of another directory entry.
335
336 // Unless this is an operation on a page file, we should go ahead and
337 // acquire the FCB exclusively at this time. Note that we will pretty
338 // much block out anything being done to the FCB from this point on.
339 if(!(Fcb->FCBFlags & UDF_FCB_PAGE_FILE) &&
340 (FunctionalityRequested != FilePositionInformation) &&
341 (FunctionalityRequested != FileRenameInformation) &&
342 (FunctionalityRequested != FileLinkInformation)) {
343 // Acquire the Parent & Main Resources exclusive.
344 if(Fcb->FileInfo->ParentFile) {
346 if(!UDFAcquireResourceExclusive(&(Fcb->ParentFcb->NTRequiredFCB->MainResource), CanWait)) {
347 PostRequest = TRUE;
349 }
350 ParentResourceAcquired = TRUE;
351 }
353 if(!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
354 PostRequest = TRUE;
356 }
357 MainResourceAcquired = TRUE;
358 } else
359 // The only operations that could conceivably proceed from this point
360 // on are paging-IO read/write operations. For delete, link (rename),
361 // set allocation size, and set EOF, should also acquire the paging-IO
362 // resource, thereby synchronizing with paging-IO requests.
363 if((Fcb->FCBFlags & UDF_FCB_PAGE_FILE) &&
364 ((FunctionalityRequested == FileDispositionInformation) ||
365 (FunctionalityRequested == FileAllocationInformation) ||
366 (FunctionalityRequested == FileEndOfFileInformation)) ) {
367
368 // Acquire the MainResource shared.
370 if(!UDFAcquireResourceShared(&(NtReqFcb->MainResource), CanWait)) {
371 PostRequest = TRUE;
373 }
374 MainResourceAcquired = TRUE;
375 // Acquire the PagingResource exclusive.
376 if(!UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), CanWait)) {
377 PostRequest = TRUE;
379 }
380 PagingIoResourceAcquired = TRUE;
381 } else if((FunctionalityRequested != FileRenameInformation) &&
382 (FunctionalityRequested != FileLinkInformation)) {
383 // Acquire the MainResource shared.
385 if(!UDFAcquireResourceShared(&(NtReqFcb->MainResource), CanWait)) {
386 PostRequest = TRUE;
388 }
389 MainResourceAcquired = TRUE;
390 }
391
392 if((Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
393 (FunctionalityRequested != FilePositionInformation)) {
394 AdPrint((" Can't change File Information on blank volume ;)\n"));
396 }
397
398 // Do whatever the caller asked us to do
399 switch (FunctionalityRequested) {
402 break;
404 // Check if no intermediate buffering has been specified.
405 // If it was specified, do not allow non-aligned set file
406 // position requests to succeed.
407 PFILE_POSITION_INFORMATION PtrFileInfoBuffer;
408
409 PtrFileInfoBuffer = (PFILE_POSITION_INFORMATION)PtrSystemBuffer;
410
413 // Invalid alignment.
415 }
416 }
417
418 FileObject->CurrentByteOffset = PtrFileInfoBuffer->CurrentByteOffset;
419 break;
420 }
423 ((PFILE_DISPOSITION_INFORMATION)PtrSystemBuffer)->DeleteFile ? TRUE : FALSE);
424 break;
426 if(!CanWait) {
427 PostRequest = TRUE;
429 }
430 RC = UDFRename(IrpSp, Fcb, Ccb, FileObject, (PFILE_RENAME_INFORMATION)PtrSystemBuffer);
431 if(RC == STATUS_PENDING) {
432 PostRequest = TRUE;
433 try_return(RC);
434 }
435 break;
436#ifdef UDF_ALLOW_HARD_LINKS
438 if(!CanWait) {
439 PostRequest = TRUE;
441 }
442 RC = UDFHardLink(IrpSp, Fcb, Ccb, FileObject, (PFILE_LINK_INFORMATION)PtrSystemBuffer);
443 break;
444#endif //UDF_ALLOW_HARD_LINKS
447 PtrIrpContext, Irp,
448 (PFILE_ALLOCATION_INFORMATION)PtrSystemBuffer);
449 break;
452 break;
453 default:
455 try_return(RC);
456 }
457#endif //UDF_READ_ONLY_BUILD
458 }
459
460try_exit: NOTHING;
461
462 } _SEH2_FINALLY {
463
464 if(PagingIoResourceAcquired) {
465 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
466 PagingIoResourceAcquired = FALSE;
467 }
468
469 if(MainResourceAcquired) {
471 UDFReleaseResource(&(NtReqFcb->MainResource));
472 MainResourceAcquired = FALSE;
473 }
474
475 if(ParentResourceAcquired) {
477 UDFReleaseResource(&(Fcb->ParentFcb->NTRequiredFCB->MainResource));
478 ParentResourceAcquired = FALSE;
479 }
480
481 // Post IRP if required
482 if(PostRequest) {
483
484 // Since, the I/O Manager gave us a system buffer, we do not
485 // need to "lock" anything.
486
487 // Perform the post operation which will mark the IRP pending
488 // and will return STATUS_PENDING back to us
489 RC = UDFPostRequest(PtrIrpContext, Irp);
490
491 } else {
492
494 Irp->IoStatus.Status = RC;
495 // Set status for "query" requests
497 // Return the amount of information transferred.
498 Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - BufferLength;
499#ifndef UDF_READ_ONLY_BUILD
500#ifdef UDF_DELAYED_CLOSE
501 } else
502 if(NT_SUCCESS(RC)) {
503 if(FunctionalityRequested == FileDispositionInformation) {
504 if(AcquiredVcb) {
505 AcquiredVcb = FALSE;
506 UDFReleaseResource(&(Vcb->VCBResource));
507 }
509 }
510#endif //UDF_DELAYED_CLOSE
511#endif //UDF_READ_ONLY_BUILD
512 }
513 // complete the IRP
515 // Free up the Irp Context
516 UDFReleaseIrpContext(PtrIrpContext);
517 } // can we complete the IRP ?
518
519 }
520 if(AcquiredVcb) {
521 UDFReleaseResource(&(Vcb->VCBResource));
522 }
523 } _SEH2_END;// end of "__finally" processing
524
525 return(RC);
526} // end UDFCommonFileInfo()
527
528/*
529 Return some time-stamps and file attributes to the caller.
530 */
535 IN PFILE_BASIC_INFORMATION PtrBuffer,
536 IN OUT LONG* PtrReturnedLength
537 )
538{
541 PDIR_INDEX_ITEM DirNdx;
542
543 AdPrint(("UDFGetBasicInformation: \n"));
544
545 _SEH2_TRY {
546
547 if(*PtrReturnedLength < (LONG)sizeof(FILE_BASIC_INFORMATION)) {
549 }
550
551 // Zero out the supplied buffer.
552 RtlZeroMemory(PtrBuffer, sizeof(FILE_BASIC_INFORMATION));
553
554 // Get information from the FCB and update TimesCache in DirIndex
555 FileInfo = Fcb->FileInfo;
556
557 if(!FileInfo) {
558 AdPrint(("!!!!!!!! Bu-u-u-u-u-g !!!!!!!!!!!\n"));
559 AdPrint(("!!!! GetBasicInfo to unopened file !!!!\n"));
561 }
562
564
565 PtrBuffer->CreationTime = Fcb->NTRequiredFCB->CreationTime;
566 DirNdx->CreationTime = PtrBuffer->CreationTime.QuadPart;
567
568 PtrBuffer->LastAccessTime = Fcb->NTRequiredFCB->LastAccessTime;
569 DirNdx->LastAccessTime = PtrBuffer->LastAccessTime.QuadPart;
570
571 PtrBuffer->LastWriteTime = Fcb->NTRequiredFCB->LastWriteTime;
572 DirNdx->LastWriteTime = PtrBuffer->LastWriteTime.QuadPart;
573
574 PtrBuffer->ChangeTime = Fcb->NTRequiredFCB->ChangeTime;
575 DirNdx->ChangeTime = PtrBuffer->ChangeTime.QuadPart;
576
577 // Now fill in the attributes.
578 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
579 PtrBuffer->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
580#ifdef UDF_DBG
581 if(!FileInfo->Dloc->DirIndex) AdPrint(("*****!!!!! Directory has no DirIndex !!!!!*****\n"));
582#endif
583 }
584 // Similarly, fill in attributes indicating a hidden file, system
585 // file, compressed file, temporary file, etc. if the FSD supports
586 // such file attribute values.
587 PtrBuffer->FileAttributes |= UDFAttributesToNT(DirNdx,NULL);
588 if(FileObject->Flags & FO_TEMPORARY_FILE) {
589 PtrBuffer->FileAttributes |= FILE_ATTRIBUTE_TEMPORARY;
590 } else {
591 PtrBuffer->FileAttributes &= ~FILE_ATTRIBUTE_TEMPORARY;
592 }
593 if(!PtrBuffer->FileAttributes) {
594 PtrBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
595 }
596
597try_exit: NOTHING;
598
599 } _SEH2_FINALLY {
600
601 if(NT_SUCCESS(RC)) {
602 // Return the amount of information filled in.
603 (*PtrReturnedLength) -= sizeof(FILE_BASIC_INFORMATION);
604 }
605 } _SEH2_END;
606 return(RC);
607} // end UDFGetBasicInformation()
608
609
610/*
611 Return file sizes to the caller.
612 */
617 IN OUT LONG* PtrReturnedLength
618 )
619{
622// PVCB Vcb;
623
624 AdPrint(("UDFGetStandardInformation: \n"));
625
626 _SEH2_TRY {
627
628 if(*PtrReturnedLength < (LONG)sizeof(FILE_STANDARD_INFORMATION)) {
630 }
631
632 // Zero out the supplied buffer.
633 RtlZeroMemory(PtrBuffer, sizeof(FILE_STANDARD_INFORMATION));
634
635 FileInfo = Fcb->FileInfo;
636
637 if(!FileInfo) {
638 AdPrint(("!!!!!!!! Bu-u-u-u-u-g !!!!!!!!!!!\n"));
639 AdPrint(("!!!! GetStandardInfo to unopened file !!!!\n"));
641 }
642// Vcb = Fcb->Vcb;
643 PtrBuffer->NumberOfLinks = UDFGetFileLinkCount(FileInfo);
644 PtrBuffer->DeletePending = (Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE) ? TRUE : FALSE;
645
646 // Case on whether this is a file or a directory, and extract
647 // the information and fill in the fcb/dcb specific parts
648 // of the output buffer
649 if(UDFIsADirectory(Fcb->FileInfo)) {
650 PtrBuffer->Directory = TRUE;
651 } else {
652 if(Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.LowPart == 0xffffffff) {
653 Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.QuadPart =
654 UDFSysGetAllocSize(Fcb->Vcb, UDFGetFileSize(FileInfo));
655 }
656 PtrBuffer->AllocationSize = Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize;
657 PtrBuffer->EndOfFile = Fcb->NTRequiredFCB->CommonFCBHeader.FileSize;
658
659 PtrBuffer->Directory = FALSE;
660 }
661
662 try_exit: NOTHING;
663 } _SEH2_FINALLY {
664 if(NT_SUCCESS(RC)) {
665 // Return the amount of information filled in.
666 *PtrReturnedLength -= sizeof(FILE_STANDARD_INFORMATION);
667 }
668 } _SEH2_END;
669 return(RC);
670} // end UDFGetStandardInformation()
671
672/*
673 Return some time-stamps and file attributes to the caller.
674 */
679 IN OUT PLONG PtrReturnedLength
680 )
681{
684
685 AdPrint(("UDFGetNetworkInformation: \n"));
686
687 _SEH2_TRY {
688
689 if(*PtrReturnedLength < (LONG)sizeof(FILE_NETWORK_OPEN_INFORMATION)) {
691 }
692
693 // Zero out the supplied buffer.
695
696 // Get information from the FCB.
697 PtrBuffer->CreationTime = Fcb->NTRequiredFCB->CreationTime;
698 PtrBuffer->LastAccessTime = Fcb->NTRequiredFCB->LastAccessTime;
699 PtrBuffer->LastWriteTime = Fcb->NTRequiredFCB->LastWriteTime;
700 PtrBuffer->ChangeTime = Fcb->NTRequiredFCB->ChangeTime;
701
702 FileInfo = Fcb->FileInfo;
703
704 if(!FileInfo) {
705 AdPrint(("!!!!!!!! Bu-u-u-u-u-g !!!!!!!!!!!\n"));
706 AdPrint(("!!!! UDFGetNetworkInformation to unopened file !!!!\n"));
708 }
709 // Now fill in the attributes.
710 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
711 PtrBuffer->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
712#ifdef UDF_DBG
713 if(!FileInfo->Dloc->DirIndex) AdPrint(("*****!!!!! Directory has no DirIndex !!!!!*****\n"));
714#endif
715 } else {
716 if(Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.LowPart == 0xffffffff) {
717 Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.QuadPart =
718 UDFSysGetAllocSize(Fcb->Vcb, UDFGetFileSize(FileInfo));
719 }
720 PtrBuffer->AllocationSize = Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize;
721 PtrBuffer->EndOfFile = Fcb->NTRequiredFCB->CommonFCBHeader.FileSize;
722 }
723 // Similarly, fill in attributes indicating a hidden file, system
724 // file, compressed file, temporary file, etc. if the FSD supports
725 // such file attribute values.
727 if(!PtrBuffer->FileAttributes) {
728 PtrBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
729 }
730
731try_exit: NOTHING;
732
733 } _SEH2_FINALLY {
734 if(NT_SUCCESS(RC)) {
735 // Return the amount of information filled in.
736 (*PtrReturnedLength) -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
737 }
738 } _SEH2_END;
739 return(RC);
740} // end UDFGetNetworkInformation()
741
742
743/*
744 Return some time-stamps and file attributes to the caller.
745 */
748 PtrUDFIrpContext PtrIrpContext,
752 IN OUT PLONG PtrReturnedLength
753 )
754{
757 PVCB Vcb;
758
759 AdPrint(("UDFGetInternalInformation\n"));
760
761 _SEH2_TRY {
762
763 if(*PtrReturnedLength < (LONG)sizeof(FILE_INTERNAL_INFORMATION)) {
765 }
766
767 // Zero out the supplied buffer.
768 RtlZeroMemory(PtrBuffer, sizeof(FILE_INTERNAL_INFORMATION));
769
770 FileInfo = Fcb->FileInfo;
771
772 if(!FileInfo) {
773 AdPrint(("!!!!!!!! Bu-u-u-u-u-g !!!!!!!!!!!\n"));
774 AdPrint(("!!!! UDFGetInternalInformation to unopened file !!!!\n"));
776 }
777
778 Vcb = Fcb->Vcb;
779 PtrBuffer->IndexNumber.QuadPart = UDFGetNTFileId(Vcb, FileInfo, &(Fcb->FCBName->ObjectName));
780
781 UDFAcquireResourceExclusive(&(Fcb->Vcb->FileIdResource), TRUE);
782 // remember File Id & full path
783 UDFStoreFileId(Fcb->Vcb, Ccb, FileInfo, PtrBuffer->IndexNumber.QuadPart);
784 UDFReleaseResource(&(Fcb->Vcb->FileIdResource));
785
786try_exit: NOTHING;
787
788 } _SEH2_FINALLY {
789 if(NT_SUCCESS(RC)) {
790 // Return the amount of information filled in.
791 *PtrReturnedLength -= sizeof(FILE_INTERNAL_INFORMATION);
792 }
793 } _SEH2_END;
794 return(RC);
795} // end UDFGetInternalInformation()
796
797/*
798 Return zero-filled EAs to the caller.
799 */
802 PtrUDFIrpContext PtrIrpContext,
804 IN PFILE_EA_INFORMATION PtrBuffer,
805 IN OUT PLONG PtrReturnedLength
806 )
807{
809
810 AdPrint(("UDFGetEaInformation\n"));
811
812 _SEH2_TRY {
813
814 if(*PtrReturnedLength < (LONG)sizeof(FILE_EA_INFORMATION)) {
816 }
817
818 // Zero out the supplied buffer.
819 PtrBuffer->EaSize = 0;
820
821try_exit: NOTHING;
822
823 } _SEH2_FINALLY {
824 if(NT_SUCCESS(RC)) {
825 // Return the amount of information filled in.
826 *PtrReturnedLength -= sizeof(FILE_EA_INFORMATION);
827 }
828 } _SEH2_END;
829 return(RC);
830} // end UDFGetEaInformation()
831
832/*
833 Return file's long name to the caller.
834 */
838 IN PFILE_NAME_INFORMATION PtrBuffer,
839 IN OUT PLONG PtrReturnedLength
840 )
841{
844
845
846 AdPrint(("UDFGetFullNameInformation\n"));
847
848 PtrBuffer->FileNameLength = FileObject->FileName.Length;
849 BytesToCopy = FileObject->FileName.Length;
850
851 if (PtrBuffer->FileNameLength + sizeof( ULONG ) > (ULONG)(*PtrReturnedLength)) {
852
853 BytesToCopy = *PtrReturnedLength - sizeof( ULONG );
855 }
856
857 RtlCopyMemory( PtrBuffer->FileName, FileObject->FileName.Buffer, BytesToCopy );
858
859 // Reduce the available bytes by the amount stored into this buffer.
860 *PtrReturnedLength -= sizeof( ULONG ) + PtrBuffer->FileNameLength;
861
862 return RC;
863} // end UDFGetFullNameInformation()
864
865/*
866 Return file short(8.3) name to the caller.
867 */
871 IN PFILE_NAME_INFORMATION PtrBuffer,
872 IN OUT PLONG PtrReturnedLength
873 )
874{
875 PDIR_INDEX_ITEM DirNdx;
878 WCHAR ShortNameBuffer[13];
879
880 AdPrint(("UDFGetAltNameInformation: \n"));
881
882 *PtrReturnedLength -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]);
883 DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(Fcb->FileInfo), Fcb->FileInfo->Index);
884
885 ShortName.MaximumLength = 13 * sizeof(WCHAR);
886 ShortName.Buffer = (PWCHAR)&ShortNameBuffer;
887
888 UDFDOSName__(Fcb->Vcb, &ShortName, &(DirNdx->FName), Fcb->FileInfo);
889
890 if(*PtrReturnedLength < ShortName.Length) {
892 } else {
893 BytesToCopy = ShortName.Length;
894 *PtrReturnedLength -= ShortName.Length;
895 }
896
897 RtlCopyMemory( &(PtrBuffer->FileName),
898 ShortName.Buffer,
899 BytesToCopy );
900
901 PtrBuffer->FileNameLength = ShortName.Length;
902
903 return(STATUS_SUCCESS);
904} // end UDFGetAltNameInformation()
905
906/*
907 Get file position information
908 */
913 IN OUT PLONG PtrReturnedLength
914 )
915{
916 if(*PtrReturnedLength < (LONG)sizeof(FILE_POSITION_INFORMATION)) {
918 }
919 PtrBuffer->CurrentByteOffset = FileObject->CurrentByteOffset;
920 // Modify the local variable for BufferLength appropriately.
921 *PtrReturnedLength -= sizeof(FILE_POSITION_INFORMATION);
922
923 return(STATUS_SUCCESS);
924} // end UDFGetAltNameInformation()
925
926/*
927 Get file file stream(s) information
928 */
933 IN OUT PLONG PtrReturnedLength
934 )
935{
938 PUDF_FILE_INFO SDirInfo;
939 PVCB Vcb;
940 BOOLEAN FcbAcquired = FALSE;
941 uint_di i;
942 LONG l;
943 PDIR_INDEX_HDR hSDirIndex;
944 PDIR_INDEX_ITEM SDirIndex;
945 PFILE_BOTH_DIR_INFORMATION NTFileInfo = NULL;
946
947 AdPrint(("UDFGetFileStreamInformation\n"));
948
949 _SEH2_TRY {
950
951 UDFAcquireResourceExclusive(&(Fcb->Vcb->FileIdResource), TRUE);
952 FcbAcquired = TRUE;
953
954 FileInfo = Fcb->FileInfo;
955 if(!FileInfo) {
956 AdPrint(("!!!!!!!! Bu-u-u-u-u-g !!!!!!!!!!!\n"));
957 AdPrint(("!!!! UDFGetFileStreamInformation to unopened file !!!!\n"));
959 }
960 Vcb = Fcb->Vcb;
961 // Zero out the supplied buffer.
962 RtlZeroMemory(PtrBuffer, *PtrReturnedLength);
963 if(!(SDirInfo = FileInfo->Dloc->SDirInfo) ||
964 UDFIsSDirDeleted(SDirInfo) ) {
965 (*PtrReturnedLength) -= (sizeof(FILE_STREAM_INFORMATION) - sizeof(WCHAR));
967 }
968
969 hSDirIndex = SDirInfo->Dloc->DirIndex;
971 if(!NTFileInfo) try_return(RC = STATUS_INSUFFICIENT_RESOURCES);
972
973 for(i=2; (SDirIndex = UDFDirIndex(hSDirIndex,i)); i++) {
974 if((SDirIndex->FI_Flags & UDF_FI_FLAG_FI_INTERNAL) ||
975 UDFIsDeleted(SDirIndex) ||
976 !SDirIndex->FName.Buffer )
977 continue;
978 // copy data to buffer
979 if(*PtrReturnedLength < (l = ((sizeof(FILE_STREAM_INFORMATION) - sizeof(WCHAR)) +
980 SDirIndex->FName.Length + 3) & (~3)) ) {
982 }
983 RC = UDFFileDirInfoToNT(Vcb, SDirIndex, NTFileInfo);
984
985 PtrBuffer->NextEntryOffset = l;
986 PtrBuffer->StreamNameLength = SDirIndex->FName.Length;
987 PtrBuffer->StreamSize = NTFileInfo->EndOfFile;
988 PtrBuffer->StreamAllocationSize = NTFileInfo->AllocationSize;
989 RtlCopyMemory(&(PtrBuffer->StreamName), SDirIndex->FName.Buffer, SDirIndex->FName.Length);
990 *PtrReturnedLength -= l;
991 *((PCHAR*)(&PtrBuffer)) += l;
992 }
993
994try_exit: NOTHING;
995
996 } _SEH2_FINALLY {
997 if(FcbAcquired)
998 UDFReleaseResource(&(Fcb->Vcb->FileIdResource));
999 if(NTFileInfo)
1000 MyFreePool__(NTFileInfo);
1001 } _SEH2_END;
1002 return(RC);
1003} // end UDFGetFileStreamInformation()
1004
1005//*******************************************************************
1006
1007#ifndef UDF_READ_ONLY_BUILD
1008
1009/*
1010 Set some time-stamps and file attributes supplied by the caller.
1011 */
1017 IN PFILE_BASIC_INFORMATION PtrBuffer)
1018{
1020 ULONG NotifyFilter = 0;
1021
1022 AdPrint(("UDFSetBasicInformation\n"));
1023
1024 _SEH2_TRY {
1025
1026 // Obtain a pointer to the directory entry associated with
1027 // the FCB being modifed. The directory entry is obviously
1028 // part of the data associated with the parent directory that
1029 // contains this particular file stream.
1030 if(PtrBuffer->FileAttributes) {
1031 UDFUpdateAttrTime(Fcb->Vcb, Fcb->FileInfo);
1032 } else
1033 if( UDFIsADirectory(Fcb->FileInfo) &&
1034 !(Fcb->Vcb->CompatFlags & UDF_VCB_IC_UPDATE_UCHG_DIR_ACCESS_TIME) &&
1035 ((Fcb->FileInfo->Dloc->DataLoc.Modified ||
1036 Fcb->FileInfo->Dloc->AllocLoc.Modified ||
1037 (Fcb->FileInfo->Dloc->FE_Flags & UDF_FE_FLAG_FE_MODIFIED) ||
1038 Fcb->FileInfo->Dloc->FELoc.Modified))
1039 ) {
1040 // ignore Access Time Modification for unchanged Dir
1041 if(!PtrBuffer->CreationTime.QuadPart &&
1042 PtrBuffer->LastAccessTime.QuadPart &&
1043 !PtrBuffer->ChangeTime.QuadPart &&
1044 !PtrBuffer->LastWriteTime.QuadPart)
1045 try_return(RC);
1046 }
1047
1048 UDFSetFileXTime(Fcb->FileInfo,
1049 &(PtrBuffer->CreationTime.QuadPart),
1050 &(PtrBuffer->LastAccessTime.QuadPart),
1051 &(PtrBuffer->ChangeTime.QuadPart),
1052 &(PtrBuffer->LastWriteTime.QuadPart) );
1053
1054 if(PtrBuffer->CreationTime.QuadPart) {
1055 // The interesting thing here is that the user has set certain time
1056 // fields. However, before doing this, the user may have performed
1057 // I/O which in turn would have caused FSD to mark the fact that
1058 // write/access time should be modifed at cleanup.
1059 // We'll mark the fact that such updates are no longer
1060 // required since the user has explicitly specified the values he
1061 // wishes to see associated with the file stream.
1062 Fcb->NTRequiredFCB->CreationTime = PtrBuffer->CreationTime;
1063 Ccb->CCBFlags |= UDF_CCB_CREATE_TIME_SET;
1065 }
1066 if(PtrBuffer->LastAccessTime.QuadPart) {
1067 Fcb->NTRequiredFCB->LastAccessTime = PtrBuffer->LastAccessTime;
1068 Ccb->CCBFlags |= UDF_CCB_ACCESS_TIME_SET;
1070 }
1071 if(PtrBuffer->ChangeTime.QuadPart) {
1072 Fcb->NTRequiredFCB->ChangeTime = PtrBuffer->ChangeTime;
1073 Ccb->CCBFlags |= UDF_CCB_MODIFY_TIME_SET;
1074 }
1075 if(PtrBuffer->LastWriteTime.QuadPart) {
1076 Fcb->NTRequiredFCB->LastWriteTime = PtrBuffer->LastWriteTime;
1077 Ccb->CCBFlags |= UDF_CCB_WRITE_TIME_SET;
1079 }
1080
1081 // Now come the attributes.
1082 if(PtrBuffer->FileAttributes) {
1083 // We have a non-zero attribute value.
1084 // The presence of a particular attribute indicates that the
1085 // user wishes to set the attribute value. The absence indicates
1086 // the user wishes to clear the particular attribute.
1087
1088 // Our routine ignores unsupported flags
1089 PtrBuffer->FileAttributes &= ~(FILE_ATTRIBUTE_NORMAL);
1090
1091 // Similarly, we should pick out other invalid flag values.
1092 if( (PtrBuffer->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
1093 !(Fcb->FCBFlags & UDF_FCB_DIRECTORY))
1095
1096 if(PtrBuffer->FileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
1097 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY)
1099 FileObject->Flags |= FO_TEMPORARY_FILE;
1100 } else {
1101 FileObject->Flags &= ~FO_TEMPORARY_FILE;
1102 }
1103
1104 if(PtrBuffer->FileAttributes & FILE_ATTRIBUTE_READONLY) {
1105 Fcb->FCBFlags |= UDF_FCB_READ_ONLY;
1106 } else {
1107 Fcb->FCBFlags &= ~UDF_FCB_READ_ONLY;
1108 }
1109
1110 UDFAttributesToUDF(UDFDirIndex(UDFGetDirIndexByFileInfo(Fcb->FileInfo), Fcb->FileInfo->Index),
1111 NULL, PtrBuffer->FileAttributes);
1112
1113 (UDFDirIndex(UDFGetDirIndexByFileInfo(Fcb->FileInfo), Fcb->FileInfo->Index))
1114 ->FI_Flags |= UDF_FI_FLAG_SYS_ATTR;
1115 // If the FSD supports file compression, we may wish to
1116 // note the user's preferences for compressing/not compressing
1117 // the file at this time.
1118 Ccb->CCBFlags |= UDF_CCB_ATTRIBUTES_SET;
1120 }
1121
1122 if(NotifyFilter) {
1123 UDFNotifyFullReportChange( Fcb->Vcb, Fcb->FileInfo,
1125 UDFSetFileSizeInDirNdx(Fcb->Vcb, Fcb->FileInfo, NULL);
1126 Fcb->FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
1127 }
1128
1129try_exit: NOTHING;
1130 } _SEH2_FINALLY {
1131 ;
1132 } _SEH2_END;
1133 return(RC);
1134} // end UDFSetBasicInformation()
1135
1138 IN PVCB Vcb,
1140 IN BOOLEAN ForDel
1141 )
1142{
1144 PUDF_FILE_INFO SDirInfo = NULL;
1146 ULONG lc;
1147 BOOLEAN SDirAcq = FALSE;
1148 BOOLEAN StrAcq = FALSE;
1149 uint_di d,i;
1150
1151 _SEH2_TRY {
1152
1153 // In some cases we needn't marking Streams for deleteion
1154 // (Not opened or Don't exist)
1155 if(UDFIsAStream(Fcb->FileInfo) ||
1156 UDFIsAStreamDir(Fcb->FileInfo) ||
1157 !UDFHasAStreamDir(Fcb->FileInfo) ||
1158 !Fcb->FileInfo->Dloc->SDirInfo ||
1159 UDFIsSDirDeleted(Fcb->FileInfo->Dloc->SDirInfo) ||
1160 (UDFGetFileLinkCount(Fcb->FileInfo) > 1) )
1161 try_return (RC /*=STATUS_SUCCESS*/);
1162
1163 // We shall mark Streams for deletion if there is no
1164 // Links to the file. Otherwise we'll delete only the file.
1165 // If we are asked to unmark Streams, we'll precess the whole Tree
1166 RC = UDFOpenStreamDir__(Vcb, Fcb->FileInfo, &SDirInfo);
1167 if(!NT_SUCCESS(RC))
1168 try_return(RC);
1169
1170 if(SDirInfo->Fcb &&
1171 SDirInfo->Fcb->NTRequiredFCB) {
1172 UDF_CHECK_PAGING_IO_RESOURCE(SDirInfo->Fcb->NTRequiredFCB);
1173 UDFAcquireResourceExclusive(&(SDirInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
1174 SDirAcq = TRUE;
1175 }
1176
1177 if(!ForDel || ((lc = UDFGetFileLinkCount(Fcb->FileInfo)) < 2)) {
1178
1179 UDF_DIR_SCAN_CONTEXT ScanContext;
1180 PDIR_INDEX_ITEM DirNdx;
1181
1182 // It is not worth checking whether the Stream can be deleted if
1183 // Undelete requested
1184 if(ForDel &&
1185 // scan DirIndex
1186 UDFDirIndexInitScan(SDirInfo, &ScanContext, 2)) {
1187
1188 // Check if we can delete Streams
1189 while((DirNdx = UDFDirIndexScan(&ScanContext, &FileInfo))) {
1190 if(!FileInfo)
1191 continue;
1192 if(FileInfo->Fcb) {
1193 FileInfo->Fcb->NTRequiredFCB->AcqFlushCount++;
1194 MmPrint((" MmFlushImageSection() for Stream\n"));
1195 if(!MmFlushImageSection(&(FileInfo->Fcb->NTRequiredFCB->SectionObject), MmFlushForDelete)) {
1196 FileInfo->Fcb->NTRequiredFCB->AcqFlushCount--;
1198 }
1199 FileInfo->Fcb->NTRequiredFCB->AcqFlushCount--;
1200 }
1201 }
1202 }
1203 // (Un)Mark Streams for deletion
1204
1205 // Perform sequencial Open for Streams & mark 'em
1206 // for deletion. We should not get FileInfo pointers directly
1207 // from DirNdx[i] to prevent great troubles with linked
1208 // files. We should mark for deletion FI with proper ParentFile
1209 // pointer.
1210 d = UDFDirIndexGetLastIndex(SDirInfo->Dloc->DirIndex);
1211 for(i=2; i<d; i++) {
1212 RC = UDFOpenFile__(Vcb,
1213 FALSE,TRUE,NULL,
1214 SDirInfo,&FileInfo,&i);
1215 ASSERT(NT_SUCCESS(RC) || (RC == STATUS_FILE_DELETED));
1216 if(NT_SUCCESS(RC)) {
1217 if(FileInfo->Fcb) {
1218 if(FileInfo->Fcb->NTRequiredFCB) {
1219 UDF_CHECK_PAGING_IO_RESOURCE(FileInfo->Fcb->NTRequiredFCB);
1220 UDFAcquireResourceExclusive(&(FileInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
1221 StrAcq = TRUE;
1222 }
1223#ifndef UDF_ALLOW_LINKS_TO_STREAMS
1224 if(UDFGetFileLinkCount(FileInfo) >= 2) {
1225 // Currently, UDF_INFO package doesn't
1226 // support this case, so we'll inform developer
1227 // about this to prevent on-disk space leaks...
1228 BrutePoint();
1230 }
1231#endif //UDF_ALLOW_LINKS_TO_STREAMS
1232 if(ForDel) {
1233 AdPrint((" SET stream DeleteOnClose\n"));
1234#ifdef UDF_DBG
1235 ASSERT(!(FileInfo->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1236 if(FileInfo->ParentFile &&
1237 FileInfo->ParentFile->Fcb) {
1238 ASSERT(!(FileInfo->ParentFile->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1239 }
1240#endif // UDF_DBG
1241 FileInfo->Fcb->FCBFlags |= (UDF_FCB_DELETE_ON_CLOSE |
1243 } else {
1244 AdPrint((" CLEAR stream DeleteOnClose\n"));
1245 FileInfo->Fcb->FCBFlags &= ~(UDF_FCB_DELETE_ON_CLOSE |
1247 }
1248 }
1250 } else
1251 if(RC == STATUS_FILE_DELETED) {
1252 // That's OK if STATUS_FILE_DELETED returned...
1253 RC = STATUS_SUCCESS;
1254 }
1255 if(FileInfo) {
1257 ASSERT(!StrAcq && !(FileInfo->Fcb));
1259 }
1260 if(StrAcq) {
1261 UDF_CHECK_PAGING_IO_RESOURCE(FileInfo->Fcb->NTRequiredFCB);
1262 UDFReleaseResource(&(FileInfo->Fcb->NTRequiredFCB->MainResource));
1263 StrAcq = FALSE;
1264 }
1265 }
1266 FileInfo = NULL;
1267 }
1268 // Mark SDir for deletion
1269 if(SDirInfo->Fcb) {
1270 if(ForDel) {
1271#ifdef UDF_DBG
1272 ASSERT(!(SDirInfo->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1273 if(SDirInfo->ParentFile &&
1274 SDirInfo->ParentFile->Fcb) {
1275 ASSERT(!(SDirInfo->ParentFile->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1276 }
1277#endif // UDF_DBG
1278 AdPrint((" SET stream dir DeleteOnClose\n"));
1279 SDirInfo->Fcb->FCBFlags |= (UDF_FCB_DELETE_ON_CLOSE |
1281 } else {
1282 AdPrint((" CLEAR stream dir DeleteOnClose\n"));
1283 SDirInfo->Fcb->FCBFlags &= ~(UDF_FCB_DELETE_ON_CLOSE |
1285 }
1286 }
1287 } else
1288 if(lc >= 2) {
1289 // if caller wants us to perform DelTree for Streams, but
1290 // someone keeps Stream opened and there is a Link to this
1291 // file, we can't delete it immediately (on Cleanup) & should
1292 // not delete the whole Tree. Instead, we'll set DELETE_PARENT
1293 // flag in SDir to kill this file later, when all the Handles
1294 // to Streams, opened via this file, would be closed
1295#ifdef UDF_DBG
1296 ASSERT(!(SDirInfo->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1297 if(SDirInfo->ParentFile &&
1298 SDirInfo->ParentFile->Fcb) {
1299 ASSERT(!(SDirInfo->ParentFile->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1300 }
1301#endif // UDF_DBG
1302 if(SDirInfo->Fcb)
1303 SDirInfo->Fcb->FCBFlags |= UDF_FCB_DELETE_PARENT;
1304 }
1305
1306try_exit: NOTHING;
1307
1308 } _SEH2_FINALLY {
1309 if(FileInfo) {
1312 ASSERT(!StrAcq && !(FileInfo->Fcb));
1314 }
1315 if(StrAcq) {
1316 UDF_CHECK_PAGING_IO_RESOURCE(FileInfo->Fcb->NTRequiredFCB);
1317 UDFReleaseResource(&(FileInfo->Fcb->NTRequiredFCB->MainResource));
1318 }
1319 SDirInfo = NULL;
1320 }
1321 if(SDirInfo) {
1322 UDFCloseFile__(Vcb, SDirInfo);
1323 if(SDirAcq) {
1324 UDF_CHECK_PAGING_IO_RESOURCE(SDirInfo->Fcb->NTRequiredFCB);
1325 UDFReleaseResource(&(SDirInfo->Fcb->NTRequiredFCB->MainResource));
1326 }
1327 if(UDFCleanUpFile__(Vcb, SDirInfo)) {
1328 MyFreePool__(SDirInfo);
1329 }
1330 SDirInfo = NULL;
1331 }
1332 } _SEH2_END;
1333 return RC;
1334} // end UDFMarkStreamsForDeletion()
1335
1336/*
1337 (Un)Mark file for deletion.
1338 */
1343 IN PVCB Vcb,
1346 )
1347{
1349// PUDF_FILE_INFO SDirInfo = NULL;
1350// PUDF_FILE_INFO FileInfo = NULL;
1351 ULONG lc;
1352
1353 AdPrint(("UDFSetDispositionInformation\n"));
1354
1355 _SEH2_TRY {
1356
1357 if(!Delete) {
1358 AdPrint((" CLEAR DeleteOnClose\n"));
1359 // "un-delete" the file.
1360 Fcb->FCBFlags &= ~UDF_FCB_DELETE_ON_CLOSE;
1361 if(FileObject)
1362 FileObject->DeletePending = FALSE;
1363 RC = UDFMarkStreamsForDeletion(Vcb, Fcb, FALSE); // Undelete
1364 try_return(RC);
1365 }
1366 AdPrint((" SET DeleteOnClose\n"));
1367
1368 // The easy part is over. Now, we know that the user wishes to
1369 // delete the corresponding directory entry (of course, if this
1370 // is the only link to the file stream, any on-disk storage space
1371 // associated with the file stream will also be released when the
1372 // (only) link is deleted!)
1373
1374 // Do some checking to see if the file can even be deleted.
1375 if(Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE) {
1376 // All done!
1377 try_return(RC);
1378 }
1379
1380 if(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) {
1382 }
1383
1384 if(Fcb->FCBFlags & UDF_FCB_READ_ONLY) {
1386 if(!NT_SUCCESS(RC)) {
1388 }
1389 }
1390
1391 // It would not be prudent to allow deletion of either a root
1392 // directory or a directory that is not empty.
1393 if(Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY)
1395
1396 lc = UDFGetFileLinkCount(Fcb->FileInfo);
1397
1398 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
1399 // Perform check to determine whether the directory
1400 // is empty or not.
1401 if(!UDFIsDirEmpty__(Fcb->FileInfo)) {
1403 }
1404
1405 } else {
1406 // An important step is to check if the file stream has been
1407 // mapped by any process. The delete cannot be allowed to proceed
1408 // in this case.
1409 MmPrint((" MmFlushImageSection()\n"));
1410 Fcb->NTRequiredFCB->AcqFlushCount++;
1411 if(!MmFlushImageSection(&(Fcb->NTRequiredFCB->SectionObject),
1412 (lc > 1) ? MmFlushForWrite : MmFlushForDelete)) {
1413 Fcb->NTRequiredFCB->AcqFlushCount--;
1415 }
1416 Fcb->NTRequiredFCB->AcqFlushCount--;
1417 }
1418 // We should also mark Streams for deletion if there are no
1419 // Links to the file. Otherwise we'll delete only the file
1420
1421 if(lc > 1) {
1422 RC = STATUS_SUCCESS;
1423 } else {
1424 RC = UDFMarkStreamsForDeletion(Vcb, Fcb, TRUE); // Delete
1425 if(!NT_SUCCESS(RC))
1426 try_return(RC);
1427 }
1428
1429 // Set a flag to indicate that this directory entry will become history
1430 // at cleanup.
1431 Fcb->FCBFlags |= UDF_FCB_DELETE_ON_CLOSE;
1432 if(FileObject)
1433 FileObject->DeletePending = TRUE;
1434
1435 if((Fcb->FCBFlags & UDF_FCB_DIRECTORY) && Ccb) {
1436 FsRtlNotifyFullChangeDirectory( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
1437 (PVOID)Ccb, NULL, FALSE, FALSE,
1438 0, NULL, NULL, NULL );
1439 }
1440
1441try_exit: NOTHING;
1442
1443 } _SEH2_FINALLY {
1444 ;
1445 } _SEH2_END;
1446 return(RC);
1447} // end UDFSetDispositionInformation()
1448
1449
1450/*
1451 Change file allocation length.
1452 */
1457 IN PVCB Vcb,
1459 IN PtrUDFIrpContext PtrIrpContext,
1460 IN PIRP Irp,
1462 )
1463{
1465 BOOLEAN TruncatedFile = FALSE;
1466 BOOLEAN ModifiedAllocSize = FALSE;
1467 BOOLEAN CacheMapInitialized = FALSE;
1468 BOOLEAN AcquiredPagingIo = FALSE;
1469
1470 AdPrint(("UDFSetAllocationInformation\n"));
1471
1472 _SEH2_TRY {
1473 // Increasing the allocation size associated with a file stream
1474 // is relatively easy. All we have to do is execute some FSD
1475 // specific code to check whether we have enough space available
1476 // (and if the FSD supports user/volume quotas, whether the user
1477 // is not exceeding quota), and then increase the file size in the
1478 // corresponding on-disk and in-memory structures.
1479 // Then, all we should do is inform the Cache Manager about the
1480 // increased allocation size.
1481
1482 // First, do whatever error checking is appropriate here (e.g. whether
1483 // the caller is trying the change size for a directory, etc.).
1484 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY)
1486
1487 Fcb->NTRequiredFCB->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
1488
1489 if ((FileObject->SectionObjectPointer->DataSectionObject != NULL) &&
1490 (FileObject->SectionObjectPointer->SharedCacheMap == NULL) &&
1491 !FlagOn(Irp->Flags, IRP_PAGING_IO)) {
1493 // Now initialize the cache map.
1494 MmPrint((" CcInitializeCacheMap()\n"));
1496 (PCC_FILE_SIZES)&Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize,
1497 FALSE,
1498 &(UDFGlobalData.CacheMgrCallBacks),
1499 Fcb->NTRequiredFCB );
1500
1501 CacheMapInitialized = TRUE;
1502 }
1503
1504 // Are we increasing the allocation size?
1505 if(Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.QuadPart <
1506 PtrBuffer->AllocationSize.QuadPart) {
1507
1508 // Yes. Do the FSD specific stuff i.e. increase reserved
1509 // space on disk.
1510 if(((LONGLONG)UDFGetFreeSpace(Vcb) << Vcb->LBlockSizeBits) < PtrBuffer->AllocationSize.QuadPart) {
1512 }
1513// RC = STATUS_SUCCESS;
1514 ModifiedAllocSize = TRUE;
1515
1516 } else if(Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.QuadPart >
1517 PtrBuffer->AllocationSize.QuadPart) {
1518 // This is the painful part. See if the VMM will allow us to proceed.
1519 // The VMM will deny the request if:
1520 // (a) any image section exists OR
1521 // (b) a data section exists and the size of the user mapped view
1522 // is greater than the new size
1523 // Otherwise, the VMM should allow the request to proceed.
1524 MmPrint((" MmCanFileBeTruncated()\n"));
1525 if(!MmCanFileBeTruncated(&(Fcb->NTRequiredFCB->SectionObject), &(PtrBuffer->AllocationSize))) {
1526 // VMM said no way!
1528 }
1529
1530 // Perform our directory entry modifications. Release any on-disk
1531 // space we may need to in the process.
1532 ModifiedAllocSize = TRUE;
1533 TruncatedFile = TRUE;
1534 }
1535
1536 ASSERT(NT_SUCCESS(RC));
1537 // This is a good place to check if we have performed a truncate
1538 // operation. If we have perform a truncate (whether we extended
1539 // or reduced file size or even leave it intact), we should update
1540 // file time stamps.
1541 FileObject->Flags |= FO_FILE_MODIFIED;
1542
1543 // Last, but not the lease, we must inform the Cache Manager of file size changes.
1544 if(ModifiedAllocSize) {
1545
1546 // If we decreased the allocation size to less than the
1547 // current file size, modify the file size value.
1548 // Similarly, if we decreased the value to less than the
1549 // current valid data length, modify that value as well.
1550
1551 AcquiredPagingIo = UDFAcquireResourceExclusiveWithCheck(&(Fcb->NTRequiredFCB->PagingIoResource));
1552 // Update the FCB Header with the new allocation size.
1553 if(TruncatedFile) {
1554 if(Fcb->NTRequiredFCB->CommonFCBHeader.ValidDataLength.QuadPart >
1555 PtrBuffer->AllocationSize.QuadPart) {
1556 // Decrease the valid data length value.
1557 Fcb->NTRequiredFCB->CommonFCBHeader.ValidDataLength =
1558 PtrBuffer->AllocationSize;
1559 }
1560 if(Fcb->NTRequiredFCB->CommonFCBHeader.FileSize.QuadPart >
1561 PtrBuffer->AllocationSize.QuadPart) {
1562 // Decrease the file size value.
1563 Fcb->NTRequiredFCB->CommonFCBHeader.FileSize =
1564 PtrBuffer->AllocationSize;
1565 RC = UDFResizeFile__(Vcb, Fcb->FileInfo, PtrBuffer->AllocationSize.QuadPart);
1566// UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo, NULL);
1567 }
1568 } else {
1569 Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize = PtrBuffer->AllocationSize;
1570// UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo,
1571// &(PtrBuffer->AllocationSize.QuadPart));
1572 }
1573 if(AcquiredPagingIo) {
1574 UDFReleaseResource(&(Fcb->NTRequiredFCB->PagingIoResource));
1575 AcquiredPagingIo = FALSE;
1576 }
1577 // If the FCB has not had caching initiated, it is still valid
1578 // for us to invoke the NT Cache Manager. It is possible in such
1579 // situations for the call to be no'oped (unless some user has
1580 // mapped in the file)
1581
1582 // NOTE: The invocation to CcSetFileSizes() will quite possibly
1583 // result in a recursive call back into the file system.
1584 // This is because the NT Cache Manager will typically
1585 // perform a flush before telling the VMM to purge pages
1586 // especially when caching has not been initiated on the
1587 // file stream, but the user has mapped the file into
1588 // the process' virtual address space.
1589 MmPrint((" CcSetFileSizes()\n"));
1590 Fcb->NTRequiredFCB->AcqFlushCount++;
1591 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&(Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize));
1592 Fcb->NTRequiredFCB->AcqFlushCount--;
1593 Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
1594
1595 // Inform any pending IRPs (notify change directory).
1596 if(UDFIsAStream(Fcb->FileInfo)) {
1597 UDFNotifyFullReportChange( Vcb, Fcb->FileInfo,
1600 } else {
1601 UDFNotifyFullReportChange( Vcb, Fcb->FileInfo,
1604 }
1605 }
1606
1607try_exit: NOTHING;
1608
1609 } _SEH2_FINALLY {
1610 if(AcquiredPagingIo) {
1611 UDFReleaseResource(&(Fcb->NTRequiredFCB->PagingIoResource));
1612 AcquiredPagingIo = FALSE;
1613 }
1614 if (CacheMapInitialized) {
1615
1616 MmPrint((" CcUninitializeCacheMap()\n"));
1618 }
1619 } _SEH2_END;
1620 return(RC);
1621} // end UDFSetAllocationInformation()
1622
1623/*
1624 Set end of file (resize).
1625 */
1628 IN PIO_STACK_LOCATION PtrSp,
1631 IN PVCB Vcb,
1633 IN PIRP Irp,
1635 )
1636{
1638 BOOLEAN TruncatedFile = FALSE;
1639 BOOLEAN ModifiedAllocSize = FALSE;
1640 ULONG Attr;
1641 PDIR_INDEX_ITEM DirNdx;
1643 LONGLONG OldFileSize;
1644// BOOLEAN ZeroBlock;
1645 BOOLEAN CacheMapInitialized = FALSE;
1646 BOOLEAN AcquiredPagingIo = FALSE;
1647
1648 AdPrint(("UDFSetEOF\n"));
1649
1650 _SEH2_TRY {
1651 // Increasing the allocation size associated with a file stream
1652 // is relatively easy. All we have to do is execute some FSD
1653 // specific code to check whether we have enough space available
1654 // (and if the FSD supports user/volume quotas, whether the user
1655 // is not exceeding quota), and then increase the file size in the
1656 // corresponding on-disk and in-memory structures.
1657 // Then, all we should do is inform the Cache Manager about the
1658 // increased allocation size.
1659
1660 // First, do whatever error checking is appropriate here (e.g. whether
1661 // the caller is trying the change size for a directory, etc.).
1662 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY)
1664
1665 NtReqFcb = Fcb->NTRequiredFCB;
1666
1667 if((Fcb->FCBFlags & UDF_FCB_DELETED) ||
1668 (NtReqFcb->NtReqFCBFlags & UDF_NTREQ_FCB_DELETED)) {
1669#ifdef UDF_DBG
1670 if(UDFGetFileLinkCount(Fcb->FileInfo) < 1) {
1671 BrutePoint();
1673 } else
1674#endif // UDF_DBG
1676 }
1677
1678 NtReqFcb->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
1679
1680 if ((FileObject->SectionObjectPointer->DataSectionObject != NULL) &&
1681 (FileObject->SectionObjectPointer->SharedCacheMap == NULL) &&
1682 !(Irp->Flags & IRP_PAGING_IO)) {
1684 // Now initialize the cache map.
1685 MmPrint((" CcInitializeCacheMap()\n"));
1687 (PCC_FILE_SIZES)&Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize,
1688 FALSE,
1689 &(UDFGlobalData.CacheMgrCallBacks),
1690 Fcb->NTRequiredFCB );
1691
1692 CacheMapInitialized = TRUE;
1693 }
1694
1695 AcquiredPagingIo = UDFAcquireResourceExclusiveWithCheck(&(Fcb->NTRequiredFCB->PagingIoResource));
1696 // Do a special case here for the lazy write of file sizes.
1697 if(PtrSp->Parameters.SetFile.AdvanceOnly) {
1698 // Never have the dirent filesize larger than the fcb filesize
1699 PtrBuffer->EndOfFile.QuadPart =
1700 min(PtrBuffer->EndOfFile.QuadPart,
1701 NtReqFcb->CommonFCBHeader.FileSize.QuadPart);
1702 // Only advance the file size, never reduce it with this call
1703 RC = STATUS_SUCCESS;
1704 if(UDFGetFileSizeFromDirNdx(Vcb, Fcb->FileInfo) >=
1705 PtrBuffer->EndOfFile.QuadPart)
1706 try_return(RC);
1707
1708 UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo, &(PtrBuffer->EndOfFile.QuadPart));
1709 goto notify_size_changes;
1710 }
1711
1712 // !!! IMPORTANT !!!
1713
1714 // We can get here after all Handles to the file are closed
1715 // To prevent allocation size incoherency we should
1716 // reference FileInfo _before_ call to UDFResizeFile__()
1717 // and use UDFCloseFile__() _after_ that
1718
1719 // Are we increasing the allocation size?
1720 OldFileSize = NtReqFcb->CommonFCBHeader.FileSize.QuadPart;
1721 if(OldFileSize < PtrBuffer->EndOfFile.QuadPart) {
1722
1723 // Yes. Do the FSD specific stuff i.e. increase reserved
1724 // space on disk.
1725/*
1726 if (FileObject->PrivateCacheMap)
1727 ZeroBlock = TRUE;
1728*/
1729
1730 // reference file to pretend that it is opened
1731 UDFReferenceFile__(Fcb->FileInfo);
1732 UDFInterlockedIncrement((PLONG)&(Fcb->ReferenceCount));
1733 UDFInterlockedIncrement((PLONG)&(NtReqFcb->CommonRefCount));
1734 // perform resize operation
1735 RC = UDFResizeFile__(Vcb, Fcb->FileInfo, PtrBuffer->EndOfFile.QuadPart);
1736 // dereference file
1737 UDFCloseFile__(Vcb, Fcb->FileInfo);
1738 UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
1739 UDFInterlockedDecrement((PLONG)&(NtReqFcb->CommonRefCount));
1740 // update values in NtReqFcb
1741 NtReqFcb->CommonFCBHeader.FileSize.QuadPart =
1742// NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart =
1743 PtrBuffer->EndOfFile.QuadPart;
1744 ModifiedAllocSize = TRUE;
1745
1746 } else if(NtReqFcb->CommonFCBHeader.FileSize.QuadPart >
1747 PtrBuffer->EndOfFile.QuadPart) {
1748
1749 // This is the painful part. See if the VMM will allow us to proceed.
1750 // The VMM will deny the request if:
1751 // (a) any image section exists OR
1752 // (b) a data section exists and the size of the user mapped view
1753 // is greater than the new size
1754 // Otherwise, the VMM should allow the request to proceed.
1755
1756 MmPrint((" MmCanFileBeTruncated()\n"));
1757 if(!MmCanFileBeTruncated(&(NtReqFcb->SectionObject), &(PtrBuffer->EndOfFile))) {
1758 // VMM said no way!
1760 }
1761
1762 // Perform directory entry modifications. Release any on-disk
1763 // space we may need to in the process.
1764 UDFReferenceFile__(Fcb->FileInfo);
1765 UDFInterlockedIncrement((PLONG)&(Fcb->ReferenceCount));
1766 UDFInterlockedIncrement((PLONG)&(NtReqFcb->CommonRefCount));
1767 // perform resize operation
1768 RC = UDFResizeFile__(Vcb, Fcb->FileInfo, PtrBuffer->EndOfFile.QuadPart);
1769 // dereference file
1770 UDFCloseFile__(Vcb, Fcb->FileInfo);
1771 UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
1772 UDFInterlockedDecrement((PLONG)&(NtReqFcb->CommonRefCount));
1773
1774 ModifiedAllocSize = TRUE;
1775 TruncatedFile = TRUE;
1776 }
1777
1778 // This is a good place to check if we have performed a truncate
1779 // operation. If we have perform a truncate (whether we extended
1780 // or reduced file size), we should update file time stamps.
1781
1782 // Last, but not the least, we must inform the Cache Manager of file size changes.
1783 if(ModifiedAllocSize && NT_SUCCESS(RC)) {
1784 // If we decreased the allocation size to less than the
1785 // current file size, modify the file size value.
1786 // Similarly, if we decreased the value to less than the
1787 // current valid data length, modify that value as well.
1788 if(TruncatedFile) {
1789 if(NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart >
1790 PtrBuffer->EndOfFile.QuadPart) {
1791 // Decrease the valid data length value.
1792 NtReqFcb->CommonFCBHeader.ValidDataLength =
1793 PtrBuffer->EndOfFile;
1794 }
1795 if(NtReqFcb->CommonFCBHeader.FileSize.QuadPart >
1796 PtrBuffer->EndOfFile.QuadPart) {
1797 // Decrease the file size value.
1798 NtReqFcb->CommonFCBHeader.FileSize =
1799 PtrBuffer->EndOfFile;
1800 }
1801 UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo, NULL);
1802 } else {
1803 // Update the FCB Header with the new allocation size.
1804 // NT expects AllocationSize to be decreased on Close only
1805 NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart =
1806 PtrBuffer->EndOfFile.QuadPart;
1807// UDFSysGetAllocSize(Vcb, UDFGetFileSize(Fcb->FileInfo));
1808 UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo, &(PtrBuffer->EndOfFile.QuadPart));
1809 }
1810
1811 FileObject->Flags |= FO_FILE_MODIFIED;
1812// UDFGetFileAllocationSize(Vcb, Fcb->FileInfo);
1813
1814 // If the FCB has not had caching initiated, it is still valid
1815 // for us to invoke the NT Cache Manager. It is possible in such
1816 // situations for the call to be no'oped (unless some user has
1817 // mapped in the file)
1818
1819 // Archive bit
1820 if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ARCH_BIT) {
1821 DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(Fcb->FileInfo), Fcb->FileInfo->Index);
1822 Ccb->CCBFlags &= ~UDF_CCB_ATTRIBUTES_SET;
1823 Attr = UDFAttributesToNT(DirNdx, Fcb->FileInfo->Dloc->FileEntry);
1824 if(!(Attr & FILE_ATTRIBUTE_ARCHIVE))
1825 UDFAttributesToUDF(DirNdx, Fcb->FileInfo->Dloc->FileEntry, Attr | FILE_ATTRIBUTE_ARCHIVE);
1826 }
1827
1828 // NOTE: The invocation to CcSetFileSizes() will quite possibly
1829 // result in a recursive call back into the file system.
1830 // This is because the NT Cache Manager will typically
1831 // perform a flush before telling the VMM to purge pages
1832 // especially when caching has not been initiated on the
1833 // file stream, but the user has mapped the file into
1834 // the process' virtual address space.
1835 MmPrint((" CcSetFileSizes(), thrd:%8.8x\n",PsGetCurrentThread()));
1836 Fcb->NTRequiredFCB->AcqFlushCount++;
1837 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&(NtReqFcb->CommonFCBHeader.AllocationSize));
1838 Fcb->NTRequiredFCB->AcqFlushCount--;
1839/* if(ZeroBlock) {
1840 UDFZeroDataEx(NtReqFcb,
1841 OldFileSize,
1842 PtrBuffer->EndOfFile.QuadPart - OldFileSize,
1843 TRUE // CanWait, Vcb, FileObject);
1844 }*/
1845 Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
1846
1847notify_size_changes:
1848 if(AcquiredPagingIo) {
1849 UDFReleaseResource(&(Fcb->NTRequiredFCB->PagingIoResource));
1850 AcquiredPagingIo = FALSE;
1851 }
1852
1853 // Inform any pending IRPs (notify change directory).
1854 if(UDFIsAStream(Fcb->FileInfo)) {
1855 UDFNotifyFullReportChange( Vcb, Fcb->FileInfo,
1858 } else {
1859 UDFNotifyFullReportChange( Vcb, Fcb->FileInfo,
1862 }
1863 }
1864
1865try_exit: NOTHING;
1866
1867 } _SEH2_FINALLY {
1868 if(AcquiredPagingIo) {
1869 UDFReleaseResource(&(Fcb->NTRequiredFCB->PagingIoResource));
1870 AcquiredPagingIo = FALSE;
1871 }
1872 if (CacheMapInitialized) {
1873
1874 MmPrint((" CcUninitializeCacheMap()\n"));
1876 }
1877 } _SEH2_END;
1878 return(RC);
1879} // end UDFSetEOF()
1880
1883 PVCB Vcb,
1884 PBOOLEAN AcquiredVcb,
1885 PBOOLEAN AcquiredVcbEx,
1886 PBOOLEAN SingleDir,
1887 PBOOLEAN AcquiredDir1,
1888 PBOOLEAN AcquiredFcb1,
1889 IN PtrUDFCCB Ccb1,
1890 PUDF_FILE_INFO File1,
1891 PUDF_FILE_INFO Dir1,
1892 PUDF_FILE_INFO Dir2,
1893 BOOLEAN HardLink
1894 )
1895{
1896 // convert acquisition to Exclusive
1897 // this will prevent us from the following situation:
1898 // There is a pair of objects among input dirs &
1899 // one of them is a parent of another. Sequential resource
1900 // acquisition may lead to deadlock due to concurrent
1901 // CleanUpFcbChain() or UDFCloseFileInfoChain()
1902 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
1903 UDFReleaseResource(&(Vcb->VCBResource));
1904 (*AcquiredVcb) = FALSE;
1905
1906 // At first, make system to issue last Close request
1907 // for our Source & Target ...
1908 // we needn't flush/purge for Source on HLink
1910 if(!HardLink && (Dir2 != Dir1))
1912
1913#ifdef UDF_DELAYED_CLOSE
1914 _SEH2_TRY {
1915 // Do actual close for all "delayed close" calls
1916
1917 // ... and now remove the rest from our queue
1918 if(!HardLink) {
1920 if(Dir2 != Dir1)
1922 } else {
1924 }
1925
1927 BrutePoint();
1928 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
1930 } _SEH2_END;
1931#endif //UDF_DELAYED_CLOSE
1932
1933 (*SingleDir) = ((Dir1 == Dir2) && (Dir1->Fcb));
1934
1935 if(!(*SingleDir) ||
1936 (UDFGetFileLinkCount(File1) != 1)) {
1937 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
1938 (*AcquiredVcb) = TRUE;
1939 (*AcquiredVcbEx) = TRUE;
1940 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
1941 } else {
1942 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
1943 (*AcquiredVcb) = TRUE;
1944 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
1945
1946 UDF_CHECK_PAGING_IO_RESOURCE(Dir1->Fcb->NTRequiredFCB);
1947 UDFAcquireResourceExclusive(&(Dir1->Fcb->NTRequiredFCB->MainResource),TRUE);
1948 (*AcquiredDir1) = TRUE;
1949
1950 UDF_CHECK_PAGING_IO_RESOURCE(File1->Fcb->NTRequiredFCB);
1951 UDFAcquireResourceExclusive(&(File1->Fcb->NTRequiredFCB->MainResource),TRUE);
1952 (*AcquiredFcb1) = TRUE;
1953 }
1954 return STATUS_SUCCESS;
1955} // end UDFPrepareForRenameMoveLink()
1956
1957/*
1958 Rename or move file
1959 */
1962 IN PIO_STACK_LOCATION PtrSp,
1963 IN PtrUDFFCB Fcb1,
1964 IN PtrUDFCCB Ccb1,
1965 IN PFILE_OBJECT FileObject1, // Source File
1967 )
1968{
1969 // Source Directory
1970 PFILE_OBJECT DirObject1 = FileObject1->RelatedFileObject;
1971 // Target Directory
1972 PFILE_OBJECT DirObject2 = PtrSp->Parameters.SetFile.FileObject;
1973 // Overwite Flag
1974 BOOLEAN Replace = PtrSp->Parameters.SetFile.ReplaceIfExists &&
1975 PtrBuffer->ReplaceIfExists;
1976 NTSTATUS RC;
1977 PVCB Vcb = Fcb1->Vcb;
1978 PtrUDFFCB Fcb2;
1979 BOOLEAN ic;
1980 BOOLEAN AcquiredVcb = TRUE;
1981 BOOLEAN AcquiredVcbEx = FALSE;
1982 BOOLEAN AcquiredDir1 = FALSE;
1983 BOOLEAN AcquiredFcb1 = FALSE;
1984 BOOLEAN SingleDir = TRUE;
1985 BOOLEAN UseClose;
1986
1987 PUDF_FILE_INFO File1;
1988 PUDF_FILE_INFO Dir1;
1989 PUDF_FILE_INFO Dir2;
1990 PUDF_FILE_INFO NextFileInfo, fi;
1991
1993 UNICODE_STRING LocalPath;
1994 PtrUDFCCB CurCcb = NULL;
1996 ULONG i;
1997 ULONG DirRefCount;
1998 ULONG FileInfoRefCount;
1999 ULONG Attr;
2000 PDIR_INDEX_ITEM DirNdx;
2001
2002 AdPrint(("UDFRename %8.8x\n", DirObject2));
2003
2004 LocalPath.Buffer = NULL;
2005
2006 _SEH2_TRY {
2007 // do we try to rename Volume ?
2008#ifdef UDF_ALLOW_RENAME_MOVE
2009 if(!(File1 = Fcb1->FileInfo))
2010#endif //UDF_ALLOW_RENAME_MOVE
2012
2013 // do we try to rename RootDir ?
2014 if(!(Dir1 = File1->ParentFile))
2016
2017 // do we try to rename to RootDir or Volume ?
2018 if(!DirObject2) {
2019 Dir2 = File1->ParentFile;
2020 DirObject2 = DirObject1;
2021 } else
2022 if(DirObject2->FsContext2 &&
2023 (Fcb2 = ((PtrUDFCCB)(DirObject2->FsContext2))->Fcb)) {
2024 Dir2 = ((PtrUDFCCB)(DirObject2->FsContext2))->Fcb->FileInfo;
2025 } else {
2027 }
2028 // invalid destination ?
2029 if(!Dir2) try_return (RC = STATUS_ACCESS_DENIED);
2030
2031 // Stream can't be a Dir or have StreamDir
2032 if(UDFIsAStreamDir(Dir2)) {
2033#ifdef UDF_ENABLE_SECURITY
2034 if(UDFIsADirectory(File1)) {
2036 }
2037 // We should check whether File1 has only Internal
2038 // (or Deleted) streams. In this case SDir should be
2039 // removed (in UDFRenameMoveFile__()). Otherwise
2040 // return STATUS_ACCESS_DENIED
2041 if(UDFHasAStreamDir(File1)) {
2042 UDFPrint(("TODO: We should remove Streams from source file\n"));
2044 }
2045#else //UDF_ENABLE_SECURITY
2046 if(UDFIsADirectory(File1) ||
2047 UDFHasAStreamDir(File1)) {
2049 }
2050#endif //UDF_ENABLE_SECURITY
2051 }
2052
2053 RC = UDFPrepareForRenameMoveLink(Vcb, &AcquiredVcb, &AcquiredVcbEx,
2054 &SingleDir,
2055 &AcquiredDir1, &AcquiredFcb1,
2056 Ccb1, File1,
2057 Dir1, Dir2,
2058 FALSE); // it is Rename operation
2059 if(!NT_SUCCESS(RC))
2060 try_return(RC);
2061
2062 // check if the source file is in use
2063 if(Fcb1->OpenHandleCount > 1)
2065 ASSERT(Fcb1->OpenHandleCount);
2066 ASSERT(!Fcb1->IrpContextLite);
2067 if(Fcb1->IrpContextLite) {
2069 }
2070 // Check if we have parallel/pending Close threads
2071 if(Fcb1->CcbCount && !SingleDir) {
2072 // if this is the 1st attempt, we'll try to
2073 // synchronize with Close requests
2074 // otherwise fail request
2076post_rename:
2077 if(Fcb1->FCBFlags & UDF_FCB_POSTED_RENAME) {
2078 Fcb1->FCBFlags &= ~UDF_FCB_POSTED_RENAME;
2079 try_return (RC);
2080 }
2081 Fcb1->FCBFlags |= UDF_FCB_POSTED_RENAME;
2083 }
2084
2085 if(!DirObject2) {
2086 // Make sure the name is of legal length.
2087 if(PtrBuffer->FileNameLength > UDF_NAME_LEN*sizeof(WCHAR)) {
2089 }
2090 NewName.Length = NewName.MaximumLength = (USHORT)(PtrBuffer->FileNameLength);
2091 NewName.Buffer = (PWCHAR)&(PtrBuffer->FileName);
2092 } else {
2093 // This name is by definition legal.
2094 NewName = *((PUNICODE_STRING)&DirObject2->FileName);
2095 }
2096
2097 ic = (Ccb1->CCBFlags & UDF_CCB_CASE_SENSETIVE) ? FALSE : TRUE;
2098
2099 AdPrint((" %ws ->\n %ws\n",
2100 Fcb1->FCBName->ObjectName.Buffer,
2101 NewName.Buffer));
2102
2103 if(UDFIsDirOpened__(File1)) {
2104 // We can't rename file because of unclean references.
2105 // UDF_INFO package can safely do it, but NT side cannot.
2106 // In this case NT requires STATUS_OBJECT_NAME_COLLISION
2107 // rather than STATUS_ACCESS_DENIED
2108 if(NT_SUCCESS(UDFFindFile__(Vcb, ic, &NewName, Dir2)))
2111 } else {
2112 // Last check before Moving.
2113 // We can't move across Dir referenced (even internally) file
2114 if(!SingleDir) {
2115 RC = UDFDoesOSAllowFileToBeMoved__(File1);
2116 if(!NT_SUCCESS(RC)) {
2117// try_return(RC);
2118 goto post_rename;
2119 }
2120 }
2121
2122 ASSERT_REF(Fcb1->ReferenceCount >= File1->RefCount);
2123 ASSERT_REF(Dir1->Fcb->ReferenceCount >= Dir1->RefCount);
2124 ASSERT_REF(Dir2->Fcb->ReferenceCount >= Dir2->RefCount);
2125
2126 RC = UDFRenameMoveFile__(Vcb, ic, &Replace, &NewName, Dir1, Dir2, File1);
2127 }
2128 if(!NT_SUCCESS(RC))
2129 try_return (RC);
2130
2131 ASSERT(UDFDirIndex(File1->ParentFile->Dloc->DirIndex, File1->Index)->FileInfo == File1);
2132
2133 RC = MyCloneUnicodeString(&LocalPath, (Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ?
2135 &(Dir2->Fcb->FCBName->ObjectName) );
2136 if(!NT_SUCCESS(RC)) try_return (RC);
2137// RC = MyAppendUnicodeStringToString(&LocalPath, (Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ? &(UDFGlobalData.UnicodeStrRoot) : &(Dir2->Fcb->FCBName->ObjectName));
2138// if(!NT_SUCCESS(RC)) try_return (RC);
2139 if(Dir2->ParentFile) {
2140 RC = MyAppendUnicodeToString(&LocalPath, L"\\");
2141 if(!NT_SUCCESS(RC)) try_return (RC);
2142 }
2143 RC = MyAppendUnicodeStringToStringTag(&LocalPath, &NewName, MEM_USREN_TAG);
2144 if(!NT_SUCCESS(RC)) try_return (RC);
2145
2146 // Set Archive bit
2147 DirNdx = UDFDirIndex(File1->ParentFile->Dloc->DirIndex, File1->Index);
2148 if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ARCH_BIT) {
2149 Attr = UDFAttributesToNT(DirNdx, File1->Dloc->FileEntry);
2150 if(!(Attr & FILE_ATTRIBUTE_ARCHIVE))
2152 }
2153 // Update Parent Objects (mark 'em as modified)
2154 if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_DIR_WRITE) {
2155 if(DirObject1)
2156 DirObject1->Flags |= FO_FILE_MODIFIED;
2157 if(DirObject2) {
2158 DirObject2->Flags |= FO_FILE_MODIFIED;
2159 if(!Replace)
2160 DirObject2->Flags |= FO_FILE_SIZE_CHANGED;
2161 }
2162 }
2163 // report changes
2164 if(SingleDir && !Replace) {
2168/* UDFNotifyFullReportChange( Vcb, File2,
2169 UDFIsADirectory(File2) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
2170 FILE_ACTION_RENAMED_NEW_NAME );*/
2171 FsRtlNotifyFullReportChange( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
2172 (PSTRING)&LocalPath,
2173 ((Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ? 0 : Dir2->Fcb->FCBName->ObjectName.Length) + sizeof(WCHAR),
2174 NULL,NULL,
2177 NULL);
2178 } else {
2182 if(Replace) {
2183/* UDFNotifyFullReportChange( Vcb, File2,
2184 FILE_NOTIFY_CHANGE_ATTRIBUTES |
2185 FILE_NOTIFY_CHANGE_SIZE |
2186 FILE_NOTIFY_CHANGE_LAST_WRITE |
2187 FILE_NOTIFY_CHANGE_LAST_ACCESS |
2188 FILE_NOTIFY_CHANGE_CREATION |
2189 FILE_NOTIFY_CHANGE_EA,
2190 FILE_ACTION_MODIFIED );*/
2191 FsRtlNotifyFullReportChange( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
2192 (PSTRING)&LocalPath,
2193 ((Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ?
2194 0 : Dir2->Fcb->FCBName->ObjectName.Length) + sizeof(WCHAR),
2195 NULL,NULL,
2203 NULL);
2204 } else {
2205/* UDFNotifyFullReportChange( Vcb, File2,
2206 UDFIsADirectory(File2) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
2207 FILE_ACTION_ADDED );*/
2208 FsRtlNotifyFullReportChange( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
2209 (PSTRING)&LocalPath,
2210 ((Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ?
2211 0 : Dir2->Fcb->FCBName->ObjectName.Length) + sizeof(WCHAR),
2212 NULL,NULL,
2213 UDFIsADirectory(File1) ?
2217 NULL);
2218 }
2219 }
2220
2221 // this will prevent structutre release before call to
2222 // UDFCleanUpFcbChain()
2223 UDFInterlockedIncrement((PLONG)&(Dir1->Fcb->ReferenceCount));
2224 UDFInterlockedIncrement((PLONG)&(Dir1->Fcb->NTRequiredFCB->CommonRefCount));
2225 ASSERT_REF(Dir1->Fcb->ReferenceCount >= Dir1->RefCount);
2226
2227 // Look through Ccb list & decrement OpenHandleCounter(s)
2228 // acquire CcbList
2229 if(!SingleDir) {
2230 UDFAcquireResourceExclusive(&(Fcb1->CcbListResource),TRUE);
2231 Link = Fcb1->NextCCB.Flink;
2232 DirRefCount = 0;
2233 FileInfoRefCount = 0;
2234 ASSERT(Link != &(Fcb1->NextCCB));
2235 while (Link != &(Fcb1->NextCCB)) {
2236 NextFileInfo = Dir1;
2237 CurCcb = CONTAINING_RECORD(Link, UDFCCB, NextCCB);
2238 ASSERT(CurCcb->TreeLength);
2239 i = (CurCcb->TreeLength) ? (CurCcb->TreeLength - 1) : 0;
2240 Link = Link->Flink;
2241 UseClose = (CurCcb->CCBFlags & UDF_CCB_CLEANED) ? FALSE : TRUE;
2242
2243 AdPrint((" Ccb:%x:%s:i:%x\n", CurCcb, UseClose ? "Close" : "",i));
2244 // cleanup old parent chain
2245 for(; i && NextFileInfo; i--) {
2246 // remember parent file now
2247 // it will prevent us from data losses
2248 // due to eventual structure release
2249 fi = NextFileInfo->ParentFile;
2250 if(UseClose) {
2251 ASSERT_REF(NextFileInfo->Fcb->ReferenceCount >= NextFileInfo->RefCount);
2252 UDFCloseFile__(Vcb, NextFileInfo);
2253 }
2254 ASSERT_REF(NextFileInfo->Fcb->ReferenceCount > NextFileInfo->RefCount);
2255 ASSERT_REF(NextFileInfo->Fcb->ReferenceCount);
2256 ASSERT_REF(NextFileInfo->Fcb->NTRequiredFCB->CommonRefCount);
2257 UDFInterlockedDecrement((PLONG)&(NextFileInfo->Fcb->ReferenceCount));
2258 UDFInterlockedDecrement((PLONG)&(NextFileInfo->Fcb->NTRequiredFCB->CommonRefCount));
2259 ASSERT_REF(NextFileInfo->Fcb->ReferenceCount >= NextFileInfo->RefCount);
2260 NextFileInfo = fi;
2261 }
2262
2263 if(CurCcb->TreeLength > 1) {
2264 DirRefCount++;
2265 if(UseClose)
2266 FileInfoRefCount++;
2267 CurCcb->TreeLength = 2;
2268#ifdef UDF_DBG
2269 } else {
2270 BrutePoint();
2271#endif // UDF_DBG
2272 }
2273 }
2274 UDFReleaseResource(&(Fcb1->CcbListResource));
2275
2276 ASSERT_REF(DirRefCount >= FileInfoRefCount);
2277 // update counters & pointers
2278 Fcb1->ParentFcb = Dir2->Fcb;
2279 // move references to Dir2
2280 UDFInterlockedExchangeAdd((PLONG)&(Dir2->Fcb->ReferenceCount), DirRefCount);
2281 UDFInterlockedExchangeAdd((PLONG)&(Dir2->Fcb->NTRequiredFCB->CommonRefCount), DirRefCount);
2282 ASSERT_REF(Dir2->Fcb->ReferenceCount > Dir2->RefCount);
2283 UDFReferenceFileEx__(Dir2,FileInfoRefCount);
2284 ASSERT_REF(Dir2->Fcb->ReferenceCount >= Dir2->RefCount);
2285 }
2286 ASSERT_REF(Dir2->Fcb->ReferenceCount >= Dir2->RefCount);
2287 ASSERT_REF(Dir2->RefCount);
2288
2289 ASSERT_REF(Dir1->Fcb->ReferenceCount >= Dir1->RefCount);
2290 // Modify name in Fcb1
2291 if(Fcb1->FCBName) {
2292 if(Fcb1->FCBName->ObjectName.Buffer) {
2293 MyFreePool__(Fcb1->FCBName->ObjectName.Buffer);
2294 }
2295 UDFReleaseObjectName(Fcb1->FCBName);
2296 }
2297 Fcb1->FCBName = UDFAllocateObjectName();
2298 if(!(Fcb1->FCBName)) {
2299insuf_res:
2300 BrutePoint();
2301 // UDFCleanUpFcbChain()...
2302 if(AcquiredFcb1) {
2303 UDF_CHECK_PAGING_IO_RESOURCE(Fcb1->NTRequiredFCB);
2304 UDFReleaseResource(&(Fcb1->NTRequiredFCB->MainResource));
2305 AcquiredDir1 = FALSE;
2306 }
2307 if(AcquiredDir1) {
2308 UDF_CHECK_PAGING_IO_RESOURCE(Dir1->Fcb->NTRequiredFCB);
2309 UDFReleaseResource(&(Dir1->Fcb->NTRequiredFCB->MainResource));
2310 AcquiredDir1 = FALSE;
2311 }
2312 UDFCleanUpFcbChain(Vcb, Dir1, 1, TRUE);
2314 }
2315
2316 RC = MyCloneUnicodeString(&(Fcb1->FCBName->ObjectName), &(Fcb2->FCBName->ObjectName));
2317 if(!NT_SUCCESS(RC))
2318 goto insuf_res;
2319/* RC = MyAppendUnicodeStringToString(&(Fcb1->FCBName->ObjectName), &(Fcb2->FCBName->ObjectName));
2320 if(!NT_SUCCESS(RC))
2321 goto insuf_res;*/
2322 // if Dir2 is a RootDir, we shoud not append '\\' because
2323 // uit will be the 2nd '\\' character (RootDir's name is also '\\')
2324 if(Dir2->ParentFile) {
2325 RC = MyAppendUnicodeToString(&(Fcb1->FCBName->ObjectName), L"\\");
2326 if(!NT_SUCCESS(RC))
2327 goto insuf_res;
2328 }
2329 RC = MyAppendUnicodeStringToStringTag(&(Fcb1->FCBName->ObjectName), &NewName, MEM_USREN2_TAG);
2330 if(!NT_SUCCESS(RC))
2331 goto insuf_res;
2332
2333 ASSERT_REF(Fcb1->ReferenceCount >= File1->RefCount);
2334 ASSERT_REF(Dir1->Fcb->ReferenceCount >= Dir1->RefCount);
2335 ASSERT_REF(Dir2->Fcb->ReferenceCount >= Dir2->RefCount);
2336
2337 RC = STATUS_SUCCESS;
2338
2339try_exit: NOTHING;
2340
2341 } _SEH2_FINALLY {
2342
2343 if(AcquiredFcb1) {
2344 UDF_CHECK_PAGING_IO_RESOURCE(Fcb1->NTRequiredFCB);
2345 UDFReleaseResource(&(Fcb1->NTRequiredFCB->MainResource));
2346 }
2347 if(AcquiredDir1) {
2348 UDF_CHECK_PAGING_IO_RESOURCE(Dir1->Fcb->NTRequiredFCB);
2349 UDFReleaseResource(&(Dir1->Fcb->NTRequiredFCB->MainResource));
2350 }
2351 // perform protected structure release
2352 if(NT_SUCCESS(RC) &&
2353 (RC != STATUS_PENDING)) {
2354 ASSERT(AcquiredVcb);
2355 UDFCleanUpFcbChain(Vcb, Dir1, 1, TRUE);
2356 ASSERT_REF(Fcb1->ReferenceCount >= File1->RefCount);
2357 ASSERT_REF(Dir2->Fcb->ReferenceCount >= Dir2->RefCount);
2358 }
2359
2360 if(AcquiredVcb) {
2361 if(AcquiredVcbEx)
2362 UDFConvertExclusiveToSharedLite(&(Vcb->VCBResource));
2363 } else {
2364 // caller assumes Vcb to be acquired shared
2365 BrutePoint();
2366 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
2367 }
2368
2369 if(LocalPath.Buffer) {
2370 MyFreePool__(LocalPath.Buffer);
2371 }
2372 } _SEH2_END;
2373
2374 return RC;
2375} // end UDFRename()
2376
2377#endif //UDF_READ_ONLY_BUILD
2378
2379LONG
2381 IN PVCB Vcb,
2382 IN LONGLONG Id
2383 )
2384{
2385 if(!Vcb->FileIdCache) return (-1);
2386 for(ULONG i=0; i<Vcb->FileIdCount; i++) {
2387 if(Vcb->FileIdCache[i].Id == Id) return i;
2388 }
2389 return (-1);
2390} // end UDFFindFileId()
2391
2392LONG
2394 IN PVCB Vcb,
2395 IN LONGLONG Id
2396 )
2397{
2398 if(!Vcb->FileIdCache) {
2400 return (-1);
2402 Vcb->FileIdCount = FILE_ID_CACHE_GRANULARITY;
2403 }
2404 for(ULONG i=0; i<Vcb->FileIdCount; i++) {
2405 if(!Vcb->FileIdCache[i].FullName.Buffer) return i;
2406 }
2407 if(!MyReallocPool__((PCHAR)(Vcb->FileIdCache), Vcb->FileIdCount*sizeof(UDFFileIDCacheItem),
2408 (PCHAR*)&(Vcb->FileIdCache), (Vcb->FileIdCount+FILE_ID_CACHE_GRANULARITY)*sizeof(UDFFileIDCacheItem))) {
2409 return (-1);
2410 }
2411 RtlZeroMemory(&(Vcb->FileIdCache[Vcb->FileIdCount]), FILE_ID_CACHE_GRANULARITY*sizeof(UDFFileIDCacheItem));
2412 Vcb->FileIdCount += FILE_ID_CACHE_GRANULARITY;
2413 return (Vcb->FileIdCount - FILE_ID_CACHE_GRANULARITY);
2414} // end UDFFindFreeFileId()
2415
2418 IN PVCB Vcb,
2420 IN PUDF_FILE_INFO fi,
2421 IN LONGLONG Id
2422 )
2423{
2424 LONG i;
2426
2427 if((i = UDFFindFileId(Vcb, Id)) == (-1)) {
2428 if((i = UDFFindFreeFileId(Vcb, Id)) == (-1)) return STATUS_INSUFFICIENT_RESOURCES;
2429 } else {
2430 return STATUS_SUCCESS;
2431 }
2432 Vcb->FileIdCache[i].Id = Id;
2433 Vcb->FileIdCache[i].CaseSens = (Ccb->CCBFlags & UDF_CCB_CASE_SENSETIVE) ? TRUE : FALSE;
2434 RC = MyCloneUnicodeString(&(Vcb->FileIdCache[i].FullName), &(Ccb->Fcb->FCBName->ObjectName));
2435/* if(NT_SUCCESS(RC)) {
2436 RC = MyAppendUnicodeStringToStringTag(&(Vcb->FileIdCache[i].FullName), &(Ccb->Fcb->FCBName->ObjectName), MEM_USFIDC_TAG);
2437 }*/
2438 return RC;
2439} // end UDFStoreFileId()
2440
2443 IN PVCB Vcb,
2444 IN LONGLONG Id
2445 )
2446{
2447 LONG i;
2448
2449 if((i = UDFFindFileId(Vcb, Id)) == (-1)) return STATUS_INVALID_PARAMETER;
2450 MyFreePool__(Vcb->FileIdCache[i].FullName.Buffer);
2451 RtlZeroMemory(&(Vcb->FileIdCache[i]), sizeof(UDFFileIDCacheItem));
2452 return STATUS_SUCCESS;
2453} // end UDFRemoveFileId()
2454
2455VOID
2457 IN PVCB Vcb
2458 )
2459{
2460 if(!Vcb->FileIdCache) return;
2461 for(ULONG i=0; i<Vcb->FileIdCount; i++) {
2462 if(Vcb->FileIdCache[i].FullName.Buffer) {
2463 MyFreePool__(Vcb->FileIdCache[i].FullName.Buffer);
2464 }
2465 }
2466 MyFreePool__(Vcb->FileIdCache);
2467 Vcb->FileIdCache = NULL;
2468 Vcb->FileIdCount = 0;
2469} // end UDFReleaseFileIdCache()
2470
2473 IN PVCB Vcb,
2474 IN LONGLONG Id,
2475 OUT PUNICODE_STRING* FName,
2476 OUT BOOLEAN* CaseSens
2477 )
2478{
2479 LONG i;
2480
2481 if((i = UDFFindFileId(Vcb, Id)) == (-1)) return STATUS_NOT_FOUND;
2482 (*FName) = &(Vcb->FileIdCache[i].FullName);
2483 (*CaseSens) = !(Vcb->FileIdCache[i].CaseSens);
2484 return STATUS_SUCCESS;
2485} // end UDFGetOpenParamsByFileId()
2486
2487#ifndef UDF_READ_ONLY_BUILD
2488
2489#ifdef UDF_ALLOW_HARD_LINKS
2490/*
2491 create hard link for the file
2492 */
2495 IN PIO_STACK_LOCATION PtrSp,
2496 IN PtrUDFFCB Fcb1,
2497 IN PtrUDFCCB Ccb1,
2498 IN PFILE_OBJECT FileObject1, // Source File
2499 IN PFILE_LINK_INFORMATION PtrBuffer
2500 )
2501{
2502 // Target Directory
2503 PFILE_OBJECT DirObject2 = PtrSp->Parameters.SetFile.FileObject;
2504 // Overwite Flag
2505 BOOLEAN Replace = PtrSp->Parameters.SetFile.ReplaceIfExists &&
2506 PtrBuffer->ReplaceIfExists;
2507 NTSTATUS RC;
2508 PVCB Vcb = Fcb1->Vcb;
2509 PtrUDFFCB Fcb2;
2510 BOOLEAN ic;
2511 BOOLEAN AcquiredVcb = TRUE;
2512 BOOLEAN AcquiredVcbEx = FALSE;
2513 BOOLEAN AcquiredDir1 = FALSE;
2514 BOOLEAN AcquiredFcb1 = FALSE;
2515 BOOLEAN SingleDir = TRUE;
2516
2517 PUDF_FILE_INFO File1;
2518 PUDF_FILE_INFO Dir1 = NULL;
2519 PUDF_FILE_INFO Dir2;
2520
2522 UNICODE_STRING LocalPath;
2523// PtrUDFCCB CurCcb = NULL;
2524
2525 AdPrint(("UDFHardLink\n"));
2526
2527 LocalPath.Buffer = NULL;
2528
2529 _SEH2_TRY {
2530
2531 // do we try to link Volume ?
2532 if(!(File1 = Fcb1->FileInfo))
2534
2535 // do we try to link RootDir ?
2536 if(!(Dir1 = File1->ParentFile))
2538
2539 // do we try to link Stream / Stream Dir ?
2540#ifdef UDF_ALLOW_LINKS_TO_STREAMS
2541 if(UDFIsAStreamDir(File1))
2543#else //UDF_ALLOW_LINKS_TO_STREAMS
2544 if(UDFIsAStream(File1) || UDFIsAStreamDir(File1) /*||
2545 UDFIsADirectory(File1) || UDFHasAStreamDir(File1)*/)
2547#endif // UDF_ALLOW_LINKS_TO_STREAMS
2548
2549 // do we try to link to RootDir or Volume ?
2550 if(!DirObject2) {
2551 Dir2 = File1->ParentFile;
2552 DirObject2 = FileObject1->RelatedFileObject;
2553 } else
2554 if(DirObject2->FsContext2 &&
2555 (Fcb2 = ((PtrUDFCCB)(DirObject2->FsContext2))->Fcb)) {
2556 Dir2 = ((PtrUDFCCB)(DirObject2->FsContext2))->Fcb->FileInfo;
2557 } else {
2559 }
2560
2561 // check target dir
2562 if(!Dir2) try_return (RC = STATUS_ACCESS_DENIED);
2563
2564 // Stream can't be a Dir or have Streams
2565 if(UDFIsAStreamDir(Dir2)) {
2567/* if(UDFIsADirectory(File1) ||
2568 UDFHasAStreamDir(File1)) {
2569 BrutePoint();
2570 try_return (RC = STATUS_ACCESS_DENIED);
2571 }*/
2572 }
2573
2574/* if(UDFIsAStreamDir(Dir2))
2575 try_return (RC = STATUS_ACCESS_DENIED);*/
2576
2577 RC = UDFPrepareForRenameMoveLink(Vcb, &AcquiredVcb, &AcquiredVcbEx,
2578 &SingleDir,
2579 &AcquiredDir1, &AcquiredFcb1,
2580 Ccb1, File1,
2581 Dir1, Dir2,
2582 TRUE); // it is HLink operation
2583 if(!NT_SUCCESS(RC))
2584 try_return(RC);
2585
2586 // check if the source file is used
2587 if(!DirObject2) {
2588 // Make sure the name is of legal length.
2589 if(PtrBuffer->FileNameLength > UDF_NAME_LEN*sizeof(WCHAR)) {
2591 }
2592 NewName.Length = NewName.MaximumLength = (USHORT)(PtrBuffer->FileNameLength);
2593 NewName.Buffer = (PWCHAR)&(PtrBuffer->FileName);
2594 } else {
2595 // This name is by definition legal.
2596 NewName = *((PUNICODE_STRING)&DirObject2->FileName);
2597 }
2598
2599 ic = (Ccb1->CCBFlags & UDF_CCB_CASE_SENSETIVE) ? FALSE : TRUE;
2600
2601 AdPrint((" %ws ->\n %ws\n",
2602 Fcb1->FCBName->ObjectName.Buffer,
2603 NewName.Buffer));
2604
2605 RC = UDFHardLinkFile__(Vcb, ic, &Replace, &NewName, Dir1, Dir2, File1);
2606 if(!NT_SUCCESS(RC)) try_return (RC);
2607
2608 // Update Parent Objects (mark 'em as modified)
2609 if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_DIR_WRITE) {
2610 if(DirObject2) {
2611 DirObject2->Flags |= FO_FILE_MODIFIED;
2612 if(!Replace)
2613 DirObject2->Flags |= FO_FILE_SIZE_CHANGED;
2614 }
2615 }
2616 // report changes
2621
2622 RC = MyCloneUnicodeString(&LocalPath, (Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ?
2624 &(Dir2->Fcb->FCBName->ObjectName));
2625 if(!NT_SUCCESS(RC)) try_return (RC);
2626/* RC = MyAppendUnicodeStringToString(&LocalPath, (Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ? &(UDFGlobalData.UnicodeStrRoot) : &(Dir2->Fcb->FCBName->ObjectName));
2627 if(!NT_SUCCESS(RC)) try_return (RC);*/
2628 // if Dir2 is a RootDir, we shoud not append '\\' because
2629 // it will be the 2nd '\\' character (RootDir's name is also '\\')
2630 if(Dir2->ParentFile) {
2631 RC = MyAppendUnicodeToString(&LocalPath, L"\\");
2632 if(!NT_SUCCESS(RC)) try_return (RC);
2633 }
2634 RC = MyAppendUnicodeStringToStringTag(&LocalPath, &NewName, MEM_USHL_TAG);
2635 if(!NT_SUCCESS(RC)) try_return (RC);
2636
2637 if(!Replace) {
2638/* UDFNotifyFullReportChange( Vcb, File2,
2639 UDFIsADirectory(File1) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
2640 FILE_ACTION_ADDED );*/
2641 FsRtlNotifyFullReportChange( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
2642 (PSTRING)&LocalPath,
2643 ((Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ? 0 : Dir2->Fcb->FCBName->ObjectName.Length) + sizeof(WCHAR),
2644 NULL,NULL,
2647 NULL);
2648 } else {
2649/* UDFNotifyFullReportChange( Vcb, File2,
2650 FILE_NOTIFY_CHANGE_ATTRIBUTES |
2651 FILE_NOTIFY_CHANGE_SIZE |
2652 FILE_NOTIFY_CHANGE_LAST_WRITE |
2653 FILE_NOTIFY_CHANGE_LAST_ACCESS |
2654 FILE_NOTIFY_CHANGE_CREATION |
2655 FILE_NOTIFY_CHANGE_EA,
2656 FILE_ACTION_MODIFIED );*/
2657 FsRtlNotifyFullReportChange( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
2658 (PSTRING)&LocalPath,
2659 ((Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ? 0 : Dir2->Fcb->FCBName->ObjectName.Length) + sizeof(WCHAR),
2660 NULL,NULL,
2668 NULL);
2669 }
2670
2671 RC = STATUS_SUCCESS;
2672
2673try_exit: NOTHING;
2674
2675 } _SEH2_FINALLY {
2676
2677 if(AcquiredFcb1) {
2678 UDF_CHECK_PAGING_IO_RESOURCE(Fcb1->NTRequiredFCB);
2679 UDFReleaseResource(&(Fcb1->NTRequiredFCB->MainResource));
2680 }
2681 if(AcquiredDir1) {
2682 UDF_CHECK_PAGING_IO_RESOURCE(Dir1->Fcb->NTRequiredFCB);
2683 UDFReleaseResource(&(Dir1->Fcb->NTRequiredFCB->MainResource));
2684 }
2685 if(AcquiredVcb) {
2686 if(AcquiredVcbEx)
2687 UDFConvertExclusiveToSharedLite(&(Vcb->VCBResource));
2688 } else {
2689 // caller assumes Vcb to be acquired shared
2690 BrutePoint();
2691 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
2692 }
2693
2694 if(LocalPath.Buffer) {
2695 MyFreePool__(LocalPath.Buffer);
2696 }
2697 } _SEH2_END;
2698
2699 return RC;
2700} // end UDFHardLink()
2701#endif //UDF_ALLOW_HARD_LINKS
2702
2703#endif //UDF_READ_ONLY_BUILD
DWORD Id
unsigned char BOOLEAN
VOID UDFSetFileXTime(IN PUDF_FILE_INFO FileInfo, IN LONGLONG *CrtTime, IN LONGLONG *AccTime, IN LONGLONG *AttrTime, IN LONGLONG *ChgTime)
VOID UDFAttributesToUDF(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry, IN ULONG NTAttr)
ULONG UDFAttributesToNT(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry)
NTSTATUS MyCloneUnicodeString(IN PUNICODE_STRING Str1, IN PUNICODE_STRING Str2)
NTSTATUS UDFFileDirInfoToNT(IN PVCB Vcb, IN PDIR_INDEX_ITEM FileDirNdx, OUT PFILE_BOTH_DIR_INFORMATION NTFileInfo)
int64 __fastcall UDFGetFreeSpace(IN PVCB Vcb)
Definition: alloc.cpp:1105
LONG NTSTATUS
Definition: precomp.h:26
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
r l[0]
Definition: byte_order.h:168
_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
struct _VCB * PVCB
Definition: fatstruc.h:557
ULONG UDFCleanUpFcbChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: close.cpp:400
_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:32
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
void Replace(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LONG radius)
Definition: drawing.cpp:132
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
BOOLEAN UDFAcquireResourceExclusiveWithCheck(IN PERESOURCE Resource)
Definition: misc.cpp:2529
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 UDFReleaseObjectName(PtrUDFObjectName PtrObjectName)
Definition: misc.cpp:670
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
PtrUDFObjectName UDFAllocateObjectName(VOID)
Definition: misc.cpp:611
__inline VOID UDFNotifyFullReportChange(PVCB V, PUDF_FILE_INFO FI, ULONG E, ULONG A)
Definition: env_spec.h:99
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define UDFConvertExclusiveToSharedLite(Resource)
Definition: env_spec_w32.h:665
#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 TmPrint(_x_)
Definition: env_spec_w32.h:290
#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 FlagOn(_F, _SF)
Definition: ext2fs.h:179
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible(IN PtrUDFFCB Fcb)
Definition: fastio.cpp:118
#define NtReqFcb
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1306
NTSTATUS UDFRemoveFileId(IN PVCB Vcb, IN LONGLONG Id)
Definition: fileinfo.cpp:2442
NTSTATUS UDFGetFileStreamInformation(IN PtrUDFFCB Fcb, IN PFILE_STREAM_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:930
#define MEM_USREN2_TAG
Definition: fileinfo.cpp:24
NTSTATUS UDFGetEaInformation(PtrUDFIrpContext PtrIrpContext, IN PtrUDFFCB Fcb, IN PFILE_EA_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:801
NTSTATUS UDFSetBasicInformation(IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PFILE_OBJECT FileObject, IN PFILE_BASIC_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:1013
NTSTATUS UDFGetInternalInformation(PtrUDFIrpContext PtrIrpContext, IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PFILE_INTERNAL_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:747
LONG UDFFindFreeFileId(IN PVCB Vcb, IN LONGLONG Id)
Definition: fileinfo.cpp:2393
NTSTATUS UDFSetAllocationInformation(IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PFILE_ALLOCATION_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:1454
NTSTATUS UDFPrepareForRenameMoveLink(PVCB Vcb, PBOOLEAN AcquiredVcb, PBOOLEAN AcquiredVcbEx, PBOOLEAN SingleDir, PBOOLEAN AcquiredDir1, PBOOLEAN AcquiredFcb1, IN PtrUDFCCB Ccb1, PUDF_FILE_INFO File1, PUDF_FILE_INFO Dir1, PUDF_FILE_INFO Dir2, BOOLEAN HardLink)
Definition: fileinfo.cpp:1882
LONG UDFFindFileId(IN PVCB Vcb, IN LONGLONG Id)
Definition: fileinfo.cpp:2380
NTSTATUS UDFSetEOF(IN PIO_STACK_LOCATION PtrSp, IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN PIRP Irp, IN PFILE_END_OF_FILE_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:1627
NTSTATUS UDFGetBasicInformation(IN PFILE_OBJECT FileObject, IN PtrUDFFCB Fcb, IN PFILE_BASIC_INFORMATION PtrBuffer, IN OUT LONG *PtrReturnedLength)
Definition: fileinfo.cpp:532
NTSTATUS UDFCommonFileInfo(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: fileinfo.cpp:114
NTSTATUS UDFGetFullNameInformation(IN PFILE_OBJECT FileObject, IN PFILE_NAME_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:836
NTSTATUS UDFMarkStreamsForDeletion(IN PVCB Vcb, IN PtrUDFFCB Fcb, IN BOOLEAN ForDel)
Definition: fileinfo.cpp:1137
#define MEM_USREN_TAG
Definition: fileinfo.cpp:23
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
NTSTATUS UDFRename(IN PIO_STACK_LOCATION PtrSp, IN PtrUDFFCB Fcb1, IN PtrUDFCCB Ccb1, IN PFILE_OBJECT FileObject1, IN PFILE_RENAME_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:1961
NTSTATUS UDFStoreFileId(IN PVCB Vcb, IN PtrUDFCCB Ccb, IN PUDF_FILE_INFO fi, IN LONGLONG Id)
Definition: fileinfo.cpp:2417
NTSTATUS UDFGetPositionInformation(IN PFILE_OBJECT FileObject, IN PFILE_POSITION_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:910
NTSTATUS UDFGetOpenParamsByFileId(IN PVCB Vcb, IN LONGLONG Id, OUT PUNICODE_STRING *FName, OUT BOOLEAN *CaseSens)
Definition: fileinfo.cpp:2472
#define MEM_USHL_TAG
Definition: fileinfo.cpp:26
VOID UDFReleaseFileIdCache(IN PVCB Vcb)
Definition: fileinfo.cpp:2456
NTSTATUS NTAPI UDFFileInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: fileinfo.cpp:46
NTSTATUS UDFSetDispositionInformation(IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN BOOLEAN Delete)
Definition: fileinfo.cpp:1340
NTSTATUS UDFHardLink(IN PIO_STACK_LOCATION PtrSp, IN PtrUDFFCB Fcb1, IN PtrUDFCCB Ccb1, IN PFILE_OBJECT FileObject1, IN PFILE_LINK_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:2494
NTSTATUS UDFGetAltNameInformation(IN PtrUDFFCB Fcb, IN PFILE_NAME_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:869
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
VOID UDFFlushTryBreak(IN PVCB Vcb)
Definition: flush.cpp:625
struct _FILE_BOTH_DIR_INFORMATION * PFILE_BOTH_DIR_INFORMATION
@ FilePositionInformation
Definition: from_kernel.h:75
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileAllInformation
Definition: from_kernel.h:79
@ FileLinkInformation
Definition: from_kernel.h:72
@ FileInternalInformation
Definition: from_kernel.h:67
@ FileEaInformation
Definition: from_kernel.h:68
@ FileAlternateNameInformation
Definition: from_kernel.h:82
@ FileNameInformation
Definition: from_kernel.h:70
@ FileAllocationInformation
Definition: from_kernel.h:80
@ FileNetworkOpenInformation
Definition: from_kernel.h:95
@ FileStreamInformation
Definition: from_kernel.h:83
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
struct _FILE_INTERNAL_INFORMATION FILE_INTERNAL_INFORMATION
#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 CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
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
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
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
struct _FILE_MODE_INFORMATION FILE_MODE_INFORMATION
struct _FILE_ALL_INFORMATION * PFILE_ALL_INFORMATION
struct _FILE_EA_INFORMATION FILE_EA_INFORMATION
struct _FILE_STREAM_INFORMATION FILE_STREAM_INFORMATION
#define NOTHING
Definition: input_list.c:10
#define d
Definition: ke_i.h:81
#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
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
#define min(a, b)
Definition: monoChain.cc:55
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_DELETE_CHILD
Definition: nt_native.h:645
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION
struct _FILE_ALIGNMENT_INFORMATION FILE_ALIGNMENT_INFORMATION
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
struct _FILE_POSITION_INFORMATION * PFILE_POSITION_INFORMATION
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
VOID NTAPI FsRtlNotifyFullReportChange(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PSTRING FullTargetName, IN USHORT TargetNameOffset, IN PSTRING StreamName OPTIONAL, IN PSTRING NormalizedParentName OPTIONAL, IN ULONG FilterMatch, IN ULONG Action, IN PVOID TargetContext)
Definition: notify.c:1552
VOID NTAPI FsRtlNotifyFullChangeDirectory(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN BOOLEAN WatchTree, IN BOOLEAN IgnoreBuffer, IN ULONG CompletionFilter, IN PIRP NotifyIrp, IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL)
Definition: notify.c:1487
#define IoCompleteRequest
Definition: irp.c:1240
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
NTSTATUS NTAPI IoCheckFunctionAccess(IN ACCESS_MASK GrantedAccess, IN UCHAR MajorFunction, IN UCHAR MinorFunction, IN ULONG IoControlCode, IN PVOID ExtraData OPTIONAL, IN PVOID ExtraData2 OPTIONAL)
Definition: util.c:276
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:711
#define L(x)
Definition: ntvdm.h:50
#define UDF_NAME_LEN
Definition: osta_misc.h:314
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define Vcb
Definition: cdprocs.h:1415
#define FileStandardInformation
Definition: propsheet.cpp:61
NTSTATUS UDFCheckAccessRights(PFILE_OBJECT FileObject, PACCESS_STATE AccessState, PtrUDFFCB Fcb, PtrUDFCCB Ccb, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
Definition: secursup.cpp:927
#define UDFRemoveFromSystemDelayedQueue(Fcb)
Definition: protos.h:109
#define UDFRemoveFromDelayedQueue(Fcb)
Definition: protos.h:106
#define UDFCloseAllDelayedInDir(Vcb, FI)
Definition: protos.h:96
#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_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
BOOLEAN NTAPI MmCanFileBeTruncated(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER NewFileSize)
Definition: section.c:4255
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4356
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define UDF_FCB_READ_ONLY
Definition: struct.h:312
#define UDF_CCB_CREATE_TIME_SET
Definition: struct.h:155
#define UDF_FCB_PAGE_FILE
Definition: struct.h:302
#define UDF_CCB_ATTRIBUTES_SET
Definition: struct.h:157
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
#define UDF_FCB_DELETED
Definition: struct.h:314
#define UDF_FCB_POSTED_RENAME
Definition: struct.h:317
struct _UDFContextControlBlock * PtrUDFCCB
#define UDF_CCB_ACCESS_TIME_SET
Definition: struct.h:153
#define UDF_CCB_CASE_SENSETIVE
Definition: struct.h:159
#define UDF_FCB_ROOT_DIRECTORY
Definition: struct.h:304
#define UDF_CCB_CLEANED
Definition: struct.h:146
#define UDF_NTREQ_FCB_DELETED
Definition: struct.h:235
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDF_CCB_MODIFY_TIME_SET
Definition: struct.h:154
#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_FCB_DELETE_PARENT
Definition: struct.h:319
#define UDF_CCB_WRITE_TIME_SET
Definition: struct.h:156
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
PVOID DeviceExtension
Definition: env_spec_w32.h:418
UNICODE_STRING FName
Definition: udf_rel.h:173
struct _UDF_FILE_INFO * FileInfo
Definition: udf_rel.h:204
int64 CreationTime
Definition: udf_rel.h:209
int64 LastAccessTime
Definition: udf_rel.h:211
uint8 FI_Flags
Definition: udf_rel.h:199
int64 LastWriteTime
Definition: udf_rel.h:210
int64 ChangeTime
Definition: udf_rel.h:212
struct _FCB * ParentFcb
Definition: cdstruc.h:940
LONGLONG CreationTime
Definition: cdstruc.h:1030
PVCB Vcb
Definition: cdstruc.h:933
ERESOURCE PagingIoResource
Definition: ntfs.h:527
struct _FCB::@720::@723 Fcb
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:922
WCHAR * ObjectName
Definition: ntfs.h:524
LARGE_INTEGER LastAccessTime
Definition: fatstruc.h:921
ULONG FileAttributes
Definition: cdstruc.h:977
FILE_STANDARD_INFORMATION StandardInformation
Definition: winternl.h:797
FILE_EA_INFORMATION EaInformation
Definition: winternl.h:799
FILE_INTERNAL_INFORMATION InternalInformation
Definition: winternl.h:798
FILE_NAME_INFORMATION NameInformation
Definition: winternl.h:804
FILE_POSITION_INFORMATION PositionInformation
Definition: winternl.h:801
FILE_BASIC_INFORMATION BasicInformation
Definition: winternl.h:796
LARGE_INTEGER AllocationSize
Definition: from_kernel.h:146
LARGE_INTEGER CurrentByteOffset
Definition: nt_native.h:955
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
Definition: typedefs.h:120
UNICODE_STRING UnicodeStrRoot
Definition: udf_common.h:616
PtrUDFObjectName FCBName
Definition: struct.h:286
uint32 IrpContextFlags
Definition: struct.h:364
uint8 MinorFunction
Definition: struct.h:368
uint8 MajorFunction
Definition: struct.h:366
UNICODE_STRING ObjectName
Definition: struct.h:94
PDIR_INDEX_HDR DirIndex
Definition: udf_rel.h:312
PUDF_DATALOC_INFO Dloc
Definition: udf_rel.h:367
struct _UDFFileControlBlock * Fcb
Definition: udf_rel.h:362
uint32 RefCount
Definition: udf_rel.h:399
struct _UDF_FILE_INFO * ParentFile
Definition: udf_rel.h:381
uint_di Index
Definition: udf_rel.h:392
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: cdstruc.h:498
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define FILE_ID_CACHE_GRANULARITY
Definition: udf_common.h:653
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
#define UDF_VCB_IC_UPDATE_ARCH_BIT
Definition: udf_common.h:496
#define UDF_VCB_IC_UPDATE_UCHG_DIR_ACCESS_TIME
Definition: udf_common.h:500
#define UDF_VCB_IC_UPDATE_DIR_WRITE
Definition: udf_common.h:497
#define UDF_VCB_SKIP_EJECT_CHECK
Definition: udf_common.h:470
#define ASSERT_REF(_a_)
Definition: udf_dbg.h:267
OSSTATUS UDFHardLinkFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN OUT BOOLEAN *Replace, IN PUNICODE_STRING fn, IN OUT PUDF_FILE_INFO DirInfo1, IN OUT PUDF_FILE_INFO DirInfo2, IN OUT PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:4672
OSSTATUS UDFRenameMoveFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN OUT BOOLEAN *Replace, IN PUNICODE_STRING fn, IN OUT PUDF_FILE_INFO DirInfo1, IN OUT PUDF_FILE_INFO DirInfo2, IN OUT PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:3176
uint16 UDFGetFileLinkCount(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1355
int64 UDFGetFileSize(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1236
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
OSSTATUS UDFOpenStreamDir__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, OUT PUDF_FILE_INFO *_SDirInfo)
Definition: udf_info.cpp:4965
void UDFSetFileSizeInDirNdx(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 *ASize)
Definition: udf_info.cpp:1190
int64 UDFGetFileSizeFromDirNdx(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1256
OSSTATUS UDFResizeFile__(IN PVCB Vcb, IN OUT PUDF_FILE_INFO FileInfo, IN int64 NewLength)
Definition: udf_info.cpp:3468
OSSTATUS UDFOpenFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN BOOLEAN NotDeleted, IN PUNICODE_STRING fn, IN PUDF_FILE_INFO DirInfo, OUT PUDF_FILE_INFO *_FileInfo, IN uint_di *IndexToOpen)
Definition: udf_info.cpp:2004
#define UDFIsSDirDeleted(FI)
Definition: udf_info.h:1004
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
#define UDFHasAStreamDir(FI)
Definition: udf_info.h:1000
#define UDFIsDirOpened__(fi)
Definition: udf_info.h:1071
#define UDFIsDeleted(DirNdx)
Definition: udf_info.h:788
#define UDFIsDirEmpty__(fi)
Definition: udf_info.h:1070
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
__inline OSSTATUS UDFFindFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN PUNICODE_STRING Name, IN PUDF_FILE_INFO DirInfo)
Definition: udf_info.h:114
#define UDFIsAStreamDir(FI)
Definition: udf_info.h:998
#define UDFDOSName__(Vcb, DosName, UdfName, FileInfo)
Definition: udf_info.h:217
#define UDFDirIndexGetLastIndex(di)
Definition: udf_info.h:1122
#define UDFReferenceFileEx__(fi, i)
Definition: udf_info.h:1052
#define UDFIsADirectory(FileInfo)
Definition: udf_info.h:792
#define UDFIsAStream(FI)
Definition: udf_info.h:1002
uint32 uint_di
Definition: udf_rel.h:29
#define UDF_FI_FLAG_FI_INTERNAL
Given entry represents the file used for internal FS purposes & must be invisible.
Definition: udf_rel.h:221
#define UDF_FE_FLAG_FE_MODIFIED
Was modified & should be flushed.
Definition: udf_rel.h:323
#define UDF_FI_FLAG_SYS_ATTR
Given entry of file list contains valid file attributes & times in NT-specific format.
Definition: udf_rel.h:219
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define UDFInterlockedExchangeAdd(addr, i)
Definition: udffs.h:257
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:262
#define UDFPrint(Args)
Definition: udffs.h:225
ULONG LowPart
Definition: typedefs.h:106
static int Link(const char **args)
Definition: vfdcmd.c:2414
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
#define DeleteFile
Definition: winbase.h:3699
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define FILE_ACTION_MODIFIED_STREAM
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_ACTION_MODIFIED
#define FO_TEMPORARY_FILE
Definition: iotypes.h:1791
#define IRP_PAGING_IO
#define FILE_ACTION_RENAMED_OLD_NAME
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define FILE_ACTION_REMOVED
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
#define FILE_NOTIFY_CHANGE_FILE_NAME
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
#define FILE_NOTIFY_CHANGE_STREAM_SIZE
* PFILE_OBJECT
Definition: iotypes.h:1998
#define FILE_ACTION_RENAMED_NEW_NAME
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1789
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1778
#define FILE_NOTIFY_CHANGE_CREATION
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define FILE_NOTIFY_CHANGE_EA
#define FILE_ACTION_ADDED
#define FILE_NOTIFY_CHANGE_DIR_NAME
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID _Out_ PIO_STATUS_BLOCK _In_ ULONG NotifyFilter
Definition: zwfuncs.h:504
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203