ReactOS  0.4.14-dev-49-gfb4591c
fileinfo.cpp
Go to the documentation of this file.
1 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 // This file was released under the GPLv2 on June 2015.
6 /*************************************************************************
7 *
8 * File: 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 *************************************************************************/
45 NTAPI
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 *************************************************************************/
113 NTSTATUS
115  PtrUDFIrpContext PtrIrpContext,
116  PIRP Irp
117  )
118 {
122  PtrUDFFCB Fcb = NULL;
123  PtrUDFCCB Ccb = NULL;
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;
259  case FileEaInformation:
260  RC = UDFGetEaInformation(PtrIrpContext, Fcb, (PFILE_EA_INFORMATION) PtrSystemBuffer, &BufferLength);
261  break;
262  case FileNameInformation:
264  break;
267  break;
268 // case FileCompressionInformation:
269 // // RC = UDFGetCompressionInformation(...);
270 // break;
273  break;
276  break;
277  case FileAllInformation:
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 
286  BufferLength -= (sizeof(FILE_MODE_INFORMATION) +
287  sizeof(FILE_ACCESS_INFORMATION) +
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) {
345  UDF_CHECK_PAGING_IO_RESOURCE(Fcb->ParentFcb->NTRequiredFCB);
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
437  case FileLinkInformation:
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;
451  RC = UDFSetEOF(IrpSp, Fcb, Ccb, Vcb, FileObject, Irp, (PFILE_END_OF_FILE_INFORMATION)PtrSystemBuffer);
452  break;
453  default:
455  try_return(RC);
456  }
457 #endif //UDF_READ_ONLY_BUILD
458  }
459 
460 try_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) {
476  UDF_CHECK_PAGING_IO_RESOURCE(Fcb->ParentFcb->NTRequiredFCB);
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 
493  if (!_SEH2_AbnormalTermination()) {
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  */
531 NTSTATUS
534  IN PtrUDFFCB Fcb,
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 
597 try_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  */
613 NTSTATUS
615  IN PtrUDFFCB Fcb,
616  IN PFILE_STANDARD_INFORMATION PtrBuffer,
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  */
675 NTSTATUS
677  IN PtrUDFFCB Fcb,
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.
694  RtlZeroMemory(PtrBuffer, sizeof(FILE_NETWORK_OPEN_INFORMATION));
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 
731 try_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  */
746 NTSTATUS
748  PtrUDFIrpContext PtrIrpContext,
749  IN PtrUDFFCB Fcb,
750  IN PtrUDFCCB Ccb,
751  IN PFILE_INTERNAL_INFORMATION PtrBuffer,
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 
786 try_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  */
800 NTSTATUS
802  PtrUDFIrpContext PtrIrpContext,
803  IN PtrUDFFCB Fcb,
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 
821 try_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  */
835 NTSTATUS
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  */
868 NTSTATUS
870  IN PtrUDFFCB Fcb,
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) {
891  return(STATUS_BUFFER_OVERFLOW);
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  */
909 NTSTATUS
912  IN PFILE_POSITION_INFORMATION PtrBuffer,
913  IN OUT PLONG PtrReturnedLength
914  )
915 {
916  if(*PtrReturnedLength < (LONG)sizeof(FILE_POSITION_INFORMATION)) {
917  return(STATUS_BUFFER_OVERFLOW);
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  */
929 NTSTATUS
931  IN PtrUDFFCB Fcb,
932  IN PFILE_STREAM_INFORMATION PtrBuffer,
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 
994 try_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  */
1012 NTSTATUS
1014  IN PtrUDFFCB Fcb,
1015  IN PtrUDFCCB Ccb,
1017  IN PFILE_BASIC_INFORMATION PtrBuffer)
1018 {
1019  NTSTATUS RC = STATUS_SUCCESS;
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 
1129 try_exit: NOTHING;
1130  } _SEH2_FINALLY {
1131  ;
1132  } _SEH2_END;
1133  return(RC);
1134 } // end UDFSetBasicInformation()
1135 
1136 NTSTATUS
1138  IN PVCB Vcb,
1139  IN PtrUDFFCB Fcb,
1140  IN BOOLEAN ForDel
1141  )
1142 {
1143  NTSTATUS RC = STATUS_SUCCESS;
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) {
1256  if(UDFCleanUpFile__(Vcb, 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 
1306 try_exit: NOTHING;
1307 
1308  } _SEH2_FINALLY {
1309  if(FileInfo) {
1311  if(UDFCleanUpFile__(Vcb, 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  */
1339 NTSTATUS
1341  IN PtrUDFFCB Fcb,
1342  IN PtrUDFCCB Ccb,
1343  IN PVCB Vcb,
1345  IN BOOLEAN Delete
1346  )
1347 {
1348  NTSTATUS RC = STATUS_SUCCESS;
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 
1441 try_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  */
1453 NTSTATUS
1455  IN PtrUDFFCB Fcb,
1456  IN PtrUDFCCB Ccb,
1457  IN PVCB Vcb,
1459  IN PtrUDFIrpContext PtrIrpContext,
1460  IN PIRP Irp,
1462  )
1463 {
1464  NTSTATUS RC = STATUS_SUCCESS;
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 
1607 try_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  */
1626 NTSTATUS
1628  IN PIO_STACK_LOCATION PtrSp,
1629  IN PtrUDFFCB Fcb,
1630  IN PtrUDFCCB Ccb,
1631  IN PVCB Vcb,
1633  IN PIRP Irp,
1635  )
1636 {
1637  NTSTATUS RC = STATUS_SUCCESS;
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();
1672  try_return(RC = STATUS_SUCCESS);
1673  } else
1674 #endif // UDF_DBG
1675  try_return(RC = STATUS_SUCCESS);
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 
1847 notify_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 
1865 try_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 
1881 NTSTATUS
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  */
1960 NTSTATUS
1962  IN PIO_STACK_LOCATION PtrSp,
1963  IN PtrUDFFCB Fcb1,
1964  IN PtrUDFCCB Ccb1,
1965  IN PFILE_OBJECT FileObject1, // Source File
1966  IN PFILE_RENAME_INFORMATION PtrBuffer
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;
1995  PLIST_ENTRY Link;
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
2075  RC = STATUS_ACCESS_DENIED;
2076 post_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;
2082  try_return (RC = STATUS_PENDING);
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))
2151  UDFAttributesToUDF(DirNdx, File1->Dloc->FileEntry, 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)) {
2299 insuf_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 
2339 try_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 
2379 LONG
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 
2392 LONG
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 
2416 NTSTATUS
2418  IN PVCB Vcb,
2419  IN PtrUDFCCB Ccb,
2420  IN PUDF_FILE_INFO fi,
2421  IN LONGLONG Id
2422  )
2423 {
2424  LONG i;
2425  NTSTATUS RC = STATUS_SUCCESS;
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 
2441 NTSTATUS
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 
2455 VOID
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 
2471 NTSTATUS
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  */
2493 NTSTATUS
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 
2673 try_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
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1294
int __inline UDFInterlockedExchangeAdd(PLONG addr, LONG i)
Definition: env_spec_w32.h:681
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
signed char * PCHAR
Definition: retypes.h:7
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
UNICODE_STRING FName
Definition: udf_rel.h:173
LONGLONG CreationTime
Definition: cdstruc.h:1036
BOOLEAN NTAPI MmCanFileBeTruncated(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN PLARGE_INTEGER NewFileSize)
Definition: section.c:4724
UNICODE_STRING UnicodeStrRoot
Definition: udf_common.h:616
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:921
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
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
VOID __fastcall UDFReleaseObjectName(PtrUDFObjectName PtrObjectName)
Definition: misc.cpp:670
#define IN
Definition: typedefs.h:38
struct _FILE_INTERNAL_INFORMATION FILE_INTERNAL_INFORMATION
#define ASSERT_REF(_a_)
Definition: udf_dbg.h:267
NTSTATUS UDFGetOpenParamsByFileId(IN PVCB Vcb, IN LONGLONG Id, OUT PUNICODE_STRING *FName, OUT BOOLEAN *CaseSens)
Definition: fileinfo.cpp:2472
struct _FILE_BOTH_DIR_INFORMATION * PFILE_BOTH_DIR_INFORMATION
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define UDFRemoveFromDelayedQueue(Fcb)
Definition: protos.h:106
struct _UDFContextControlBlock * PtrUDFCCB
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
FILE_POSITION_INFORMATION PositionInformation
Definition: winternl.h:801
#define FsRtlEnterFileSystem
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:61
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
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
#define FILE_ACTION_RENAMED_OLD_NAME
ULONG UDFCleanUpFcbChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: close.cpp:400
UNICODE_STRING ObjectName
Definition: struct.h:94
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define FsRtlExitFileSystem
__inline OSSTATUS UDFFindFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN PUNICODE_STRING Name, IN PUDF_FILE_INFO DirInfo)
Definition: udf_info.h:114
#define UDF_NAME_LEN
Definition: osta_misc.h:314
USHORT MaximumLength
Definition: env_spec_w32.h:370
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
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:1458
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
int64 __fastcall UDFGetFreeSpace(IN PVCB Vcb)
Definition: alloc.cpp:1105
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
_In_ PIRP Irp
Definition: csq.h:116
#define UDF_FCB_DELETE_PARENT
Definition: struct.h:319
#define UDF_FCB_POSTED_RENAME
Definition: struct.h:317
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
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
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define UDF_CCB_ATTRIBUTES_SET
Definition: struct.h:157
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
ULONG FileAttributes
Definition: cdstruc.h:983
PDIR_INDEX_HDR DirIndex
Definition: udf_rel.h:312
LONG NTSTATUS
Definition: precomp.h:26
ULONG MyReallocPool__(PCHAR addr, ULONG len, PCHAR *pnewaddr, ULONG newlen)
Definition: mem_tools.h:224
NTSTATUS UDFGetEaInformation(PtrUDFIrpContext PtrIrpContext, IN PtrUDFFCB Fcb, IN PFILE_EA_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:801
#define UDF_FCB_DELETE_ON_CLOSE
Definition: struct.h:309
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
NTSTATUS UDFFileDirInfoToNT(IN PVCB Vcb, IN PDIR_INDEX_ITEM FileDirNdx, OUT PFILE_BOTH_DIR_INFORMATION NTFileInfo)
#define UDF_VCB_IC_UPDATE_UCHG_DIR_ACCESS_TIME
Definition: udf_common.h:500
#define UDF_CCB_CASE_SENSETIVE
Definition: struct.h:159
Definition: cdstruc.h:504
#define FILE_NOTIFY_CHANGE_SIZE
struct _FILE_EA_INFORMATION FILE_EA_INFORMATION
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define UDFReferenceFileEx__(fi, i)
Definition: udf_info.h:1052
NTSTATUS UDFMarkStreamsForDeletion(IN PVCB Vcb, IN PtrUDFFCB Fcb, IN BOOLEAN ForDel)
Definition: fileinfo.cpp:1137
#define FILE_NOTIFY_CHANGE_FILE_NAME
int64 UDFGetFileSize(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1236
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:1523
PUDF_DATALOC_INFO Dloc
Definition: udf_rel.h:367
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSTATUS UDFCheckAccessRights(PFILE_OBJECT FileObject, PACCESS_STATE AccessState, PtrUDFFCB Fcb, PtrUDFCCB Ccb, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
Definition: secursup.cpp:927
void Replace(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LONG radius)
Definition: drawing.cpp:134
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1735
void UDFSetFileSizeInDirNdx(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 *ASize)
Definition: udf_info.cpp:1190
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION
#define DeleteFile
Definition: winbase.h:3581
#define FILE_NOTIFY_CHANGE_DIR_NAME
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
NTSTATUS UDFGetBasicInformation(IN PFILE_OBJECT FileObject, IN PtrUDFFCB Fcb, IN PFILE_BASIC_INFORMATION PtrBuffer, IN OUT LONG *PtrReturnedLength)
Definition: fileinfo.cpp:532
static int Link(const char **args)
Definition: vfdcmd.c:2414
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3167
struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION
uint32 uint_di
Definition: udf_rel.h:29
#define FILE_NOTIFY_CHANGE_STREAM_SIZE
#define UDF_CCB_MODIFY_TIME_SET
Definition: struct.h:154
_SEH2_TRY
Definition: create.c:4250
DWORD Id
NTSTATUS UDFGetFullNameInformation(IN PFILE_OBJECT FileObject, IN PFILE_NAME_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:836
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
PtrUDFObjectName FCBName
Definition: struct.h:286
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1746
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define FO_FILE_MODIFIED
Definition: iotypes.h:1745
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
LARGE_INTEGER LastAccessTime
Definition: fatstruc.h:920
#define FILE_DELETE_CHILD
Definition: nt_native.h:645
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:1092
long LONG
Definition: pedump.c:60
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define UDFIsADirectory(FileInfo)
Definition: udf_info.h:792
#define UDF_CCB_CLEANED
Definition: struct.h:146
#define FILE_ACTION_MODIFIED
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
LARGE_INTEGER AllocationSize
Definition: from_kernel.h:146
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
struct _FILE_STREAM_INFORMATION FILE_STREAM_INFORMATION
#define FILE_ACTION_MODIFIED_STREAM
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define UDFInterlockedDecrement(addr)
Definition: env_spec_w32.h:677
#define TmPrint(_x_)
Definition: env_spec_w32.h:290
smooth NULL
Definition: ftsmooth.c:416
#define FILE_ACTION_REMOVED
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
NTSTATUS UDFSetBasicInformation(IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PFILE_OBJECT FileObject, IN PFILE_BASIC_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:1013
#define IoCompleteRequest
Definition: irp.c:1240
LARGE_INTEGER CurrentByteOffset
Definition: nt_native.h:955
WCHAR * ObjectName
Definition: ntfs.h:520
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:697
uint32 IrpContextFlags
Definition: struct.h:364
int64 LastAccessTime
Definition: udf_rel.h:211
#define UDF_FE_FLAG_FE_MODIFIED
Was modified & should be flushed.
Definition: udf_rel.h:323
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
__inline VOID UDFNotifyFullReportChange(PVCB V, PUDF_FILE_INFO FI, ULONG E, ULONG A)
Definition: env_spec.h:99
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define FILE_NOTIFY_CHANGE_CREATION
OSSTATUS UDFOpenStreamDir__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, OUT PUDF_FILE_INFO *_SDirInfo)
Definition: udf_info.cpp:4965
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
#define UDFIsAStreamDir(FI)
Definition: udf_info.h:998
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
r l[0]
Definition: byte_order.h:167
#define UDF_CCB_CREATE_TIME_SET
Definition: struct.h:155
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
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
int64_t LONGLONG
Definition: typedefs.h:66
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
#define UDFConvertExclusiveToSharedLite(Resource)
Definition: env_spec_w32.h:665
struct _FILE_MODE_INFORMATION FILE_MODE_INFORMATION
#define STATUS_NOT_FOUND
Definition: shellext.h:67
NTSTATUS UDFGetPositionInformation(IN PFILE_OBJECT FileObject, IN PFILE_POSITION_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:910
#define UDF_VCB_SKIP_EJECT_CHECK
Definition: udf_common.h:470
VOID UDFReleaseFileIdCache(IN PVCB Vcb)
Definition: fileinfo.cpp:2456
#define UDFRemoveFromSystemDelayedQueue(Fcb)
Definition: protos.h:109
#define d
Definition: ke_i.h:81
NTSTATUS MyCloneUnicodeString(IN PUNICODE_STRING Str1, IN PUNICODE_STRING Str2)
int64 CreationTime
Definition: udf_rel.h:209
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint_di Index
Definition: udf_rel.h:392
#define STATUS_PENDING
Definition: ntstatus.h:82
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:193
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4798
#define try_return(S)
Definition: cdprocs.h:2189
NTSTATUS UDFGetStandardInformation(IN PtrUDFFCB Fcb, IN PFILE_STANDARD_INFORMATION PtrBuffer, IN OUT LONG *PtrReturnedLength)
Definition: fileinfo.cpp:614
struct _FILE_ALL_INFORMATION * PFILE_ALL_INFORMATION
#define UDF_VCB_IC_UPDATE_ARCH_BIT
Definition: udf_common.h:496
#define Vcb
Definition: cdprocs.h:1425
#define UDFCloseAllDelayedInDir(Vcb, FI)
Definition: protos.h:96
struct _FILE_ALIGNMENT_INFORMATION FILE_ALIGNMENT_INFORMATION
#define MyFreePool__(addr)
Definition: mem_tools.h:152
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define BrutePoint()
Definition: env_spec_w32.h:504
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
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
NTSTATUS UDFCommonFileInfo(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: fileinfo.cpp:114
VOID UDFSetFileXTime(IN PUDF_FILE_INFO FileInfo, IN LONGLONG *CrtTime, IN LONGLONG *AccTime, IN LONGLONG *AttrTime, IN LONGLONG *ChgTime)
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
NTSTATUS UDFSetDispositionInformation(IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN BOOLEAN Delete)
Definition: fileinfo.cpp:1340
* PFILE_OBJECT
Definition: iotypes.h:1955
struct _UDF_FILE_INFO * ParentFile
Definition: udf_rel.h:381
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
#define UDF_FCB_ROOT_DIRECTORY
Definition: struct.h:304
NTSTATUS UDFStoreFileId(IN PVCB Vcb, IN PtrUDFCCB Ccb, IN PUDF_FILE_INFO fi, IN LONGLONG Id)
Definition: fileinfo.cpp:2417
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
int64 ChangeTime
Definition: udf_rel.h:212
#define NtReqFcb
NTSTATUS UDFGetAltNameInformation(IN PtrUDFFCB Fcb, IN PFILE_NAME_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:869
#define STATUS_CANNOT_DELETE
Definition: shellext.h:66
PDIR_INDEX_ITEM UDFDirIndexScan(PUDF_DIR_SCAN_CONTEXT Context, PUDF_FILE_INFO *_FileInfo)
Definition: dirtree.cpp:378
#define UDF_NTREQ_FCB_DELETED
Definition: struct.h:235
char * PBOOLEAN
Definition: retypes.h:11
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define UDFIsSDirDeleted(FI)
Definition: udf_info.h:1004
#define UDF_FCB_DELETED
Definition: struct.h:314
#define MEM_USREN2_TAG
Definition: fileinfo.cpp:24
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
FILE_EA_INFORMATION EaInformation
Definition: winternl.h:799
static const WCHAR L[]
Definition: oid.c:1250
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define UDFIsDirEmpty__(fi)
Definition: udf_info.h:1070
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
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
#define FILE_ACTION_RENAMED_NEW_NAME
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
FILE_NAME_INFORMATION NameInformation
Definition: winternl.h:804
ULONG LowPart
Definition: typedefs.h:104
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:556
Definition: typedefs.h:117
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
#define UDFDOSName__(Vcb, DosName, UdfName, FileInfo)
Definition: udf_info.h:217
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
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
#define UDF_FCB_PAGE_FILE
Definition: struct.h:302
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
VOID UDFFlushTryBreak(IN PVCB Vcb)
Definition: flush.cpp:625
#define FSRTL_FAST_IO_TOP_LEVEL_IRP
Definition: fsrtltypes.h:62
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
#define UDF_CCB_ACCESS_TIME_SET
Definition: struct.h:153
#define FILE_ID_CACHE_GRANULARITY
Definition: udf_common.h:653
int64 LastWriteTime
Definition: udf_rel.h:210
PtrUDFObjectName UDFAllocateObjectName(VOID)
Definition: misc.cpp:611
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible(IN PtrUDFFCB Fcb)
Definition: fastio.cpp:118
uint8 MinorFunction
Definition: struct.h:368
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
#define UDFIsDirOpened__(fi)
Definition: udf_info.h:1071
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
VOID UDFAttributesToUDF(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry, IN ULONG NTAttr)
_SEH2_END
Definition: create.c:4424
NTSTATUS UDFGetNetworkInformation(IN PtrUDFFCB Fcb, IN PFILE_NETWORK_OPEN_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:676
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
#define FILE_NOTIFY_CHANGE_EA
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:284
#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 FO_CLEANUP_COMPLETE
Definition: iotypes.h:1747
#define FO_TEMPORARY_FILE
Definition: iotypes.h:1748
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:354
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:262
OSSTATUS UDFResizeFile__(IN PVCB Vcb, IN OUT PUDF_FILE_INFO FileInfo, IN int64 NewLength)
Definition: udf_info.cpp:3468
struct _FCB::@693::@696 Fcb
#define UDF_FCB_READ_ONLY
Definition: struct.h:312
struct _UDF_FILE_INFO * FileInfo
Definition: udf_rel.h:204
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
NTSTATUS NTAPI UDFFileInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: fileinfo.cpp:46
_SEH2_FINALLY
Definition: create.c:4395
#define UDF_CCB_WRITE_TIME_SET
Definition: struct.h:156
#define min(a, b)
Definition: monoChain.cc:55
#define MEM_USREN_TAG
Definition: fileinfo.cpp:23
ULONG UDFAttributesToNT(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry)
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define IRP_PAGING_IO
int64 UDFGetFileSizeFromDirNdx(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1256
#define FILE_ACTION_ADDED
#define FileStandardInformation
Definition: propsheet.cpp:61
NTSTATUS UDFRemoveFileId(IN PVCB Vcb, IN LONGLONG Id)
Definition: fileinfo.cpp:2442
LONG UDFFindFileId(IN PVCB Vcb, IN LONGLONG Id)
Definition: fileinfo.cpp:2380
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203
struct _FILE_POSITION_INFORMATION * PFILE_POSITION_INFORMATION
#define OUT
Definition: typedefs.h:39
struct FileInfo FileInfo
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
BOOLEAN UDFDirIndexInitScan(IN PUDF_FILE_INFO DirInfo, OUT PUDF_DIR_SCAN_CONTEXT Context, IN uint_di Index)
Definition: dirtree.cpp:347
NTSTATUS UDFGetFileStreamInformation(IN PtrUDFFCB Fcb, IN PFILE_STREAM_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:930
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
unsigned int ULONG
Definition: retypes.h:1
FILE_BASIC_INFORMATION BasicInformation
Definition: winternl.h:796
ERESOURCE PagingIoResource
Definition: ntfs.h:523
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS UDFGetInternalInformation(PtrUDFIrpContext PtrIrpContext, IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PFILE_INTERNAL_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:747
PVCB Vcb
Definition: cdstruc.h:939
struct _FCB * ParentFcb
Definition: cdstruc.h:946
BOOLEAN UDFAcquireResourceExclusiveWithCheck(IN PERESOURCE Resource)
Definition: misc.cpp:2529
#define UDFDirIndexGetLastIndex(di)
Definition: udf_info.h:1122
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define UDFHasAStreamDir(FI)
Definition: udf_info.h:1000
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
FILE_INTERNAL_INFORMATION InternalInformation
Definition: winternl.h:798
struct _UDFFileControlBlock * Fcb
Definition: udf_rel.h:362
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
_In_ PFCB Fcb
Definition: cdprocs.h:151
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
#define MEM_USHL_TAG
Definition: fileinfo.cpp:26
uint8 FI_Flags
Definition: udf_rel.h:199
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define UDFIsAStream(FI)
Definition: udf_info.h:1002
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
uint8 MajorFunction
Definition: struct.h:366
signed int * PLONG
Definition: retypes.h:5
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID _Out_ PIO_STATUS_BLOCK _In_ ULONG NotifyFilter
Definition: zwfuncs.h:500
#define UDFIsDeleted(DirNdx)
Definition: udf_info.h:788
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
#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
LONG UDFFindFreeFileId(IN PVCB Vcb, IN LONGLONG Id)
Definition: fileinfo.cpp:2393
uint16 UDFGetFileLinkCount(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1355
#define UDF_NTREQ_FCB_MODIFIED
Definition: struct.h:236
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
#define UDF_VCB_IC_UPDATE_DIR_WRITE
Definition: udf_common.h:497
FILE_STANDARD_INFORMATION StandardInformation
Definition: winternl.h:797
uint32 RefCount
Definition: udf_rel.h:399